/*
Manually send a message to Sentry

@param {string} msg A plain message to be captured in Sentry
@param {object} options A specific set of options for this message [optional]
@return {Raven}
function captureMessage(msg, options) {
	    // config() automagically converts ignoreErrors from a list to a RegExp so we need to test for an
	    // early call; we'll error on the side of logging anything called before configuration since it's
	    // probably something you should see:
	    if (!!this._globalOptions.ignoreErrors.test && this._globalOptions.ignoreErrors.test(msg)) {
	      return;
	    }

	    options = options || {};
	    msg = msg + ''; // Make sure it's actually a string

	    var data = objectMerge$1({
	      message: msg
	    }, options);
	    var ex; // Generate a "synthetic" stack trace from this point.
	    // NOTE: If you are a Sentry user, and you are seeing this stack frame, it is NOT indicative
	    //       of a bug with Raven.js. Sentry generates synthetic traces either by configuration,
	    //       or if it catches a thrown object without a "stack" property.

	    try {
	      throw new Error(msg);
	    } catch (ex1) {
	      ex = ex1;
	    } // null exception name so `Error` isn't prefixed to msg


	    ex.name = null;
	    var stack = tracekit.computeStackTrace(ex); // stack[0] is `throw new Error(msg)` call itself, we are interested in the frame that was just before that, stack[1]

	    var initialCall = isArray$1(stack.stack) && stack.stack[1]; // if stack[1] is `Raven.captureException`, it means that someone passed a string to it and we redirected that call
	    // to be handled by `captureMessage`, thus `initialCall` is the 3rd one, not 2nd
	    // initialCall => captureException(string) => captureMessage(string)

	    if (initialCall && initialCall.func === 'Raven.captureException') {
	      initialCall = stack.stack[2];
	    }

	    var fileurl = initialCall && initialCall.url || '';

	    if (!!this._globalOptions.ignoreUrls.test && this._globalOptions.ignoreUrls.test(fileurl)) {
	      return;
	    }

	    if (!!this._globalOptions.whitelistUrls.test && !this._globalOptions.whitelistUrls.test(fileurl)) {
	      return;
	    } // Always attempt to get stacktrace if message is empty.
	    // It's the only way to provide any helpful information to the user.


	    if (this._globalOptions.stacktrace || options.stacktrace || data.message === '') {
	      // fingerprint on msg, not stack trace (legacy behavior, could be revisited)
	      data.fingerprint = data.fingerprint == null ? msg : data.fingerprint;
	      options = objectMerge$1({
	        trimHeadFrames: 0
	      }, options); // Since we know this is a synthetic trace, the top frame (this function call)
	      // MUST be from Raven.js, so mark it for trimming
	      // We add to the trim counter so that callers can choose to trim extra frames, such
	      // as utility functions.

	      options.trimHeadFrames += 1;

	      var frames = this._prepareFrames(stack, options);

	      data.stacktrace = {
	        // Sentry expects frames oldest to newest
	        frames: frames.reverse()
	      };
	    } // Make sure that fingerprint is always wrapped in an array


	    if (data.fingerprint) {
	      data.fingerprint = isArray$1(data.fingerprint) ? data.fingerprint : [data.fingerprint];
	    } // Fire away!


	    this._send(data);

	    return this;
	  }