function IntersectionObserver(callback, opt_options) {
    var options = opt_options || {}

    if (typeof callback != 'function') {
      throw new Error('callback must be a function')
    }

    if (
      options.root &&
      options.root.nodeType != 1 &&
      options.root.nodeType != 9
    ) {
      throw new Error('root must be a Document or Element')
    }

    // Binds and throttles `this._checkForIntersections`.
    this._checkForIntersections = throttle(
      this._checkForIntersections.bind(this),
      this.THROTTLE_TIMEOUT
    )

    // Private properties.
    this._callback = callback
    this._observationTargets = []
    this._queuedEntries = []
    this._rootMarginValues = this._parseRootMargin(options.rootMargin)

    // Public properties.
    this.thresholds = this._initThresholds(options.threshold)
    this.root = options.root || null
    this.rootMargin = this._rootMarginValues
      .map(function (margin) {
        return margin.value + margin.unit
      })
      .join(' ')

    /** @private @const {!Array<!Document>} */
    this._monitoringDocuments = []
    /** @private @const {!Array<function()>} */
    this._monitoringUnsubscribes = []
  }
Creates the global IntersectionObserver constructor.
https://w3c.github.io/IntersectionObserver/#intersection-observer-interface
@param {Function} callback The function to be invoked after intersection
    changes have queued. The function is not invoked if the queue has
    been emptied by calling the `takeRecords` method.
@param {Object=} opt_options Optional configuration options.
@constructor