function CesiumInspectorViewModel(scene, performanceContainer) {
  //>>includeStart('debug', pragmas.debug);
  if (!defined(scene)) {
    throw new DeveloperError("scene is required");
  }

  if (!defined(performanceContainer)) {
    throw new DeveloperError("performanceContainer is required");
  }
  //>>includeEnd('debug');

  const that = this;
  const canvas = scene.canvas;
  const eventHandler = new ScreenSpaceEventHandler(canvas);
  this._eventHandler = eventHandler;
  this._scene = scene;
  this._canvas = canvas;
  this._primitive = undefined;
  this._tile = undefined;
  this._modelMatrixPrimitive = undefined;
  this._performanceDisplay = undefined;
  this._performanceContainer = performanceContainer;

  const globe = this._scene.globe;
  globe.depthTestAgainstTerrain = true;

  /**
   * Gets or sets the show frustums state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.frustums = false;

  /**
   * Gets or sets the show frustum planes state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.frustumPlanes = false;

  /**
   * Gets or sets the show performance display state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.performance = false;

  /**
   * Gets or sets the shader cache text.  This property is observable.
   * @type {string}
   * @default ''
   */
  this.shaderCacheText = "";

  /**
   * Gets or sets the show primitive bounding sphere state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.primitiveBoundingSphere = false;

  /**
   * Gets or sets the show primitive reference frame state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.primitiveReferenceFrame = false;

  /**
   * Gets or sets the filter primitive state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.filterPrimitive = false;

  /**
   * Gets or sets the show tile bounding sphere state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.tileBoundingSphere = false;

  /**
   * Gets or sets the filter tile state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.filterTile = false;

  /**
   * Gets or sets the show wireframe state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.wireframe = false;

  /**
   * Gets or sets the index of the depth frustum to display.  This property is observable.
   * @type {number}
   * @default 1
   */
  this.depthFrustum = 1;
  this._numberOfFrustums = 1;

  /**
   * Gets or sets the suspend updates state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.suspendUpdates = false;

  /**
   * Gets or sets the show tile coordinates state.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.tileCoordinates = false;

  /**
   * Gets or sets the frustum statistic text.  This property is observable.
   * @type {string}
   * @default ''
   */
  this.frustumStatisticText = false;

  /**
   * Gets or sets the selected tile information text.  This property is observable.
   * @type {string}
   * @default ''
   */
  this.tileText = "";

  /**
   * Gets if a primitive has been selected.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.hasPickedPrimitive = false;

  /**
   * Gets if a tile has been selected.  This property is observable
   * @type {boolean}
   * @default false
   */
  this.hasPickedTile = false;

  /**
   * Gets if the picking primitive command is active.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.pickPrimitiveActive = false;

  /**
   * Gets if the picking tile command is active.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.pickTileActive = false;

  /**
   * Gets or sets if the cesium inspector drop down is visible.  This property is observable.
   * @type {boolean}
   * @default true
   */
  this.dropDownVisible = true;

  /**
   * Gets or sets if the general section is visible.  This property is observable.
   * @type {boolean}
   * @default true
   */
  this.generalVisible = true;

  /**
   * Gets or sets if the primitive section is visible.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.primitivesVisible = false;

  /**
   * Gets or sets if the terrain section is visible.  This property is observable.
   * @type {boolean}
   * @default false
   */
  this.terrainVisible = false;

  /**
   * Gets or sets the index of the depth frustum text.  This property is observable.
   * @type {string}
   * @default ''
   */
  this.depthFrustumText = "";

  knockout.track(this, [
    "frustums",
    "frustumPlanes",
    "performance",
    "shaderCacheText",
    "primitiveBoundingSphere",
    "primitiveReferenceFrame",
    "filterPrimitive",
    "tileBoundingSphere",
    "filterTile",
    "wireframe",
    "depthFrustum",
    "suspendUpdates",
    "tileCoordinates",
    "frustumStatisticText",
    "tileText",
    "hasPickedPrimitive",
    "hasPickedTile",
    "pickPrimitiveActive",
    "pickTileActive",
    "dropDownVisible",
    "generalVisible",
    "primitivesVisible",
    "terrainVisible",
    "depthFrustumText",
  ]);

  this._toggleDropDown = createCommand(function () {
    that.dropDownVisible = !that.dropDownVisible;
  });

  this._toggleGeneral = createCommand(function () {
    that.generalVisible = !that.generalVisible;
  });

  this._togglePrimitives = createCommand(function () {
    that.primitivesVisible = !that.primitivesVisible;
  });

  this._toggleTerrain = createCommand(function () {
    that.terrainVisible = !that.terrainVisible;
  });

  this._frustumsSubscription = knockout
    .getObservable(this, "frustums")
    .subscribe(function (val) {
      that._scene.debugShowFrustums = val;
      that._scene.requestRender();
    });

  this._frustumPlanesSubscription = knockout
    .getObservable(this, "frustumPlanes")
    .subscribe(function (val) {
      that._scene.debugShowFrustumPlanes = val;
      that._scene.requestRender();
    });

  this._performanceSubscription = knockout
    .getObservable(this, "performance")
    .subscribe(function (val) {
      if (val) {
        that._performanceDisplay = new PerformanceDisplay({
          container: that._performanceContainer,
        });
      } else {
        that._performanceContainer.innerHTML = "";
      }
    });

  this._showPrimitiveBoundingSphere = createCommand(function () {
    that._primitive.debugShowBoundingVolume = that.primitiveBoundingSphere;
    that._scene.requestRender();
    return true;
  });

  this._primitiveBoundingSphereSubscription = knockout
    .getObservable(this, "primitiveBoundingSphere")
    .subscribe(function () {
      that._showPrimitiveBoundingSphere();
    });

  this._showPrimitiveReferenceFrame = createCommand(function () {
    if (that.primitiveReferenceFrame) {
      const modelMatrix = that._primitive.modelMatrix;
      that._modelMatrixPrimitive = new DebugModelMatrixPrimitive({
        modelMatrix: modelMatrix,
      });
      that._scene.primitives.add(that._modelMatrixPrimitive);
    } else if (defined(that._modelMatrixPrimitive)) {
      that._scene.primitives.remove(that._modelMatrixPrimitive);
      that._modelMatrixPrimitive = undefined;
    }
    that._scene.requestRender();
    return true;
  });

  this._primitiveReferenceFrameSubscription = knockout
    .getObservable(this, "primitiveReferenceFrame")
    .subscribe(function () {
      that._showPrimitiveReferenceFrame();
    });

  this._doFilterPrimitive = createCommand(function () {
    if (that.filterPrimitive) {
      that._scene.debugCommandFilter = function (command) {
        if (
          defined(that._modelMatrixPrimitive) &&
          command.owner === that._modelMatrixPrimitive._primitive
        ) {
          return true;
        } else if (defined(that._primitive)) {
          return (
            command.owner === that._primitive ||
            command.owner === that._primitive._billboardCollection ||
            command.owner.primitive === that._primitive
          );
        }
        return false;
      };
    } else {
      that._scene.debugCommandFilter = undefined;
    }
    return true;
  });

  this._filterPrimitiveSubscription = knockout
    .getObservable(this, "filterPrimitive")
    .subscribe(function () {
      that._doFilterPrimitive();
      that._scene.requestRender();
    });

  this._wireframeSubscription = knockout
    .getObservable(this, "wireframe")
    .subscribe(function (val) {
      globe._surface.tileProvider._debug.wireframe = val;
      that._scene.requestRender();
    });

  this._depthFrustumSubscription = knockout
    .getObservable(this, "depthFrustum")
    .subscribe(function (val) {
      that._scene.debugShowDepthFrustum = val;
      that._scene.requestRender();
    });

  this._incrementDepthFrustum = createCommand(function () {
    const next = that.depthFrustum + 1;
    that.depthFrustum = boundDepthFrustum(1, that._numberOfFrustums, next);
    that._scene.requestRender();
    return true;
  });

  this._decrementDepthFrustum = createCommand(function () {
    const next = that.depthFrustum - 1;
    that.depthFrustum = boundDepthFrustum(1, that._numberOfFrustums, next);
    that._scene.requestRender();
    return true;
  });

  this._suspendUpdatesSubscription = knockout
    .getObservable(this, "suspendUpdates")
    .subscribe(function (val) {
      globe._surface._debug.suspendLodUpdate = val;
      if (!val) {
        that.filterTile = false;
      }
    });

  let tileBoundariesLayer;
  this._showTileCoordinates = createCommand(function () {
    if (that.tileCoordinates && !defined(tileBoundariesLayer)) {
      tileBoundariesLayer = scene.imageryLayers.addImageryProvider(
        new TileCoordinatesImageryProvider({
          tilingScheme: scene.terrainProvider.tilingScheme,
        }),
      );
    } else if (!that.tileCoordinates && defined(tileBoundariesLayer)) {
      scene.imageryLayers.remove(tileBoundariesLayer);
      tileBoundariesLayer = undefined;
    }
    return true;
  });

  this._tileCoordinatesSubscription = knockout
    .getObservable(this, "tileCoordinates")
    .subscribe(function () {
      that._showTileCoordinates();
      that._scene.requestRender();
    });

  this._tileBoundingSphereSubscription = knockout
    .getObservable(this, "tileBoundingSphere")
    .subscribe(function () {
      that._showTileBoundingSphere();
      that._scene.requestRender();
    });

  this._showTileBoundingSphere = createCommand(function () {
    if (that.tileBoundingSphere) {
      globe._surface.tileProvider._debug.boundingSphereTile = that._tile;
    } else {
      globe._surface.tileProvider._debug.boundingSphereTile = undefined;
    }
    that._scene.requestRender();
    return true;
  });

  this._doFilterTile = createCommand(function () {
    if (!that.filterTile) {
      that.suspendUpdates = false;
    } else {
      that.suspendUpdates = true;

      globe._surface._tilesToRender = [];

      if (defined(that._tile) && that._tile.renderable) {
        globe._surface._tilesToRender.push(that._tile);
      }
    }
    return true;
  });

  this._filterTileSubscription = knockout
    .getObservable(this, "filterTile")
    .subscribe(function () {
      that.doFilterTile();
      that._scene.requestRender();
    });

  function pickPrimitive(e) {
    const newPick = that._scene.pick({
      x: e.position.x,
      y: e.position.y,
    });
    if (defined(newPick)) {
      that.primitive = defined(newPick.collection)
        ? newPick.collection
        : newPick.primitive;
    }

    that._scene.requestRender();
    that.pickPrimitiveActive = false;
  }

  this._pickPrimitive = createCommand(function () {
    that.pickPrimitiveActive = !that.pickPrimitiveActive;
  });

  this._pickPrimitiveActiveSubscription = knockout
    .getObservable(this, "pickPrimitiveActive")
    .subscribe(function (val) {
      if (val) {
        eventHandler.setInputAction(
          pickPrimitive,
          ScreenSpaceEventType.LEFT_CLICK,
        );
      } else {
        eventHandler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
      }
    });

  function selectTile(e) {
    let selectedTile;
    const ellipsoid = globe.ellipsoid;

    const ray = that._scene.camera.getPickRay(e.position, scratchPickRay);
    const cartesian = globe.pick(ray, that._scene, scratchPickCartesian);

    if (defined(cartesian)) {
      const cartographic = ellipsoid.cartesianToCartographic(cartesian);
      const tilesRendered =
        globe._surface.tileProvider._tilesToRenderByTextureCount;
      for (
        let textureCount = 0;
        !selectedTile && textureCount < tilesRendered.length;
        ++textureCount
      ) {
        const tilesRenderedByTextureCount = tilesRendered[textureCount];
        if (!defined(tilesRenderedByTextureCount)) {
          continue;
        }

        for (
          let tileIndex = 0;
          !selectedTile && tileIndex < tilesRenderedByTextureCount.length;
          ++tileIndex
        ) {
          const tile = tilesRenderedByTextureCount[tileIndex];
          if (Rectangle.contains(tile.rectangle, cartographic)) {
            selectedTile = tile;
          }
        }
      }
    }

    that.tile = selectedTile;

    that.pickTileActive = false;
  }

  this._pickTile = createCommand(function () {
    that.pickTileActive = !that.pickTileActive;
  });

  this._pickTileActiveSubscription = knockout
    .getObservable(this, "pickTileActive")
    .subscribe(function (val) {
      if (val) {
        eventHandler.setInputAction(
          selectTile,
          ScreenSpaceEventType.LEFT_CLICK,
        );
      } else {
        eventHandler.removeInputAction(ScreenSpaceEventType.LEFT_CLICK);
      }
    });

  this._removePostRenderEvent = scene.postRender.addEventListener(function () {
    that._update();
  });
}
The view model for {@link CesiumInspector}.
@alias CesiumInspectorViewModel
@constructor

@param {Scene} scene The scene instance to use.
@param {Element} performanceContainer The instance to use for performance container.