import { Runloop } from './ember.js';

function getDefaultExportFromCjs (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

var backburner = {};

var hasRequiredBackburner;

function requireBackburner () {
	if (hasRequiredBackburner) return backburner;
	hasRequiredBackburner = 1;

	Object.defineProperty(backburner, '__esModule', {
	  value: true
	});
	var SET_TIMEOUT = setTimeout;
	var NOOP = function () {};
	function buildNext(flush) {
	  // Using "promises first" here to:
	  //
	  // 1) Ensure more consistent experience on browsers that
	  //    have differently queued microtasks (separate queues for
	  //    MutationObserver vs Promises).
	  // 2) Ensure better debugging experiences (it shows up in Chrome
	  //    call stack as "Promise.then (async)") which is more consistent
	  //    with user expectations
	  //
	  // When Promise is unavailable use MutationObserver (mostly so that we
	  // still get microtasks on IE11), and when neither MutationObserver and
	  // Promise are present use a plain old setTimeout.
	  if (typeof Promise === 'function') {
	    var autorunPromise = Promise.resolve();
	    return function () {
	      return autorunPromise.then(flush);
	    };
	  } else if (typeof MutationObserver === 'function') {
	    var iterations = 0;
	    var observer = new MutationObserver(flush);
	    var node = document.createTextNode('');
	    observer.observe(node, {
	      characterData: true
	    });
	    return function () {
	      iterations = ++iterations % 2;
	      node.data = '' + iterations;
	      return iterations;
	    };
	  } else {
	    return function () {
	      return SET_TIMEOUT(flush, 0);
	    };
	  }
	}
	function buildPlatform(flush) {
	  var clearNext = NOOP;
	  return {
	    setTimeout: function setTimeout$1(fn, ms) {
	      return setTimeout(fn, ms);
	    },
	    clearTimeout: function clearTimeout$1(timerId) {
	      return clearTimeout(timerId);
	    },
	    now: function now() {
	      return Date.now();
	    },
	    next: buildNext(flush),
	    clearNext: clearNext
	  };
	}
	var NUMBER = /\d+/;
	var TIMERS_OFFSET = 6;
	function isCoercableNumber(suspect) {
	  var type = typeof suspect;
	  return type === 'number' && suspect === suspect || type === 'string' && NUMBER.test(suspect);
	}
	function getOnError(options) {
	  return options.onError || options.onErrorTarget && options.onErrorTarget[options.onErrorMethod];
	}
	function findItem(target, method, collection) {
	  var index = -1;
	  for (var i = 0, l = collection.length; i < l; i += 4) {
	    if (collection[i] === target && collection[i + 1] === method) {
	      index = i;
	      break;
	    }
	  }
	  return index;
	}
	function findTimerItem(target, method, collection) {
	  var index = -1;
	  for (var i = 2, l = collection.length; i < l; i += 6) {
	    if (collection[i] === target && collection[i + 1] === method) {
	      index = i - 2;
	      break;
	    }
	  }
	  return index;
	}
	function getQueueItems(items, queueItemLength, queueItemPositionOffset) {
	  if (queueItemPositionOffset === void 0) queueItemPositionOffset = 0;
	  var queueItems = [];
	  for (var i = 0; i < items.length; i += queueItemLength) {
	    var maybeError = items[i + 3 /* stack */ + queueItemPositionOffset];
	    var queueItem = {
	      target: items[i + 0 /* target */ + queueItemPositionOffset],
	      method: items[i + 1 /* method */ + queueItemPositionOffset],
	      args: items[i + 2 /* args */ + queueItemPositionOffset],
	      stack: maybeError !== undefined && 'stack' in maybeError ? maybeError.stack : ''
	    };
	    queueItems.push(queueItem);
	  }
	  return queueItems;
	}
	function binarySearch(time, timers) {
	  var start = 0;
	  var end = timers.length - TIMERS_OFFSET;
	  var middle;
	  var l;
	  while (start < end) {
	    // since timers is an array of pairs 'l' will always
	    // be an integer
	    l = (end - start) / TIMERS_OFFSET;
	    // compensate for the index in case even number
	    // of pairs inside timers
	    middle = start + l - l % TIMERS_OFFSET;
	    if (time >= timers[middle]) {
	      start = middle + TIMERS_OFFSET;
	    } else {
	      end = middle;
	    }
	  }
	  return time >= timers[start] ? start + TIMERS_OFFSET : start;
	}
	var QUEUE_ITEM_LENGTH = 4;
	var Queue = function Queue(name, options, globalOptions) {
	  if (options === void 0) options = {};
	  if (globalOptions === void 0) globalOptions = {};
	  this._queueBeingFlushed = [];
	  this.targetQueues = new Map();
	  this.index = 0;
	  this._queue = [];
	  this.name = name;
	  this.options = options;
	  this.globalOptions = globalOptions;
	};
	Queue.prototype.stackFor = function stackFor(index) {
	  if (index < this._queue.length) {
	    var entry = this._queue[index * 3 + QUEUE_ITEM_LENGTH];
	    if (entry) {
	      return entry.stack;
	    } else {
	      return null;
	    }
	  }
	};
	Queue.prototype.flush = function flush(sync) {
	  var ref = this.options;
	  var before = ref.before;
	  var after = ref.after;
	  var target;
	  var method;
	  var args;
	  var errorRecordedForStack;
	  this.targetQueues.clear();
	  if (this._queueBeingFlushed.length === 0) {
	    this._queueBeingFlushed = this._queue;
	    this._queue = [];
	  }
	  if (before !== undefined) {
	    before();
	  }
	  var invoke;
	  var queueItems = this._queueBeingFlushed;
	  if (queueItems.length > 0) {
	    var onError = getOnError(this.globalOptions);
	    invoke = onError ? this.invokeWithOnError : this.invoke;
	    for (var i = this.index; i < queueItems.length; i += QUEUE_ITEM_LENGTH) {
	      this.index += QUEUE_ITEM_LENGTH;
	      method = queueItems[i + 1];
	      // method could have been nullified / canceled during flush
	      if (method !== null) {
	        //
	        //** Attention intrepid developer **
	        //
	        //To find out the stack of this task when it was scheduled onto
	        //the run loop, add the following to your app.js:
	        //
	        //Ember.run.backburner.DEBUG = true; // NOTE: This slows your app, don't leave it on in production.
	        //
	        //Once that is in place, when you are at a breakpoint and navigate
	        //here in the stack explorer, you can look at `errorRecordedForStack.stack`,
	        //which will be the captured stack when this job was scheduled.
	        //
	        //One possible long-term solution is the following Chrome issue:
	        //   https://bugs.chromium.org/p/chromium/issues/detail?id=332624
	        //
	        target = queueItems[i];
	        args = queueItems[i + 2];
	        errorRecordedForStack = queueItems[i + 3]; // Debugging assistance
	        invoke(target, method, args, onError, errorRecordedForStack);
	      }
	      if (this.index !== this._queueBeingFlushed.length && this.globalOptions.mustYield && this.globalOptions.mustYield()) {
	        return 1 /* Pause */;
	      }
	    }
	  }
	  if (after !== undefined) {
	    after();
	  }
	  this._queueBeingFlushed.length = 0;
	  this.index = 0;
	  if (sync !== false && this._queue.length > 0) {
	    // check if new items have been added
	    this.flush(true);
	  }
	};
	Queue.prototype.hasWork = function hasWork() {
	  return this._queueBeingFlushed.length > 0 || this._queue.length > 0;
	};
	Queue.prototype.cancel = function cancel(ref) {
	  var target = ref.target;
	  var method = ref.method;
	  var queue = this._queue;
	  var targetQueueMap = this.targetQueues.get(target);
	  if (targetQueueMap !== undefined) {
	    targetQueueMap.delete(method);
	  }
	  var index = findItem(target, method, queue);
	  if (index > -1) {
	    queue[index + 1] = null;
	    return true;
	  }
	  // if not found in current queue
	  // could be in the queue that is being flushed
	  queue = this._queueBeingFlushed;
	  index = findItem(target, method, queue);
	  if (index > -1) {
	    queue[index + 1] = null;
	    return true;
	  }
	  return false;
	};
	Queue.prototype.push = function push(target, method, args, stack) {
	  this._queue.push(target, method, args, stack);
	  return {
	    queue: this,
	    target: target,
	    method: method
	  };
	};
	Queue.prototype.pushUnique = function pushUnique(target, method, args, stack) {
	  var localQueueMap = this.targetQueues.get(target);
	  if (localQueueMap === undefined) {
	    localQueueMap = new Map();
	    this.targetQueues.set(target, localQueueMap);
	  }
	  var index = localQueueMap.get(method);
	  if (index === undefined) {
	    var queueIndex = this._queue.push(target, method, args, stack) - QUEUE_ITEM_LENGTH;
	    localQueueMap.set(method, queueIndex);
	  } else {
	    var queue = this._queue;
	    queue[index + 2] = args; // replace args
	    queue[index + 3] = stack; // replace stack
	  }
	  return {
	    queue: this,
	    target: target,
	    method: method
	  };
	};
	Queue.prototype._getDebugInfo = function _getDebugInfo(debugEnabled) {
	  if (debugEnabled) {
	    var debugInfo = getQueueItems(this._queue, QUEUE_ITEM_LENGTH);
	    return debugInfo;
	  }
	  return undefined;
	};
	Queue.prototype.invoke = function invoke(target, method, args /*, onError, errorRecordedForStack */) {
	  if (args === undefined) {
	    method.call(target);
	  } else {
	    method.apply(target, args);
	  }
	};
	Queue.prototype.invokeWithOnError = function invokeWithOnError(target, method, args, onError, errorRecordedForStack) {
	  try {
	    if (args === undefined) {
	      method.call(target);
	    } else {
	      method.apply(target, args);
	    }
	  } catch (error) {
	    onError(error, errorRecordedForStack);
	  }
	};
	var DeferredActionQueues = function DeferredActionQueues(queueNames, options) {
	  if (queueNames === void 0) queueNames = [];
	  this.queues = {};
	  this.queueNameIndex = 0;
	  this.queueNames = queueNames;
	  queueNames.reduce(function (queues, queueName) {
	    queues[queueName] = new Queue(queueName, options[queueName], options);
	    return queues;
	  }, this.queues);
	};
	/**
	 * @method schedule
	 * @param {String} queueName
	 * @param {Any} target
	 * @param {Any} method
	 * @param {Any} args
	 * @param {Boolean} onceFlag
	 * @param {Any} stack
	 * @return queue
	 */
	DeferredActionQueues.prototype.schedule = function schedule(queueName, target, method, args, onceFlag, stack) {
	  var queues = this.queues;
	  var queue = queues[queueName];
	  if (queue === undefined) {
	    throw new Error("You attempted to schedule an action in a queue (" + queueName + ") that doesn't exist");
	  }
	  if (method === undefined || method === null) {
	    throw new Error("You attempted to schedule an action in a queue (" + queueName + ") for a method that doesn't exist");
	  }
	  this.queueNameIndex = 0;
	  if (onceFlag) {
	    return queue.pushUnique(target, method, args, stack);
	  } else {
	    return queue.push(target, method, args, stack);
	  }
	};
	/**
	 * DeferredActionQueues.flush() calls Queue.flush()
	 *
	 * @method flush
	 * @param {Boolean} fromAutorun
	 */
	DeferredActionQueues.prototype.flush = function flush(fromAutorun) {
	  if (fromAutorun === void 0) fromAutorun = false;
	  var queue;
	  var queueName;
	  var numberOfQueues = this.queueNames.length;
	  while (this.queueNameIndex < numberOfQueues) {
	    queueName = this.queueNames[this.queueNameIndex];
	    queue = this.queues[queueName];
	    if (queue.hasWork() === false) {
	      this.queueNameIndex++;
	      if (fromAutorun && this.queueNameIndex < numberOfQueues) {
	        return 1 /* Pause */;
	      }
	    } else {
	      if (queue.flush(false /* async */) === 1 /* Pause */) {
	        return 1 /* Pause */;
	      }
	    }
	  }
	};
	/**
	 * Returns debug information for the current queues.
	 *
	 * @method _getDebugInfo
	 * @param {Boolean} debugEnabled
	 * @returns {IDebugInfo | undefined}
	 */
	DeferredActionQueues.prototype._getDebugInfo = function _getDebugInfo(debugEnabled) {
	  if (debugEnabled) {
	    var debugInfo = {};
	    var queue;
	    var queueName;
	    var numberOfQueues = this.queueNames.length;
	    var i = 0;
	    while (i < numberOfQueues) {
	      queueName = this.queueNames[i];
	      queue = this.queues[queueName];
	      debugInfo[queueName] = queue._getDebugInfo(debugEnabled);
	      i++;
	    }
	    return debugInfo;
	  }
	  return;
	};
	function iteratorDrain(fn) {
	  var iterator = fn();
	  var result = iterator.next();
	  while (result.done === false) {
	    result.value();
	    result = iterator.next();
	  }
	}
	var noop = function () {};
	var DISABLE_SCHEDULE = Object.freeze([]);
	function parseArgs() {
	  var arguments$1 = arguments;
	  var length = arguments.length;
	  var args;
	  var method;
	  var target;
	  if (length === 0) ;else if (length === 1) {
	    target = null;
	    method = arguments[0];
	  } else {
	    var argsIndex = 2;
	    var methodOrTarget = arguments[0];
	    var methodOrArgs = arguments[1];
	    var type = typeof methodOrArgs;
	    if (type === 'function') {
	      target = methodOrTarget;
	      method = methodOrArgs;
	    } else if (methodOrTarget !== null && type === 'string' && methodOrArgs in methodOrTarget) {
	      target = methodOrTarget;
	      method = target[methodOrArgs];
	    } else if (typeof methodOrTarget === 'function') {
	      argsIndex = 1;
	      target = null;
	      method = methodOrTarget;
	    }
	    if (length > argsIndex) {
	      var len = length - argsIndex;
	      args = new Array(len);
	      for (var i = 0; i < len; i++) {
	        args[i] = arguments$1[i + argsIndex];
	      }
	    }
	  }
	  return [target, method, args];
	}
	function parseTimerArgs() {
	  var ref = parseArgs.apply(void 0, arguments);
	  var target = ref[0];
	  var method = ref[1];
	  var args = ref[2];
	  var wait = 0;
	  var length = args !== undefined ? args.length : 0;
	  if (length > 0) {
	    var last = args[length - 1];
	    if (isCoercableNumber(last)) {
	      wait = parseInt(args.pop(), 10);
	    }
	  }
	  return [target, method, args, wait];
	}
	function parseDebounceArgs() {
	  var assign;
	  var target;
	  var method;
	  var isImmediate;
	  var args;
	  var wait;
	  if (arguments.length === 2) {
	    method = arguments[0];
	    wait = arguments[1];
	    target = null;
	  } else {
	    assign = parseArgs.apply(void 0, arguments), target = assign[0], method = assign[1], args = assign[2];
	    if (args === undefined) {
	      wait = 0;
	    } else {
	      wait = args.pop();
	      if (!isCoercableNumber(wait)) {
	        isImmediate = wait === true;
	        wait = args.pop();
	      }
	    }
	  }
	  wait = parseInt(wait, 10);
	  return [target, method, args, wait, isImmediate];
	}
	var UUID = 0;
	var beginCount = 0;
	var endCount = 0;
	var beginEventCount = 0;
	var endEventCount = 0;
	var runCount = 0;
	var joinCount = 0;
	var deferCount = 0;
	var scheduleCount = 0;
	var scheduleIterableCount = 0;
	var deferOnceCount = 0;
	var scheduleOnceCount = 0;
	var setTimeoutCount = 0;
	var laterCount = 0;
	var throttleCount = 0;
	var debounceCount = 0;
	var cancelTimersCount = 0;
	var cancelCount = 0;
	var autorunsCreatedCount = 0;
	var autorunsCompletedCount = 0;
	var deferredActionQueuesCreatedCount = 0;
	var nestedDeferredActionQueuesCreated = 0;
	var Backburner = function Backburner(queueNames, options) {
	  var this$1$1 = this;
	  this.DEBUG = false;
	  this.currentInstance = null;
	  this.instanceStack = [];
	  this._eventCallbacks = {
	    end: [],
	    begin: []
	  };
	  this._timerTimeoutId = null;
	  this._timers = [];
	  this._autorun = false;
	  this._autorunStack = null;
	  this.queueNames = queueNames;
	  this.options = options || {};
	  if (typeof this.options.defaultQueue === 'string') {
	    this._defaultQueue = this.options.defaultQueue;
	  } else {
	    this._defaultQueue = this.queueNames[0];
	  }
	  this._onBegin = this.options.onBegin || noop;
	  this._onEnd = this.options.onEnd || noop;
	  this._boundRunExpiredTimers = this._runExpiredTimers.bind(this);
	  this._boundAutorunEnd = function () {
	    autorunsCompletedCount++;
	    // if the autorun was already flushed, do nothing
	    if (this$1$1._autorun === false) {
	      return;
	    }
	    this$1$1._autorun = false;
	    this$1$1._autorunStack = null;
	    this$1$1._end(true /* fromAutorun */);
	  };
	  var builder = this.options._buildPlatform || buildPlatform;
	  this._platform = builder(this._boundAutorunEnd);
	};
	var prototypeAccessors = {
	  counters: {
	    configurable: true
	  },
	  defaultQueue: {
	    configurable: true
	  }
	};
	prototypeAccessors.counters.get = function () {
	  return {
	    begin: beginCount,
	    end: endCount,
	    events: {
	      begin: beginEventCount,
	      end: endEventCount
	    },
	    autoruns: {
	      created: autorunsCreatedCount,
	      completed: autorunsCompletedCount
	    },
	    run: runCount,
	    join: joinCount,
	    defer: deferCount,
	    schedule: scheduleCount,
	    scheduleIterable: scheduleIterableCount,
	    deferOnce: deferOnceCount,
	    scheduleOnce: scheduleOnceCount,
	    setTimeout: setTimeoutCount,
	    later: laterCount,
	    throttle: throttleCount,
	    debounce: debounceCount,
	    cancelTimers: cancelTimersCount,
	    cancel: cancelCount,
	    loops: {
	      total: deferredActionQueuesCreatedCount,
	      nested: nestedDeferredActionQueuesCreated
	    }
	  };
	};
	prototypeAccessors.defaultQueue.get = function () {
	  return this._defaultQueue;
	};
	/*
	  @method begin
	  @return instantiated class DeferredActionQueues
	*/
	Backburner.prototype.begin = function begin() {
	  beginCount++;
	  var options = this.options;
	  var previousInstance = this.currentInstance;
	  var current;
	  if (this._autorun !== false) {
	    current = previousInstance;
	    this._cancelAutorun();
	  } else {
	    if (previousInstance !== null) {
	      nestedDeferredActionQueuesCreated++;
	      this.instanceStack.push(previousInstance);
	    }
	    deferredActionQueuesCreatedCount++;
	    current = this.currentInstance = new DeferredActionQueues(this.queueNames, options);
	    beginEventCount++;
	    this._trigger('begin', current, previousInstance);
	  }
	  this._onBegin(current, previousInstance);
	  return current;
	};
	Backburner.prototype.end = function end() {
	  endCount++;
	  this._end(false);
	};
	Backburner.prototype.on = function on(eventName, callback) {
	  if (typeof callback !== 'function') {
	    throw new TypeError("Callback must be a function");
	  }
	  var callbacks = this._eventCallbacks[eventName];
	  if (callbacks !== undefined) {
	    callbacks.push(callback);
	  } else {
	    throw new TypeError("Cannot on() event " + eventName + " because it does not exist");
	  }
	};
	Backburner.prototype.off = function off(eventName, callback) {
	  var callbacks = this._eventCallbacks[eventName];
	  if (!eventName || callbacks === undefined) {
	    throw new TypeError("Cannot off() event " + eventName + " because it does not exist");
	  }
	  var callbackFound = false;
	  if (callback) {
	    for (var i = 0; i < callbacks.length; i++) {
	      if (callbacks[i] === callback) {
	        callbackFound = true;
	        callbacks.splice(i, 1);
	        i--;
	      }
	    }
	  }
	  if (!callbackFound) {
	    throw new TypeError("Cannot off() callback that does not exist");
	  }
	};
	Backburner.prototype.run = function run() {
	  runCount++;
	  var ref = parseArgs.apply(void 0, arguments);
	  var target = ref[0];
	  var method = ref[1];
	  var args = ref[2];
	  return this._run(target, method, args);
	};
	Backburner.prototype.join = function join() {
	  joinCount++;
	  var ref = parseArgs.apply(void 0, arguments);
	  var target = ref[0];
	  var method = ref[1];
	  var args = ref[2];
	  return this._join(target, method, args);
	};
	/**
	 * @deprecated please use schedule instead.
	 */
	Backburner.prototype.defer = function defer(queueName, target, method) {
	  var ref;
	  var args = [],
	    len = arguments.length - 3;
	  while (len-- > 0) args[len] = arguments[len + 3];
	  deferCount++;
	  return (ref = this).schedule.apply(ref, [queueName, target, method].concat(args));
	};
	Backburner.prototype.schedule = function schedule(queueName) {
	  var _args = [],
	    len = arguments.length - 1;
	  while (len-- > 0) _args[len] = arguments[len + 1];
	  scheduleCount++;
	  var ref = parseArgs.apply(void 0, _args);
	  var target = ref[0];
	  var method = ref[1];
	  var args = ref[2];
	  var stack = this.DEBUG ? new Error() : undefined;
	  return this._ensureInstance().schedule(queueName, target, method, args, false, stack);
	};
	/*
	  Defer the passed iterable of functions to run inside the specified queue.

	  @method scheduleIterable
	  @param {String} queueName
	  @param {Iterable} an iterable of functions to execute
	  @return method result
	*/
	Backburner.prototype.scheduleIterable = function scheduleIterable(queueName, iterable) {
	  scheduleIterableCount++;
	  var stack = this.DEBUG ? new Error() : undefined;
	  return this._ensureInstance().schedule(queueName, null, iteratorDrain, [iterable], false, stack);
	};
	/**
	 * @deprecated please use scheduleOnce instead.
	 */
	Backburner.prototype.deferOnce = function deferOnce(queueName, target, method) {
	  var ref;
	  var args = [],
	    len = arguments.length - 3;
	  while (len-- > 0) args[len] = arguments[len + 3];
	  deferOnceCount++;
	  return (ref = this).scheduleOnce.apply(ref, [queueName, target, method].concat(args));
	};
	Backburner.prototype.scheduleOnce = function scheduleOnce(queueName) {
	  var _args = [],
	    len = arguments.length - 1;
	  while (len-- > 0) _args[len] = arguments[len + 1];
	  scheduleOnceCount++;
	  var ref = parseArgs.apply(void 0, _args);
	  var target = ref[0];
	  var method = ref[1];
	  var args = ref[2];
	  var stack = this.DEBUG ? new Error() : undefined;
	  return this._ensureInstance().schedule(queueName, target, method, args, true, stack);
	};
	Backburner.prototype.setTimeout = function setTimeout() {
	  var ref;
	  setTimeoutCount++;
	  return (ref = this).later.apply(ref, arguments);
	};
	Backburner.prototype.later = function later() {
	  laterCount++;
	  var ref = parseTimerArgs.apply(void 0, arguments);
	  var target = ref[0];
	  var method = ref[1];
	  var args = ref[2];
	  var wait = ref[3];
	  return this._later(target, method, args, wait);
	};
	Backburner.prototype.throttle = function throttle() {
	  throttleCount++;
	  var ref = parseDebounceArgs.apply(void 0, arguments);
	  var target = ref[0];
	  var method = ref[1];
	  var args = ref[2];
	  var wait = ref[3];
	  var isImmediate = ref[4];
	  if (isImmediate === void 0) isImmediate = true;
	  var index = findTimerItem(target, method, this._timers);
	  var timerId;
	  if (index === -1) {
	    timerId = this._later(target, method, isImmediate ? DISABLE_SCHEDULE : args, wait);
	    if (isImmediate) {
	      this._join(target, method, args);
	    }
	  } else {
	    timerId = this._timers[index + 1];
	    var argIndex = index + 4;
	    if (this._timers[argIndex] !== DISABLE_SCHEDULE) {
	      this._timers[argIndex] = args;
	    }
	  }
	  return timerId;
	};
	Backburner.prototype.debounce = function debounce() {
	  debounceCount++;
	  var ref = parseDebounceArgs.apply(void 0, arguments);
	  var target = ref[0];
	  var method = ref[1];
	  var args = ref[2];
	  var wait = ref[3];
	  var isImmediate = ref[4];
	  if (isImmediate === void 0) isImmediate = false;
	  var _timers = this._timers;
	  var index = findTimerItem(target, method, _timers);
	  var timerId;
	  if (index === -1) {
	    timerId = this._later(target, method, isImmediate ? DISABLE_SCHEDULE : args, wait);
	    if (isImmediate) {
	      this._join(target, method, args);
	    }
	  } else {
	    var executeAt = this._platform.now() + wait;
	    var argIndex = index + 4;
	    if (_timers[argIndex] === DISABLE_SCHEDULE) {
	      args = DISABLE_SCHEDULE;
	    }
	    timerId = _timers[index + 1];
	    var i = binarySearch(executeAt, _timers);
	    if (index + TIMERS_OFFSET === i) {
	      _timers[index] = executeAt;
	      _timers[argIndex] = args;
	    } else {
	      var stack = this._timers[index + 5];
	      this._timers.splice(i, 0, executeAt, timerId, target, method, args, stack);
	      this._timers.splice(index, TIMERS_OFFSET);
	    }
	    if (index === 0) {
	      this._reinstallTimerTimeout();
	    }
	  }
	  return timerId;
	};
	Backburner.prototype.cancelTimers = function cancelTimers() {
	  cancelTimersCount++;
	  this._clearTimerTimeout();
	  this._timers = [];
	  this._cancelAutorun();
	};
	Backburner.prototype.hasTimers = function hasTimers() {
	  return this._timers.length > 0 || this._autorun;
	};
	Backburner.prototype.cancel = function cancel(timer) {
	  cancelCount++;
	  if (timer === null || timer === undefined) {
	    return false;
	  }
	  var timerType = typeof timer;
	  if (timerType === 'number') {
	    // we're cancelling a setTimeout or throttle or debounce
	    return this._cancelLaterTimer(timer);
	  } else if (timerType === 'object' && timer.queue && timer.method) {
	    // we're cancelling a deferOnce
	    return timer.queue.cancel(timer);
	  }
	  return false;
	};
	Backburner.prototype.ensureInstance = function ensureInstance() {
	  this._ensureInstance();
	};
	/**
	 * Returns debug information related to the current instance of Backburner
	 *
	 * @method getDebugInfo
	 * @returns {Object | undefined} Will return and Object containing debug information if
	 * the DEBUG flag is set to true on the current instance of Backburner, else undefined.
	 */
	Backburner.prototype.getDebugInfo = function getDebugInfo() {
	  var this$1$1 = this;
	  if (this.DEBUG) {
	    return {
	      autorun: this._autorunStack,
	      counters: this.counters,
	      timers: getQueueItems(this._timers, TIMERS_OFFSET, 2),
	      instanceStack: [this.currentInstance].concat(this.instanceStack).map(function (deferredActionQueue) {
	        return deferredActionQueue && deferredActionQueue._getDebugInfo(this$1$1.DEBUG);
	      })
	    };
	  }
	  return undefined;
	};
	Backburner.prototype._end = function _end(fromAutorun) {
	  var currentInstance = this.currentInstance;
	  var nextInstance = null;
	  if (currentInstance === null) {
	    throw new Error("end called without begin");
	  }
	  // Prevent double-finally bug in Safari 6.0.2 and iOS 6
	  // This bug appears to be resolved in Safari 6.0.5 and iOS 7
	  var finallyAlreadyCalled = false;
	  var result;
	  try {
	    result = currentInstance.flush(fromAutorun);
	  } finally {
	    if (!finallyAlreadyCalled) {
	      finallyAlreadyCalled = true;
	      if (result === 1 /* Pause */) {
	        var plannedNextQueue = this.queueNames[currentInstance.queueNameIndex];
	        this._scheduleAutorun(plannedNextQueue);
	      } else {
	        this.currentInstance = null;
	        if (this.instanceStack.length > 0) {
	          nextInstance = this.instanceStack.pop();
	          this.currentInstance = nextInstance;
	        }
	        this._trigger('end', currentInstance, nextInstance);
	        this._onEnd(currentInstance, nextInstance);
	      }
	    }
	  }
	};
	Backburner.prototype._join = function _join(target, method, args) {
	  if (this.currentInstance === null) {
	    return this._run(target, method, args);
	  }
	  if (target === undefined && args === undefined) {
	    return method();
	  } else {
	    return method.apply(target, args);
	  }
	};
	Backburner.prototype._run = function _run(target, method, args) {
	  var onError = getOnError(this.options);
	  this.begin();
	  if (onError) {
	    try {
	      return method.apply(target, args);
	    } catch (error) {
	      onError(error);
	    } finally {
	      this.end();
	    }
	  } else {
	    try {
	      return method.apply(target, args);
	    } finally {
	      this.end();
	    }
	  }
	};
	Backburner.prototype._cancelAutorun = function _cancelAutorun() {
	  if (this._autorun) {
	    this._platform.clearNext();
	    this._autorun = false;
	    this._autorunStack = null;
	  }
	};
	Backburner.prototype._later = function _later(target, method, args, wait) {
	  var stack = this.DEBUG ? new Error() : undefined;
	  var executeAt = this._platform.now() + wait;
	  var id = UUID++;
	  if (this._timers.length === 0) {
	    this._timers.push(executeAt, id, target, method, args, stack);
	    this._installTimerTimeout();
	  } else {
	    // find position to insert
	    var i = binarySearch(executeAt, this._timers);
	    this._timers.splice(i, 0, executeAt, id, target, method, args, stack);
	    // always reinstall since it could be out of sync
	    this._reinstallTimerTimeout();
	  }
	  return id;
	};
	Backburner.prototype._cancelLaterTimer = function _cancelLaterTimer(timer) {
	  for (var i = 1; i < this._timers.length; i += TIMERS_OFFSET) {
	    if (this._timers[i] === timer) {
	      this._timers.splice(i - 1, TIMERS_OFFSET);
	      if (i === 1) {
	        this._reinstallTimerTimeout();
	      }
	      return true;
	    }
	  }
	  return false;
	};
	/**
	 Trigger an event. Supports up to two arguments. Designed around
	 triggering transition events from one run loop instance to the
	 next, which requires an argument for theinstance and then
	 an argument for the next instance.

	 @private
	 @method _trigger
	 @param {String} eventName
	 @param {any} arg1
	 @param {any} arg2
	 */
	Backburner.prototype._trigger = function _trigger(eventName, arg1, arg2) {
	  var callbacks = this._eventCallbacks[eventName];
	  if (callbacks !== undefined) {
	    for (var i = 0; i < callbacks.length; i++) {
	      callbacks[i](arg1, arg2);
	    }
	  }
	};
	Backburner.prototype._runExpiredTimers = function _runExpiredTimers() {
	  this._timerTimeoutId = null;
	  if (this._timers.length > 0) {
	    this.begin();
	    this._scheduleExpiredTimers();
	    this.end();
	  }
	};
	Backburner.prototype._scheduleExpiredTimers = function _scheduleExpiredTimers() {
	  var timers = this._timers;
	  var i = 0;
	  var l = timers.length;
	  var defaultQueue = this._defaultQueue;
	  var n = this._platform.now();
	  for (; i < l; i += TIMERS_OFFSET) {
	    var executeAt = timers[i];
	    if (executeAt > n) {
	      break;
	    }
	    var args = timers[i + 4];
	    if (args !== DISABLE_SCHEDULE) {
	      var target = timers[i + 2];
	      var method = timers[i + 3];
	      var stack = timers[i + 5];
	      this.currentInstance.schedule(defaultQueue, target, method, args, false, stack);
	    }
	  }
	  timers.splice(0, i);
	  this._installTimerTimeout();
	};
	Backburner.prototype._reinstallTimerTimeout = function _reinstallTimerTimeout() {
	  this._clearTimerTimeout();
	  this._installTimerTimeout();
	};
	Backburner.prototype._clearTimerTimeout = function _clearTimerTimeout() {
	  if (this._timerTimeoutId === null) {
	    return;
	  }
	  this._platform.clearTimeout(this._timerTimeoutId);
	  this._timerTimeoutId = null;
	};
	Backburner.prototype._installTimerTimeout = function _installTimerTimeout() {
	  if (this._timers.length === 0) {
	    return;
	  }
	  var minExpiresAt = this._timers[0];
	  var n = this._platform.now();
	  var wait = Math.max(0, minExpiresAt - n);
	  this._timerTimeoutId = this._platform.setTimeout(this._boundRunExpiredTimers, wait);
	};
	Backburner.prototype._ensureInstance = function _ensureInstance() {
	  var currentInstance = this.currentInstance;
	  if (currentInstance === null) {
	    this._autorunStack = this.DEBUG ? new Error() : undefined;
	    currentInstance = this.begin();
	    this._scheduleAutorun(this.queueNames[0]);
	  }
	  return currentInstance;
	};
	Backburner.prototype._scheduleAutorun = function _scheduleAutorun(plannedNextQueue) {
	  autorunsCreatedCount++;
	  var next = this._platform.next;
	  var flush = this.options.flush;
	  if (flush) {
	    flush(plannedNextQueue, next);
	  } else {
	    next();
	  }
	  this._autorun = true;
	};
	Object.defineProperties(Backburner.prototype, prototypeAccessors);
	Backburner.Queue = Queue;
	Backburner.buildPlatform = buildPlatform;
	Backburner.buildNext = buildNext;
	backburner.buildPlatform = buildPlatform;
	backburner.default = Backburner;
	return backburner;
}

var backburnerExports = requireBackburner();
var Backburner = /*@__PURE__*/getDefaultExportFromCjs(backburnerExports);

let currentRunLoop = null;
function _getCurrentRunLoop() {
  return currentRunLoop;
}
const _backburner$1 = new Backburner(['actions', 'afterRender'], {
  defaultQueue: 'actions'
});
function run$1(...args) {
  return _backburner$1.run(...args);
}
function join$1(methodOrTarget, methodOrArg, ...additionalArgs) {
  return _backburner$1.join(methodOrTarget, methodOrArg, ...additionalArgs);
}
function bind(...curried) {
  return (...args) => join$1(...curried.concat(args));
}
function begin() {
  _backburner$1.begin();
}
function end() {
  _backburner$1.end();
}
function schedule(...args) {
  // @ts-expect-error TS doesn't like the rest args here
  return _backburner$1.schedule(...args);
}
// Used by global test teardown
function _hasScheduledTimers() {
  return _backburner$1.hasTimers();
}
// Used by global test teardown
function _cancelTimers() {
  _backburner$1.cancelTimers();
}
function later$1(...args) {
  return _backburner$1.later(...args);
}
function once(...args) {
  // @ts-expect-error TS doesn't like the rest args here
  return _backburner$1.scheduleOnce('actions', ...args);
}
function scheduleOnce$1(...args) {
  // @ts-expect-error TS doesn't like the rest args here
  return _backburner$1.scheduleOnce(...args);
}
function next(...args) {
  return _backburner$1.later(...args, 1);
}
function cancel$1(timer) {
  return _backburner$1.cancel(timer);
}
function debounce$1(...args) {
  // @ts-expect-error TS doesn't like the rest args here
  return _backburner$1.debounce(...args);
}
function throttle(...args) {
  // @ts-expect-error TS doesn't like the rest args here
  return _backburner$1.throttle(...args);
}

var runloop = /*#__PURE__*/Object.freeze({
	__proto__: null,
	_backburner: _backburner$1,
	_cancelTimers: _cancelTimers,
	_getCurrentRunLoop: _getCurrentRunLoop,
	_hasScheduledTimers: _hasScheduledTimers,
	begin: begin,
	bind: bind,
	cancel: cancel$1,
	debounce: debounce$1,
	end: end,
	join: join$1,
	later: later$1,
	next: next,
	once: once,
	run: run$1,
	schedule: schedule,
	scheduleOnce: scheduleOnce$1,
	throttle: throttle
});

// it could happen that runloop is available but _backburner is not exported (dead code)
// then we need to use our own.
let module = runloop;
let _backburner = _backburner$1;
const keys = ['cancel', 'debounce', 'join', 'later', 'scheduleOnce'];
if (Runloop) {
  module = Runloop;
  _backburner = Runloop._backburner || Runloop.backburner;
}
if (!keys.every(k => k in module)) {
  module = runloop;
}

// if it is our own, run a internal to trigger `end`
// required in object inspector & render debug
function loop() {
  _backburner.later('actions', loop, 300);
}
if (_backburner === _backburner$1) {
  loop();
}
let run = run$1;
let {
  cancel,
  debounce,
  join,
  later,
  scheduleOnce
} = module;

export { _backburner as _, cancel as c, debounce as d, join as j, later as l, run as r, scheduleOnce as s };
