function Instrumenter() {
    var _this = this;

    _classCallCheck(this, Instrumenter);

    this.channel = void 0;
    this.initialized = false;
    this.state = void 0;
    this.channel = _storybook_addons__WEBPACK_IMPORTED_MODULE_29__.addons.getChannel(); // Restore state from the parent window in case the iframe was reloaded.

    this.state = (global__WEBPACK_IMPORTED_MODULE_28___default().window.parent.__STORYBOOK_ADDON_INTERACTIONS_INSTRUMENTER_STATE__) || {}; // When called from `start`, isDebugging will be true

    var resetState = function resetState(_ref3) {
      var storyId = _ref3.storyId,
          _ref3$isPlaying = _ref3.isPlaying,
          isPlaying = _ref3$isPlaying === void 0 ? true : _ref3$isPlaying,
          _ref3$isDebugging = _ref3.isDebugging,
          isDebugging = _ref3$isDebugging === void 0 ? false : _ref3$isDebugging;

      var state = _this.getState(storyId);

      _this.setState(storyId, Object.assign({}, getInitialState(), getRetainedState(state, isDebugging), {
        shadowCalls: isDebugging ? state.shadowCalls : [],
        chainedCallIds: isDebugging ? state.chainedCallIds : new Set(),
        playUntil: isDebugging ? state.playUntil : undefined,
        isPlaying: isPlaying,
        isDebugging: isDebugging
      })); // Don't sync while debugging, as it'll cause flicker.


      if (!isDebugging) _this.sync(storyId);
    }; // A forceRemount might be triggered for debugging (on `start`), or elsewhere in Storybook.


    this.channel.on(_storybook_core_events__WEBPACK_IMPORTED_MODULE_30__.FORCE_REMOUNT, resetState); // Start with a clean slate before playing after a remount, and stop debugging when done.

    this.channel.on(_storybook_core_events__WEBPACK_IMPORTED_MODULE_30__.STORY_RENDER_PHASE_CHANGED, function (_ref4) {
      var storyId = _ref4.storyId,
          newPhase = _ref4.newPhase;

      var _this$getState = _this.getState(storyId),
          isDebugging = _this$getState.isDebugging,
          forwardedException = _this$getState.forwardedException;

      _this.setState(storyId, {
        renderPhase: newPhase
      });

      if (newPhase === 'playing') {
        resetState({
          storyId: storyId,
          isDebugging: isDebugging
        });
      }

      if (newPhase === 'played') {
        _this.setState(storyId, {
          isLocked: false,
          isPlaying: false,
          isDebugging: false,
          forwardedException: undefined
        }); // Rethrow any unhandled forwarded exception so it doesn't go unnoticed.


        if (forwardedException) throw forwardedException;
      }
    }); // Trash non-retained state and clear the log when switching stories, but not on initial boot.

    this.channel.on(_storybook_core_events__WEBPACK_IMPORTED_MODULE_30__.SET_CURRENT_STORY, function () {
      if (_this.initialized) _this.cleanup();else _this.initialized = true;
    });

    var start = function start(_ref5) {
      var storyId = _ref5.storyId,
          playUntil = _ref5.playUntil;

      if (!_this.getState(storyId).isDebugging) {
        _this.setState(storyId, function (_ref6) {
          var calls = _ref6.calls;
          return {
            calls: [],
            shadowCalls: calls.map(function (call) {
              return Object.assign({}, call, {
                status: _types__WEBPACK_IMPORTED_MODULE_31__.CallStates.WAITING
              });
            }),
            isDebugging: true
          };
        });
      }

      var log = _this.getLog(storyId);

      _this.setState(storyId, function (_ref7) {
        var _shadowCalls$slice$fi;

        var shadowCalls = _ref7.shadowCalls;
        var firstRowIndex = shadowCalls.findIndex(function (call) {
          return call.id === log[0].callId;
        });
        return {
          playUntil: playUntil || ((_shadowCalls$slice$fi = shadowCalls.slice(0, firstRowIndex).filter(function (call) {
            return call.interceptable;
          }).slice(-1)[0]) === null || _shadowCalls$slice$fi === void 0 ? void 0 : _shadowCalls$slice$fi.id)
        };
      }); // Force remount may trigger a page reload if the play function can't be aborted.


      _this.channel.emit(_storybook_core_events__WEBPACK_IMPORTED_MODULE_30__.FORCE_REMOUNT, {
        storyId: storyId,
        isDebugging: true
      });
    };

    var back = function back(_ref8) {
      var _log;

      var storyId = _ref8.storyId;

      var _this$getState2 = _this.getState(storyId),
          isDebugging = _this$getState2.isDebugging;

      var log = _this.getLog(storyId);

      var next = isDebugging ? log.findIndex(function (_ref9) {
        var status = _ref9.status;
        return status === _types__WEBPACK_IMPORTED_MODULE_31__.CallStates.WAITING;
      }) : log.length;
      start({
        storyId: storyId,
        playUntil: (_log = log[next - 2]) === null || _log === void 0 ? void 0 : _log.callId
      });
    };

    var goto = function goto(_ref10) {
      var storyId = _ref10.storyId,
          callId = _ref10.callId;

      var _this$getState3 = _this.getState(storyId),
          calls = _this$getState3.calls,
          shadowCalls = _this$getState3.shadowCalls,
          resolvers = _this$getState3.resolvers;

      var call = calls.find(function (_ref11) {
        var id = _ref11.id;
        return id === callId;
      });
      var shadowCall = shadowCalls.find(function (_ref12) {
        var id = _ref12.id;
        return id === callId;
      });

      if (!call && shadowCall && Object.values(resolvers).length > 0) {
        var _this$getLog$find;

        var nextId = (_this$getLog$find = _this.getLog(storyId).find(function (c) {
          return c.status === _types__WEBPACK_IMPORTED_MODULE_31__.CallStates.WAITING;
        })) === null || _this$getLog$find === void 0 ? void 0 : _this$getLog$find.callId;
        if (shadowCall.id !== nextId) _this.setState(storyId, {
          playUntil: shadowCall.id
        });
        Object.values(resolvers).forEach(function (resolve) {
          return resolve();
        });
      } else {
        start({
          storyId: storyId,
          playUntil: callId
        });
      }
    };

    var next = function next(_ref13) {
      var storyId = _ref13.storyId;

      var _this$getState4 = _this.getState(storyId),
          resolvers = _this$getState4.resolvers;

      if (Object.values(resolvers).length > 0) {
        Object.values(resolvers).forEach(function (resolve) {
          return resolve();
        });
      } else {
        var _this$getLog$find2;

        var nextId = (_this$getLog$find2 = _this.getLog(storyId).find(function (c) {
          return c.status === _types__WEBPACK_IMPORTED_MODULE_31__.CallStates.WAITING;
        })) === null || _this$getLog$find2 === void 0 ? void 0 : _this$getLog$find2.callId;
        if (nextId) start({
          storyId: storyId,
          playUntil: nextId
        });else end({
          storyId: storyId
        });
      }
    };

    var end = function end(_ref14) {
      var storyId = _ref14.storyId;

      _this.setState(storyId, {
        playUntil: undefined,
        isDebugging: false
      });

      Object.values(_this.getState(storyId).resolvers).forEach(function (resolve) {
        return resolve();
      });
    };

    this.channel.on(EVENTS.START, start);
    this.channel.on(EVENTS.BACK, back);
    this.channel.on(EVENTS.GOTO, goto);
    this.channel.on(EVENTS.NEXT, next);
    this.channel.on(EVENTS.END, end);
  }
This class is not supposed to be used directly. Use the `instrument` function below instead.