Computes intersection rectangle between two rectangles.

@param {ClientRect} rootRect - Rectangle of container element.
@param {ClientRect} targetRect - Rectangle of target element.
@returns {ClientRect} Intersection rectangle.
507198
function computeIntersection(rootRect, targetRect) {
    const left      = Math.max(targetRect.left, rootRect.left);
    const right     = Math.min(targetRect.right, rootRect.right);
    const top       = Math.max(targetRect.top, rootRect.top);
    const bottom    = Math.min(targetRect.bottom, rootRect.bottom);

    const width = right - left;
    const height = bottom - top;

    return createRectangle(left, top, width, height);
}
287090
public void drawRect(double[] topLeft, double[] rightBottom) {
        if (!(projection instanceof Projection2D)) {
            throw new UnsupportedOperationException("Only 2D graphics supports drawing rectangles.");
        }

        int[] sc = projection.screenProjection(topLeft);
        int[] sc2 = projection.screenProjection(rightBottom);

        g2d.drawRect(sc[0], sc[1], sc2[0] - sc[0], sc2[1] - sc[1]);
    }
1192461
function _getBoundingRect (rects) {
  var bounds = {
    left: Number.POSITIVE_INFINITY,
    top: Number.POSITIVE_INFINITY,
    right: Number.NEGATIVE_INFINITY,
    bottom: Number.NEGATIVE_INFINITY,
    width: Number.NaN,
    height: Number.NaN
  }

  forEach(rects, function (rect) {
    if (rect.left < bounds.left) {
      bounds.left = rect.left
    }
    if (rect.top < bounds.top) {
      bounds.top = rect.top
    }
    if (rect.left + rect.width > bounds.right) {
      bounds.right = rect.left + rect.width
    }
    if (rect.top + rect.height > bounds.bottom) {
      bounds.bottom = rect.top + rect.height
    }
  })
  bounds.width = bounds.right - bounds.left
  bounds.height = bounds.bottom - bounds.top
  return bounds
}
1232070
function contentOverlapping(targetElement, bgNode) {
	// get content box of target element
	// check to see if the current bgNode is overlapping
	var targetRect = targetElement.getClientRects()[0];
	var obscuringElements = dom.shadowElementsFromPoint(
		targetRect.left,
		targetRect.top
	);
	if (obscuringElements) {
		for (var i = 0; i < obscuringElements.length; i++) {
			if (
				obscuringElements[i] !== targetElement &&
				obscuringElements[i] === bgNode
			) {
				return true;
			}
		}
	}
	return false;
}
154220
function(rectangle) {
        var topLeft = this.viewport.pixelFromPointNoRotate(rectangle.getTopLeft(), true);
        var size = this.viewport.deltaPixelsFromPointsNoRotate(rectangle.getSize(), true);

        return new $.Rect(
            topLeft.x * $.pixelDensityRatio,
            topLeft.y * $.pixelDensityRatio,
            size.x * $.pixelDensityRatio,
            size.y * $.pixelDensityRatio
        );
    }
451747
function (element) {
      var bounds = angular.element(element)[0].getBoundingClientRect();
      var isPositiveSizeClientRect = function (rect) {
        return rect && (rect.width > 0) && (rect.height > 0);
      };

      // If the event origin element has zero size, it has probably been hidden.
      return isPositiveSizeClientRect(bounds) ? self.copyRect(bounds) : null;
    }
796612
function getOverlapTrapezoid(x1, y1, x2, y2) {
    var factor = 2 / (widthTop + widthBottom); // correction for surface=1
    if (y1 === 0 || y2 === 0) return 0;
    if (x1 === x2) { // they have the same position
      return Math.min(y1, y2);
    }

    var diff = Math.abs(x1 - x2);
    if (diff >= widthBottom) return 0;
    if (y1 === y2) { // do they have the same height ???
      // we need to find the common length
      if (diff <= widthTop) {
        return (((widthTop + widthBottom) / 2 - diff) * y1) * factor;
      } else if (diff <= widthBottom) {
        return (widthBottom - diff) * y1 / 2 * (diff - widthTop) / (widthBottom - widthTop) * factor;
      }
      return 0;
    } else { // the height are different and not the same position ...
      // we need to consider only one segment to find its intersection

      var small = Math.min(y1, y2);
      var big = Math.max(y1, y2);

      var targets = [
        [[0, 0], [widthSlope, small]],
        [[widthSlope, small], [widthSlope + widthTop, small]],
        [[widthTop + widthSlope, small], [widthBottom, 0]]
      ];
      var segment;
      if ((x1 > x2 && y1 > y2) || (x1 < x2 && y1 < y2)) {
        segment = [[diff, 0], [diff + widthSlope, big]];
      } else {
        segment = [[diff + widthSlope, big], [diff, 0]];
      }


      for (var i = 0; i < 3; i++) {
        var intersection = getIntersection(targets[i], segment);
        if (intersection) {
          switch (i) {
            case 0:
              return small - ((diff * intersection.y / 2)) * factor;
            case 1: // to simplify ...
              //     console.log("           ",widthSlope,small,big,intersection.x)
              return ((widthSlope * small / (2 * big)) * small +
                                (widthTop + widthSlope - intersection.x) * small +
                                widthSlope * small / 2) * factor;
            case 2:
              return ((widthBottom - diff) * intersection.y / 2) * factor;
            default:
              throw new Error(`unexpected intersection value: ${i}`);
          }
        }
      }
    }
    return NaN;
  }
825814
public Rectangle getRect2() {
        verifyPropertyPresence(RECT2);
        //noinspection unchecked
        return mapToRect((Map<String, Object>) getCommandResult().get(RECT2));
    }
1261800
function(rect) {
        var thisBoundingBox = this.getBoundingBox();
        var otherBoundingBox = rect.getBoundingBox();

        var left = Math.min(thisBoundingBox.x, otherBoundingBox.x);
        var top = Math.min(thisBoundingBox.y, otherBoundingBox.y);
        var right = Math.max(
            thisBoundingBox.x + thisBoundingBox.width,
            otherBoundingBox.x + otherBoundingBox.width);
        var bottom = Math.max(
            thisBoundingBox.y + thisBoundingBox.height,
            otherBoundingBox.y + otherBoundingBox.height);

        return new $.Rect(
            left,
            top,
            right - left,
            bottom - top);
    }
1092239
function rectIntersect(r1, r2) {
    var right1 = r1.x + r1.width;
    var bottom1 = r1.y + r1.height;
    var right2 = r2.x + r2.width;
    var bottom2 = r2.y + r2.height;

    var x = Math.max(r1.x, r2.x);
    var y = Math.max(r1.y, r2.y);
    var w = Math.max(Math.min(right1, right2) - x, 0);
    var h = Math.max(Math.min(bottom1, bottom2) - y, 0);
    return {x: x, y: y, width: w, height: h};
}
172777
public Rectangle intersection(Rectangle other) {
		int left = Math.max(this.left, other.left);
		int top = Math.max(this.top, other.top);
		int right = Math.min(this.right, other.right);
		int bottom = Math.min(this.bottom, other.bottom);
		if (right >= left && bottom >= top) {
			int height = bottom - top;
			int width = right - left;
			return new Rectangle(top, left, bottom, right, width, height);
		} else {
			return null;
		}
	}
1185134
function(text, callback) {
    var maxAttempts = 5,
      attempts = 0,

      intersects = function(rect1, rect2) {
        return !(rect1.right < rect2.left ||
          rect1.left > rect2.right ||
          rect1.bottom < rect2.top ||
          rect1.top > rect2.bottom);
      },

      loop = function(text) {
        var intersecting = false,
          index = 0,
          bb,
          pbb,
          last;
        text.each(function() {
          if (index > 0) {
            bb = this.getBoundingClientRect();
            pbb = last.getBoundingClientRect();
            if (intersects(bb, pbb)) {
              callback.bind(this)(pbb, bb);
              intersecting = true;
            }
          }
          index++;
          last = this;
        });

        if (intersecting && attempts < maxAttempts) {
          attempts++;
          loop.bind(this)(text);
        }
      };
    loop.bind(this)(text);
  }
1302123
function recursiveMerge (target, src) {
    for (var prop in src) {
        if (src.hasOwnProperty(prop)) {
            if (target.prototype && target.prototype.constructor === target) {
                // If the target object is a constructor override off prototype.
                clobber(target.prototype, prop, src[prop]);
            } else {
                if (typeof src[prop] === 'object' && typeof target[prop] === 'object') {
                    recursiveMerge(target[prop], src[prop]);
                } else {
                    clobber(target, prop, src[prop]);
                }
            }
        }
    }
}
806262
function(obj) {
                if (obj.normal || (obj.start && obj.end)) { return obj.intersectionWith(this); }
                if (!this.intersects(obj)) { return null; }
                var P = this.anchor.elements, X = this.direction.elements,
                    Q = obj.anchor.elements, Y = obj.direction.elements;
                var X1 = X[0], X2 = X[1], X3 = X[2], Y1 = Y[0], Y2 = Y[1], Y3 = Y[2];
                var PsubQ1 = P[0] - Q[0], PsubQ2 = P[1] - Q[1], PsubQ3 = P[2] - Q[2];
                var XdotQsubP = - X1*PsubQ1 - X2*PsubQ2 - X3*PsubQ3;
                var YdotPsubQ = Y1*PsubQ1 + Y2*PsubQ2 + Y3*PsubQ3;
                var XdotX = X1*X1 + X2*X2 + X3*X3;
                var YdotY = Y1*Y1 + Y2*Y2 + Y3*Y3;
                var XdotY = X1*Y1 + X2*Y2 + X3*Y3;
                var k = (XdotQsubP * YdotY / XdotX + XdotY * YdotPsubQ) / (YdotY - XdotY * XdotY);
                return vector.create([P[0] + k*X1, P[1] + k*X2, P[2] + k*X3]);
              }
669819
function (rect, obj, root) {
    var hitStack = []; // Contains the elements that overlap
    var countStack = []; // Contains the elements that overlap
    var retArray = [];
    var currentDepth = 1;
    var tree, i, ltree;
    if (!rect || !rectangle.overlapRectangle(rect, root)) {
      return retArray;
    }
    var retObj = {x: rect.x, y: rect.y, w: rect.w, h: rect.h, target: obj};

    countStack.push(root.nodes.length);
    hitStack.push(root);
    while (hitStack.length > 0) {
      tree = hitStack.pop();
      i = countStack.pop() - 1;
      if ('target' in retObj) { // will this ever be false?
        while (i >= 0) {
          ltree = tree.nodes[i];
          if (rectangle.overlapRectangle(retObj, ltree)) {
            if ((retObj.target && 'leaf' in ltree && ltree.leaf === retObj.target) || (!retObj.target && ('leaf' in ltree || rectangle.containsRectangle(ltree, retObj)))) {
              // A Match !!
            // Yup we found a match...
            // we can cancel search and start walking up the list
              if ('nodes' in ltree) {// If we are deleting a node not a leaf...
                retArray = flatten(tree.nodes.splice(i, 1));
              } else {
                retArray = tree.nodes.splice(i, 1);
              }
              // Resize MBR down...
              rectangle.makeMBR(tree.nodes, tree);
              delete retObj.target;
              //if (tree.nodes.length < minWidth) { // Underflow
              //  retObj.nodes = searchSubtree(tree, true, [], tree);
              //}
              break;
            } else if ('nodes' in ltree) { // Not a Leaf
              currentDepth++;
              countStack.push(i);
              hitStack.push(tree);
              tree = ltree;
              i = ltree.nodes.length;
            }
          }
          i--;
        }

      } else if ('nodes' in retObj) { // We are unsplitting

        tree.nodes.splice(i + 1, 1); // Remove unsplit node
        if (tree.nodes.length > 0) {
          rectangle.makeMBR(tree.nodes, tree);
        }
        for (var t = 0;t < retObj.nodes.length;t++) {
          insertSubtree(retObj.nodes[t], tree);
        }
        retObj.nodes = [];
        if (hitStack.length === 0 && tree.nodes.length <= 1) { // Underflow..on root!
          retObj.nodes = searchSubtree(tree, true, retObj.nodes, tree);
          tree.nodes = [];
          hitStack.push(tree);
          countStack.push(1);
        } else if (hitStack.length > 0 && tree.nodes.length < minWidth) { // Underflow..AGAIN!
          retObj.nodes = searchSubtree(tree, true, retObj.nodes, tree);
          tree.nodes = [];
        } else {
          delete retObj.nodes; // Just start resizing
        }
      } else { // we are just resizing
        rectangle.makeMBR(tree.nodes, tree);
      }
      currentDepth -= 1;
    }
    return retArray;
  }
1034681
function(rectangle) {
        return $.Rect.fromSummits(
            this.pixelFromPoint(rectangle.getTopLeft(), true),
            this.pixelFromPoint(rectangle.getTopRight(), true),
            this.pixelFromPoint(rectangle.getBottomLeft(), true)
        );
    }
889711
function getElementBoundingRect(elementSelector) {
    /**
     * @param {Window} win
     * @param {Object} [dims]
     * @returns {Object}
     */
    function computeFrameOffset(win, dims) {
        // initialize our result variable
        dims = dims || {
            left: win.pageXOffset,
            top: win.pageYOffset
        };

        // add the offset & recurse up the frame chain
        var frame = win.frameElement;
        if (frame) {
            var rect = frame.getBoundingClientRect();
            dims.left += rect.left + frame.contentWindow.pageXOffset;
            dims.top += rect.top + frame.contentWindow.pageYOffset;

            if (win !== window.top) {
                computeFrameOffset(win.parent, dims);
            }
        }

        return dims;
    }

    /**
     * @param {HTMLElement} element
     * @param {Object} frameOffset
     * @returns {Object}
     */
    function computeElementRect(element, frameOffset) {
        var rect = element.getBoundingClientRect();

        return {
            left: rect.left + frameOffset.left,
            right: rect.right + frameOffset.left,
            top: rect.top + frameOffset.top,
            bottom: rect.bottom + frameOffset.top,
            width: rect.width,
            height: rect.height
        };
    }

    var element = document.querySelectorAll(elementSelector)[0];
    if (element) {
        var frameOffset = computeFrameOffset(window);
        var elementRect = computeElementRect(element, frameOffset);

        return elementRect;
    }
}