function createCommonjsModule(fn, module) {
	return module = { exports: {} }, fn(module, module.exports), module.exports;
}

var makeError_1 = createCommonjsModule(function (module, exports) {
// ISC @ Julien Fontanet

'use strict';

// ===================================================================

var defineProperty = Object.defineProperty;

// -------------------------------------------------------------------

var captureStackTrace = Error.captureStackTrace;
if (!captureStackTrace) {
  captureStackTrace = function captureStackTrace (error) {
    var container = new Error();

    defineProperty(error, 'stack', {
      configurable: true,
      get: function getStack () {
        var stack = container.stack;

        // Replace property with value for faster future accesses.
        defineProperty(this, 'stack', {
          value: stack
        });

        return stack
      },
      set: function setStack (stack) {
        defineProperty(error, 'stack', {
          configurable: true,
          value: stack,
          writable: true
        });
      }
    });
  };
}

// -------------------------------------------------------------------

function BaseError (message) {
  if (message) {
    defineProperty(this, 'message', {
      configurable: true,
      value: message,
      writable: true
    });
  }

  var cname = this.constructor.name;
  if (
    cname &&
    cname !== this.name
  ) {
    defineProperty(this, 'name', {
      configurable: true,
      value: cname,
      writable: true
    });
  }

  captureStackTrace(this, this.constructor);
}

BaseError.prototype = Object.create(Error.prototype, {
  // See: https://github.com/JsCommunity/make-error/issues/4
  constructor: {
    configurable: true,
    value: BaseError,
    writable: true
  }
});

// -------------------------------------------------------------------

// Sets the name of a function if possible (depends of the JS engine).
var setFunctionName = (function () {
  function setFunctionName (fn, name) {
    return defineProperty(fn, 'name', {
      configurable: true,
      value: name
    })
  }
  try {
    var f = function () {};
    setFunctionName(f, 'foo');
    if (f.name === 'foo') {
      return setFunctionName
    }
  } catch (_) {}
})();

// -------------------------------------------------------------------

function makeError (constructor, super_) {
  if (super_ == null || super_ === Error) {
    super_ = BaseError;
  } else if (typeof super_ !== 'function') {
    throw new TypeError('super_ should be a function')
  }

  var name;
  if (typeof constructor === 'string') {
    name = constructor;
    constructor = function () { super_.apply(this, arguments); };

    // If the name can be set, do it once and for all.
    if (setFunctionName) {
      setFunctionName(constructor, name);
      name = null;
    }
  } else if (typeof constructor !== 'function') {
    throw new TypeError('constructor should be either a string or a function')
  }

  // Also register the super constructor also as `constructor.super_` just
  // like Node's `util.inherits()`.
  constructor.super_ = constructor['super'] = super_;

  var properties = {
    constructor: {
      configurable: true,
      value: constructor,
      writable: true
    }
  };

  // If the name could not be set on the constructor, set it on the
  // prototype.
  if (name != null) {
    properties.name = {
      configurable: true,
      value: name,
      writable: true
    };
  }
  constructor.prototype = Object.create(super_.prototype, properties);

  return constructor
}
exports = module.exports = makeError;
exports.BaseError = BaseError;
});

var makeError_2 = makeError_1.BaseError;

/**
 * @author Joel Hernandez <lifenautjoe@gmail.com>
 */
var __extends = (undefined && undefined.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
var NoelError = /** @class */ (function (_super) {
    __extends(NoelError, _super);
    function NoelError(message) {
        var _this = _super.call(this, message) || this;
        _this.name = 'NoelError';
        return _this;
    }
    return NoelError;
}(makeError_2));
var NoelReplayNotEnabledError = /** @class */ (function (_super) {
    __extends(NoelReplayNotEnabledError, _super);
    function NoelReplayNotEnabledError() {
        var _this = _super.call(this, 'Replay for noel is not enabled') || this;
        _this.name = 'NoelReplayNotEnabledError';
        return _this;
    }
    return NoelReplayNotEnabledError;
}(NoelError));
var NoelEventError = /** @class */ (function (_super) {
    __extends(NoelEventError, _super);
    function NoelEventError(message) {
        var _this = _super.call(this, message) || this;
        _this.name = 'NoelEventError';
        return _this;
    }
    return NoelEventError;
}(NoelError));
var NoelEventReplayNotEnabled = /** @class */ (function (_super) {
    __extends(NoelEventReplayNotEnabled, _super);
    function NoelEventReplayNotEnabled(event) {
        var _this = _super.call(this, "Replay for event \"" + event.getName() + "\" is not enabled") || this;
        _this.name = 'NoelEventReplayNotEnabled';
        return _this;
    }
    return NoelEventReplayNotEnabled;
}(NoelEventError));
var NoelEventConfigError = /** @class */ (function (_super) {
    __extends(NoelEventConfigError, _super);
    function NoelEventConfigError(message) {
        var _this = _super.call(this, message) || this;
        _this.name = 'NoelEventConfigError';
        return _this;
    }
    return NoelEventConfigError;
}(NoelEventError));
var NoelEventListenerError = /** @class */ (function (_super) {
    __extends(NoelEventListenerError, _super);
    function NoelEventListenerError(message) {
        var _this = _super.call(this, message) || this;
        _this.name = 'NoelEventListenerError';
        return _this;
    }
    return NoelEventListenerError;
}(NoelEventError));
var NoelBufferSizeNotValidError = /** @class */ (function (_super) {
    __extends(NoelBufferSizeNotValidError, _super);
    function NoelBufferSizeNotValidError(message) {
        var _this = _super.call(this, message) || this;
        _this.name = 'NoelBufferSizeNotValidError';
        return _this;
    }
    return NoelBufferSizeNotValidError;
}(NoelEventError));

/**
 * @author Joel Hernandez <lifenautjoe@gmail.com>
 */
var __read$2 = (undefined && undefined.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spread$2 = (undefined && undefined.__spread) || function () {
    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read$2(arguments[i]));
    return ar;
};
var NoelEventListenerManager = /** @class */ (function () {
    function NoelEventListenerManager(listener, event, noel) {
        this.listener = listener;
        this.event = event;
        this.noel = noel;
    }
    NoelEventListenerManager.prototype.remove = function () {
        // We remove it from noel instead of the event itself because noel will remove it
        // if it was the last listener
        this.noel.removeEventListener(this.event, this.listener);
    };
    NoelEventListenerManager.prototype.replay = function (bufferSize) {
        var _this = this;
        var event = this.event;
        if (!event.getReplayIsEnabled())
            throw new NoelEventReplayNotEnabled(event);
        var actualBufferSize = event.getReplayBufferSize();
        if (bufferSize > actualBufferSize) {
            var logger = event.getLogger();
            logger.warn("Attempted to replay " + bufferSize + " emits from the event \"" + event.getName() + "\" but the replay buffer size is set to " + actualBufferSize + ".");
        }
        var eventReplayBuffer = this.event.getReplayBufferAmount(bufferSize);
        eventReplayBuffer.forEach(function (eventReplayBufferItem) {
            _this.listener.apply(_this, __spread$2(eventReplayBufferItem));
        });
        return this;
    };
    return NoelEventListenerManager;
}());

var __read$1 = (undefined && undefined.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spread$1 = (undefined && undefined.__spread) || function () {
    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read$1(arguments[i]));
    return ar;
};
var NoelEvent = /** @class */ (function () {
    function NoelEvent(config) {
        this.replayBuffer = null;
        this.listeners = null;
        config = config || {};
        if (typeof config.name === 'undefined')
            throw new NoelEventConfigError('config.name:string is required');
        this.name = config.name;
        if (!config.noel)
            throw new NoelEventConfigError('config.noel:Noel is required');
        this.noel = config.noel;
        if (config.logger)
            this.setLogger(config.logger);
        this.replayBufferSize = config.replayBufferSize || 1;
        var noListenersWarning = typeof config.noListenersWarning === 'boolean' ? config.noListenersWarning : true;
        noListenersWarning ? this.enableNoListenersWarning() : this.disableNoListenersWarning();
        this.replayEnabled = typeof config.replay === 'boolean' ? config.replay : false;
    }
    NoelEvent.prototype.enableReplay = function () {
        this.replayEnabled = true;
    };
    NoelEvent.prototype.disableReplay = function () {
        this.replayEnabled = false;
        this.replayBuffer = null;
    };
    NoelEvent.prototype.emit = function () {
        var eventArgs = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            eventArgs[_i] = arguments[_i];
        }
        var listeners = this.listeners;
        if (listeners) {
            listeners.forEach(function (listener) { return listener.apply(void 0, __spread$1(eventArgs)); });
        }
        else if (!this.replayEnabled && this.noListenersWarning) {
            this.logWarn("Event \"" + this.name + "\" was emitted but had no listeners.");
        }
        if (this.replayEnabled)
            this.pushEventArgsToReplayBuffer(eventArgs);
    };
    NoelEvent.prototype.on = function (listener) {
        if (typeof listener !== 'function')
            throw new NoelEventListenerError('Given listener is not a function');
        var listeners = this.getListeners();
        listeners.add(listener);
        return new NoelEventListenerManager(listener, this, this.noel);
    };
    NoelEvent.prototype.removeListener = function (listener) {
        var listeners = this.listeners;
        if (!listeners)
            return;
        listeners.delete(listener);
    };
    NoelEvent.prototype.countListeners = function () {
        return this.listeners ? this.listeners.size : 0;
    };
    NoelEvent.prototype.clearReplayBuffer = function () {
        this.replayBuffer = null;
    };
    NoelEvent.prototype.removeAllListeners = function () {
        this.listeners = null;
    };
    NoelEvent.prototype.setReplayBufferSize = function (replayBufferSize) {
        if (!this.replayEnabled)
            throw new NoelEventReplayNotEnabled(this);
        if (replayBufferSize <= 0)
            throw new NoelBufferSizeNotValidError('Replay buffer size needs to be >=1');
        this.replayBufferSize = replayBufferSize;
        var replayBuffer = this.replayBuffer;
        if (!replayBuffer)
            return;
        this.setReplayBuffer(replayBuffer.slice(0, replayBufferSize));
    };
    NoelEvent.prototype.getReplayBufferAmount = function (replayBufferAmount) {
        if (!this.replayEnabled)
            throw new NoelEventReplayNotEnabled(this);
        var replayBuffer = this.getReplayBuffer();
        return typeof replayBufferAmount === 'undefined' || replayBufferAmount === replayBuffer.length ? replayBuffer : replayBuffer.slice(0, replayBufferAmount);
    };
    NoelEvent.prototype.setLogger = function (logger) {
        this.logger = logger;
    };
    NoelEvent.prototype.enableNoListenersWarning = function () {
        this.noListenersWarning = true;
    };
    NoelEvent.prototype.disableNoListenersWarning = function () {
        this.noListenersWarning = false;
    };
    NoelEvent.prototype.getName = function () {
        return this.name;
    };
    NoelEvent.prototype.getLogger = function () {
        return this.logger;
    };
    NoelEvent.prototype.getReplayBufferSize = function () {
        return this.replayBufferSize;
    };
    NoelEvent.prototype.getReplayIsEnabled = function () {
        return this.replayEnabled;
    };
    NoelEvent.prototype.setReplayBuffer = function (replayBuffer) {
        this.replayBuffer = replayBuffer;
    };
    NoelEvent.prototype.getListeners = function () {
        return this.listeners || (this.listeners = new Set());
    };
    NoelEvent.prototype.pushEventArgsToReplayBuffer = function (eventArgs) {
        var replayBuffer = this.getReplayBuffer();
        replayBuffer.push(eventArgs);
        if (replayBuffer.length > this.replayBufferSize)
            replayBuffer.shift();
    };
    NoelEvent.prototype.getReplayBuffer = function () {
        return this.replayBuffer || (this.replayBuffer = []);
    };
    NoelEvent.prototype.logWarn = function (warn) {
        this.logger.warn(warn);
    };
    return NoelEvent;
}());

/**
 * @author Joel Hernandez <lifenautjoe@gmail.com>
 */
var consolePoly = {
    warn: function () { }
};
var NoelLogger = /** @class */ (function () {
    function NoelLogger() {
        this.console = typeof console === 'undefined' ? consolePoly : console;
    }
    NoelLogger.prototype.warn = function (warn) {
        this.console.warn(warn);
    };
    return NoelLogger;
}());

// Import here Polyfills if needed. Recommended core-js (npm i -D core-js)
// import "core-js/fn/array.find"
// ...
var __read = (undefined && undefined.__read) || function (o, n) {
    var m = typeof Symbol === "function" && o[Symbol.iterator];
    if (!m) return o;
    var i = m.call(o), r, ar = [], e;
    try {
        while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
    }
    catch (error) { e = { error: error }; }
    finally {
        try {
            if (r && !r.done && (m = i["return"])) m.call(i);
        }
        finally { if (e) throw e.error; }
    }
    return ar;
};
var __spread = (undefined && undefined.__spread) || function () {
    for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
    return ar;
};
var __values = (undefined && undefined.__values) || function (o) {
    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
    if (m) return m.call(o);
    return {
        next: function () {
            if (o && i >= o.length) o = void 0;
            return { value: o && o[i++], done: !o };
        }
    };
};
var defaultLogger = new NoelLogger();
var Noel = /** @class */ (function () {
    function Noel(config) {
        this.eventsMap = null;
        config = config || {};
        this.noEventListenersWarning = typeof config.noEventListenersWarning === 'boolean' ? config.noEventListenersWarning : true;
        this.replayBufferSize = config.replayBufferSize || 1;
        this.replayEnabled = typeof config.replay === 'boolean' ? config.replay : true;
        var logger = config.logger || defaultLogger;
        this.setLogger(logger);
    }
    Noel.prototype.emit = function (eventName) {
        var eventArgs = [];
        for (var _i = 1; _i < arguments.length; _i++) {
            eventArgs[_i - 1] = arguments[_i];
        }
        var event = this.getEvent(eventName);
        event.emit.apply(event, __spread(eventArgs));
    };
    Noel.prototype.on = function (eventName, listener) {
        var event = this.getEvent(eventName);
        return event.on(listener);
    };
    Noel.prototype.removeListener = function (eventName, listener) {
        var eventsMap = this.eventsMap;
        if (eventsMap) {
            var event_1 = eventsMap.get(eventName);
            if (event_1) {
                this.removeEventListener(event_1, listener);
            }
        }
    };
    Noel.prototype.removeEventListener = function (event, listener) {
        event.removeListener(listener);
        var eventListenersCount = event.countListeners();
        if (eventListenersCount === 0)
            this.removeEvent(event.getName());
    };
    Noel.prototype.setLogger = function (logger) {
        this.logger = logger;
        if (this.eventsMap) {
            try {
                for (var _a = __values(this.eventsMap.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
                    var event_2 = _b.value;
                    event_2.setLogger(logger);
                }
            }
            catch (e_1_1) { e_1 = { error: e_1_1 }; }
            finally {
                try {
                    if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
                }
                finally { if (e_1) throw e_1.error; }
            }
        }
        var e_1, _c;
    };
    Noel.prototype.enableNoEventListenersWarning = function () {
        if (this.noEventListenersWarning)
            return;
        this.noEventListenersWarning = true;
        if (this.eventsMap) {
            try {
                for (var _a = __values(this.eventsMap.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
                    var event_3 = _b.value;
                    event_3.enableNoListenersWarning();
                }
            }
            catch (e_2_1) { e_2 = { error: e_2_1 }; }
            finally {
                try {
                    if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
                }
                finally { if (e_2) throw e_2.error; }
            }
        }
        var e_2, _c;
    };
    Noel.prototype.disableNoEventListenersWarning = function () {
        if (typeof this.noEventListenersWarning !== 'undefined' && !this.noEventListenersWarning)
            return;
        this.noEventListenersWarning = false;
        if (this.eventsMap) {
            try {
                for (var _a = __values(this.eventsMap.values()), _b = _a.next(); !_b.done; _b = _a.next()) {
                    var event_4 = _b.value;
                    event_4.disableNoListenersWarning();
                }
            }
            catch (e_3_1) { e_3 = { error: e_3_1 }; }
            finally {
                try {
                    if (_b && !_b.done && (_c = _a.return)) _c.call(_a);
                }
                finally { if (e_3) throw e_3.error; }
            }
        }
        var e_3, _c;
    };
    Noel.prototype.replayIsEnabled = function () {
        return this.replayEnabled;
    };
    Noel.prototype.enableReplay = function () {
        if (this.replayEnabled)
            return;
        this.enableEventsReplay();
        this.replayEnabled = true;
    };
    Noel.prototype.disableReplay = function () {
        if (!this.replayEnabled)
            return;
        this.disableEventsReplay();
        this.replayEnabled = false;
    };
    Noel.prototype.setReplayBufferSize = function (replayBufferSize) {
        if (!this.replayEnabled)
            throw new NoelReplayNotEnabledError();
        if (replayBufferSize <= 0)
            throw new NoelBufferSizeNotValidError('Replay buffer size needs to be >=1');
        this.replayBufferSize = replayBufferSize;
        this.setEventsReplayBuffersSize(this.replayBufferSize);
    };
    Noel.prototype.clearEventsReplayBuffers = function () {
        if (!this.replayEnabled)
            throw new NoelReplayNotEnabledError();
        var events = this.getEvents();
        try {
            for (var events_1 = __values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) {
                var event_5 = events_1_1.value;
                event_5.clearReplayBuffer();
            }
        }
        catch (e_4_1) { e_4 = { error: e_4_1 }; }
        finally {
            try {
                if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1);
            }
            finally { if (e_4) throw e_4.error; }
        }
        var e_4, _a;
    };
    Noel.prototype.clearReplayBufferForEvent = function (eventName) {
        if (!this.replayEnabled)
            throw new NoelReplayNotEnabledError();
        var eventsMap = this.eventsMap;
        if (eventsMap) {
            var event_6 = eventsMap.get(eventName);
            if (event_6)
                event_6.clearReplayBuffer();
        }
    };
    Noel.prototype.getEvent = function (eventName) {
        var eventsMap = this.getEventsMap();
        var event = eventsMap.get(eventName);
        if (!event) {
            event = this.makeEvent(eventName);
            eventsMap.set(eventName, event);
        }
        return event;
    };
    Noel.prototype.removeEvent = function (eventName) {
        var eventsMap = this.eventsMap;
        if (eventsMap) {
            eventsMap.delete(eventName);
        }
    };
    Noel.prototype.removeAllListeners = function (eventName) {
        var eventsMap = this.eventsMap;
        if (eventsMap) {
            var event_7 = eventsMap.get(eventName);
            if (event_7)
                event_7.removeAllListeners();
        }
    };
    Noel.prototype.makeEvent = function (eventName) {
        return new NoelEvent({
            name: eventName,
            replay: this.replayEnabled,
            replayBufferSize: this.replayBufferSize,
            noListenersWarning: this.noEventListenersWarning,
            noel: this,
            logger: this.logger
        });
    };
    Noel.prototype.setEventsReplayBuffersSize = function (replayBuffersSize) {
        var eventsMap = this.eventsMap;
        if (eventsMap) {
            var events = eventsMap.values();
            try {
                for (var events_2 = __values(events), events_2_1 = events_2.next(); !events_2_1.done; events_2_1 = events_2.next()) {
                    var event_8 = events_2_1.value;
                    event_8.setReplayBufferSize(replayBuffersSize);
                }
            }
            catch (e_5_1) { e_5 = { error: e_5_1 }; }
            finally {
                try {
                    if (events_2_1 && !events_2_1.done && (_a = events_2.return)) _a.call(events_2);
                }
                finally { if (e_5) throw e_5.error; }
            }
        }
        var e_5, _a;
    };
    Noel.prototype.disableEventsReplay = function () {
        var eventsMap = this.eventsMap;
        if (eventsMap) {
            var events = eventsMap.values();
            try {
                for (var events_3 = __values(events), events_3_1 = events_3.next(); !events_3_1.done; events_3_1 = events_3.next()) {
                    var event_9 = events_3_1.value;
                    event_9.disableReplay();
                }
            }
            catch (e_6_1) { e_6 = { error: e_6_1 }; }
            finally {
                try {
                    if (events_3_1 && !events_3_1.done && (_a = events_3.return)) _a.call(events_3);
                }
                finally { if (e_6) throw e_6.error; }
            }
        }
        var e_6, _a;
    };
    Noel.prototype.enableEventsReplay = function () {
        var eventsMap = this.eventsMap;
        if (eventsMap) {
            var events = eventsMap.values();
            try {
                for (var events_4 = __values(events), events_4_1 = events_4.next(); !events_4_1.done; events_4_1 = events_4.next()) {
                    var event_10 = events_4_1.value;
                    event_10.enableReplay();
                }
            }
            catch (e_7_1) { e_7 = { error: e_7_1 }; }
            finally {
                try {
                    if (events_4_1 && !events_4_1.done && (_a = events_4.return)) _a.call(events_4);
                }
                finally { if (e_7) throw e_7.error; }
            }
        }
        var e_7, _a;
    };
    Noel.prototype.getEvents = function () {
        var eventsMap = this.getEventsMap();
        return eventsMap.values();
    };
    Noel.prototype.getEventsMap = function () {
        return this.eventsMap || (this.eventsMap = new Map());
    };
    return Noel;
}());

export default Noel;
//# sourceMappingURL=noel.es5.js.map
