(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.tasksf = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Task = require('../tasks/Task');

var _Task2 = _interopRequireDefault(_Task);

var _Factory = require('../factory/Factory');

var _Factory2 = _interopRequireDefault(_Factory);

var _Injector = require('../tasks/Injector');

var _Injector2 = _interopRequireDefault(_Injector);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Collection. Abstract class.
 *
 * Basic collection class. Do NOT instantiate directly.
 *
 * @param {Function} complete function to be called on complete
 * @param {Function} recover function to be called on recover
 */
var Collection = function () {
  /**
   * Task constructor
   *
   * @param {Function} complete function to be called on complete
   * @param {Function} recover function to be called on recover
   */
  function Collection(complete, recover) {
    _classCallCheck(this, Collection);

    this.tasks = [];

    this._autoRun = false;
    this._running = false;

    this._attached = {};

    this.__complete = new _Task2.default(undefined, complete, undefined);
    this.__recover = new _Task2.default(undefined, undefined, recover);

    this.__complete.attach(_Factory2.default._CHAIN_, this);
    this.__recover.attach(_Factory2.default._CHAIN_, this);

    _Injector2.default.addChainGetter(this.__complete);
    _Injector2.default.addChainGetter(this.__recover);
  }

  /**
   * Attaches variable with a key
   *
   * Used to avoid using global variables or trying to scope
   * in some way. After attach() you can get().
   * Attach will also keep the variable from GC.
   *
   * @param {string} key accessor for the variable
   * @param {any} value variable value
   */


  _createClass(Collection, [{
    key: 'attach',
    value: function attach(key, value) {
      this._attached[key] = value;
    }

    /**
     * Detaches variable with a key
     *
     * @param {string} key accessor for the variable
     */

  }, {
    key: 'detach',
    value: function detach(key) {
      delete this._attached[key];
    }

    /**
     * Gets variable with a key
     *
     * @param {string} key accessor for the variable
     * @return {any} value variable value
     */

  }, {
    key: 'get',
    value: function get(key) {
      return this._attached[key];
    }

    /**
     * Pushes task to the collection
     *
     * @param {Task} task task to push
     * @return {Collection} collection current collection
     */

  }, {
    key: 'push',
    value: function push(task) {
      this._chainTask(task);
      this.tasks.push(task);

      this._postTaskAdds();

      return this;
    }

    /**
     * Unshifts task to the collection
     *
     * @param {Task} task task to push
     * @return {Collection} collection current collection
     */

  }, {
    key: 'unshift',
    value: function unshift(task) {
      this._chainTask(task);
      this.tasks.unshift(task);

      this._postTaskAdds();

      return this;
    }

    /**
     * Removes task from the collection
     *
     * @param {Task} task task to push
     * @return {Collection} collection current collection
     */

  }, {
    key: 'remove',
    value: function remove(task) {
      var index = this.tasks.indexOf(task);
      if (index !== -1) {
        this._unchainTask(task);
        this.tasks.splice(index, 1);
      }

      return this;
    }

    /**
     * Runs all tasks in the collection
     */

  }, {
    key: 'run',
    value: function run() {
      this._running = true;
    }

    /**
     * Stops all tasks in the collection
     *
     * @return {boolean} stopped stopped status
     */

  }, {
    key: 'stop',
    value: function stop() {
      return false;
    }

    /**
     * Resets a stopped collection
     *
     * @return {boolean} reset reset status
     */

  }, {
    key: 'reset',
    value: function reset() {
      if (!this._running) {
        this._attached = {};
        while (this.tasks.length > 0) {
          this.remove(this.tasks[0]);
        }

        return true;
      } else {
        return false;
      }
    }

    /**
     * Complete
     *
     * Runs complete task
     *
     * @protected
     */

  }, {
    key: '_complete',
    value: function _complete() {
      this._running = false;

      this.__complete.run();
    }

    /**
     * Recover
     *
     * Runs recover task
     *
     * @protected
     */

  }, {
    key: '_recover',
    value: function _recover(error) {
      this._running = false;

      this.__recover.recover(error);
    }

    /**
     * Chain task
     *
     * Attach the chain to the task
     *
     * @param {Task} task task to chain
     *
     * @protected
     */

  }, {
    key: '_chainTask',
    value: function _chainTask(task) {
      task.attach(_Factory2.default._CHAIN_, this);
      _Injector2.default.addChainGetter(task);
    }

    /**
     * Unchain task
     *
     * Detach the chain from the task
     *
     * @param {Task} task task to chain
     *
     * @protected
     */

  }, {
    key: '_unchainTask',
    value: function _unchainTask(task) {
      _Injector2.default.removeChainGetter(task);
      task.detach(_Factory2.default._CHAIN_);
    }

    /**
     * Probe post add actions
     *
     * Try all post add triggers
     *
     * @protected
     */

  }, {
    key: '_postTaskAdds',
    value: function _postTaskAdds() {
      if (this.autoRun) {
        this.run();
      }
    }

    /**
     * Gets the running status
     *
     * @return {boolean} running running status
     */

  }, {
    key: 'running',
    get: function get() {
      return this._running;
    }

    /**
     * Gets the current task(s)
     *
     * @return {Task|Array<Task>} task current task(s)
     */

  }, {
    key: 'current',
    get: function get() {
      return undefined;
    }

    /**
     * Gets the passed task(s)
     *
     * @return {Array<Task>} task passed task(s)
     */

  }, {
    key: 'passed',
    get: function get() {
      return undefined;
    }

    /**
     * Sets autoRun
     *
     * Will autorun on push or unshift
      * @param {boolean} autoRun auto runs on push or unshift
     */

  }, {
    key: 'autoRun',
    set: function set(value) {
      this._autoRun = value;
    }

    /**
     * Gets autoRun
     *
     * @return {boolean} autoStart auto start on push or unshift
     */
    ,
    get: function get() {
      return this._autoRun;
    }
  }]);

  return Collection;
}();

exports.default = Collection;
},{"../factory/Factory":7,"../tasks/Injector":16,"../tasks/Task":18}],2:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Parallel2 = require('./Parallel');

var _Parallel3 = _interopRequireDefault(_Parallel2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Limiter
 *
 * Parallel with limit for max running tasks
 *
 * @param {number} limit max running tasks
 * @param {Function} complete function to be called on complete
 * @param {Function} recover function to be called on recover
 * @param {boolean} completeOnFirst completes on last or on first
 */
var Limiter = function (_Parallel) {
  _inherits(Limiter, _Parallel);

  /**
   * Limiter constructor
   *
   * @param {number} limit max running tasks
   * @param {Function} complete function to be called on complete
   * @param {Function} recover function to be called on recover
   * @param {boolean} completeOnFirst completes on last or on first
   */
  function Limiter(limit, complete, recover, completeOnFirst) {
    _classCallCheck(this, Limiter);

    var _this = _possibleConstructorReturn(this, (Limiter.__proto__ || Object.getPrototypeOf(Limiter)).call(this, complete, recover, completeOnFirst));

    _this._limit = limit > 1 ? limit : 1;
    return _this;
  }

  /**
   * Returns the run condition
   *
   * @return {boolean} condition run condition
   * @protected
   */


  _createClass(Limiter, [{
    key: '_taskComplete',


    /**
     * Performs on every task complete
     *
     * @protected
     */
    value: function _taskComplete() {
      if (this.tasks.length > 0) {
        this._run(this.tasks.shift());
      }
    }
  }, {
    key: '_runCondition',
    get: function get() {
      return this.tasks.length > 0 && this._current.length < this._limit;
    }
  }]);

  return Limiter;
}(_Parallel3.default);

exports.default = Limiter;
},{"./Parallel":4}],3:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };

var _Sequence2 = require('./Sequence');

var _Sequence3 = _interopRequireDefault(_Sequence2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Loop
 *
 * Recurrent tasks
 *
 * @param {number} repeats number of repeats. 0 for infinite
 * @param {Function} repeat function to be called on repeat
 * @param {Function} recover function to be called on recover
 */
var Loop = function (_Sequence) {
  _inherits(Loop, _Sequence);

  /**
   * Loop constructor
   *
   * @param {number} repeats number of repeats. 0 for infinite
   * @param {Function} repeat function to be called on repeat
   * @param {Function} recover function to be called on recover
   */
  function Loop(repeats, repeat, recover) {
    _classCallCheck(this, Loop);

    var _this = _possibleConstructorReturn(this, (Loop.__proto__ || Object.getPrototypeOf(Loop)).call(this, repeat, recover));

    _this._repeats = repeats === undefined ? 0 : repeats;
    _this._repeat = 0;
    _this._looped = [];
    return _this;
  }

  /**
   * Complete
   *
   * Runs complete task
   *
   * @protected
   */


  _createClass(Loop, [{
    key: '_complete',
    value: function _complete() {
      var _this2 = this;

      _get(Loop.prototype.__proto__ || Object.getPrototypeOf(Loop.prototype), '_complete', this).call(this);

      if (!this._stopped) {
        if (this._repeats === 0 || ++this._repeat < this._repeats) {
          while (this._looped.length > 0) {
            this.tasks.push(this._looped.shift());

            this._chainTask(this.tasks[this.tasks.length - 1]);
          }

          setTimeout(function () {
            return _this2.run();
          }, 0);
        }
      }
    }

    /**
     * Gets next task from the loop
     *
     * @return {Task} task next task
     * @protected
     */

  }, {
    key: '__next',
    get: function get() {
      var current = _get(Loop.prototype.__proto__ || Object.getPrototypeOf(Loop.prototype), '__next', this);

      if (this._looped.length === 0 || this._looped[this._looped.length - 1] !== current) {
        this._looped.push(current);
      }

      return current;
    }

    /**
     * Gets the passed task(s)
     *
     * @return {Array<Task>} task passed task(s)
     */

  }, {
    key: 'passed',
    get: function get() {
      return undefined;
    }
  }]);

  return Loop;
}(_Sequence3.default);

exports.default = Loop;
},{"./Sequence":5}],4:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };

var _Collection2 = require('./Collection');

var _Collection3 = _interopRequireDefault(_Collection2);

var _Injector = require('../tasks/Injector');

var _Injector2 = _interopRequireDefault(_Injector);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Parallel
 *
 * Executes tasks all at once
 *
 * @param {Function} complete function to be called on complete
 * @param {Function} recover function to be called on recover
 * @param {boolean} completeOnFirst completes on last or on first
 */
var Parallel = function (_Collection) {
  _inherits(Parallel, _Collection);

  /**
   * Parallel constructor
   *
   * @param {Function} complete function to be called on complete
   * @param {Function} recover function to be called on recover
   * @param {boolean} completeOnFirst completes on last or on first
   */
  function Parallel(complete, recover, completeOnFirst) {
    _classCallCheck(this, Parallel);

    var _this = _possibleConstructorReturn(this, (Parallel.__proto__ || Object.getPrototypeOf(Parallel)).call(this, complete, recover));

    _this._current = [];
    _this._passed = [];
    _this._completeOnFirst = completeOnFirst === true;
    return _this;
  }

  /**
   * Runs all tasks in the collection
   */


  _createClass(Parallel, [{
    key: 'run',
    value: function run() {
      _get(Parallel.prototype.__proto__ || Object.getPrototypeOf(Parallel.prototype), 'run', this).call(this);

      while (this._runCondition) {
        this._run(this.tasks.shift());
      }
    }

    /**
     * Runs a single task
     *
     * @protected
     */

  }, {
    key: '_run',
    value: function _run(task) {
      var _this2 = this;

      _Injector2.default.afterComplete(task, function (error, self) {
        _Injector2.default.resetAfterComplete(self, 'parallelAfterComplete');
        _this2._unchainTask(self);

        var index = _this2._current.indexOf(self);
        if (index !== -1) {
          _this2._current.splice(index, 1);
        }
        if (_this2._passed.indexOf(self) === -1) {
          _this2._passed.push(task);
        }

        if (_this2._completeOnFirst && _this2._passed.length === 1) {
          _this2._complete();
        } else if (!_this2._completeOnFirst && _this2._current.length === 0 && _this2.tasks.length === 0) {
          _this2._complete();
        }

        _this2._taskComplete();
      }, 'parallelAfterComplete');

      this._current.push(task);
      task.run();
    }

    /**
     * Returns the run condition
     *
     * @return {boolean} condition run condition
     * @protected
     */

  }, {
    key: '_taskComplete',


    /**
     * Performs on every task complete
     *
     * @protected
     */
    value: function _taskComplete() {}
    //


    /**
     * Stops all tasks in the collection
     *
     * @param {boolean} skip force the stopped task to be skipped
     * @return {boolean} stopped stopped status
     */

  }, {
    key: 'stop',
    value: function stop() {
      var _this3 = this;

      var skip = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      this._running = false;

      var result = true;

      this._current.forEach(function (item) {
        result = result || item.stop();

        if (skip) {
          _Injector2.default.resetAfterComplete(item, 'parallelAfterComplete');
          _this3._unchainTask(item);
        }
      });

      if (skip) {
        this._current = [];
      } else {
        while (this._current.length > 0) {
          this.tasks.push(this._current.shift());
        }
      }

      return result;
    }

    /**
     * Resets a stopped collection
     *
     * @return {boolean} reset reset status
     */

  }, {
    key: 'reset',
    value: function reset() {
      if (_get(Parallel.prototype.__proto__ || Object.getPrototypeOf(Parallel.prototype), 'reset', this).call(this)) {
        this._passed = [];

        return true;
      } else {
        return false;
      }
    }

    /**
     * Gets the current tasks
     *
     * @return {Array<Task>} task current tasks
     */

  }, {
    key: '_runCondition',
    get: function get() {
      return this.tasks.length > 0;
    }
  }, {
    key: 'current',
    get: function get() {
      return this._current;
    }

    /**
     * Gets the passed task(s)
     *
     * @return {Array<Task>} task passed task(s)
     */

  }, {
    key: 'passed',
    get: function get() {
      return this._passed;
    }
  }]);

  return Parallel;
}(_Collection3.default);

exports.default = Parallel;
},{"../tasks/Injector":16,"./Collection":1}],5:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };

var _Collection2 = require('./Collection');

var _Collection3 = _interopRequireDefault(_Collection2);

var _Injector = require('../tasks/Injector');

var _Injector2 = _interopRequireDefault(_Injector);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Sequence
 *
 * Executes tasks one by one
 *
 * @param {Function} complete function to be called on complete
 * @param {Function} recover function to be called on recover
 */
var Sequence = function (_Collection) {
  _inherits(Sequence, _Collection);

  /**
   * Sequence constructor
   *
   * @param {Function} complete function to be called on complete
   * @param {Function} recover function to be called on recover
   */
  function Sequence(complete, recover) {
    _classCallCheck(this, Sequence);

    var _this = _possibleConstructorReturn(this, (Sequence.__proto__ || Object.getPrototypeOf(Sequence)).call(this, complete, recover));

    _this._current = undefined;
    _this._passed = [];
    _this._stopped = false;
    return _this;
  }

  /**
   * Runs all tasks in the collection
   */


  _createClass(Sequence, [{
    key: 'run',
    value: function run() {
      _get(Sequence.prototype.__proto__ || Object.getPrototypeOf(Sequence.prototype), 'run', this).call(this);

      this._stopped = false;

      this._next();
    }

    /**
     * Stops all tasks in the collection
     *
     * @param {boolean} skip force the stopped task to be skipped
     * @return {boolean} stopped stopped status
     */

  }, {
    key: 'stop',
    value: function stop() {
      var skip = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      this._stopped = true;
      this._running = false;

      var current = this.current;
      if (current !== undefined) {
        if (skip === true) {
          this._resetCurrent(true, true);
        } else {
          if (this.tasks.indexOf(current) === -1) {
            this.unshift(current);
          }
        }

        return current.stop() || this.tasks.length > 0;
      } else {
        return false;
      }
    }

    /**
     * Resets a stopped collection
     *
     * @return {boolean} reset reset status
     */

  }, {
    key: 'reset',
    value: function reset() {
      if (_get(Sequence.prototype.__proto__ || Object.getPrototypeOf(Sequence.prototype), 'reset', this).call(this)) {
        this._passed = [];

        return true;
      } else {
        return false;
      }
    }

    /**
     * Runs next in the sequence
     *
     * @protected
     */

  }, {
    key: '_next',
    value: function _next() {
      if (this._stopped) return;

      if (this.tasks.length > 0) {
        this.__next.run();
      } else {
        this._complete();
      }
    }

    /**
     * Complete
     *
     * Runs complete task
     *
     * @protected
     */

  }, {
    key: '_complete',
    value: function _complete() {
      this._resetCurrent(true);

      _get(Sequence.prototype.__proto__ || Object.getPrototypeOf(Sequence.prototype), '_complete', this).call(this);
    }

    /**
     * Recover
     *
     * Runs recover task
     *
     * @protected
     */

  }, {
    key: '_recover',
    value: function _recover(error) {
      if (this._stopped) return;

      if (this.tasks.length > 0) {
        var task = this.__next;
        task.recover(error);
        if (!task.running && !task.done) {
          this._resetCurrent(true);

          _get(Sequence.prototype.__proto__ || Object.getPrototypeOf(Sequence.prototype), '_recover', this).call(this, error);
        }
      } else {
        this._complete();
      }
    }

    /**
     * Resets current
     *
     * @protected
     */

  }, {
    key: '_resetCurrent',
    value: function _resetCurrent() {
      var unchain = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
      var resetAfterComplete = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

      if (this._current !== undefined) {
        if (unchain) {
          this._unchainTask(this._current);
        }
        if (resetAfterComplete) {
          _Injector2.default.resetAfterComplete(this._current, 'sequenceAfterComplete');
        }
        this._current = undefined;
      }
    }

    /**
     * Gets next task from the loop
     *
     * @return {Task} task next task
     * @protected
     */

  }, {
    key: '__next',
    get: function get() {
      var _this2 = this;

      this._current = this.tasks.length > 0 ? _Injector2.default.afterComplete(this.tasks.shift(), function (error) {
        _Injector2.default.resetAfterComplete(_this2._current, 'sequenceAfterComplete');

        if (_this2._passed.length === 0 || _this2._passed.indexOf(_this2._current) === -1) {
          _this2._passed.push(_this2._current);
        }

        _this2._resetCurrent(true);

        if (error === undefined) {
          _this2._next();
        } else {
          _this2._recover(error);
        }
      }, 'sequenceAfterComplete') : undefined;

      return this._current;
    }

    /**
     * Gets the current task
     *
     * @return {Task} task current task
     */

  }, {
    key: 'current',
    get: function get() {
      return this._current;
    }

    /**
     * Gets the passed task(s)
     *
     * @return {Array<Task>} task passed task(s)
     */

  }, {
    key: 'passed',
    get: function get() {
      return this._passed;
    }
  }]);

  return Sequence;
}(_Collection3.default);

exports.default = Sequence;
},{"../tasks/Injector":16,"./Collection":1}],6:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Map2 = require('./Map');

var _Map3 = _interopRequireDefault(_Map2);

var _Match = require('./Match');

var _Match2 = _interopRequireDefault(_Match);

var _AsyncTask = require('../tasks/AsyncTask');

var _AsyncTask2 = _interopRequireDefault(_AsyncTask);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Map for AsyncTask
 *
 * Maps the default ways to get a AsyncTask
 */
var AsyncMap = function (_Map) {
  _inherits(AsyncMap, _Map);

  function AsyncMap() {
    _classCallCheck(this, AsyncMap);

    return _possibleConstructorReturn(this, (AsyncMap.__proto__ || Object.getPrototypeOf(AsyncMap)).apply(this, arguments));
  }

  _createClass(AsyncMap, [{
    key: 'match',

    /**
     * Match argument with a specific TriggerMap
     *
     * @param {Function} run function to be called on run
     * @param {Function} complete function to be called on complete
     * @param {Function} recover function to be called on recover
     * @param {number} marker 0 marks a async task
     * @return {Match} match
     */
    value: function match() {
      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      if (args.length === 4 && typeof args[0] === 'function' && typeof args[1] === 'function' && typeof args[2] === 'function' && args[3] === 0) {
        return new _Match2.default(new (Function.prototype.bind.apply(_AsyncTask2.default, [null].concat(_toConsumableArray(args.slice(0, -1)))))());
      } else if (args.length === 3 && typeof args[0] === 'function' && typeof args[1] === 'function' && args[2] === 0) {
        return new _Match2.default(new (Function.prototype.bind.apply(_AsyncTask2.default, [null].concat(_toConsumableArray(args.slice(0, -1)))))());
      } else if (args.length === 2 && typeof args[0] === 'function' && args[1] === 0) {
        return new _Match2.default(new (Function.prototype.bind.apply(_AsyncTask2.default, [null].concat(_toConsumableArray(args.slice(0, -1)))))());
      } else {
        return undefined;
      }
    }
  }]);

  return AsyncMap;
}(_Map3.default);

exports.default = AsyncMap;
},{"../tasks/AsyncTask":15,"./Map":8,"./Match":9}],7:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _RawMap = require('./RawMap');

var _RawMap2 = _interopRequireDefault(_RawMap);

var _TimeoutMap = require('./TimeoutMap');

var _TimeoutMap2 = _interopRequireDefault(_TimeoutMap);

var _TriggerMap = require('./TriggerMap');

var _TriggerMap2 = _interopRequireDefault(_TriggerMap);

var _AsyncMap = require('./AsyncMap');

var _AsyncMap2 = _interopRequireDefault(_AsyncMap);

var _PromiseMap = require('./PromiseMap');

var _PromiseMap2 = _interopRequireDefault(_PromiseMap);

var _Sequence = require('../chains/Sequence');

var _Sequence2 = _interopRequireDefault(_Sequence);

var _Parallel = require('../chains/Parallel');

var _Parallel2 = _interopRequireDefault(_Parallel);

var _Loop = require('../chains/Loop');

var _Loop2 = _interopRequireDefault(_Loop);

var _Limiter = require('../chains/Limiter');

var _Limiter2 = _interopRequireDefault(_Limiter);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Tasks and Collections Factory
 *
 * It's a static class - do not instantiate with new
 *
 * @static
 */
var Factory = function () {
  function Factory() {
    _classCallCheck(this, Factory);
  }

  _createClass(Factory, null, [{
    key: 'task',


    /**
     * Gets a task by registered map match
     *
     * @param {any} args parameters depend on installed maps
     * @return {Task} task matching the parameters
     */


    /**
     * Attached variables
     *
     * @param {object} attached collection of any attachments
     */

    /**
     * Predefined name for a chain in attached task
     *
     * @param {string} _CHAIN_ predefined name
     */
    value: function task() {
      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      Factory.initialize();

      var match = void 0;
      Factory.maps.forEach(function (item) {
        var result = item.match.apply(item, args);

        if (result !== undefined) {
          if (match === undefined) {
            match = result;
          } else if (match.percentage <= result.percentage) {
            match = result;
          }
        }
      });

      return match !== undefined ? match.instance : undefined;
    }

    /**
     * Gets a sequence
     *
     * @param {Function} complete function to be called on complete
     * @param {Function} recover function to be called on recover
     * @return {Sequence} new sequence
     */


    /**
     * Initialized status
     *
     * @param {boolean} initialized initialized status
     */


    /**
     * Maps collection for task matching
     *
     * @param {Array<Map>} maps list of all maps
     */

  }, {
    key: 'sequence',
    value: function sequence(complete, recover) {
      Factory.initialize();

      return new _Sequence2.default(complete, recover);
    }

    /**
     * Gets a parallel
     *
     * @param {Function} complete function to be called on complete
     * @param {Function} recover function to be called on recover
     * @param {boolean} completeOnFirst completes on last or on first
     * @return {Parallel} new sequence
     */

  }, {
    key: 'parallel',
    value: function parallel(complete, recover, completeOnFirst) {
      Factory.initialize();

      return new _Parallel2.default(complete, recover, completeOnFirst);
    }

    /**
     * Gets a loop
     *
     * @param {number} repeats number of repeats, 0 for infinite
     * @param {Function} repeat function to be called on repeat
     * @param {Function} recover function to be called on recover
     * @return {Loop} new loop
     */

  }, {
    key: 'loop',
    value: function loop(repeats, repeat, recover) {
      Factory.initialize();

      return new _Loop2.default(repeats, repeat, recover);
    }

    /**
     * Gets a limiter
     *
     * @param {number} limit max running tasks
     * @param {Function} complete function to be called on complete
     * @param {Function} recover function to be called on recover
     * @param {boolean} completeOnFirst completes on last or on first
     * @return {Limiter} new limiter
     */

  }, {
    key: 'limiter',
    value: function limiter(limit, complete, recover, completeOnFirst) {
      Factory.initialize();

      return new _Limiter2.default(limit, complete, recover, completeOnFirst);
    }

    /**
     * Initializes the factory.
     *
     * Initializes the factory. Will be called automatically on first task
     * or sequence call. Can be called explicitly with *force*
     *
     * @param {boolean} force reinitialize if true
     */

  }, {
    key: 'initialize',
    value: function initialize() {
      var force = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

      if (!Factory.initialized || force) {
        Factory.initialized = true;

        Factory.maps = [new _RawMap2.default(), new _TimeoutMap2.default(), new _TriggerMap2.default(), new _AsyncMap2.default(), new _PromiseMap2.default()];
      }
    }

    /**
     * Adds new map for tasks matching
     *
     * @param {Map} map map for tasks matching
     */

  }, {
    key: 'map',
    value: function map(_map) {
      if (Factory.maps.indexOf(_map) === -1) {
        Factory.maps.push(_map);
      }
    }

    /**
     * Removes map from tasks matching
     *
     * @param {Map} map map to remove from tasks matching
     */

  }, {
    key: 'unmap',
    value: function unmap(map) {
      var index = Factory.maps.indexOf(map);
      if (index !== -1) {
        Factory.maps.splice(index, 1);
      }
    }

    /**
     * Removes all maps
     */

  }, {
    key: 'unmapAll',
    value: function unmapAll() {
      Factory.maps = [];
    }

    /**
     * Attaches variable to the factory
     *
     * Useful to store your collections and access them
     * later on from anywhere. Or store anything you want
     * in this predefined place
     *
     * @param {string} key accessor for the variable
     * @param {any} value variable value
     */

  }, {
    key: 'attach',
    value: function attach(key, value) {
      Factory.attached[key] = value;
    }

    /**
     * Detaches variable by name
     *
     * @param {string} key accessor for the variable
     */

  }, {
    key: 'detach',
    value: function detach(key) {
      delete Factory.attached[key];
    }

    /**
     * Gets variable by name
     *
     * @param {string} key accessor for the variable
     * @return {any} variable value
     */

  }, {
    key: 'get',
    value: function get(key) {
      return Factory.attached[key];
    }
  }]);

  return Factory;
}();

Factory._CHAIN_ = '_chain_';
Factory.maps = [];
Factory.attached = {};
Factory.initialized = false;
exports.default = Factory;
},{"../chains/Limiter":2,"../chains/Loop":3,"../chains/Parallel":4,"../chains/Sequence":5,"./AsyncMap":6,"./PromiseMap":10,"./RawMap":11,"./TimeoutMap":12,"./TriggerMap":13}],8:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Map for tasks
 *
 * Map is used to match parameters with tasks. Every map shall
 * match and return Match class unique for parameters. In case
 * of Match overlapping the one with bigger priority will be
 * selected.
 *
 * This class is the base for all Map classes. Cannot be used
 * directly. Extend to use.
 *
 * @abstract
 */
var Map = function () {
  function Map() {
    _classCallCheck(this, Map);
  }

  _createClass(Map, [{
    key: "match",

    /**
     * Match argument with a specific tasks
     *
     * @return {Match} match
     */
    value: function match() {
      return undefined;
    }
  }]);

  return Map;
}();

exports.default = Map;
},{}],9:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Match for a Map
 *
 * Match contains the instance of the Task and a
 * percentage from 0 to 1. In cases of overlapping
 * of Matches the one with bigger percentage will be
 * used
 *
 * @param {Task} instance any Task instance
 * @param {number} percentage from 0 to 1
 */
var Match = function () {
  /**
   * Match constructor
   *
   * @param {Task} instance any Task instance
   * @param {number} percentage from 0 to 1
   */
  function Match(instance, percentage) {
    _classCallCheck(this, Match);

    this._percentage = 0.5;
    this.instance = instance;

    this.percentage = percentage;
  }

  /**
   * Percentage setter
   *
   * @param {number} value from 0 to 1
   */


  _createClass(Match, [{
    key: "percentage",
    set: function set(value) {
      if (value !== undefined && value !== null && value !== false) {
        this._percentage = value > 1 ? 1 : value < 0 ? 0 : value;
      }
    }

    /**
     * Percentage getter
     *
     * @return {number} percentage value from 0 to 1
     */
    ,
    get: function get() {
      return this._percentage;
    }
  }]);

  return Match;
}();

exports.default = Match;
},{}],10:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Map2 = require('./Map');

var _Map3 = _interopRequireDefault(_Map2);

var _Match = require('./Match');

var _Match2 = _interopRequireDefault(_Match);

var _PromiseTask = require('../tasks/PromiseTask');

var _PromiseTask2 = _interopRequireDefault(_PromiseTask);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Map for PromiseTask
 *
 * Maps the default ways to get a PromiseTask
 */
var PromiseMap = function (_Map) {
  _inherits(PromiseMap, _Map);

  function PromiseMap() {
    _classCallCheck(this, PromiseMap);

    return _possibleConstructorReturn(this, (PromiseMap.__proto__ || Object.getPrototypeOf(PromiseMap)).apply(this, arguments));
  }

  _createClass(PromiseMap, [{
    key: 'match',

    /**
     * Match argument with a specific PromiseMap
     *
     * @param {Promise} promise promise to wait for
     * @param {Function} complete function to be called on complete
     * @param {Function} recover function to be called on recover
     * @return {Match} match
     */
    value: function match() {
      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      if (args.length === 3 && _typeof(args[0]) === 'object' && typeof args[1] === 'function' && typeof args[2] === 'function') {
        return new _Match2.default(new (Function.prototype.bind.apply(_PromiseTask2.default, [null].concat(args)))());
      } else if (args.length === 2 && _typeof(args[0]) === 'object' && typeof args[1] === 'function') {
        return new _Match2.default(new (Function.prototype.bind.apply(_PromiseTask2.default, [null].concat(args)))());
      } else if (args.length === 1 && _typeof(args[0]) === 'object') {
        return new _Match2.default(new (Function.prototype.bind.apply(_PromiseTask2.default, [null].concat(args)))());
      } else {
        return undefined;
      }
    }
  }]);

  return PromiseMap;
}(_Map3.default);

exports.default = PromiseMap;
},{"../tasks/PromiseTask":17,"./Map":8,"./Match":9}],11:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Map2 = require('./Map');

var _Map3 = _interopRequireDefault(_Map2);

var _Match = require('./Match');

var _Match2 = _interopRequireDefault(_Match);

var _Task = require('../tasks/Task');

var _Task2 = _interopRequireDefault(_Task);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Raw map for Task
 *
 * Maps the default ways to get a Task
 */
var RawMap = function (_Map) {
  _inherits(RawMap, _Map);

  function RawMap() {
    _classCallCheck(this, RawMap);

    return _possibleConstructorReturn(this, (RawMap.__proto__ || Object.getPrototypeOf(RawMap)).apply(this, arguments));
  }

  _createClass(RawMap, [{
    key: 'match',

    /**
     * Match argument with a specific Task
     *
     * @param {Function} run function to be called on run
     * @param {Function} complete function to be called on complete
     * @param {Function} recover function to be called on recover
     * @return {Match} match
     */
    value: function match() {
      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      if (args.length === 3 && typeof args[0] === 'function' && typeof args[1] === 'function' && typeof args[2] === 'function') {
        return new _Match2.default(new (Function.prototype.bind.apply(_Task2.default, [null].concat(args)))());
      } else if (args.length === 2 && typeof args[0] === 'function' && typeof args[1] === 'function') {
        return new _Match2.default(new (Function.prototype.bind.apply(_Task2.default, [null].concat(args)))());
      } else if (args.length === 1 && typeof args[0] === 'function') {
        return new _Match2.default(new (Function.prototype.bind.apply(_Task2.default, [null].concat(args)))());
      } else {
        return undefined;
      }
    }
  }]);

  return RawMap;
}(_Map3.default);

exports.default = RawMap;
},{"../tasks/Task":18,"./Map":8,"./Match":9}],12:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Map2 = require('./Map');

var _Map3 = _interopRequireDefault(_Map2);

var _Match = require('./Match');

var _Match2 = _interopRequireDefault(_Match);

var _TimeoutTask = require('../tasks/TimeoutTask');

var _TimeoutTask2 = _interopRequireDefault(_TimeoutTask);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Map for TimeoutTasks
 *
 * Maps the default ways to get a TimeoutTask
 */
var TimeoutMap = function (_Map) {
  _inherits(TimeoutMap, _Map);

  function TimeoutMap() {
    _classCallCheck(this, TimeoutMap);

    return _possibleConstructorReturn(this, (TimeoutMap.__proto__ || Object.getPrototypeOf(TimeoutMap)).apply(this, arguments));
  }

  _createClass(TimeoutMap, [{
    key: 'match',

    /**
     * Match argument with a specific TimeoutTask
     *
     * @param {number} timeout timeout in ms
     * @param {Function} run function to be called on run
     * @param {Function} complete function to be called on complete
     * @param {Function} recover function to be called on recover
     * @return {Match} match
     */
    value: function match() {
      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      if (args.length === 4 && typeof args[0] === 'number' && typeof args[1] === 'function' && typeof args[2] === 'function' && typeof args[3] === 'function') {
        return new _Match2.default(new (Function.prototype.bind.apply(_TimeoutTask2.default, [null].concat(args)))());
      } else if (args.length === 3 && typeof args[0] === 'number' && typeof args[1] === 'function' && typeof args[2] === 'function') {
        return new _Match2.default(new (Function.prototype.bind.apply(_TimeoutTask2.default, [null].concat(args)))());
      } else if (args.length === 2 && typeof args[0] === 'number' && typeof args[1] === 'function') {
        return new _Match2.default(new (Function.prototype.bind.apply(_TimeoutTask2.default, [null].concat(args)))());
      } else if (args.length === 1 && typeof args[0] === 'number') {
        return new _Match2.default(new (Function.prototype.bind.apply(_TimeoutTask2.default, [null].concat(args)))());
      } else {
        return undefined;
      }
    }
  }]);

  return TimeoutMap;
}(_Map3.default);

exports.default = TimeoutMap;
},{"../tasks/TimeoutTask":19,"./Map":8,"./Match":9}],13:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Map2 = require('./Map');

var _Map3 = _interopRequireDefault(_Map2);

var _Match = require('./Match');

var _Match2 = _interopRequireDefault(_Match);

var _TriggerTask = require('../tasks/TriggerTask');

var _TriggerTask2 = _interopRequireDefault(_TriggerTask);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * Map for TriggerTask
 *
 * Maps the default ways to get a TriggerTask
 */
var TriggerMap = function (_Map) {
  _inherits(TriggerMap, _Map);

  function TriggerMap() {
    _classCallCheck(this, TriggerMap);

    return _possibleConstructorReturn(this, (TriggerMap.__proto__ || Object.getPrototypeOf(TriggerMap)).apply(this, arguments));
  }

  _createClass(TriggerMap, [{
    key: 'match',

    /**
     * Match argument with a specific TriggerTask
     *
     * @param {Function} complete function to be called on complete
     * @param {boolean} marker false marks a trigger task
     * @return {Match} match
     */
    value: function match() {
      if (arguments.length === 2 && typeof (arguments.length <= 0 ? undefined : arguments[0]) === 'function' && (arguments.length <= 1 ? undefined : arguments[1]) === false) {
        return new _Match2.default(new _TriggerTask2.default(arguments.length <= 0 ? undefined : arguments[0]));
      } else if (arguments.length === 0) {
        return new _Match2.default(new _TriggerTask2.default(), 0);
      } else {
        return undefined;
      }
    }
  }]);

  return TriggerMap;
}(_Map3.default);

exports.default = TriggerMap;
},{"../tasks/TriggerTask":20,"./Map":8,"./Match":9}],14:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.Match = exports.Map = exports.tf = exports.Factory = exports.Limiter = exports.Loop = exports.Parallel = exports.Sequence = exports.Collection = exports.PromiseTask = exports.AsyncTask = exports.TriggerTask = exports.TimeoutTask = exports.Task = undefined;

var _Task = require('./tasks/Task');

var _Task2 = _interopRequireDefault(_Task);

var _TimeoutTask = require('./tasks/TimeoutTask');

var _TimeoutTask2 = _interopRequireDefault(_TimeoutTask);

var _TriggerTask = require('./tasks/TriggerTask');

var _TriggerTask2 = _interopRequireDefault(_TriggerTask);

var _AsyncTask = require('./tasks/AsyncTask');

var _AsyncTask2 = _interopRequireDefault(_AsyncTask);

var _PromiseTask = require('./tasks/PromiseTask');

var _PromiseTask2 = _interopRequireDefault(_PromiseTask);

var _Factory = require('./factory/Factory');

var _Factory2 = _interopRequireDefault(_Factory);

var _Map = require('./factory/Map');

var _Map2 = _interopRequireDefault(_Map);

var _Match = require('./factory/Match');

var _Match2 = _interopRequireDefault(_Match);

var _Collection = require('./chains/Collection');

var _Collection2 = _interopRequireDefault(_Collection);

var _Sequence = require('./chains/Sequence');

var _Sequence2 = _interopRequireDefault(_Sequence);

var _Parallel = require('./chains/Parallel');

var _Parallel2 = _interopRequireDefault(_Parallel);

var _Loop = require('./chains/Loop');

var _Loop2 = _interopRequireDefault(_Loop);

var _Limiter = require('./chains/Limiter');

var _Limiter2 = _interopRequireDefault(_Limiter);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

exports.Task = _Task2.default;
exports.TimeoutTask = _TimeoutTask2.default;
exports.TriggerTask = _TriggerTask2.default;
exports.AsyncTask = _AsyncTask2.default;
exports.PromiseTask = _PromiseTask2.default;
exports.Collection = _Collection2.default;
exports.Sequence = _Sequence2.default;
exports.Parallel = _Parallel2.default;
exports.Loop = _Loop2.default;
exports.Limiter = _Limiter2.default;
exports.Factory = _Factory2.default;
exports.tf = _Factory2.default;
exports.Map = _Map2.default;
exports.Match = _Match2.default;
},{"./chains/Collection":1,"./chains/Limiter":2,"./chains/Loop":3,"./chains/Parallel":4,"./chains/Sequence":5,"./factory/Factory":7,"./factory/Map":8,"./factory/Match":9,"./tasks/AsyncTask":15,"./tasks/PromiseTask":17,"./tasks/Task":18,"./tasks/TimeoutTask":19,"./tasks/TriggerTask":20}],15:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Task2 = require('./Task');

var _Task3 = _interopRequireDefault(_Task2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * AsyncTask
 *
 * Executes run and does not complete automatically.
 * Need manual call of complete() method.
 * Useful for triggers.
 *
 * Similar with TriggerTask, but with full set of run, complete and recover.
 * In run method first parameter will be complete callback, second self and
 * ...args to follow. Does not care what run returns.
 *
 * @example run = (complete, self, ...args) => { complete(); }
 *
 * @param {Function} run function to be called on run
 * @param {Function} complete function to be called on complete
 * @param {Function} recover function to be called on recover
 */
var AsyncTask = function (_Task) {
  _inherits(AsyncTask, _Task);

  /**
   * AsyncTask constructor
   *
   * @param {Function} run function to be called on run
   * @param {Function} complete function to be called on complete
   * @param {Function} recover function to be called on recover
   */
  function AsyncTask(run, complete, recover) {
    _classCallCheck(this, AsyncTask);

    return _possibleConstructorReturn(this, (AsyncTask.__proto__ || Object.getPrototypeOf(AsyncTask)).call(this, run, complete, recover));
  }

  /**
   * Runs a task
   *
   * Executes the run function if defined. All arguments will be
   * passed to it.
   *
   * @param {any} args any arguments
   */


  _createClass(AsyncTask, [{
    key: 'run',
    value: function run() {
      this._running = true;

      if (this._run !== undefined) {
        try {
          for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          this._run.apply(this, [this.complete.bind(this), this].concat(args));
        } catch (error) {
          this._exceptions.run = error;
        }
      }
    }
  }]);

  return AsyncTask;
}(_Task3.default);

exports.default = AsyncTask;
},{"./Task":18}],16:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Factory = require('../factory/Factory');

var _Factory2 = _interopRequireDefault(_Factory);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Injector. Internal class
 *
 * Injects functions into objects. Used internally.
 * Not intended to be used on it's own.
 *
 * @static
 */
var Injector = function () {
  function Injector() {
    _classCallCheck(this, Injector);
  }

  _createClass(Injector, null, [{
    key: 'afterComplete',

    /**
     * Appends a function after complete and remembers the original
     *
     * @param {Task} task task to be modified
     * @param {Function} callback function to be called after complete
     * @param {String} key map for the original callback
     * @return {Task} task modified task
     */
    value: function afterComplete(task, callback, key) {
      Injector.resetAfterComplete(task, key);

      var current = task._complete;

      Object.defineProperty(task, '__injected__' + key, {
        configurable: true,
        enumerable: true,
        value: current
      });

      task._complete = function (self) {
        for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
          args[_key - 1] = arguments[_key];
        }

        var error = void 0;
        try {
          if (current !== undefined) {
            current.apply(undefined, [self].concat(args));
          }
        } catch (e) {
          error = e;
        }
        callback.apply(undefined, [error, self].concat(args));
      };

      return task;
    }

    /**
     * Resets the complete method to it's original state
     *
     * @param {Task} task task to be modified
     * @param {String} key map for the original callback
     * @return {Task} task modified task
     */

  }, {
    key: 'resetAfterComplete',
    value: function resetAfterComplete(task, key) {
      var property = '__injected__' + key;
      if (task.hasOwnProperty(property)) {
        task._complete = task[property];
      }

      delete task['__injected__' + key];

      return task;
    }

    /**
     * Adds a method called chain to get Factory._CHAIN_
     *
     * Shortcut for task.get(Factory._CHAIN_)
     *
     * @param {Task} task task to be modified
     * @return {Task} task modified task
     */

  }, {
    key: 'addChainGetter',
    value: function addChainGetter(task) {
      Object.defineProperty(task, 'chain', {
        get: function get() {
          return this.get(_Factory2.default._CHAIN_);
        },
        configurable: true,
        enumerable: true
      });

      return task;
    }

    /**
     * Remove a method called chain to get Factory._CHAIN_
     *
     * @param {Task} task task to be modified
     * @return {Task} task modified task
     */

  }, {
    key: 'removeChainGetter',
    value: function removeChainGetter(task) {
      delete task.chain;

      return task;
    }
  }]);

  return Injector;
}();

exports.default = Injector;
},{"../factory/Factory":7}],17:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Task2 = require('./Task');

var _Task3 = _interopRequireDefault(_Task2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * PromiseTask
 *
 * Takes a Promise and waits for it to complete.
 * Will attack to finally and complete.
 * Useful for triggers.
 *
 * Similar with TriggerTask, but with set of complete and recover.
 *
 * @param {Promise} promise promise instance to wait for
 * @param {Function} complete function to be called on complete
 * @param {Function} recover function to be called on recover
 */
var PromiseTask = function (_Task) {
  _inherits(PromiseTask, _Task);

  /**
   * PromiseTask constructor
   *
   * @param {Promise} promise promise instance to wait for
   * @param {Function} complete function to be called on complete
   * @param {Function} recover function to be called on recover
   */
  function PromiseTask(promise, complete, recover) {
    _classCallCheck(this, PromiseTask);

    var _this = _possibleConstructorReturn(this, (PromiseTask.__proto__ || Object.getPrototypeOf(PromiseTask)).call(this, undefined, complete, recover));

    _this._promise = undefined;
    _this._setPromise(promise);

    _this._resolved = false;
    return _this;
  }

  /**
   * Runs a task
   *
   * Checks if promise already resolved. If not does nothing.
   *
   * @param {any} args any arguments
   */


  _createClass(PromiseTask, [{
    key: 'run',
    value: function run() {
      this._running = true;

      if (this._resolved) {
        this.complete();
      }
    }

    /**
     * Checks if instance is Promise
     *
     * We do not want promises as a dependency - as it's conditionally used.
     * The checks for promise will be a bit loose - just checking for finally
     * and assuming it's a Promise.
     *
     * @param {Promise} promise promise instance
     * @return {boolean}
     */

  }, {
    key: '_isPromise',
    value: function _isPromise(promise) {
      return promise && (promise.constructor && promise.constructor.name === 'Promise' || promise.finally && promise.finally.constructor.name === 'Function');
    }

    /**
     * Sets promise and attaches to finally
     *
     * @param {Promise} promise promise instance
     */

  }, {
    key: '_setPromise',
    value: function _setPromise(promise) {
      var _this2 = this;

      if (this._isPromise(promise)) {
        this._promise = promise;

        this._promise.finally(function () {
          return _this2._promiseFinally();
        });
      }
    }

    /**
     * Handles promise finally resolved
     */

  }, {
    key: '_promiseFinally',
    value: function _promiseFinally() {
      this._resolved = true;

      if (this._running) {
        this.complete();
      }
    }
  }]);

  return PromiseTask;
}(_Task3.default);

exports.default = PromiseTask;
},{"./Task":18}],18:[function(require,module,exports){
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

/**
 * Task
 *
 * Basic task with run, complete and recover
 *
 * run function can return nothing(undefined) and it will
 * call complete instantly. if run returns anything it will
 * NOT call complete automatically and it's up to you to
 * trigger complete.
 * @example run = () => { console.log('next thing is complete'); }
 * @example run = (self) => {
 *   console.log('will manually call complete()');
 *   // some logic to call self.complete() later
 *   // or call complete() from outside to make a trigger waiter
 *   return 1; // or whatever you want but undefined
 * }
 *
 * @param {Function} run function to be called on run
 * @param {Function} complete function to be called on complete
 * @param {Function} recover function to be called on recover
 */
var Task = function () {
  /**
   * Task constructor
   *
   * @param {Function} run function to be called on run
   * @param {Function} complete function to be called on complete
   * @param {Function} recover function to be called on recover
   */
  function Task(run, complete, recover) {
    _classCallCheck(this, Task);

    this._run = run;
    this._complete = complete;
    this._recover = recover;

    this._running = false;
    this._done = false;

    this._attached = {};

    this._exceptions = {
      run: undefined,
      complete: undefined,
      recover: undefined
    };
  }

  /**
   * Attaches variable to the task
   *
   * @param {string} key accessor for the variable
   * @param {any} value variable value
   */


  _createClass(Task, [{
    key: "attach",
    value: function attach(key, value) {
      this._attached[key] = value;
    }

    /**
     * Detaches variable by name
     *
     * @param {string} key accessor for the variable
     */

  }, {
    key: "detach",
    value: function detach(key) {
      delete this._attached[key];
    }

    /**
     * Gets variable by name
     *
     * @param {string} key accessor for the variable
     * @return {any} variable value
     */

  }, {
    key: "get",
    value: function get(key) {
      return this._attached[key];
    }

    /**
     * Runs a task
     *
     * Executes the run function if defined. All arguments will be
     * passed to it.
     *
     * @param {any} args any arguments
     */

  }, {
    key: "run",
    value: function run() {
      this._running = true;

      if (this._run !== undefined) {
        try {
          for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
            args[_key] = arguments[_key];
          }

          if (this._run.apply(this, [this].concat(args)) === undefined) {
            this.complete();
          }
        } catch (error) {
          this._exceptions.run = error;

          this.complete(error);
        }
      } else {
        this.complete();
      }
    }

    /**
     * Completes a task
     *
     * Executes the complete function if defined. All arguments will be
     * passed to it.
     *
     * @param {any} args any arguments
     */

  }, {
    key: "complete",
    value: function complete() {
      this._running = false;
      this._done = true;

      if (this._complete !== undefined) {
        try {
          for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
            args[_key2] = arguments[_key2];
          }

          this._complete.apply(this, [this].concat(args));
        } catch (error) {
          this._exceptions.complete = error;
        }
      }
    }

    /**
     * Recovers a task
     *
     * Executes the recover function if defined. All arguments will be
     * passed to it.
     *
     * @param {any} args any arguments
     */

  }, {
    key: "recover",
    value: function recover() {
      if (this._recover !== undefined) {
        try {
          for (var _len3 = arguments.length, args = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
            args[_key3] = arguments[_key3];
          }

          var recovered = this._recover.apply(this, [this].concat(args));
          if (recovered !== undefined) {
            this.run(recovered);
          }
        } catch (error) {
          this._exceptions.recover = error;
        }
      }
    }

    /**
     * Stops a task
     *
     * @return {boolean} success
     */

  }, {
    key: "stop",
    value: function stop() {
      return false;
    }

    /**
     * Restarts a task
     *
     * If stopped will start it
     * If running will respect stop()
     *
     * @return {boolean} success
     */

  }, {
    key: "restart",
    value: function restart() {
      if (this.running) {
        if (this.stop()) {
          this.run.apply(this, arguments);

          return true;
        } else {
          return false;
        }
      } else {
        this.run.apply(this, arguments);

        return true;
      }
    }

    /**
     * Gets the running status
     *
     * @return {boolean} running
     */

  }, {
    key: "running",
    get: function get() {
      return this._running;
    }

    /**
     * Gets the done status
     *
     * @return {boolean} done
     */

  }, {
    key: "done",
    get: function get() {
      return this._done;
    }

    /**
     * Gets the failed status
     *
     * @return {boolean} failed
     */

  }, {
    key: "failed",
    get: function get() {
      return this._exceptions.run !== undefined || this._exceptions.complete !== undefined || this._exceptions.recover !== undefined;
    }

    /**
     * Gets the exceptions if any
     *
     * @return {Object} exceptions
     */

  }, {
    key: "exceptions",
    get: function get() {
      return this._exceptions;
    }
  }]);

  return Task;
}();

exports.default = Task;
},{}],19:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };

var _Task2 = require('./Task');

var _Task3 = _interopRequireDefault(_Task2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * TimeoutTask
 *
 * Timeout task with run, complete and recover.
 * Executes after initial timeout
 *
 * @param {number} timeout wait before run
 * @param {Function} run function to be called on run
 * @param {Function} complete function to be called on complete
 * @param {Function} recover function to be called on recover
 */
var TimeoutTask = function (_Task) {
  _inherits(TimeoutTask, _Task);

  /**
   * TimeoutTask constructor
   *
   * @param {number} timeout wait before run
   * @param {Function} run function to be called on run
   * @param {Function} complete function to be called on complete
   * @param {Function} recover function to be called on recover
   */
  function TimeoutTask(timeout, run, complete, recover) {
    _classCallCheck(this, TimeoutTask);

    var _this = _possibleConstructorReturn(this, (TimeoutTask.__proto__ || Object.getPrototypeOf(TimeoutTask)).call(this, run, complete, recover));

    _this._timeout = timeout;
    _this._index = undefined;
    return _this;
  }

  /**
   * Runs a task
   *
   * Executes the run function if defined. All arguments will be
   * passed to it.
   *
   * @param {any} args any arguments
   */


  _createClass(TimeoutTask, [{
    key: 'run',
    value: function run() {
      var _this2 = this;

      for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      this._running = true;

      this._index = setTimeout(function () {
        var _get2;

        return (_get2 = _get(TimeoutTask.prototype.__proto__ || Object.getPrototypeOf(TimeoutTask.prototype), 'run', _this2)).call.apply(_get2, [_this2].concat(args));
      }, this._timeout);
    }

    /**
     * Completes a task
     *
     * Executes the complete function if defined. All arguments will be
     * passed to it.
     *
     * @param {any} args any arguments
     */

  }, {
    key: 'complete',
    value: function complete() {
      var _get3;

      this.stop();

      for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        args[_key2] = arguments[_key2];
      }

      (_get3 = _get(TimeoutTask.prototype.__proto__ || Object.getPrototypeOf(TimeoutTask.prototype), 'complete', this)).call.apply(_get3, [this].concat(args));
    }

    /**
     * Stops a task
     *
     * @return {boolean} success
     */

  }, {
    key: 'stop',
    value: function stop() {
      if (this._running) {
        clearTimeout(this._index);

        this._index = undefined;

        return true;
      } else {
        return false;
      }
    }
  }]);

  return TimeoutTask;
}(_Task3.default);

exports.default = TimeoutTask;
},{"./Task":18}],20:[function(require,module,exports){
'use strict';

Object.defineProperty(exports, "__esModule", {
  value: true
});

var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

var _Task2 = require('./Task');

var _Task3 = _interopRequireDefault(_Task2);

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }

function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }

/**
 * TriggerTask
 *
 * Trigger task with complete.
 * Executes run and does not complete automatically.
 * Need manual call of complete() method.
 * Useful for triggers.
 *
 * @param {Function} complete function to be called on complete
 */
var TriggerTask = function (_Task) {
  _inherits(TriggerTask, _Task);

  /**
   * TriggerTask constructor
   *
   * @param {Function} complete function to be called on complete
   */
  function TriggerTask(complete) {
    _classCallCheck(this, TriggerTask);

    return _possibleConstructorReturn(this, (TriggerTask.__proto__ || Object.getPrototypeOf(TriggerTask)).call(this, undefined, complete, undefined));
  }

  /**
   * Runs a task
   *
   * Executes the run function if defined. All arguments will be
   * passed to it.
   *
   * @param {any} args any arguments
   */


  _createClass(TriggerTask, [{
    key: 'run',
    value: function run() {
      this._running = true;
    }
  }]);

  return TriggerTask;
}(_Task3.default);

exports.default = TriggerTask;
},{"./Task":18}]},{},[14])(14)
});