var LRFWebcore =
/******/ (function(modules) { // webpackBootstrap
/******/ 	// install a JSONP callback for chunk loading
/******/ 	var parentJsonpFunction = window["webpackJsonpLRFWebcore"];
/******/ 	window["webpackJsonpLRFWebcore"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
/******/ 		// add "moreModules" to the modules object,
/******/ 		// then flag all "chunkIds" as loaded and fire callback
/******/ 		var moduleId, chunkId, i = 0, resolves = [], result;
/******/ 		for(;i < chunkIds.length; i++) {
/******/ 			chunkId = chunkIds[i];
/******/ 			if(installedChunks[chunkId]) {
/******/ 				resolves.push(installedChunks[chunkId][0]);
/******/ 			}
/******/ 			installedChunks[chunkId] = 0;
/******/ 		}
/******/ 		for(moduleId in moreModules) {
/******/ 			if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
/******/ 				modules[moduleId] = moreModules[moduleId];
/******/ 			}
/******/ 		}
/******/ 		if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);
/******/ 		while(resolves.length) {
/******/ 			resolves.shift()();
/******/ 		}
/******/
/******/ 	};
/******/
/******/ 	// The module cache
/******/ 	var installedModules = {};
/******/
/******/ 	// objects to store loaded and loading chunks
/******/ 	var installedChunks = {
/******/ 		2: 0
/******/ 	};
/******/
/******/ 	// The require function
/******/ 	function __webpack_require__(moduleId) {
/******/
/******/ 		// Check if module is in cache
/******/ 		if(installedModules[moduleId]) {
/******/ 			return installedModules[moduleId].exports;
/******/ 		}
/******/ 		// Create a new module (and put it into the cache)
/******/ 		var module = installedModules[moduleId] = {
/******/ 			i: moduleId,
/******/ 			l: false,
/******/ 			exports: {}
/******/ 		};
/******/
/******/ 		// Execute the module function
/******/ 		modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ 		// Flag the module as loaded
/******/ 		module.l = true;
/******/
/******/ 		// Return the exports of the module
/******/ 		return module.exports;
/******/ 	}
/******/
/******/ 	// This file contains only the entry chunk.
/******/ 	// The chunk loading function for additional chunks
/******/ 	__webpack_require__.e = function requireEnsure(chunkId) {
/******/ 		var installedChunkData = installedChunks[chunkId];
/******/ 		if(installedChunkData === 0) {
/******/ 			return new Promise(function(resolve) { resolve(); });
/******/ 		}
/******/
/******/ 		// a Promise means "currently loading".
/******/ 		if(installedChunkData) {
/******/ 			return installedChunkData[2];
/******/ 		}
/******/
/******/ 		// setup Promise in chunk cache
/******/ 		var promise = new Promise(function(resolve, reject) {
/******/ 			installedChunkData = installedChunks[chunkId] = [resolve, reject];
/******/ 		});
/******/ 		installedChunkData[2] = promise;
/******/
/******/ 		// start chunk loading
/******/ 		var head = document.getElementsByTagName('head')[0];
/******/ 		var script = document.createElement('script');
/******/ 		script.type = 'text/javascript';
/******/ 		script.charset = 'utf-8';
/******/ 		script.async = true;
/******/ 		script.timeout = 120000;
/******/
/******/ 		if (__webpack_require__.nc) {
/******/ 			script.setAttribute("nonce", __webpack_require__.nc);
/******/ 		}
/******/ 		script.src = __webpack_require__.p + "" + chunkId + ".lrf-webcore.js";
/******/ 		var timeout = setTimeout(onScriptComplete, 120000);
/******/ 		script.onerror = script.onload = onScriptComplete;
/******/ 		function onScriptComplete() {
/******/ 			// avoid mem leaks in IE.
/******/ 			script.onerror = script.onload = null;
/******/ 			clearTimeout(timeout);
/******/ 			var chunk = installedChunks[chunkId];
/******/ 			if(chunk !== 0) {
/******/ 				if(chunk) {
/******/ 					chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
/******/ 				}
/******/ 				installedChunks[chunkId] = undefined;
/******/ 			}
/******/ 		};
/******/ 		head.appendChild(script);
/******/
/******/ 		return promise;
/******/ 	};
/******/
/******/ 	// expose the modules object (__webpack_modules__)
/******/ 	__webpack_require__.m = modules;
/******/
/******/ 	// expose the module cache
/******/ 	__webpack_require__.c = installedModules;
/******/
/******/ 	// identity function for calling harmony imports with the correct context
/******/ 	__webpack_require__.i = function(value) { return value; };
/******/
/******/ 	// define getter function for harmony exports
/******/ 	__webpack_require__.d = function(exports, name, getter) {
/******/ 		if(!__webpack_require__.o(exports, name)) {
/******/ 			Object.defineProperty(exports, name, {
/******/ 				configurable: false,
/******/ 				enumerable: true,
/******/ 				get: getter
/******/ 			});
/******/ 		}
/******/ 	};
/******/
/******/ 	// getDefaultExport function for compatibility with non-harmony modules
/******/ 	__webpack_require__.n = function(module) {
/******/ 		var getter = module && module.__esModule ?
/******/ 			function getDefault() { return module['default']; } :
/******/ 			function getModuleExports() { return module; };
/******/ 		__webpack_require__.d(getter, 'a', getter);
/******/ 		return getter;
/******/ 	};
/******/
/******/ 	// Object.prototype.hasOwnProperty.call
/******/ 	__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ 	// __webpack_public_path__
/******/ 	__webpack_require__.p = "";
/******/
/******/ 	// on error function for async loading
/******/ 	__webpack_require__.oe = function(err) { console.error(err); throw err; };
/******/
/******/ 	// Load entry module and return exports
/******/ 	return __webpack_require__(__webpack_require__.s = 11);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

"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"); } }

var LRFOctave = exports.LRFOctave = Object.freeze({
  lowest: 0,
  low: 1,
  midLow: 2,
  mid: 3,
  midhigh: 4,
  high: 5,
  higher: 6,
  highest: 7
});

var LRFNote = exports.LRFNote = Object.freeze({
  a: 0,
  as: 1,
  b: 2,
  c: 3,
  cs: 4,
  d: 5,
  ds: 6,
  e: 7,
  f: 8,
  fs: 9,
  g: 10,
  gs: 11,
  mute: 12,
  null: 15
});

var LRFIntonation = exports.LRFIntonation = Object.freeze({
  flat: 0,
  rising: 1,
  falling: 2,
  peaking: 3,
  dipping: 4
});

var LRFDuration = exports.LRFDuration = Object.freeze({
  none: 0,
  short: 1, //1 block
  doubleShort: 2, //2 blocks
  medium: 3, //4 blocks
  doubleMedium: 4, //8 blocks
  long: 5, //16 blocks
  doubleLong: 6,
  veryLong: 7
});

var LRFColor = exports.LRFColor = Object.freeze({
  none: 0,
  red: 1,
  green: 2,
  blue: 3,
  orange: 4,
  cyan: 5,
  purple: 6,
  yellow: 7,
  pink: 8,
  white: 15
});

//TODO: change to object enum
var LRFPersonalityTraits = exports.LRFPersonalityTraits = Object.freeze(["chattiness", "bravery", "happiness", "enthusiasm", "neediness", "humour"]);

var LRFTransform = exports.LRFTransform = {
  None: 0, // 0b00000000,
  Boomerang: 1 << 0, // 0b00000001,
  ZigZag: 1 << 2, // 0b00000010,
  Flat: 1 << 3, // 0b00000100,
  Flip: 1 << 4, // 0b00001000,
  Random: 1 << 5 // 0b00010000,
};

var LRFAction = exports.LRFAction = {
  LRF2Event_None: 0xff,

  // "Robot" (System) Events (0x00 - 0x1F)
  "robot-power-up": 0x00,
  "robot-is-hungry": 0x01,
  "robot-is-bored": 0x02,
  "robot-is-sleeping": 0x03,
  "robot-is-awake": 0x04,

  "robot-got-message": 0x10,

  // Tap Events (0x20 - 0x2F)
  tap: 0x20,
  tickle: 0x21,
  hug: 0x22,

  "tap-left": 0x23,
  "tickle-left": 0x24,
  "hug-left": 0x25,

  "tap-right": 0x26,
  "tickle-right": 0x27,
  "hug-right": 0x28,

  "big-hug": 0x29,
  "super-hug": 0x2a, //bear hug

  // Light Events (0x30 - 0x3F)
  "light-normal": 0x30,
  "light-too-dark": 0x31,
  "light-too-bright": 0x32,
  "light-too-dark-too-long": 0x33,
  "light-too-bright-too-long": 0x34,

  // Sound Events (0x40 - 0x4F)
  "sound-normal": 0x40,
  "sound-too-loud": 0x41,
  "sound-like-talking": 0x42,
  "sound-like-no-talking": 0x43,

  // Motion Events (0x50 - 0x5F)
  "tilt-none": 0x50,
  "tilt-left": 0x51,
  "tilt-right": 0x52,
  "tilt-forward": 0x53,
  "tilt-back": 0x54,
  "lay-left": 0x55,
  "lay-right": 0x56,
  "lay-forward": 0x57,
  "lay-back": 0x58,
  "shake": 0x59

  // Reserved (0x60 - 0x7f)
};

var actionRange = exports.actionRange = {
  hair: {
    startIndex: LRFAction["tap"],
    endIndex: LRFAction["hug"]
  },
  right: {
    startIndex: LRFAction["tap-right"],
    endIndex: LRFAction["hug-right"]
  },
  left: {
    startIndex: LRFAction["tap-left"],
    endIndex: LRFAction["hug-left"]
  },
  mic: {
    startIndex: LRFAction["sound-normal"],
    endIndex: LRFAction["sound-too-loud"]
  },
  light: {
    startIndex: LRFAction["light-normal"],
    endIndex: LRFAction["light-too-bright-too-long"]
  },
  motion: {
    startIndex: LRFAction["tilt-none"],
    endIndex: LRFAction["shake"]
  },
  brain: {
    startIndex: LRFAction["robot-power-up"],
    endIndex: LRFAction["robot-got-message"]
  }
};

var sensorMap = exports.sensorMap = {
  "hair": ["tap", "tickle", "hug"],
  "right": ["tap-right", "tickle-right", "hug-right"],
  "left": ["tap-left", "tickle-left", "hug-left"],
  "mic": ["sound-normal", "sound-too-loud" /*, "sound-like-talking", "sound-like-no-talking"*/],
  "light": ["light-normal", "light-too-dark", "light-too-bright", "light-too-dark-too-long", "light-too-bright-too-long"],
  "motion": [/*"tilt-none",*/"tilt-left", "tilt-right", /*"tilt-forward", "tilt-back",*/"lay-left", "lay-right", /*"lay-forward", "lay-back",*/"shake"],
  "brain": [/*"robot-power-up",*/"robot-is-hungry", "robot-is-bored" /*, "robot-is-sleeping","robot-is-awake", "robot-got-message"*/]
};

var LRFExpression = exports.LRFExpression = {
  // Hellos (3)
  "hello": 0,
  "happy-hello": 1,
  "angry-hello": 2,

  // Moods (8)
  "happy": 3,
  "very-happy": 4,
  "excited": 5,
  "very-excited": 6,
  "annoyed": 7,
  "very-annoyed": 8,
  "angry": 9,
  "very-angry": 10,

  // Laughs (4)
  "giggle": 11,
  "laugh": 12,
  "hysterical": 13,
  "evil-cackle": 14,

  // Cries (2)
  "pout": 15,
  "sob": 16,

  // Scared (3)
  "scared": 17,
  "terrified": 18,
  "relieved": 19,

  // Sleepy (3)
  "bored": 20,
  "yawn": 21,
  "snoring": 22,

  // System (3)
  "hungry": 23,
  "power-up": 24,
  "alarm": 25,

  "awww": 26,
  "yikes": 27,
  "whoa-up": 28,
  "whoa-down": 29,
  "whoa-whoa-whoa": 30,

  // Special
  custom: 0xa0,
  temp: 0xfd,
  signature: 0xfe,
  null: 0xff
};

var LRFSound = exports.LRFSound = function () {
  function LRFSound() {
    _classCallCheck(this, LRFSound);

    this.note = LRFNote.ds;
    this.octave = LRFOctave.mid;
    this.intonation = LRFIntonation.flat;
    this.duration = LRFDuration.short;
    this.pause = LRFDuration.short;
  }

  _createClass(LRFSound, [{
    key: "getRaw",
    value: function getRaw() {

      var rawValue = this.note << 0 | this.octave << 4 | this.intonation << 7 | this.duration << 10 | this.pause << 13;

      var swap = rawValue << 8 | rawValue >> 8;

      // console.log("swap is: " + swap);
      //Returns 16 bit packed integer
      return swap; //rawValue;
    }
  }, {
    key: "unpackRaw",
    value: function unpackRaw(raw) {
      var swap = raw << 8 | raw >> 8;

      this.note = swap & 0xf;
      this.octave = swap >> 4 & 0x7;
      this.intonation = swap >> 7 & 0x7;
      this.duration = swap >> 10 & 0x7;
      this.pause = swap >> 13 & 0x7;
    }
  }, {
    key: "assign",
    value: function assign(properties) {
      Object.assign(this, properties);
    }
  }]);

  return LRFSound;
}();

var LRFPattern = exports.LRFPattern = function () {
  function LRFPattern() {
    _classCallCheck(this, LRFPattern);

    this.rightLed = LRFColor.none;
    this.leftLed = LRFColor.none;
    this.boomerang = false;
    this.zigzag = false;
    this.flat = false;
    this.flip = false;
    this.random = false;
    this.duration = LRFDuration.medium;
  }

  _createClass(LRFPattern, [{
    key: "getRaw",
    value: function getRaw() {

      var rawValue = this.leftLed << 8 | this.rightLed << 12 |
      //bit shifting booleans works, but is this language spec, good part spec?
      this.boomerang << 0 | this.zigzag << 1 | this.flat << 2 | this.flip << 3 | this.random << 4 | this.duration << 5;

      //returns 16 bit packed integer value
      return rawValue;
    }
    //Raw: Uint16

  }, {
    key: "unpackRaw",
    value: function unpackRaw(raw) {
      this.leftLed = raw >> 8 & 0xf;
      this.rightLed = raw >> 12 & 0xf;
      this.boomerang = raw >> 0 & 0x1;
      this.zigzag = raw >> 1 & 0x1;
      this.flat = raw >> 2 & 0x1;
      this.flip = raw >> 3 & 0x1;
      this.random = raw >> 4 & 0x1;
      this.duration = raw >> 5 & 0x7;
    }

    //Assign with a properties object that mirrors a patter"s properties
    //{zigzag:..., rightLed:..., etc}

  }, {
    key: "assign",
    value: function assign(properties) {
      Object.assign(this, properties);
    }
  }]);

  return LRFPattern;
}();

var SoundCollection = exports.SoundCollection = function () {
  function SoundCollection(name) {
    _classCallCheck(this, SoundCollection);

    this.sounds = [];
    this.pattern = new LRFPattern();
    this.uname = name || "";
  }

  _createClass(SoundCollection, [{
    key: "assign",
    value: function assign(properties) {
      Object.assign(this.pattern, properties.pattern);

      var sc = this;

      properties.sounds.forEach(function (sourceSound, index) {
        if (typeof sc.sounds[index] === "undefined") {
          sc.sounds.push(new LRFSound());
        }
        Object.assign(sc.sounds[index], sourceSound);
      });

      if (properties.uname) this.uname = properties.uname;
    }

    //[isStrictComparison] will also compare the uname of both expressions. Defalts to false

  }, {
    key: "isEqual",
    value: function isEqual(soundCollection) {
      var isStrictComparison = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;


      //if strict comparison check unames
      if (isStrictComparison && this.uname !== soundCollection.uname) return false;

      //False if different lengths
      if (this.sounds.length !== soundCollection.sounds.length) return false;

      //False if different patterns
      if (this.pattern.getRaw() !== soundCollection.pattern.getRaw()) return false;

      var numSounds = this.sounds.length;

      for (var i = 0; i < numSounds; i++) {
        if (this.sounds[i].getRaw() !== soundCollection.sounds[i].getRaw()) return false;
      }

      return true;
    }
  }]);

  return SoundCollection;
}();

//TODO: refactor to LRFRobotType


var RobotType = exports.RobotType = {
  SpikeyBot: "lrf-spiky-bot",
  CurvyBot: "lrf-curvy-bot",
  GhostyBot: "lrf-ghosty-bot",
  CraftyBot: "lrf-crafty-bot",

  //Meta Bots
  DisconnectedBot: "lrf-disconnected-bot",
  ErrorBot: "lrf-error-bot"
};

var typeTable = {
  0: RobotType.DisconnectedBot,
  1: RobotType.SpikeyBot,
  2: RobotType.CurvyBot,
  3: RobotType.GhostyBot,
  4: RobotType.CraftyBot,
  //Meta Bots
  255: RobotType.ErrorBot
};

//TODO: extract NULL_SOUND from CONSTANTS
var CONSTANTS = exports.CONSTANTS = {
  NULL_SOUND: 0xF00
};

//Utitlity
//----

//This function is required for converting raw robot types from incoming lrf messages
//robot types are represented as a uint8, and converted to a string identifier
var robotTypeLookup = exports.robotTypeLookup = function robotTypeLookup(rawRobotType) {
  return typeTable[rawRobotType];
};

//TODO: depends on LODASH
// export const getExpressionLabelWithIndex = (expressionIndex) => {
//   return _.invert(this.LRFExpression)[expressionIndex];
// }


//TODO: deprecate below
//---
var createSound = exports.createSound = function createSound() {
  return new LRFSound();
};

var createPattern = exports.createPattern = function createPattern() {
  return new LRFPattern();
};

var createExpression = exports.createExpression = function createExpression(name) {
  return new SoundCollection(name);
};

var createSong = exports.createSong = function createSong(name) {
  return new SoundCollection(name);
};

/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


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

var _eventemitter = __webpack_require__(12);

var _eventemitter2 = _interopRequireDefault(_eventemitter);

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

//Manages all events in the LRF_WebCore ecosystem
var LRFRootScope = new _eventemitter2.default();

exports.default = LRFRootScope;
module.exports = exports["default"];

/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


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

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 _LRFWebCoreEvents = __webpack_require__(1);

var _LRFWebCoreEvents2 = _interopRequireDefault(_LRFWebCoreEvents);

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"); } }

var LRF_PRODUCT_ID_RE = /0CAC|0x0cac|3244|0cac/i;
var LRF_RECOVERY_PRODUCT_ID_RE = /0caa|0x0caa/i;
var LRF_VENDOR_ID_RE = /16d0|0x16d0/i;

var _isAutoConnecting = false,
    userOnReceiveCallback = void 0,
    serialAdapter = void 0;

//Multi Connect
var receiveFilter = []; //list of connections we're listening to
var reserveConnections = [];

var SerialConnection = function () {
  function SerialConnection() {
    _classCallCheck(this, SerialConnection);

    this.connectionId = 0;
    this.device = undefined;
    this.devicePath = "";
    this.isActive = false;

    //NodeSerialPort specific
    this.node_connection = undefined; //serialport object

    //chrome serial port
    this.chrome_connection = undefined; //chrome connectionInfo //TODO is this even used?

    var bitrate = 115200;

    this.connectionOptions = {
      baudRate: bitrate,
      bitrate: bitrate
    };
  }

  _createClass(SerialConnection, [{
    key: "reset",
    value: function reset() {
      this.connectionId = 0;
      this.device = undefined;
      this.devicePath = "";
      this.isActive = false;
      this.node_connection = undefined;
      this.chrome_connection = undefined;
    }
  }, {
    key: "isConnected",
    value: function isConnected() {
      return this.connectionId !== 0;
    }
  }]);

  return SerialConnection;
}();

var _connection = undefined;

var serial = undefined;

var EVENT = exports.EVENT = Object.freeze({
  DISCONNECTED: "robotDisconnected",
  CONNECTED: "robotConnected",
  ACTIVE_CONNECTION_SWITCHED: "ACTIVE_CONNECTION_SWITCHED",
  RESERVE_DISCONNECTED: "RESERVE_DISCONNECTED",
  RESERVE_CONNECTED: "RESERVE_CONNECTED",
  RECOVERY_CONNECTED: "RECOVERY_CONNECTED"
});

var PORTFILTER_WIN32 = /com\w+/i,
    ///com[2-9]\d{0,3}/i,
PORTFILTER_MAC = /\/dev\/(tty|cu)\.usbmodem\w+/i,
    PORTFILTER_LINUX = /\/dev\/ttyACM\w+/i;
var portFilter = void 0;

var setPlatform = function setPlatform(platform) {
  console.log("Platform is: " + platform);
  if (platform === "win32" || platform === "win") {
    portFilter = PORTFILTER_WIN32;
  } else if (platform === "linux" || platform === "cros") {
    portFilter = PORTFILTER_LINUX;
  }
  //If mac
  else if (platform === "mac" || platform === "darwin") {
      portFilter = PORTFILTER_MAC;
    }
};

var removeReserveConnection = function removeReserveConnection(rawConnection) {
  console.log("Removing connection");

  var reserveId = void 0,
      reservePath = void 0,
      reserveIndex = void 0;

  var _iteratorNormalCompletion = true;
  var _didIteratorError = false;
  var _iteratorError = undefined;

  try {
    for (var _iterator = reserveConnections[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
      var reserveConnection = _step.value;

      if (serialAdapter.isConnectionChildOfStore(rawConnection, reserveConnection)) {
        reserveId = reserveConnection.connectionId;
        reservePath = reserveConnection.devicePath;
        reserveIndex = reserveConnections.indexOf(reserveConnection);
        break;
      }
    }
  } catch (err) {
    _didIteratorError = true;
    _iteratorError = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion && _iterator.return) {
        _iterator.return();
      }
    } finally {
      if (_didIteratorError) {
        throw _iteratorError;
      }
    }
  }

  if (reserveId) {
    reserveConnections.splice(reserveIndex, 1);
    _LRFWebCoreEvents2.default.emit(EVENT.RESERVE_DISCONNECTED, reserveId, reservePath);
  }
};

var onDisconnect = function onDisconnect(err, rawConnection) {
  //handle serial errors

  if (reserveConnections.length !== 0) {
    removeReserveConnection(rawConnection);
  }
  if (this.isConnectionChildOfStore(rawConnection, _connection)) {
    console.log("Robot disconnected: ", err);
    _connection.reset();
    _LRFWebCoreEvents2.default.emit(EVENT.DISCONNECTED);
  }
};

var onReceive = function onReceive(receivedBuffer, rawConnection) {

  // let connection = this;
  if (false) console.log("LRFSerial - receiving bytes");

  if (!receiveFilter.length) {
    console.log("onReceive_node - receiveFilter has no elements");
    return;
  }

  var passesFilter = false;
  //TODO: rewrite with array.includes?
  var _iteratorNormalCompletion2 = true;
  var _didIteratorError2 = false;
  var _iteratorError2 = undefined;

  try {
    for (var _iterator2 = receiveFilter[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
      var serialConnection = _step2.value;

      // if (connection === serialConnection.node_connection) {
      if (this.isConnectionChildOfStore(rawConnection, serialConnection)) {
        passesFilter = true;
        // console.log("PASS FILTER IS TRUE");
        break;
      }
    }
  } catch (err) {
    _didIteratorError2 = true;
    _iteratorError2 = err;
  } finally {
    try {
      if (!_iteratorNormalCompletion2 && _iterator2.return) {
        _iterator2.return();
      }
    } finally {
      if (_didIteratorError2) {
        throw _iteratorError2;
      }
    }
  }

  if (passesFilter) {
    userOnReceiveCallback(receivedBuffer);
  }
};

var isLRFDevice = function isLRFDevice(device) {
  return portFilter.test(device.comName) && LRF_PRODUCT_ID_RE.test(device.productId);
};

var isLRFRecoveryDevice = function isLRFRecoveryDevice(device) {
  return portFilter.test(device.comName) && LRF_RECOVERY_PRODUCT_ID_RE.test(device.productId);
};

//callback(serialconnection) - Where callback is fed the new reserve connection
var addReserveConnection = function addReserveConnection(device) {

  //check if we already have the connection stored
  // let isDuplicate = false;
  var duplicate = void 0;

  if (reserveConnections.length !== 0) {
    // console.log("reserveConnections: ", reserveConnections);
    duplicate = reserveConnections.find(function (connection) {
      return connection.devicePath === device.comName;
    });
  }

  //If not then add it to the reserve
  if (!duplicate) {
    var newReserveConnection = new SerialConnection();
    return serialAdapter.connect(device, newReserveConnection).then(function (newFulfilledConnection) {
      _LRFWebCoreEvents2.default.emit(EVENT.RESERVE_CONNECTED);
      reserveConnections.push(newFulfilledConnection);
      // console.log("Reserve Connections: ", reserveConnections);
      // console.log(newFulfilledConnection);
      return newFulfilledConnection;
    });
  } else {
    return Promise.reject(new Error("a duplicate connection exists"));
  }
};

var setActiveConnection = function setActiveConnection(connection) {
  if (_connection) {
    _connection.isActive = false;
  }
  _connection = connection;
  _connection.isActive = true;
};

var setFilterActiveConnection = function setFilterActiveConnection() {
  receiveFilter = [_connection];
};

var setFilterReserveConnections = function setFilterReserveConnections() {
  receiveFilter = reserveConnections;
};

var connect = function connect(device, connection) {
  return serialAdapter.connect(device, connection);
};

//Automatically connect to the first available LittleRobotFriend
var autoConnect = function autoConnect() {
  var searchFlags = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
    friends: true,
    recovery: true
  };

  if (_isAutoConnecting) return;
  _isAutoConnecting = true;
  serialAdapter.getDevices().then(function (devices) {

    console.log(devices);
    var device = searchFlags.friends ? devices.find(isLRFDevice) : undefined;
    var recoveryDevice = searchFlags.recovery ? devices.find(isLRFRecoveryDevice) : undefined;

    if (device) {
      //TODO: should return a promise with the serial connection?
      return addReserveConnection(device).then(function (serialConnection) {
        setActiveConnection(serialConnection);
        setFilterActiveConnection();
        serialConnection.isActive = true;
        _isAutoConnecting = false;
        _LRFWebCoreEvents2.default.emit(EVENT.CONNECTED);
        return serialConnection;
      });
    } else if (recoveryDevice) {
      return connect(recoveryDevice, new SerialConnection()).then(function (serialConnection) {
        serialConnection.isActive = true;
        _isAutoConnecting = false;
        setActiveConnection(serialConnection);
        setFilterActiveConnection();
        _LRFWebCoreEvents2.default.emit(EVENT.RECOVERY_CONNECTED);
        return serialConnection;
      });
    } else {
      return Promise.reject(new Error("None of your devices are a robot"));
    }
  }).catch(function (err) {
    console.error(err);
    console.log("Attempting to connect again in 2 seconds...");
    setTimeout(function () {
      _isAutoConnecting = false;
      autoConnect(searchFlags);
    }, 2000);
  });
};

/*
 * @param os                :string -> "win32", "mac", "linux"
 * @param serialPlatform    :string -> "node" or "chrome"
 * @returns                 a promise that succeeds if the serial setup was successful
 */
var setup = function setup(os, serialPlatform) {

  //Set our platform for proper device discovery
  setPlatform(os);

  var adapterOptions = {
    onReceiveCB: onReceive,
    onDisconnectCB: onDisconnect
  };

  //Set our serial object
  if (serialPlatform.toLowerCase() === "chrome") {
    serial = chrome.serial;
    return __webpack_require__.e/* import() */(1).then(__webpack_require__.bind(null, 13)).then(function (ChromeSerialAdapter) {
      serialAdapter = new ChromeSerialAdapter(serial, adapterOptions);
    }).catch(function (err) {
      console.log(err);
    });
  } else if (serialPlatform.toLowerCase() === "node") {
    return new Promise(function(resolve) { resolve(); }).then(__webpack_require__.bind(null, 15)).then(function (serialport) {
      serial = serialport;
    }).then(function () {
      return __webpack_require__.e/* import() */(0).then(__webpack_require__.bind(null, 14)).then(function (NodeSerialAdapter) {
        serialAdapter = new NodeSerialAdapter(serial, adapterOptions);
      });
    }).catch(function (err) {
      console.error(err);
    });
  } else {
    return Promise.reject(new Error(serialPlatform + " is not a supported serial platform"));
  }
};

var isConnected = function isConnected() {
  return _connection ? _connection.isConnected() : false;
};

exports.default = {
  EVENT: EVENT,
  setPlatform: setPlatform,
  getDevices: function getDevices() {
    return serialAdapter.getDevices();
  },
  isLRFDevice: isLRFDevice,
  isLRFRecoveryDevice: isLRFRecoveryDevice,
  reserveConnections: reserveConnections, //TODO this shouldn't be exposed
  connect: connect, //TODO: does this need to be here?
  addReserveConnection: addReserveConnection, //OR just use add reserve as the default connect
  autoConnect: autoConnect,
  setActiveConnection: setActiveConnection,
  setFilterActiveConnection: setFilterActiveConnection,
  setFilterReserveConnections: setFilterReserveConnections,
  get connection() {
    return _connection;
  },
  isConnected: isConnected,
  get isAutoConnecting() {
    return _isAutoConnecting;
  },
  send: function send(buffer) {
    var connection = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : _connection;

    serialAdapter.send(buffer, connection);
  },
  enterBootLoader: function enterBootLoader(cb) {
    return serialAdapter.enterBootLoader(_connection, cb);
  },
  disconnect: function disconnect() {
    var connection = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : _connection;

    serialAdapter.disconnect(connection);
  },
  setReceiveCallback: function setReceiveCallback(callback) {
    userOnReceiveCallback = callback;
  },
  setup: setup
};

// setPlatform(ionic.Platform.platform());

/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


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

var _LRFSerial = __webpack_require__(2);

var _LRFSerial2 = _interopRequireDefault(_LRFSerial);

var _LRFComm = __webpack_require__(6);

var LRFComm = _interopRequireWildcard(_LRFComm);

var _LRFWifi = __webpack_require__(5);

var _LRFWifi2 = _interopRequireDefault(_LRFWifi);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

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

var PLATFORMS = {
  CHROME_APP: "chrome",
  ELECTRON: "electron",
  NODE: "node",
  WEB: "web",
  NATIVE: "native"
};

var _platform = void 0;

var set = function set(platform) {
  _platform = platform;
};

var getPlatform = function getPlatform() {
  return _platform;
};

var isElectron = function isElectron() {
  return _platform === PLATFORMS.ELECTRON;
};
var isChrome = function isChrome() {
  return _platform === PLATFORMS.CHROME;
};
var isWeb = function isWeb() {
  return _platform === PLATFORMS.WEB;
};
var isNode = function isNode() {
  return _platform === PLATFORMS.NODE;
};
var isNative = function isNative() {
  return _platform === PLATFORMS.NATIVE;
};

//Set the platform, as well as setup the transport layer
var setup = function setup(platform) {
  set(platform);

  if (isElectron() || isNode()) {
    (0, _LRFComm.setTransportMethod)(_LRFComm.LRF_TRANSPORT_METHOD.SERIAL);
    var process = isNode() ? __webpack_require__(9) : window.process;
    return _LRFSerial2.default.setup(process.platform, PLATFORMS.NODE).then(function () {
      _LRFSerial2.default.setReceiveCallback(function (buffer) {
        LRFComm.unpack(buffer);
      });
    });
  } else if (isWeb()) {
    (0, _LRFComm.setTransportMethod)(_LRFComm.LRF_TRANSPORT_METHOD.WIFI);
    _LRFWifi2.default.setup(function (buffer) {
      LRFComm.unpack(buffer);
    });
    return Promise.resolve();
  } else if (isChrome()) {
    (0, _LRFComm.setTransportMethod)(_LRFComm.LRF_TRANSPORT_METHOD.SERIAL);
    return new Promise(function (resolve, reject) {
      chrome.runtime.getPlatformInfo(function (chromePlatformInfo) {
        if (chromePlatformInfo) resolve(chromePlatformInfo);else reject(new Error("chrome.runtime.getPlatformInfo could not retrieve PlatformInfo"));
      });
    }).then(function (chromePlatformInfo) {
      return _LRFSerial2.default.setup(chromePlatformInfo.os, PLATFORMS.CHROME_APP).then(function () {
        _LRFSerial2.default.setReceiveCallback(function (buffer) {
          LRFComm.unpack(buffer);
        });
      });
    });
  }

  return Promise.reject();
};

exports.default = {
  PLATFORMS: PLATFORMS,
  isElectron: isElectron,
  isChrome: isChrome,
  isWeb: isWeb,
  isNode: isNode,
  isNative: isNative,
  set: set,
  setup: setup,
  getPlatform: getPlatform
};
module.exports = exports["default"];

/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.compareVersions = exports.compareBuffers = exports.getColorClass = exports.stringToBuffer = exports.bufferToString = exports.englishToSnake = exports.snakeToEnglish = undefined;

var _LRFTypes = __webpack_require__(0);

var snakeToEnglish = exports.snakeToEnglish = function snakeToEnglish(snakeCaseString, useCaps) {
  var snakeToEnglishRE = /(\w)(\w*)(-+)?/g;

  var result = snakeCaseString.replace(snakeToEnglishRE, function (match, firstChar, body, dashes) {
    var englishString = "";
    if (useCaps) englishString += firstChar.toUpperCase();else englishString += firstChar;
    englishString += body;
    englishString += dashes ? dashes.replace(/(-)/g, " ") : ""; //dashes.replace("-", " ");

    return englishString;
  });

  return result;
};

var englishToSnake = exports.englishToSnake = function englishToSnake(englishString) {
  var englishToSnakeRE = /(\w+)\s*/ig;
  var staging = [];
  englishString.replace(englishToSnakeRE, function (match, word) {
    staging.push(word.toLowerCase());
  });
  return staging.join("-");
};

var bufferToString = exports.bufferToString = function bufferToString(buffer) {
  var charBuffer = void 0,
      string = void 0;
  if (Array.isArray(buffer)) {
    string = String.fromCharCode.apply(null, buffer);
  } else {
    charBuffer = new Uint8Array(buffer);
    string = String.fromCharCode.apply(null, charBuffer);
  }
  return string;
};

var stringToBuffer = exports.stringToBuffer = function stringToBuffer(string) {
  var charBuffer = new Uint8Array(string.length);
  for (var i = 0; i < string.length; i++) {
    charBuffer[i] = string.charCodeAt(i);
  }
  return charBuffer.buffer;
};

var getColorClass = exports.getColorClass = function getColorClass(lrfColor) {
  var colorCSS = {};
  colorCSS[_LRFTypes.LRFColor.red] = "red";
  colorCSS[_LRFTypes.LRFColor.green] = "green";
  colorCSS[_LRFTypes.LRFColor.blue] = "blue";
  colorCSS[_LRFTypes.LRFColor.orange] = "orange";
  colorCSS[_LRFTypes.LRFColor.cyan] = "cyan";
  colorCSS[_LRFTypes.LRFColor.purple] = "purple";
  colorCSS[_LRFTypes.LRFColor.yellow] = "yellow";
  colorCSS[_LRFTypes.LRFColor.pink] = "pink";
  colorCSS[_LRFTypes.LRFColor.white] = "white";
  colorCSS[_LRFTypes.LRFColor.none] = "none";

  if (lrfColor === undefined) return colorCSS[_LRFTypes.LRFColor.none];

  return colorCSS[lrfColor];
};

var compareBuffers = exports.compareBuffers = function compareBuffers(buff1, buff2) {
  var uint8Buff1 = new Uint8Array(buff1);
  var uint8Buff2 = new Uint8Array(buff2);

  return buff1.byteLength === buff2.byteLength && uint8Buff1.every(function (val, index) {
    return val === uint8Buff2[index];
  });
};

//Takes in two semantic version strings: eg "1.0.0" & "1.0.3";
//returns whether semVer is newer than semVer2
//No meta data is allowed eg: 1.0.0-alpha
var compareVersions = exports.compareVersions = function compareVersions(semVer1, semVer2) {
  var semVer1_Unpacked = semVer1.split(".");
  var semVer2_Unpacked = semVer2.split(".");

  var compareNums = function compareNums(n1, n2, index, length) {
    var nextIndex = index + 1;
    if (n1 > n2) return true;else if (n1 === n2 && nextIndex < length) {
      return compareNums(semVer1_Unpacked[nextIndex], semVer2_Unpacked[nextIndex], nextIndex, length);
    } else return false;
  };

  return compareNums(semVer1_Unpacked[0], semVer2_Unpacked[0], 0, 3);
};

/***/ }),
/* 5 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


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

var _LRFPlatform = __webpack_require__(3);

var _LRFPlatform2 = _interopRequireDefault(_LRFPlatform);

var _LRFWebCoreEvents = __webpack_require__(1);

var _LRFWebCoreEvents2 = _interopRequireDefault(_LRFWebCoreEvents);

var _LRFUtil = __webpack_require__(4);

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

// TODO: multiple connections
// let connectionStore = [];
// let connectionFilter = [];

var lastConnectionID = 0;

var onReceiveCB = void 0;

var activeConnection = undefined;

var ackReferenceBuffer = new Uint8Array([60, 0, 0, 254, 2, 10]).buffer;

var onReceive = function onReceive(buffer) {

  if (typeof buffer === "string") {
    console.log("WS - On Receive: type of data is string, not arraybuffer");
  }

  if ((0, _LRFUtil.compareBuffers)(buffer, ackReferenceBuffer)) {
    _LRFWebCoreEvents2.default.emit(EVENT.ACK);
    console.log("GOT ACK");
    return;
  }

  //TODO: multiple connection filtering goes here eventually
  onReceiveCB(buffer);
};

//Returns the websocket object containing the connection
var connect = function connect(address) {

  return new Promise(function (resolve, reject) {

    try {
      var connection = new WebSocket(address);
      connection.binaryType = "arraybuffer";
      connection.ID = ++lastConnectionID;
      activeConnection = connection;

      connection.addEventListener("message", function (message) {
        console.log("Websocket message received on connection " + connection.ID);
        console.log("message data: " + message.data);
        console.log("message data as uint8array: [" + new Uint8Array(message.data) + "]");
        onReceive(message.data);
      });

      connection.addEventListener("close", function () {
        console.log("Websocket Connection Closing");
        _LRFWebCoreEvents2.default.emit(EVENT.DISCONNECTED);
      });

      connection.addEventListener("error", function (error) {
        console.error(error);
      });

      connection.addEventListener("open", function () {
        resolve();
        _LRFWebCoreEvents2.default.emit(EVENT.CONNECTED);
      });
    } catch (exception) {
      reject(exception);
    }
  });
};

// TODO: multiple connections
// Adds this connection
// let addReserveConnection = (socket) => {
//   // connectionStore.push
// };

// let setConnectionFilter = () => {
//
// };

var setup = function setup(receiveCallback) {
  if (_LRFPlatform2.default.getPlatform() === _LRFPlatform2.default.PLATFORMS.WEB) {
    onReceiveCB = receiveCallback;
  } else {
    console.error(_LRFPlatform2.default.getPlatform() + " is not a recognized javascript environment");
  }
};

var send = function send(data) {
  if (activeConnection) {
    activeConnection.send(data);
  }
};

var disconnect = function disconnect() {
  if (activeConnection) {
    console.log("CLOSING WEBSOCKET");
    activeConnection.close();
    activeConnection = undefined;
  }
};

var EVENT = {
  DISCONNECTED: "WIFI.DISCONNECTED",
  CONNECTED: "WIFI.CONNECTED",
  ACK: "WIFI.ACK"
};

var isConnected = function isConnected() {
  return activeConnection ? true : false;
};

exports.default = {
  connect: connect,
  isConnected: isConnected,
  // addReserveConnection,
  // setConnectionFilter,
  disconnect: disconnect,
  send: send,
  setup: setup,
  EVENT: EVENT
};
module.exports = exports["default"];

/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.autoConnect = exports.isConnected = exports.setTransportMethod = exports.LRF_TRANSPORT_METHOD = exports.motionRead = exports.sightRead = exports.hearingRead = exports.touchRead = exports.getPresetExpressions = exports.getCustomPresetExpression = exports.eventsGetMap = exports.getRobotInfo = exports.getCharacterName = exports.sendAwaitingResponse = exports.send = exports.unpack = exports.resetComm = exports.EVENT = undefined;

var _LRFMessages = __webpack_require__(7);

var LRFMessages = _interopRequireWildcard(_LRFMessages);

var _LRFTypes = __webpack_require__(0);

var LRFCore = _interopRequireWildcard(_LRFTypes);

var _LRFWebCoreEvents = __webpack_require__(1);

var _LRFWebCoreEvents2 = _interopRequireDefault(_LRFWebCoreEvents);

var _LRFSerial = __webpack_require__(2);

var _LRFSerial2 = _interopRequireDefault(_LRFSerial);

var _LRFWifi = __webpack_require__(5);

var _LRFWifi2 = _interopRequireDefault(_LRFWifi);

var _LRFPlatform = __webpack_require__(3);

var _LRFPlatform2 = _interopRequireDefault(_LRFPlatform);

var _LRFRobotModel = __webpack_require__(8);

var LRFRobotModel = _interopRequireWildcard(_LRFRobotModel);

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

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

var EVENT = exports.EVENT = {
  EVENT_RECEIVED: "COMM.EventReceived",
  CONNECTED: "COMM.CONNECTED",
  DISCONNECTED: "COMM.DISCONNECTED"
};

var unpackingMessage = false,

// timeout,
maxWaitTime = 1000; //ms

var lastSent = void 0,
    defaultMessageDelay = 80;

var messageIn = new _LRFMessages.Message();
// messageOut = new Message();

var debugMode = true;

//Internal Circular Buffer
var received = {
  head: 0,
  tail: 0,
  bytes: new Uint8Array(512),
  length: 0,
  peek: function peek(index) {
    if (index !== undefined) {
      return this.bytes[(this.head + index) % this.bytes.length];
    }
    return this.bytes[this.head];
  },
  pop: function pop() {
    // console.log("popping!");
    if (this.length === 0) return;
    var tip = this.bytes[this.head];
    this.head = ++this.head % this.bytes.length;
    this.length--;
    return tip;
  },
  //new_bytes of type Uint8Array
  pushBytes: function pushBytes(new_bytes) {

    //Check if incoming buffer is too big
    if (new_bytes.length + this.length > this.bytes.length) {
      console.log("Received.pushBytes - pushed buffer is too big");
      return;
    }
    //If hypothetical new tail overflows buffer and there's free space: wrap
    if (this.tail + new_bytes.length > this.bytes.length) {
      // 500 + 100 = 600 // too big need wrap 600%512  512 - 500 = 12, 0-11, 12-99
      var spaceleft = this.bytes.length - this.tail;

      var firstChunk = new_bytes.slice(0, spaceleft);
      this.bytes.set(firstChunk, this.tail);
      this.tail = 0;

      var secondChunk = new_bytes.slice(spaceleft);
      this.bytes.set(secondChunk, this.tail);
      this.tail += secondChunk.length;
    } else {
      this.bytes.set(new_bytes, this.tail);
      this.tail = (this.tail + new_bytes.length) % this.bytes.length;
    }
    this.length += new_bytes.length;
  },
  flush: function flush(numBytes) {
    if (arguments.length) {
      // this.bytes.copyWithin(0, numberOfBytes);
      //head should never cross tail... erase up to and including tail, but never move past tail

      // numBytes = smaller between length & numBytes
      numBytes = Math.min(numBytes, this.length);

      var originalHead = this.head;

      //if we require wrapping and flush in phases
      if (this.head + numBytes > this.bytes.length) {
        var numBytesFirstPhase = this.bytes.length - this.head;
        this.bytes.fill(0, this.head);
        this.head = 0;
        var numBytesSecondPhase = numBytes - numBytesFirstPhase;
        this.bytes.fill(0, this.head, numBytesSecondPhase);
      } else {
        this.bytes.fill(0, this.head, this.head + numBytes);
      }
      this.head = (originalHead + numBytes) % this.bytes.length;
      this.length -= numBytes;
    } else {
      this.head = 0;
      this.tail = 0;
      this.length = 0;
      this.bytes.fill(0);
    }
  }
};

var unpackResults = [];
var unpackStrategy = {};

var unpackResolver = function unpackResolver(resolveValue) {
  //first in first out
  console.log("UNPACK RESULTS SHIFTING");
  var result = unpackResults.shift();
  clearTimeout(result.timeout);
  result.resolver(resolveValue);
  return result.promise;
};

unpackStrategy.generic = function () {
  console.log("Unpack - Generic Message Handler applied!");
  if (unpackResults.length != 0) {
    console.log("Returning data for last async request!");
    return unpackResolver(messageIn);
  } else {
    console.log("Unpack - No message was requested, dumping raw message");
    return messageIn;
  }
};

unpackStrategy[_LRFMessages.lrfMessageCode.EventsDidFire] = function () {
  var eventReceived;

  eventReceived = messageIn.bytes[0];

  _LRFWebCoreEvents2.default.emit(EVENT.EVENT_RECEIVED, eventReceived);
};

// Senses Unpack Strategies
// -----------------------------------------------------------------

unpackStrategy[_LRFMessages.lrfMessageCode.SensorUpdate] = function () {
  // console.log(`Unpack - SensorUpdate`);
  var dv = new DataView(messageIn.bytes.buffer);
  var values = {
    touch: {
      hair: dv.getUint8(0),
      left: dv.getUint8(1),
      right: dv.getUint8(2)
    },
    hearing: {
      level: dv.getInt16(3, true)
    },
    sight: {
      level: dv.getUint16(5, true)
    },
    motion: {
      x: dv.getInt16(7, true),
      y: dv.getInt16(9, true),
      z: dv.getInt16(11, true)
    }
  };
  // console.log('sensorUpdate:',values);
  // need to update a model here.
  LRFRobotModel.updateSenses(values);
  // return unpackResolver(values); // need to make this a flag
};

unpackStrategy[_LRFMessages.lrfMessageCode.TouchRead] = function () {
  // console.log(`Unpack - TouchRead`);
  var dv = new DataView(messageIn.bytes.buffer);
  var values = {
    hair: dv.getUint8(0),
    left: dv.getUint8(1),
    right: dv.getUint8(2)
  };
  // console.log('touchRead:',values);
  return unpackResolver(values);
};

unpackStrategy[_LRFMessages.lrfMessageCode.HearingRead] = function () {
  // console.log(`Unpack - HearingRead`);
  var dv = new DataView(messageIn.bytes.buffer);
  var values = {
    level: dv.getInt16(0, true)
  };
  // console.log('hearingRead:',values);
  return unpackResolver(values);
};

unpackStrategy[_LRFMessages.lrfMessageCode.SightRead] = function () {
  // console.log(`Unpack - SightRead`);
  var dv = new DataView(messageIn.bytes.buffer);
  var values = {
    level: dv.getUint16(0, true)
  };
  // console.log('sightRead:',values);
  return unpackResolver(values);
};

unpackStrategy[_LRFMessages.lrfMessageCode.MotionRead] = function () {
  // console.log(`Unpack - MotionRead`);
  var dv = new DataView(messageIn.bytes.buffer);
  var values = {
    x: dv.getInt16(0, true),
    y: dv.getInt16(2, true),
    z: dv.getInt16(4, true)
  };
  // console.log('motionRead:',values);
  return unpackResolver(values);
};

// Other Unpack Strategies
// -----------------------------------------------------------------

unpackStrategy[_LRFMessages.lrfMessageCode.GetCharacterName] = function () {
  console.log("Unpack - GetCharacterName: " + messageIn.string);

  var string = "";

  for (var i = 0; i < messageIn.length; i++) {
    string += String.fromCharCode(messageIn.bytes[i]);
  }

  messageIn.string = string.replace(String.fromCharCode(255), "");
  messageIn.string = string.replace(/[\0]/g, "");

  return unpackResolver(messageIn.string);
};

unpackStrategy[_LRFMessages.lrfMessageCode.GetRobotInfo] = function () {
  console.log("Unpack - GetRobotInfo");

  var robotInfo = {
    faceType: -1, //index 0
    name: "", //index 1
    faceSerial: "", //index 33
    baseSerial: "", //index 43
    firmwareVersion: "" //index 59
  };

  var faceTypeLength = 1,
      nameLength = 32,
      faceSerialStartIndex = faceTypeLength + nameLength,
      //33
  faceSerialLength = 10,
      baseSerialStartIndex = faceSerialStartIndex + faceSerialLength,
      //43
  baseSerialLength = 16,
      firmwareStartIndex = baseSerialStartIndex + baseSerialLength,
      //49
  // firmwareLength = 3,
  i = void 0;

  //Get face type
  robotInfo.faceType = messageIn.bytes[0];

  //Get Character Name
  for (i = faceTypeLength; i < faceSerialStartIndex; i++) {
    robotInfo.name += String.fromCharCode(messageIn.bytes[i]);
  }

  //Remove null chars from name
  robotInfo.name = robotInfo.name.replace(String.fromCharCode(255), "");
  robotInfo.name = robotInfo.name.replace(/[\0]/g, "");

  //Get Face Serial
  for (i = faceSerialStartIndex; i < baseSerialStartIndex; i++) {
    robotInfo.faceSerial += messageIn.bytes[i] < 0xf ? "0" + messageIn.bytes[i].toString(16) : messageIn.bytes[i].toString(16);
    if (i + 1 !== baseSerialStartIndex) robotInfo.faceSerial += " ";
  }

  for (i = baseSerialStartIndex; i < baseSerialStartIndex + baseSerialLength; i++) {
    robotInfo.baseSerial += messageIn.bytes[i] < 0xf ? "0" + messageIn.bytes[i].toString(16) : messageIn.bytes[i].toString(16);
    if (i + 1 !== baseSerialStartIndex + baseSerialLength) robotInfo.baseSerial += " ";
  }

  if (messageIn.bytes.length === 62) {
    robotInfo.firmwareVersion = messageIn.bytes[firmwareStartIndex].toString() + "." + messageIn.bytes[firmwareStartIndex + 1].toString() + "." + messageIn.bytes[firmwareStartIndex + 2].toString();
  }

  return unpackResolver(robotInfo);
};

unpackStrategy[_LRFMessages.lrfMessageCode.GetCustomPresetExpression] = function () {

  var customExpressionBundle = {
    index: 0,
    name: "",
    expression: LRFCore.createExpression()
  };

  console.log("Unpack - GetCustomPresetExpression");
  // console.log(messageIn.bytes);
  var dv = new DataView(messageIn.bytes.buffer);
  var soundIndex, sound, soundRaw;

  //Get Custom Expression Index
  customExpressionBundle.index = messageIn.bytes[0];

  //Get Pattern
  customExpressionBundle.expression.pattern.unpackRaw(dv.getUint16(1));

  //Get Sounds
  for (soundIndex = 0; soundIndex < 4; soundIndex++) {
    soundRaw = dv.getUint16(3 + soundIndex * 2);
    sound = soundRaw !== LRFCore.CONSTANTS.NULL_SOUND ? LRFCore.createSound() : undefined;
    if (!sound) {
      break;
    }
    sound.unpackRaw(soundRaw);
    customExpressionBundle.expression.sounds.push(sound);
  }

  for (var i = 11; i < messageIn.length; i++) {
    customExpressionBundle.name += String.fromCharCode(messageIn.bytes[i]);
  }

  customExpressionBundle.name = customExpressionBundle.name.replace(/[^\w-]/g, "");

  customExpressionBundle.expression.uname = customExpressionBundle.name;

  return unpackResolver(customExpressionBundle);
};

unpackStrategy[_LRFMessages.lrfMessageCode.GetPresetExpressions] = function () {

  console.log("Unpack - GetPresetExpressions");

  var dv = new DataView(messageIn.bytes.buffer);

  var expressions = {},
      expression,
      chunkSize = _LRFMessages.LRFEXPRESSION_SIZE + _LRFMessages.LRFMEMORYINDEX_SIZE,
      numExpressions = messageIn.length / chunkSize,
      i,
      sound,
      soundRaw,
      soundOffset,
      soundsEndIndex,
      soundsStartIndex,
      expressionIndex,
      patternOffset;

  for (i = 0; i < numExpressions; i++) {

    expression = LRFCore.createExpression();
    expressionIndex = messageIn.bytes[i * chunkSize]; //0*11 = 0, 1*11 = 11, 2*11 = 22
    patternOffset = i * chunkSize + _LRFMessages.LRFMEMORYINDEX_SIZE; //0 + 1 = 1, 11 + 1 = 12, 22+1 = 23

    soundsStartIndex = patternOffset + _LRFMessages.LRFPATTERN_SIZE; //patern [1,2] 1+2 = 3, 3
    soundsEndIndex = patternOffset + _LRFMessages.LRFEXPRESSION_SIZE - _LRFMessages.LRFPATTERN_SIZE;

    expression.pattern.unpackRaw(dv.getUint16(patternOffset));

    for (soundOffset = soundsStartIndex; soundOffset <= soundsEndIndex; soundOffset += _LRFMessages.LRFSOUND_SIZE) {

      soundRaw = dv.getUint16(soundOffset); //TODO: sometimes gets hung up with offset outside of bounds of dataview

      if (soundRaw == LRFCore.CONSTANTS.NULL_SOUND) {
        break;
      }

      sound = LRFCore.createSound();
      sound.unpackRaw(soundRaw);
      expression.sounds.push(sound);
    }

    expressions[expressionIndex] = expression;
  }

  return unpackResolver(expressions);
};

unpackStrategy[_LRFMessages.lrfMessageCode.EventsGetMap] = function () {

  console.log("Unpack - EventsGetMap");

  var expressionIndices = [],
      dataView = new DataView(messageIn.bytes.buffer),
      i;

  for (i = 0; i < messageIn.length; i++) {
    expressionIndices.push(dataView.getUint8(i));
  }
  // console.log("expression indices are: " + expressionIndices);
  return unpackResolver(expressionIndices);
};

var unpackTimeout;

_LRFWebCoreEvents2.default.on(_LRFSerial2.default.EVENT.CONNECTED, function () {
  _LRFWebCoreEvents2.default.emit(EVENT.CONNECTED);
});
_LRFWebCoreEvents2.default.on(_LRFSerial2.default.EVENT.DISCONNECTED, function () {
  resetComm();
  _LRFWebCoreEvents2.default.emit(EVENT.DISCONNECTED);
});

_LRFWebCoreEvents2.default.on(_LRFWifi2.default.EVENT.CONNECTED, function () {
  _LRFWebCoreEvents2.default.emit(EVENT.CONNECTED);
});
_LRFWebCoreEvents2.default.on(_LRFWifi2.default.EVENT.DISCONNECTED, function () {
  resetComm();
  _LRFWebCoreEvents2.default.emit(EVENT.DISCONNECTED);
});

var resetComm = exports.resetComm = function resetComm() {
  console.log("Resetting LRFComm");
  received.flush();

  unpackResults.forEach(function (resultBundle) {
    clearTimeout(resultBundle.timeout);
  });
  unpackResults = [];
  messageIn.clear();
  _LRFMessages.messageOut.clear();
};

var unpack = exports.unpack = function unpack(buffer) {

  var newbytes = new Uint8Array(buffer);
  var result = "";

  //Get bytes from buffer
  // Is incoming buffer larger than internal buffer?
  if (newbytes.length > received.bytes.length) {
    console.log("Size of incoming buffer is: " + newbytes.length);
    console.log("Incoming buffer length too large.");
    return;
  }

  //is incoming buffer larger than the available space in our internal buffer?
  if (newbytes.length > received.bytes.length - received.length) {
    console.log("Buffer overflowed and packets were dropped.");
    if (unpackingMessage) {
      unpackingMessage = false;
      clearTimeout(unpackTimeout); // $timeout.cancel(unpackTimeout);
    }
    return;
  }

  //Get bytes
  received.pushBytes(newbytes);

  while (received.length >= _LRFMessages.headerLength) {
    //Get message header if we don't have one
    if (!unpackingMessage) {
      //Do we have enough bytes for a message?
      if (received.peek() === _LRFMessages.startByte) {

        //Get Message Length
        messageIn.length = received.peek(1);

        //Get Message Info
        messageIn.info = received.peek(2);

        //Get Message Command
        messageIn.command = received.peek(3);

        //header unpacked, change phase for new packets
        unpackingMessage = true;

        unpackTimeout = setTimeout(function () {
          unpackingMessage = false;
          console.log("unpack function timed out waiting for new bytes");
          received.pop(); //dump start byte
          messageIn.clear();
        }, maxWaitTime);
      } else if (debugMode) {
        result += String.fromCharCode(received.pop());
      } else {
        received.pop();
      }
    }
    //If we found a message header and we have enough bytes to fulfil this message
    // if (unpackingMessage && received.length >= messageIn.length + footerLength) {
    if (unpackingMessage && received.length >= _LRFMessages.headerLength + messageIn.length + _LRFMessages.footerLength) {
      clearTimeout(unpackTimeout); // $timeout.cancel(unpackTimeout);
      unpackingMessage = false;

      var sliceStartIndex = (received.head + _LRFMessages.headerLength) % received.bytes.length;
      var sliceEndIndex = (sliceStartIndex + messageIn.length) % received.bytes.length;

      if (sliceStartIndex > sliceEndIndex) {
        messageIn.bytes = new Uint8Array(messageIn.length);
        var firstChunkLength = received.bytes.length - sliceStartIndex;
        messageIn.bytes.set(received.bytes.slice(sliceStartIndex));
        messageIn.bytes.set(received.bytes.slice(0, sliceEndIndex), firstChunkLength);
      } else {
        messageIn.bytes = received.bytes.slice(sliceStartIndex, sliceEndIndex);
      }

      messageIn.crc = received.peek(_LRFMessages.headerLength + messageIn.length);

      var receivedEndByte = received.peek(_LRFMessages.headerLength + messageIn.length + 1);

      //Validate CRC & end byte
      if (messageIn.crc == (0, _LRFMessages.getCRC)(messageIn) && receivedEndByte == _LRFMessages.endByte) {
        //Successfully populated message, print, flush, unpack and clean up

        if (false) {
          console.log("Got Message: ");
          messageIn.print();
        }

        received.flush(_LRFMessages.headerLength + messageIn.length + _LRFMessages.footerLength); //dump all message bytes

        result = unpackStrategy[messageIn.command] ? unpackStrategy[messageIn.command]() : unpackStrategy.generic();
        messageIn.clear();
      }
      //if bad crc or end byte, pop head and retry
      else {
          if (messageIn.crc !== (0, _LRFMessages.getCRC)(messageIn)) {
            console.log("BAD CRC - messageIn.crc: " + messageIn.crc + " | getCRC(): " + (0, _LRFMessages.getCRC)(messageIn));
          }
          if (receivedEndByte !== _LRFMessages.endByte) {
            console.log("BAD END BYTE - received endByte: " + receivedEndByte);
          }
          console.log("Faulty Message: ");
          messageIn.print();
          messageIn.clear();
          received.pop(); //pop startByte and try again!
        }
    }
    //If we've found a message header, but don't have enough bytes to fulfil it, break out of the loop and wait for more
    else if (unpackingMessage && received.length < _LRFMessages.headerLength + messageIn.length + _LRFMessages.footerLength) {
        break;
      }
  } //end while

  return result;
};

//buffer, [requiresDelay]
var send = exports.send = function send(lrfmessagebuffer, requiresDelay) {
  if (_LRFPlatform2.default.isWeb()) {
    if (_LRFWifi2.default.isConnected()) {
      //TODO: implement a universal send delay
      _LRFWifi2.default.send(lrfmessagebuffer);
    }
  } else {
    if (_LRFSerial2.default.isConnected()) {
      if (requiresDelay) {
        var messageDelay = 0;
        if (lastSent) {
          var timeDiff = new Date().getTime() - lastSent;
          messageDelay = timeDiff > defaultMessageDelay ? 0 : defaultMessageDelay - timeDiff;
          lastSent = new Date().getTime();
        } else {
          lastSent = new Date().getTime();
        }
        console.log("Queued message. Will send in: " + messageDelay + " ms");
        setTimeout(function () {
          _LRFSerial2.default.send(lrfmessagebuffer);
          if (false) {
            console.log("Sending Message:");
            _LRFMessages.messageOut.print();
          }
        }, messageDelay);
      } else {
        if (false) {
          console.log("Sending Message:");
          _LRFMessages.messageOut.print();
        }
        _LRFSerial2.default.send(lrfmessagebuffer);
      }
    }
  }
};

//FETCH FUNCTIONS

var sendAwaitingResponse = exports.sendAwaitingResponse = function sendAwaitingResponse(lrfmessagebuffer) {

  var resultPromise = new Promise(function (resolve, reject) {

    var timeout = void 0;

    send(lrfmessagebuffer, false);

    timeout = setTimeout(function () {
      var error = new Error("Timed out waiting for response");
      // result = Promise.reject(error);
      unpackResults.shift();
      reject(error);
    }, maxWaitTime);

    //Pushes a reference to the promise, resolver, and timeout to a handler
    //queue that will be resolved upon receipt of a response message
    unpackResults.push({
      promise: resultPromise,
      resolver: resolve,
      timeout: timeout
    });
  });

  return resultPromise;
};

var getCharacterName = exports.getCharacterName = function getCharacterName() {
  return sendAwaitingResponse(LRFMessages.getCharacterName());
};
var getRobotInfo = exports.getRobotInfo = function getRobotInfo() {
  return sendAwaitingResponse(LRFMessages.getRobotInfo());
};
//TODO: this is broken
var eventsGetMap = exports.eventsGetMap = function eventsGetMap(actionIndexRange) {
  return sendAwaitingResponse(LRFMessages.eventsGetMap(actionIndexRange));
};
var getCustomPresetExpression = exports.getCustomPresetExpression = function getCustomPresetExpression(customExpressionIndex) {
  return sendAwaitingResponse(LRFMessages.getCustomPresetExpression(customExpressionIndex));
};
//End Index is optional
var getPresetExpressions = exports.getPresetExpressions = function getPresetExpressions(startIndex, endIndex) {
  return sendAwaitingResponse(LRFMessages.getPresetExpressions(startIndex, endIndex));
};

// Sensor Getters

var touchRead = exports.touchRead = function touchRead() {
  return sendAwaitingResponse(LRFMessages.touchRead());
};
var hearingRead = exports.hearingRead = function hearingRead() {
  return sendAwaitingResponse(LRFMessages.hearingRead());
};
var sightRead = exports.sightRead = function sightRead() {
  return sendAwaitingResponse(LRFMessages.sightRead());
};
var motionRead = exports.motionRead = function motionRead() {
  return sendAwaitingResponse(LRFMessages.motionRead());
};

var LRF_TRANSPORT_METHOD = exports.LRF_TRANSPORT_METHOD = {
  WIFI: "WIFI",
  SERIAL: "SERIAL"
};

var transportMethod = void 0;

var setTransportMethod = exports.setTransportMethod = function setTransportMethod(method) {
  transportMethod = method;
};
var isConnected = exports.isConnected = function isConnected() {
  if (transportMethod === LRF_TRANSPORT_METHOD.WIFI) return _LRFWifi2.default.isConnected();else if (transportMethod === LRF_TRANSPORT_METHOD.SERIAL) {
    return _LRFSerial2.default.isConnected();
  }
};
var autoConnect = exports.autoConnect = function autoConnect() {
  if (transportMethod === LRF_TRANSPORT_METHOD.SERIAL) {
    _LRFSerial2.default.autoConnect();
  } else if (transportMethod === LRF_TRANSPORT_METHOD.WIFI) {
    console.log("Attempting to connect to robot on 192.168.4.1:80");
    _LRFWifi2.default.connect("ws://192.168.4.1:80").then(null, function () {
      setTimeout(function () {
        autoConnect();
      }, 2000);
    });
  }
};
// } //end lrf comm

/***/ }),
/* 7 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.motionRead = exports.motionSetConfig = exports.motionGetConfig = exports.sightRead = exports.sightSetConfig = exports.sightGetConfig = exports.hearingRead = exports.hearingSetConfig = exports.hearingGetConfig = exports.touchRead = exports.touchSetConfig = exports.touchGetConfig = exports.sensesSetEnabled = exports.sensesGetEnabled = exports.getPresetSong = exports.setPresetSong = exports.singSong = exports.chatter = exports.setCustomPresetExpression = exports.getCustomPresetExpression = exports.getPresetExpressions = exports.blinkAndSay = exports.blinkAndSayPresetWithIndex = exports.blinkAndSayPreset = exports.speechSaySounds = exports.speechSet = exports.eyesBlinkPatterns = exports.eyesSetColors = exports.eyesSet = exports.eventsGetMap = exports.eventsSetMap = exports.setCharacterName = exports.getCharacterName = exports.getRobotInfo = exports.sensorUpdate = exports.setControlMode = exports.ackMessage = exports.getCRC = exports.messageOut = exports.Message = exports.minMessageLength = exports.endByte = exports.startByte = exports.minBodyLength = exports.footerLength = exports.headerLength = exports.LRFMEMORYINDEX_SIZE = exports.LRFEXPRESSION_SIZE = exports.LRFSOUND_SIZE = exports.LRFPATTERN_SIZE = exports.lrfMessageCode = undefined;

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 _LRFTypes = __webpack_require__(0);

var LRFCore = _interopRequireWildcard(_LRFTypes);

var _LRFUtil = __webpack_require__(4);

var LRFUtil = _interopRequireWildcard(_LRFUtil);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

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

//LRFMessages defines messages for interacting with a Little Robot Friends

// Message Format is as follows:
// [startbyte, length, options, command, [bytes], crc, endbyte]

var lrfMessageCode = exports.lrfMessageCode = {

  //ROBOT META
  GetRobotInfo: 0x40,
  GetCharacterName: 0x41,
  SetCharacterName: 0x42,
  SetControlMode: 0x43,
  SensorUpdate: 0x44,

  EventsDidFire: 0x4a,
  EventsGetMap: 0x4b, //gets the expression map
  EventsSetMap: 0x4c, //sets a mapping between action and expression
  EventsFire: 0x4d,
  EventsClear: 0x4e,

  //EYES
  EyesSet: 0x50,
  EyesSetColors: 0x51,
  EyesBlinkPatterns: 0x52,

  //Sounds
  SpeechSet: 0x53,
  SpeechSaySounds: 0x54,

  //Expressions
  BlinkAndSay: 0x57,
  BlinkAndSayPreset: 0x58,

  GetPresetExpressions: 0x59,
  GetCustomPresetExpression: 0x5a,
  SetCustomPresetExpression: 0x5b,

  Chatter: 0x5c,

  SingSong: 0x5d,
  GetPresetSong: 0x5e,
  SetPresetSong: 0x5f,

  SensesGetEnabled: 0x60, // 96
  SensesSetEnabled: 0x61, // 97
  TouchGetConfig: 0x62, // 98
  TouchSetConfig: 0x63, // 99
  TouchRead: 0x64, // 100
  HearingGetConfig: 0x65, // 101
  HearingSetConfig: 0x66, // 102
  HearingRead: 0x67, // 103
  SightGetConfig: 0x68, // 104
  SightSetConfig: 0x69, // 105
  SightRead: 0x6a, // 106
  MotionGetConfig: 0x6b, // 107
  MotionSetConfig: 0x6c, // 108
  MotionRead: 0x6d, // 109


  ack: 0xfe
};

var LRFPATTERN_SIZE = exports.LRFPATTERN_SIZE = 2,
    LRFSOUND_SIZE = exports.LRFSOUND_SIZE = 2,
    LRFEXPRESSION_SIZE = exports.LRFEXPRESSION_SIZE = 10,
    LRFMEMORYINDEX_SIZE = exports.LRFMEMORYINDEX_SIZE = 1,
    headerLength = exports.headerLength = 4,
    //startbyte, length, info, cmd
footerLength = exports.footerLength = 2,
    //crc + end byte
minBodyLength = exports.minBodyLength = 0,
    startByte = exports.startByte = "<".charCodeAt(0),
    endByte = exports.endByte = "\n".charCodeAt(0),
    minMessageLength = exports.minMessageLength = headerLength + minBodyLength + footerLength;

function makeDataView(size) {
  var buffer = new ArrayBuffer(size);
  return new DataView(buffer);
}

//Message Format
//startByte, length, options, command, bytes, crc, end byte

var Message = exports.Message = function () {
  function Message() {
    _classCallCheck(this, Message);

    this.command = 0;
    this.info = 0;
    this.options = {};
    this.crc = 0;
    this.length = 0;
    this.bytes = new Uint8Array(0);
    this.string = "";
  }

  _createClass(Message, [{
    key: "clear",
    value: function clear() {
      this.length = 0;
      this.options = {};
      this.info = 0;
      this.command = 0;
      this.bytes = new Uint8Array(0);
      this.crc = 0;
      this.string = "";
    }

    //Set options with an options object:
    /*
      {
        requiresResponse : boolean,
        version:
        interface:
        prefersBlocking: boolean
      }
    */

  }, {
    key: "unpackOptions",
    value: function unpackOptions(rawOptions) {
      if (!rawOptions) return 0;

      this.options.requiresResponse = rawOptions & 254;
      this.options.version = rawOptions & 14 >> 1;
      this.options.interface = rawOptions & 48 >> 4;
      this.options.prefersBlocking = rawOptions & 64 >> 6;

      return this.options;
    }
  }, {
    key: "packOptions",
    value: function packOptions() {
      if (!this.options) return 0;

      var packedOptions = 0;

      if (this.options.requiresResponse) {
        packedOptions |= 1;
      }

      if (this.options.version) {
        packedOptions |= (this.options.version & 7) << 1;
      }

      if (this.options.interface) {
        packedOptions |= (this.options.interface & 3) << 4;
      }

      if (this.options.prefersBlocking) {
        packedOptions |= 1 << 6;
      }

      return packedOptions;
    }
  }, {
    key: "compose",
    value: function compose() {
      var byteArray = new Uint8Array(headerLength + this.bytes.length + footerLength + 1 /*temp fix for samd 1.6.15*/);

      //generate CRC
      this.info = this.packOptions();
      this.crc = getCRC(this);

      byteArray[0] = startByte;
      byteArray[1] = this.length;
      byteArray[2] = this.info;
      byteArray[3] = this.command;

      for (var i = headerLength, j = 0; i < headerLength + this.bytes.length; i++, j++) {
        byteArray[i] = this.bytes[j];
      }

      byteArray[headerLength + this.bytes.length] = this.crc;
      byteArray[headerLength + this.bytes.length + 1] = endByte;
      byteArray[headerLength + this.bytes.length + 2] = endByte;
      // byteArray[byteArray.length - 2] = this.crc;
      // byteArray[byteArray.length - 1] = endByte;

      console.log(byteArray);

      return byteArray;
    }
  }, {
    key: "print",
    value: function print() {
      console.log("---");
      console.log("Length: " + this.length + "; Options: " + this.options + "; Command: " + this.command + "; CRC: " + this.crc);
      console.log("Bytes " + this.bytes);
      console.log("---");
    }
  }]);

  return Message;
}();

var messageOut = exports.messageOut = new Message();

var getCRC = exports.getCRC = function getCRC(message) {
  var crc = 0;

  //TODO: clean this up?
  crc += message.length; // "
  crc &= 0xff;
  crc += message.info;
  crc &= 0xff;
  crc += message.command; //always < 256
  crc &= 0xff;

  if (message.bytes.length > 0) {
    crc += message.bytes.reduce(function (previous, current) {
      return previous + current & 0xff;
    });
  }

  crc = ~crc;
  crc &= 0xff;
  crc += 1;
  crc &= 0xff;

  return crc;
};

//Message Buffers

var ackMessage = exports.ackMessage = function ackMessage() {
  console.log("generating ack");
  messageOut.command = lrfMessageCode.ack;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

// controlMode: number -> 1  = control; 0 = release control;
var setControlMode = exports.setControlMode = function setControlMode(controlMode) {
  messageOut.command = lrfMessageCode.SetControlMode;
  messageOut.length = 1;
  messageOut.bytes = new Uint8Array([controlMode]);
  return messageOut.compose().buffer;
};

var sensorUpdate = exports.sensorUpdate = function sensorUpdate() {
  messageOut.command = lrfMessageCode.sensorUpdate;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var getRobotInfo = exports.getRobotInfo = function getRobotInfo() {
  messageOut.command = lrfMessageCode.GetRobotInfo;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var getCharacterName = exports.getCharacterName = function getCharacterName() {
  messageOut.command = lrfMessageCode.GetCharacterName;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

//TODO: depends on LRFUtil
var setCharacterName = exports.setCharacterName = function setCharacterName(newName) {
  newName = newName.slice(0, 32); //limit to 32 byte strings
  messageOut.command = lrfMessageCode.SetCharacterName;
  messageOut.length = 32;
  messageOut.bytes = new Uint8Array(32);
  messageOut.bytes.set(new Uint8Array(LRFUtil.stringToBuffer(newName)));
  return messageOut.compose().buffer;
};

var eventsSetMap = exports.eventsSetMap = function eventsSetMap(actionIndex, expressionIndex) {
  messageOut.command = lrfMessageCode.EventsSetMap;
  messageOut.length = 2;

  messageOut.bytes = new Uint8Array([actionIndex, expressionIndex]);
  return messageOut.compose().buffer;
};

//actionIndexRange: type: object or number; format: {startIndex, endIndex}, 0
//See LRFCore for predefined range values
//Send Format: start index, [end index]
//Receive Format: <action index, expression data[, ..., action index, expression data]>
var eventsGetMap = exports.eventsGetMap = function eventsGetMap(actionRange) {
  messageOut.command = lrfMessageCode.EventsGetMap;
  if (typeof actionRange === "number") {
    messageOut.length = 1;
    messageOut.bytes = new Uint8Array([actionRange]);
  } else if ((typeof actionRange === "undefined" ? "undefined" : _typeof(actionRange)) === "object") {
    messageOut.length = 2;
    messageOut.bytes = new Uint8Array([actionRange.startIndex, actionRange.endIndex]);
  }
  return messageOut.compose().buffer;
};

//LED COLOURS
var eyesSet = exports.eyesSet = function eyesSet(leftRedVal, leftGreenVal, leftBlueVal, rightRedVal, rightGreenVal, rightBlueVal) {

  messageOut.command = lrfMessageCode.EyesSet;
  messageOut.length = 6;
  messageOut.bytes = new Uint8Array([leftRedVal, leftGreenVal, leftBlueVal, rightRedVal, rightGreenVal, rightBlueVal]);

  return messageOut.compose().buffer;
};

var eyesSetColors = exports.eyesSetColors = function eyesSetColors(lrfColor_left, lrfColor_right) {

  messageOut.command = lrfMessageCode.EyesSetColors;
  messageOut.length = 2;
  messageOut.bytes = new Uint8Array([lrfColor_left, lrfColor_right]);
  return messageOut.compose().buffer;
};

//PATTERNS

//lrfPatterns: a lrfPattern or array of lrfPatterns
var eyesBlinkPatterns = exports.eyesBlinkPatterns = function eyesBlinkPatterns(lrfPatterns) {
  var prefersBlocking = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;


  messageOut.command = lrfMessageCode.EyesBlinkPatterns;
  messageOut.options = {
    prefersBlocking: prefersBlocking
  };

  var dataView = void 0;

  if (Array.isArray(lrfPatterns)) {
    messageOut.length = lrfPatterns.length * LRFPATTERN_SIZE;
    dataView = makeDataView(messageOut.length);
    lrfPatterns.forEach(function (lrfPattern, index) {
      dataView.setUint16(2 * index, lrfPattern);
    });
  } else {
    messageOut.length = LRFPATTERN_SIZE;
    dataView = makeDataView(messageOut.length);
    dataView.setUint16(0, lrfPatterns.getRaw());
  }

  messageOut.bytes = new Uint8Array(dataView.buffer);

  return messageOut.compose().buffer;
};

//SOUNDS

//Get yo freq on by setting the frequency of the little robot friends speaker
//freq : value between 80 and 4000
var speechSet = exports.speechSet = function speechSet(freq) {
  freq = freq === 0 ? 0 : Math.max(Math.min(freq, 15000), 10);
  messageOut.command = lrfMessageCode.SpeechSet;
  messageOut.length = 2;
  messageOut.bytes = new Uint8Array(new Uint16Array([freq]).buffer);
  return messageOut.compose().buffer;
};

//lrfSounds - an array comprised of lrfSound objects
var speechSaySounds = exports.speechSaySounds = function speechSaySounds(lrfSounds) {
  var prefersBlocking = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;


  messageOut.command = lrfMessageCode.SpeechSaySounds;
  messageOut.options = {
    prefersBlocking: prefersBlocking
  };

  var dataView = void 0;

  if (Array.isArray(lrfSounds)) {
    messageOut.length = lrfSounds.length * LRFSOUND_SIZE;
    dataView = makeDataView(messageOut.length);
    lrfSounds.forEach(function (sound, index) {
      dataView.setUint16(index * 2, sound.getRaw());
    });
  } else {
    messageOut.length = LRFSOUND_SIZE;
    dataView = makeDataView(messageOut.length);
    dataView.setUint16(0, lrfSounds.getRaw());
  }

  messageOut.bytes = new Uint8Array(dataView.buffer);
  return messageOut.compose().buffer;
};

//EXPRESSIONS
//expressionLabel: lower case snake-case expression label
var blinkAndSayPreset = exports.blinkAndSayPreset = function blinkAndSayPreset(expressionLabel) {
  var prefersBlocking = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

  var expressionIndex = LRFCore.LRFExpression[expressionLabel];
  return blinkAndSayPresetWithIndex(expressionIndex, prefersBlocking);
};

var blinkAndSayPresetWithIndex = exports.blinkAndSayPresetWithIndex = function blinkAndSayPresetWithIndex(expressionIndex) {
  var prefersBlocking = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

  messageOut.options = {
    prefersBlocking: prefersBlocking
  };
  messageOut.length = LRFMEMORYINDEX_SIZE;
  messageOut.command = lrfMessageCode.BlinkAndSayPreset;
  messageOut.bytes = new Uint8Array([expressionIndex]);
  return messageOut.compose().buffer;
};

var blinkAndSay = exports.blinkAndSay = function blinkAndSay(expression) {
  var prefersBlocking = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;


  messageOut.options = {
    prefersBlocking: prefersBlocking
  };
  messageOut.command = lrfMessageCode.BlinkAndSay;
  messageOut.length = 10; //Array.isArray(expression) ? expression.length*2 : 8;//expression.sounds.length*2 + 2;//pattern;
  var dataView = makeDataView(messageOut.length);

  if (Array.isArray(expression)) {
    expression.forEach(function (rawValue, index) {
      dataView.setUint16(index * 2, rawValue);
    });
  } else {
    dataView.setUint16(0, expression.pattern.getRaw());
    expression.sounds.forEach(function (sound, index) {
      dataView.setUint16(index * 2 + 2, sound.getRaw());
    });
  }

  messageOut.bytes = new Uint8Array(dataView.buffer);
  return messageOut.compose().buffer;
};

//Fetches expression data for a given index, or a range of indices
//startIndex: the expressionIndex to startFetching at
//[endIndex]: the expressionIndex to stop fetching at (inclusive)
var getPresetExpressions = exports.getPresetExpressions = function getPresetExpressions(startIndex, endIndex) {
  messageOut.command = lrfMessageCode.GetPresetExpressions;
  messageOut.length = endIndex ? 2 : 1;

  if (endIndex) messageOut.bytes = new Uint8Array([startIndex, endIndex]);else messageOut.bytes = new Uint8Array([startIndex]);

  return messageOut.compose().buffer;
};
var getCustomPresetExpression = exports.getCustomPresetExpression = function getCustomPresetExpression(lrfMemoryIndex) {

  messageOut.command = lrfMessageCode.GetCustomPresetExpression;
  messageOut.length = 1;
  messageOut.bytes = new Uint8Array([lrfMemoryIndex]);
  return messageOut.compose().buffer;
};

//TODO: depends on LRFCore.constants
var setCustomPresetExpression = exports.setCustomPresetExpression = function setCustomPresetExpression(lrfMemoryIndex, expressionData, expressionName) {

  messageOut.command = lrfMessageCode.SetCustomPresetExpression;
  messageOut.length = 43; //Array.isArray(expression) ? expression.length * 2 + 1 : expression.sounds.length * 2 + 3; //pattern + memory index

  var dataView = makeDataView(messageOut.length);

  //Pack index
  dataView.setUint8(0, lrfMemoryIndex);

  //Pack expression
  var nullSoundCount = 4 - expressionData.sounds.length,
      nullSoundStartIndex = void 0;

  //Pack Pattern
  dataView.setUint16(1, expressionData.pattern.getRaw());

  //Pack sounds
  var soundsStartIndex = LRFMEMORYINDEX_SIZE + LRFPATTERN_SIZE; //0 index, 1 pattern, 2 pattern, 3 soundsStartIndex (LRFMEMORYINDEX_SIZE=1 + LRFPATTERN_SIZE=2)
  console.log("soundsStartIndex");
  expressionData.sounds.forEach(function (sound, index) {
    console.log("Sound " + index + " packed at " + (soundsStartIndex + index * LRFSOUND_SIZE) + " in data buffer");
    dataView.setUint16(soundsStartIndex + index * LRFSOUND_SIZE, sound.getRaw());
    nullSoundStartIndex = soundsStartIndex + LRFSOUND_SIZE + index * LRFSOUND_SIZE;
    console.log("nullSoundStartIndex: " + nullSoundStartIndex);
  });

  for (var i = 0; i < nullSoundCount; i++) {
    dataView.setUint16(nullSoundStartIndex + i * LRFSOUND_SIZE, LRFCore.CONSTANTS.NULL_SOUND); //Set null sound
  }

  //Pack name
  expressionName = expressionName.slice(0, 32); // limit to 32 bytes
  expressionName.split("").forEach(function (char, index) {
    dataView.setUint8(11 + index, char.charCodeAt());
  });

  messageOut.bytes = new Uint8Array(dataView.buffer);

  return messageOut.compose().buffer;
};

var chatter = exports.chatter = function chatter() {
  var prefersBlocking = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;

  messageOut.options = {
    prefersBlocking: prefersBlocking
  };
  messageOut.command = lrfMessageCode.Chatter;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

//SONGS
//TODO: check that the following messages are up to date in reference to robot spec

var singSong = exports.singSong = function singSong(lrfSong) {
  var prefersBlocking = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;

  messageOut.options = {
    prefersBlocking: prefersBlocking
  };
  messageOut.command = lrfMessageCode.SingSong;
  messageOut.length = lrfSong.sounds.length * LRFSOUND_SIZE + LRFPATTERN_SIZE;

  var dataView = makeDataView(messageOut.length);

  if (Array.isArray(lrfSong)) {
    lrfSong.forEach(function (rawValue, index) {
      dataView.setUint16(index * 2, rawValue);
    });
  } else {
    dataView.setUint16(0, lrfSong.pattern.getRaw());
    lrfSong.sounds.forEach(function (sound, index) {
      dataView.setUint16(2 + index * 2, sound.getRaw());
    });
  }

  messageOut.bytes = new Uint8Array(dataView.buffer);
  return messageOut.compose().buffer;
};

var setPresetSong = exports.setPresetSong = function setPresetSong(lrfMemoryIndex, lrfSong) {
  messageOut.command = lrfMessageCode.SetPresetSong;
  messageOut.length = Array.isArray(lrfSong) ? lrfSong.length * 2 + 1 : lrfSong.sounds.length * 2 + 3; //pattern + memory index

  var dataView = makeDataView(messageOut.length);
  dataView.setUint8(0, lrfMemoryIndex);

  if (Array.isArray(lrfSong)) {
    lrfSong.forEach(function (rawValue, index) {
      dataView.setUint16(1 + index * 2, rawValue);
    });
  } else {
    dataView.setUint16(1, lrfSong.pattern.getRaw());
    lrfSong.sounds.forEach(function (sound, index) {
      dataView.setUint16(3 + index * 2, sound.getRaw());
    });
  }

  messageOut.bytes = new Uint8Array(dataView.buffer);
  return messageOut.compose().buffer;
};

var getPresetSong = exports.getPresetSong = function getPresetSong(lrfMemoryIndex) {
  messageOut.command = lrfMessageCode.GetPresetSong;
  messageOut.length = LRFMEMORYINDEX_SIZE;
  messageOut.bytes = new Uint8Array([lrfMemoryIndex]);
  return messageOut.compose().buffer;
};

// Senses
// -----------------------------------------------------------

var sensesGetEnabled = exports.sensesGetEnabled = function sensesGetEnabled() {
  messageOut.command = lrfMessageCode.SensesGetEnabled;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var sensesSetEnabled = exports.sensesSetEnabled = function sensesSetEnabled() {
  messageOut.command = lrfMessageCode.SensesSetEnabled;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

// Touch
// -----------------------------------------------------------

var touchGetConfig = exports.touchGetConfig = function touchGetConfig() {
  messageOut.command = lrfMessageCode.TouchGetConfig;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var touchSetConfig = exports.touchSetConfig = function touchSetConfig() {
  messageOut.command = lrfMessageCode.TouchSetConfig;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var touchRead = exports.touchRead = function touchRead() {
  messageOut.command = lrfMessageCode.TouchRead;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

// Hearing
// -----------------------------------------------------------

var hearingGetConfig = exports.hearingGetConfig = function hearingGetConfig() {
  messageOut.command = lrfMessageCode.HearingGetConfig;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var hearingSetConfig = exports.hearingSetConfig = function hearingSetConfig() {
  messageOut.command = lrfMessageCode.HearingSetConfig;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var hearingRead = exports.hearingRead = function hearingRead() {
  messageOut.command = lrfMessageCode.HearingRead;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

// Sight
// -----------------------------------------------------------

var sightGetConfig = exports.sightGetConfig = function sightGetConfig() {
  messageOut.command = lrfMessageCode.SightGetConfig;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var sightSetConfig = exports.sightSetConfig = function sightSetConfig() {
  messageOut.command = lrfMessageCode.SightSetConfig;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var sightRead = exports.sightRead = function sightRead() {
  messageOut.command = lrfMessageCode.SightRead;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

// Motion
// -----------------------------------------------------------

var motionGetConfig = exports.motionGetConfig = function motionGetConfig() {
  messageOut.command = lrfMessageCode.MotionGetConfig;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var motionSetConfig = exports.motionSetConfig = function motionSetConfig() {
  messageOut.command = lrfMessageCode.MotionSetConfig;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

var motionRead = exports.motionRead = function motionRead() {
  messageOut.command = lrfMessageCode.MotionRead;
  messageOut.length = 0;
  return messageOut.compose().buffer;
};

/***/ }),
/* 8 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


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


var senses = {
  touch: {
    hair: 0,
    left: 0,
    right: 0
  },
  hearing: {
    level: 0
  },
  sight: {
    level: 0
  },
  motion: {
    x: 0,
    y: 0,
    z: 0
  }
};

var updateSenses = function updateSenses(values) {
  senses.touch.hair = values.touch.hair;
  senses.touch.left = values.touch.left;
  senses.touch.right = values.touch.right;
  senses.hearing.level = values.hearing.level;
  senses.sight.level = values.sight.level;
  senses.motion.x = values.motion.x;
  senses.motion.y = values.motion.y;
  senses.motion.z = values.motion.z;
  if (false) console.log('[MODEL] updated senses:', senses);
};

exports.default = {
  senses: senses,
  updateSenses: updateSenses
};
module.exports = exports['default'];

/***/ }),
/* 9 */
/***/ (function(module, exports) {

// shim for using process in browser
var process = module.exports = {};

// cached from whatever global is present so that test runners that stub it
// don't break things.  But we need to wrap it in a try catch in case it is
// wrapped in strict mode code which doesn't define any globals.  It's inside a
// function because try/catches deoptimize in certain engines.

var cachedSetTimeout;
var cachedClearTimeout;

function defaultSetTimout() {
    throw new Error('setTimeout has not been defined');
}
function defaultClearTimeout () {
    throw new Error('clearTimeout has not been defined');
}
(function () {
    try {
        if (typeof setTimeout === 'function') {
            cachedSetTimeout = setTimeout;
        } else {
            cachedSetTimeout = defaultSetTimout;
        }
    } catch (e) {
        cachedSetTimeout = defaultSetTimout;
    }
    try {
        if (typeof clearTimeout === 'function') {
            cachedClearTimeout = clearTimeout;
        } else {
            cachedClearTimeout = defaultClearTimeout;
        }
    } catch (e) {
        cachedClearTimeout = defaultClearTimeout;
    }
} ())
function runTimeout(fun) {
    if (cachedSetTimeout === setTimeout) {
        //normal enviroments in sane situations
        return setTimeout(fun, 0);
    }
    // if setTimeout wasn't available but was latter defined
    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
        cachedSetTimeout = setTimeout;
        return setTimeout(fun, 0);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedSetTimeout(fun, 0);
    } catch(e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
            return cachedSetTimeout.call(null, fun, 0);
        } catch(e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
            return cachedSetTimeout.call(this, fun, 0);
        }
    }


}
function runClearTimeout(marker) {
    if (cachedClearTimeout === clearTimeout) {
        //normal enviroments in sane situations
        return clearTimeout(marker);
    }
    // if clearTimeout wasn't available but was latter defined
    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
        cachedClearTimeout = clearTimeout;
        return clearTimeout(marker);
    }
    try {
        // when when somebody has screwed with setTimeout but no I.E. maddness
        return cachedClearTimeout(marker);
    } catch (e){
        try {
            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
            return cachedClearTimeout.call(null, marker);
        } catch (e){
            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
            return cachedClearTimeout.call(this, marker);
        }
    }



}
var queue = [];
var draining = false;
var currentQueue;
var queueIndex = -1;

function cleanUpNextTick() {
    if (!draining || !currentQueue) {
        return;
    }
    draining = false;
    if (currentQueue.length) {
        queue = currentQueue.concat(queue);
    } else {
        queueIndex = -1;
    }
    if (queue.length) {
        drainQueue();
    }
}

function drainQueue() {
    if (draining) {
        return;
    }
    var timeout = runTimeout(cleanUpNextTick);
    draining = true;

    var len = queue.length;
    while(len) {
        currentQueue = queue;
        queue = [];
        while (++queueIndex < len) {
            if (currentQueue) {
                currentQueue[queueIndex].run();
            }
        }
        queueIndex = -1;
        len = queue.length;
    }
    currentQueue = null;
    draining = false;
    runClearTimeout(timeout);
}

process.nextTick = function (fun) {
    var args = new Array(arguments.length - 1);
    if (arguments.length > 1) {
        for (var i = 1; i < arguments.length; i++) {
            args[i - 1] = arguments[i];
        }
    }
    queue.push(new Item(fun, args));
    if (queue.length === 1 && !draining) {
        runTimeout(drainQueue);
    }
};

// v8 likes predictible objects
function Item(fun, array) {
    this.fun = fun;
    this.array = array;
}
Item.prototype.run = function () {
    this.fun.apply(null, this.array);
};
process.title = 'browser';
process.browser = true;
process.env = {};
process.argv = [];
process.version = ''; // empty string to avoid regexp issues
process.versions = {};

function noop() {}

process.on = noop;
process.addListener = noop;
process.once = noop;
process.off = noop;
process.removeListener = noop;
process.removeAllListeners = noop;
process.emit = noop;
process.prependListener = noop;
process.prependOnceListener = noop;

process.listeners = function (name) { return [] }

process.binding = function (name) {
    throw new Error('process.binding is not supported');
};

process.cwd = function () { return '/' };
process.chdir = function (dir) {
    throw new Error('process.chdir is not supported');
};
process.umask = function() { return 0; };


/***/ }),
/* 10 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


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

var _LRFTypes = __webpack_require__(0);

var LRFCore = _interopRequireWildcard(_LRFTypes);

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

// function LRFExpressions (LRFCore) {
var _expressions = {

  //Hellos
  "hello": LRFCore.createExpression("Hello"),
  "happy-hello": LRFCore.createExpression("Happy Hello"),
  "angry-hello": LRFCore.createExpression("Angry Hello"),

  //Moods
  "happy": LRFCore.createExpression("Happy"),
  "very-happy": LRFCore.createExpression("Very Happy"),
  "excited": LRFCore.createExpression("Excited"),
  "very-excited": LRFCore.createExpression("Very Excited"),
  "annoyed": LRFCore.createExpression("Annoyed"),
  "very-annoyed": LRFCore.createExpression("Very Annoyed"),
  "angry": LRFCore.createExpression("Angry"),
  "very-angry": LRFCore.createExpression("Very Angry"),

  //Laughs
  "giggle": LRFCore.createExpression("Giggle"),
  "laugh": LRFCore.createExpression("Laugh"),
  "hysterical": LRFCore.createExpression("Hysterical"),
  "evil-cackle": LRFCore.createExpression("Evil Cackle"),

  //Cries
  "pout": LRFCore.createExpression("Pout"),
  "sob": LRFCore.createExpression("Sob"),

  //Scared
  "scared": LRFCore.createExpression("Scared"),
  "terrified": LRFCore.createExpression("Terrified"),
  "relieved": LRFCore.createExpression("Relieved"),

  //Sleepy
  "bored": LRFCore.createExpression("Bored"),
  "yawn": LRFCore.createExpression("Yawn"),
  "snoring": LRFCore.createExpression("Snoring"),

  //System
  "hungry": LRFCore.createExpression("Hungry"),
  "power-up": LRFCore.createExpression("Power Up"),
  "alarm": LRFCore.createExpression("Alarm"),

  "awww": LRFCore.createExpression("Awww"),
  "yikes": LRFCore.createExpression("Yikes"),
  "whoa-up": LRFCore.createExpression("Whoa Up"),
  "whoa-down": LRFCore.createExpression("Whoa Down"),
  "whoa-whoa-whoa": LRFCore.createExpression("Whoa Whoa Whoa"),

  //Misc
  "uncertain": LRFCore.createExpression("Uncertain")
};

//EXPRESSION DATA
_expressions.hello.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.green,
    rightLed: LRFCore.LRFColor.none,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }]
});

_expressions["happy-hello"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.green,
    rightLed: LRFCore.LRFColor.yellow,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.cs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["angry-hello"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.red,
    rightLed: LRFCore.LRFColor.green,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }]
});
_expressions.happy.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.green,
    rightLed: LRFCore.LRFColor.yellow,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["very-happy"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.green,
    rightLed: LRFCore.LRFColor.pink,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.excited.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.yellow,
    rightLed: LRFCore.LRFColor.orange,
    zigzag: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.doubleShort
  }, {
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.doubleShort
  }, {
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["very-excited"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.yellow,
    rightLed: LRFCore.LRFColor.pink,
    zigzag: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.fs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.fs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.fs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.doubleShort
  }, {
    note: LRFCore.LRFNote.fs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.annoyed.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.red,
    rightLed: LRFCore.LRFColor.none,
    zigzag: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.doubleMedium
  }, {
    note: LRFCore.LRFNote.g,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.gs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["very-annoyed"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.red,
    rightLed: LRFCore.LRFColor.yellow,
    zigzag: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.b,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.doubleMedium
  }, {
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.angry.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.red,
    rightLed: LRFCore.LRFColor.none,
    zigzag: true,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.a,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.a,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.a,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["very-angry"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.red,
    rightLed: LRFCore.LRFColor.yellow,
    zigzag: true,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.b,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.a,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.a,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.giggle.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.orange,
    rightLed: LRFCore.LRFColor.yellow,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.gs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.g,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.laugh.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.orange,
    rightLed: LRFCore.LRFColor.green,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.gs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.g,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.hysterical.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.orange,
    rightLed: LRFCore.LRFColor.pink,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["evil-cackle"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.orange,
    rightLed: LRFCore.LRFColor.red,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.cs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.doubleShort
  }, {
    note: LRFCore.LRFNote.ds,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.cs,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.pout.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.cyan,
    rightLed: LRFCore.LRFColor.none,
    flip: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.b,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.sob.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.cyan,
    rightLed: LRFCore.LRFColor.none,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.dipping,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.medium
  }, {
    note: LRFCore.LRFNote.b,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.b,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.b,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.scared.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.purple,
    rightLed: LRFCore.LRFColor.red,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.doubleMedium
  }, {
    note: LRFCore.LRFNote.g,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.g,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.terrified.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.purple,
    rightLed: LRFCore.LRFColor.red,
    boomerang: true,
    zigzag: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.b,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.d,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.relieved.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.purple,
    rightLed: LRFCore.LRFColor.green,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.f,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.bored.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.blue,
    rightLed: LRFCore.LRFColor.cyan,
    flat: true,
    flip: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.a,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.yawn.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.blue,
    rightLed: LRFCore.LRFColor.none,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.b,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.doubleMedium
  }]
});

_expressions.snoring.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.none,
    rightLed: LRFCore.LRFColor.blue,
    boomerang: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.lowest,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.veryLong,
    pause: LRFCore.LRFDuration.long
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.lowest,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.veryLong,
    pause: LRFCore.LRFDuration.long
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.lowest,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.veryLong,
    pause: LRFCore.LRFDuration.long
  }]
});

_expressions.hungry.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.red,
    rightLed: LRFCore.LRFColor.none,
    zigzag: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.higher,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.medium
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.higher,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.medium
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.higher,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.medium
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.higher,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.medium
  }]
});

_expressions["power-up"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.none,
    rightLed: LRFCore.LRFColor.none,
    flat: true,
    random: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.midlow,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.e,
    octave: LRFCore.LRFOctave.midlow,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.g,
    octave: LRFCore.LRFOctave.midlow,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleShort,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.alarm.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.green,
    rightLed: LRFCore.LRFColor.none,
    zigzag: true,
    flip: true,
    flat: true,
    duration: LRFCore.LRFDuration.medium
  },
  sounds: [{
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.high,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.medium
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.high,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.medium
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.high,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.medium
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.high,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleMedium,
    pause: LRFCore.LRFDuration.medium
  }]
});

_expressions.awww.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.pink,
    rightLed: LRFCore.LRFColor.red,
    duration: LRFCore.LRFDuration.medium,
    boomerang: true
  },
  sounds: [{
    note: LRFCore.LRFNote.a,
    octave: LRFCore.LRFOctave.high,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions.yikes.assign({
  pattern: {
    leftLed: LRFCore.LRFColor.red,
    rightLed: LRFCore.LRFColor.orange,
    duration: LRFCore.LRFDuration.medium,
    flat: true,
    flip: true,
    zigzag: true
  },
  sounds: [{
    note: LRFCore.LRFNote.a,
    octave: LRFCore.LRFOctave.lowest,
    intonation: LRFCore.LRFIntonation.flat,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.midhigh,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.medium
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.midhigh,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.medium,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["whoa-up"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.blue,
    rightLed: LRFCore.LRFColor.purple,
    duration: LRFCore.LRFDuration.medium,
    zigzag: true,
    boomerang: true
  },
  sounds: [{
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.rising,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["whoa-down"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.purple,
    rightLed: LRFCore.LRFColor.blue,
    duration: LRFCore.LRFDuration.medium,
    zigzag: true,
    boomerang: true
  },
  sounds: [{
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.midhigh,
    intonation: LRFCore.LRFIntonation.falling,
    duration: LRFCore.LRFDuration.doubleLong,
    pause: LRFCore.LRFDuration.none
  }]
});

_expressions["whoa-whoa-whoa"].assign({
  pattern: {
    leftLed: LRFCore.LRFColor.pink,
    rightLed: LRFCore.LRFColor.blue,
    duration: LRFCore.LRFDuration.medium,
    zigzag: true,
    boomerang: true
  },
  sounds: [{
    note: LRFCore.LRFNote.g,
    octave: LRFCore.LRFOctave.mid,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.c,
    octave: LRFCore.LRFOctave.midhigh,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.short
  }, {
    note: LRFCore.LRFNote.g,
    octave: LRFCore.LRFOctave.midhigh,
    intonation: LRFCore.LRFIntonation.peaking,
    duration: LRFCore.LRFDuration.long,
    pause: LRFCore.LRFDuration.short
  }]
});

exports.default = _expressions;
module.exports = exports["default"];

/***/ }),
/* 11 */
/***/ (function(module, exports, __webpack_require__) {

"use strict";


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

var _LRFTypes = __webpack_require__(0);

var types = _interopRequireWildcard(_LRFTypes);

var _LRFMessages = __webpack_require__(7);

var messages = _interopRequireWildcard(_LRFMessages);

var _LRFComm = __webpack_require__(6);

var comm = _interopRequireWildcard(_LRFComm);

var _LRFUtil = __webpack_require__(4);

var util = _interopRequireWildcard(_LRFUtil);

var _LRFSerial = __webpack_require__(2);

var _LRFSerial2 = _interopRequireDefault(_LRFSerial);

var _LRFWebCoreEvents = __webpack_require__(1);

var _LRFWebCoreEvents2 = _interopRequireDefault(_LRFWebCoreEvents);

var _LRFExpressionData = __webpack_require__(10);

var _LRFExpressionData2 = _interopRequireDefault(_LRFExpressionData);

var _LRFPlatform = __webpack_require__(3);

var _LRFPlatform2 = _interopRequireDefault(_LRFPlatform);

var _LRFWifi = __webpack_require__(5);

var _LRFWifi2 = _interopRequireDefault(_LRFWifi);

var _LRFRobotModel = __webpack_require__(8);

var model = _interopRequireWildcard(_LRFRobotModel);

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

function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }

exports.default = {
  platform: _LRFPlatform2.default,
  wifi: _LRFWifi2.default,
  types: types,
  messages: messages,
  comm: comm,
  serial: _LRFSerial2.default,
  events: _LRFWebCoreEvents2.default,
  expressionData: _LRFExpressionData2.default,
  util: util,
  model: model
};
module.exports = exports["default"];

/***/ }),
/* 12 */
/***/ (function(module, exports, __webpack_require__) {

/* WEBPACK VAR INJECTION */(function(process) {var __WEBPACK_AMD_DEFINE_RESULT__;/*!
 * EventEmitter2
 * https://github.com/hij1nx/EventEmitter2
 *
 * Copyright (c) 2013 hij1nx
 * Licensed under the MIT license.
 */
;!function(undefined) {

  var isArray = Array.isArray ? Array.isArray : function _isArray(obj) {
    return Object.prototype.toString.call(obj) === "[object Array]";
  };
  var defaultMaxListeners = 10;

  function init() {
    this._events = {};
    if (this._conf) {
      configure.call(this, this._conf);
    }
  }

  function configure(conf) {
    if (conf) {
      this._conf = conf;

      conf.delimiter && (this.delimiter = conf.delimiter);
      this._maxListeners = conf.maxListeners !== undefined ? conf.maxListeners : defaultMaxListeners;

      conf.wildcard && (this.wildcard = conf.wildcard);
      conf.newListener && (this.newListener = conf.newListener);
      conf.verboseMemoryLeak && (this.verboseMemoryLeak = conf.verboseMemoryLeak);

      if (this.wildcard) {
        this.listenerTree = {};
      }
    } else {
      this._maxListeners = defaultMaxListeners;
    }
  }

  function logPossibleMemoryLeak(count, eventName) {
    var errorMsg = '(node) warning: possible EventEmitter memory ' +
        'leak detected. ' + count + ' listeners added. ' +
        'Use emitter.setMaxListeners() to increase limit.';

    if(this.verboseMemoryLeak){
      errorMsg += ' Event name: ' + eventName + '.';
    }

    if(typeof process !== 'undefined' && process.emitWarning){
      var e = new Error(errorMsg);
      e.name = 'MaxListenersExceededWarning';
      e.emitter = this;
      e.count = count;
      process.emitWarning(e);
    } else {
      console.error(errorMsg);

      if (console.trace){
        console.trace();
      }
    }
  }

  function EventEmitter(conf) {
    this._events = {};
    this.newListener = false;
    this.verboseMemoryLeak = false;
    configure.call(this, conf);
  }
  EventEmitter.EventEmitter2 = EventEmitter; // backwards compatibility for exporting EventEmitter property

  //
  // Attention, function return type now is array, always !
  // It has zero elements if no any matches found and one or more
  // elements (leafs) if there are matches
  //
  function searchListenerTree(handlers, type, tree, i) {
    if (!tree) {
      return [];
    }
    var listeners=[], leaf, len, branch, xTree, xxTree, isolatedBranch, endReached,
        typeLength = type.length, currentType = type[i], nextType = type[i+1];
    if (i === typeLength && tree._listeners) {
      //
      // If at the end of the event(s) list and the tree has listeners
      // invoke those listeners.
      //
      if (typeof tree._listeners === 'function') {
        handlers && handlers.push(tree._listeners);
        return [tree];
      } else {
        for (leaf = 0, len = tree._listeners.length; leaf < len; leaf++) {
          handlers && handlers.push(tree._listeners[leaf]);
        }
        return [tree];
      }
    }

    if ((currentType === '*' || currentType === '**') || tree[currentType]) {
      //
      // If the event emitted is '*' at this part
      // or there is a concrete match at this patch
      //
      if (currentType === '*') {
        for (branch in tree) {
          if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
            listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+1));
          }
        }
        return listeners;
      } else if(currentType === '**') {
        endReached = (i+1 === typeLength || (i+2 === typeLength && nextType === '*'));
        if(endReached && tree._listeners) {
          // The next element has a _listeners, add it to the handlers.
          listeners = listeners.concat(searchListenerTree(handlers, type, tree, typeLength));
        }

        for (branch in tree) {
          if (branch !== '_listeners' && tree.hasOwnProperty(branch)) {
            if(branch === '*' || branch === '**') {
              if(tree[branch]._listeners && !endReached) {
                listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], typeLength));
              }
              listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
            } else if(branch === nextType) {
              listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i+2));
            } else {
              // No match on this one, shift into the tree but not in the type array.
              listeners = listeners.concat(searchListenerTree(handlers, type, tree[branch], i));
            }
          }
        }
        return listeners;
      }

      listeners = listeners.concat(searchListenerTree(handlers, type, tree[currentType], i+1));
    }

    xTree = tree['*'];
    if (xTree) {
      //
      // If the listener tree will allow any match for this part,
      // then recursively explore all branches of the tree
      //
      searchListenerTree(handlers, type, xTree, i+1);
    }

    xxTree = tree['**'];
    if(xxTree) {
      if(i < typeLength) {
        if(xxTree._listeners) {
          // If we have a listener on a '**', it will catch all, so add its handler.
          searchListenerTree(handlers, type, xxTree, typeLength);
        }

        // Build arrays of matching next branches and others.
        for(branch in xxTree) {
          if(branch !== '_listeners' && xxTree.hasOwnProperty(branch)) {
            if(branch === nextType) {
              // We know the next element will match, so jump twice.
              searchListenerTree(handlers, type, xxTree[branch], i+2);
            } else if(branch === currentType) {
              // Current node matches, move into the tree.
              searchListenerTree(handlers, type, xxTree[branch], i+1);
            } else {
              isolatedBranch = {};
              isolatedBranch[branch] = xxTree[branch];
              searchListenerTree(handlers, type, { '**': isolatedBranch }, i+1);
            }
          }
        }
      } else if(xxTree._listeners) {
        // We have reached the end and still on a '**'
        searchListenerTree(handlers, type, xxTree, typeLength);
      } else if(xxTree['*'] && xxTree['*']._listeners) {
        searchListenerTree(handlers, type, xxTree['*'], typeLength);
      }
    }

    return listeners;
  }

  function growListenerTree(type, listener) {

    type = typeof type === 'string' ? type.split(this.delimiter) : type.slice();

    //
    // Looks for two consecutive '**', if so, don't add the event at all.
    //
    for(var i = 0, len = type.length; i+1 < len; i++) {
      if(type[i] === '**' && type[i+1] === '**') {
        return;
      }
    }

    var tree = this.listenerTree;
    var name = type.shift();

    while (name !== undefined) {

      if (!tree[name]) {
        tree[name] = {};
      }

      tree = tree[name];

      if (type.length === 0) {

        if (!tree._listeners) {
          tree._listeners = listener;
        }
        else {
          if (typeof tree._listeners === 'function') {
            tree._listeners = [tree._listeners];
          }

          tree._listeners.push(listener);

          if (
            !tree._listeners.warned &&
            this._maxListeners > 0 &&
            tree._listeners.length > this._maxListeners
          ) {
            tree._listeners.warned = true;
            logPossibleMemoryLeak.call(this, tree._listeners.length, name);
          }
        }
        return true;
      }
      name = type.shift();
    }
    return true;
  }

  // By default EventEmitters will print a warning if more than
  // 10 listeners are added to it. This is a useful default which
  // helps finding memory leaks.
  //
  // Obviously not all Emitters should be limited to 10. This function allows
  // that to be increased. Set to zero for unlimited.

  EventEmitter.prototype.delimiter = '.';

  EventEmitter.prototype.setMaxListeners = function(n) {
    if (n !== undefined) {
      this._maxListeners = n;
      if (!this._conf) this._conf = {};
      this._conf.maxListeners = n;
    }
  };

  EventEmitter.prototype.event = '';


  EventEmitter.prototype.once = function(event, fn) {
    return this._once(event, fn, false);
  };

  EventEmitter.prototype.prependOnceListener = function(event, fn) {
    return this._once(event, fn, true);
  };

  EventEmitter.prototype._once = function(event, fn, prepend) {
    this._many(event, 1, fn, prepend);
    return this;
  };

  EventEmitter.prototype.many = function(event, ttl, fn) {
    return this._many(event, ttl, fn, false);
  }

  EventEmitter.prototype.prependMany = function(event, ttl, fn) {
    return this._many(event, ttl, fn, true);
  }

  EventEmitter.prototype._many = function(event, ttl, fn, prepend) {
    var self = this;

    if (typeof fn !== 'function') {
      throw new Error('many only accepts instances of Function');
    }

    function listener() {
      if (--ttl === 0) {
        self.off(event, listener);
      }
      return fn.apply(this, arguments);
    }

    listener._origin = fn;

    this._on(event, listener, prepend);

    return self;
  };

  EventEmitter.prototype.emit = function() {

    this._events || init.call(this);

    var type = arguments[0];

    if (type === 'newListener' && !this.newListener) {
      if (!this._events.newListener) {
        return false;
      }
    }

    var al = arguments.length;
    var args,l,i,j;
    var handler;

    if (this._all && this._all.length) {
      handler = this._all.slice();
      if (al > 3) {
        args = new Array(al);
        for (j = 0; j < al; j++) args[j] = arguments[j];
      }

      for (i = 0, l = handler.length; i < l; i++) {
        this.event = type;
        switch (al) {
        case 1:
          handler[i].call(this, type);
          break;
        case 2:
          handler[i].call(this, type, arguments[1]);
          break;
        case 3:
          handler[i].call(this, type, arguments[1], arguments[2]);
          break;
        default:
          handler[i].apply(this, args);
        }
      }
    }

    if (this.wildcard) {
      handler = [];
      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
      searchListenerTree.call(this, handler, ns, this.listenerTree, 0);
    } else {
      handler = this._events[type];
      if (typeof handler === 'function') {
        this.event = type;
        switch (al) {
        case 1:
          handler.call(this);
          break;
        case 2:
          handler.call(this, arguments[1]);
          break;
        case 3:
          handler.call(this, arguments[1], arguments[2]);
          break;
        default:
          args = new Array(al - 1);
          for (j = 1; j < al; j++) args[j - 1] = arguments[j];
          handler.apply(this, args);
        }
        return true;
      } else if (handler) {
        // need to make copy of handlers because list can change in the middle
        // of emit call
        handler = handler.slice();
      }
    }

    if (handler && handler.length) {
      if (al > 3) {
        args = new Array(al - 1);
        for (j = 1; j < al; j++) args[j - 1] = arguments[j];
      }
      for (i = 0, l = handler.length; i < l; i++) {
        this.event = type;
        switch (al) {
        case 1:
          handler[i].call(this);
          break;
        case 2:
          handler[i].call(this, arguments[1]);
          break;
        case 3:
          handler[i].call(this, arguments[1], arguments[2]);
          break;
        default:
          handler[i].apply(this, args);
        }
      }
      return true;
    } else if (!this._all && type === 'error') {
      if (arguments[1] instanceof Error) {
        throw arguments[1]; // Unhandled 'error' event
      } else {
        throw new Error("Uncaught, unspecified 'error' event.");
      }
      return false;
    }

    return !!this._all;
  };

  EventEmitter.prototype.emitAsync = function() {

    this._events || init.call(this);

    var type = arguments[0];

    if (type === 'newListener' && !this.newListener) {
        if (!this._events.newListener) { return Promise.resolve([false]); }
    }

    var promises= [];

    var al = arguments.length;
    var args,l,i,j;
    var handler;

    if (this._all) {
      if (al > 3) {
        args = new Array(al);
        for (j = 1; j < al; j++) args[j] = arguments[j];
      }
      for (i = 0, l = this._all.length; i < l; i++) {
        this.event = type;
        switch (al) {
        case 1:
          promises.push(this._all[i].call(this, type));
          break;
        case 2:
          promises.push(this._all[i].call(this, type, arguments[1]));
          break;
        case 3:
          promises.push(this._all[i].call(this, type, arguments[1], arguments[2]));
          break;
        default:
          promises.push(this._all[i].apply(this, args));
        }
      }
    }

    if (this.wildcard) {
      handler = [];
      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
      searchListenerTree.call(this, handler, ns, this.listenerTree, 0);
    } else {
      handler = this._events[type];
    }

    if (typeof handler === 'function') {
      this.event = type;
      switch (al) {
      case 1:
        promises.push(handler.call(this));
        break;
      case 2:
        promises.push(handler.call(this, arguments[1]));
        break;
      case 3:
        promises.push(handler.call(this, arguments[1], arguments[2]));
        break;
      default:
        args = new Array(al - 1);
        for (j = 1; j < al; j++) args[j - 1] = arguments[j];
        promises.push(handler.apply(this, args));
      }
    } else if (handler && handler.length) {
      handler = handler.slice();
      if (al > 3) {
        args = new Array(al - 1);
        for (j = 1; j < al; j++) args[j - 1] = arguments[j];
      }
      for (i = 0, l = handler.length; i < l; i++) {
        this.event = type;
        switch (al) {
        case 1:
          promises.push(handler[i].call(this));
          break;
        case 2:
          promises.push(handler[i].call(this, arguments[1]));
          break;
        case 3:
          promises.push(handler[i].call(this, arguments[1], arguments[2]));
          break;
        default:
          promises.push(handler[i].apply(this, args));
        }
      }
    } else if (!this._all && type === 'error') {
      if (arguments[1] instanceof Error) {
        return Promise.reject(arguments[1]); // Unhandled 'error' event
      } else {
        return Promise.reject("Uncaught, unspecified 'error' event.");
      }
    }

    return Promise.all(promises);
  };

  EventEmitter.prototype.on = function(type, listener) {
    return this._on(type, listener, false);
  };

  EventEmitter.prototype.prependListener = function(type, listener) {
    return this._on(type, listener, true);
  };

  EventEmitter.prototype.onAny = function(fn) {
    return this._onAny(fn, false);
  };

  EventEmitter.prototype.prependAny = function(fn) {
    return this._onAny(fn, true);
  };

  EventEmitter.prototype.addListener = EventEmitter.prototype.on;

  EventEmitter.prototype._onAny = function(fn, prepend){
    if (typeof fn !== 'function') {
      throw new Error('onAny only accepts instances of Function');
    }

    if (!this._all) {
      this._all = [];
    }

    // Add the function to the event listener collection.
    if(prepend){
      this._all.unshift(fn);
    }else{
      this._all.push(fn);
    }

    return this;
  }

  EventEmitter.prototype._on = function(type, listener, prepend) {
    if (typeof type === 'function') {
      this._onAny(type, listener);
      return this;
    }

    if (typeof listener !== 'function') {
      throw new Error('on only accepts instances of Function');
    }
    this._events || init.call(this);

    // To avoid recursion in the case that type == "newListeners"! Before
    // adding it to the listeners, first emit "newListeners".
    this.emit('newListener', type, listener);

    if (this.wildcard) {
      growListenerTree.call(this, type, listener);
      return this;
    }

    if (!this._events[type]) {
      // Optimize the case of one listener. Don't need the extra array object.
      this._events[type] = listener;
    }
    else {
      if (typeof this._events[type] === 'function') {
        // Change to array.
        this._events[type] = [this._events[type]];
      }

      // If we've already got an array, just add
      if(prepend){
        this._events[type].unshift(listener);
      }else{
        this._events[type].push(listener);
      }

      // Check for listener leak
      if (
        !this._events[type].warned &&
        this._maxListeners > 0 &&
        this._events[type].length > this._maxListeners
      ) {
        this._events[type].warned = true;
        logPossibleMemoryLeak.call(this, this._events[type].length, type);
      }
    }

    return this;
  }

  EventEmitter.prototype.off = function(type, listener) {
    if (typeof listener !== 'function') {
      throw new Error('removeListener only takes instances of Function');
    }

    var handlers,leafs=[];

    if(this.wildcard) {
      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
      leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);
    }
    else {
      // does not use listeners(), so no side effect of creating _events[type]
      if (!this._events[type]) return this;
      handlers = this._events[type];
      leafs.push({_listeners:handlers});
    }

    for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
      var leaf = leafs[iLeaf];
      handlers = leaf._listeners;
      if (isArray(handlers)) {

        var position = -1;

        for (var i = 0, length = handlers.length; i < length; i++) {
          if (handlers[i] === listener ||
            (handlers[i].listener && handlers[i].listener === listener) ||
            (handlers[i]._origin && handlers[i]._origin === listener)) {
            position = i;
            break;
          }
        }

        if (position < 0) {
          continue;
        }

        if(this.wildcard) {
          leaf._listeners.splice(position, 1);
        }
        else {
          this._events[type].splice(position, 1);
        }

        if (handlers.length === 0) {
          if(this.wildcard) {
            delete leaf._listeners;
          }
          else {
            delete this._events[type];
          }
        }

        this.emit("removeListener", type, listener);

        return this;
      }
      else if (handlers === listener ||
        (handlers.listener && handlers.listener === listener) ||
        (handlers._origin && handlers._origin === listener)) {
        if(this.wildcard) {
          delete leaf._listeners;
        }
        else {
          delete this._events[type];
        }

        this.emit("removeListener", type, listener);
      }
    }

    function recursivelyGarbageCollect(root) {
      if (root === undefined) {
        return;
      }
      var keys = Object.keys(root);
      for (var i in keys) {
        var key = keys[i];
        var obj = root[key];
        if ((obj instanceof Function) || (typeof obj !== "object") || (obj === null))
          continue;
        if (Object.keys(obj).length > 0) {
          recursivelyGarbageCollect(root[key]);
        }
        if (Object.keys(obj).length === 0) {
          delete root[key];
        }
      }
    }
    recursivelyGarbageCollect(this.listenerTree);

    return this;
  };

  EventEmitter.prototype.offAny = function(fn) {
    var i = 0, l = 0, fns;
    if (fn && this._all && this._all.length > 0) {
      fns = this._all;
      for(i = 0, l = fns.length; i < l; i++) {
        if(fn === fns[i]) {
          fns.splice(i, 1);
          this.emit("removeListenerAny", fn);
          return this;
        }
      }
    } else {
      fns = this._all;
      for(i = 0, l = fns.length; i < l; i++)
        this.emit("removeListenerAny", fns[i]);
      this._all = [];
    }
    return this;
  };

  EventEmitter.prototype.removeListener = EventEmitter.prototype.off;

  EventEmitter.prototype.removeAllListeners = function(type) {
    if (arguments.length === 0) {
      !this._events || init.call(this);
      return this;
    }

    if (this.wildcard) {
      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
      var leafs = searchListenerTree.call(this, null, ns, this.listenerTree, 0);

      for (var iLeaf=0; iLeaf<leafs.length; iLeaf++) {
        var leaf = leafs[iLeaf];
        leaf._listeners = null;
      }
    }
    else if (this._events) {
      this._events[type] = null;
    }
    return this;
  };

  EventEmitter.prototype.listeners = function(type) {
    if (this.wildcard) {
      var handlers = [];
      var ns = typeof type === 'string' ? type.split(this.delimiter) : type.slice();
      searchListenerTree.call(this, handlers, ns, this.listenerTree, 0);
      return handlers;
    }

    this._events || init.call(this);

    if (!this._events[type]) this._events[type] = [];
    if (!isArray(this._events[type])) {
      this._events[type] = [this._events[type]];
    }
    return this._events[type];
  };

  EventEmitter.prototype.eventNames = function(){
    return Object.keys(this._events);
  }

  EventEmitter.prototype.listenerCount = function(type) {
    return this.listeners(type).length;
  };

  EventEmitter.prototype.listenersAny = function() {

    if(this._all) {
      return this._all;
    }
    else {
      return [];
    }

  };

  if (true) {
     // AMD. Register as an anonymous module.
    !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {
      return EventEmitter;
    }.call(exports, __webpack_require__, exports, module),
				__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));
  } else if (typeof exports === 'object') {
    // CommonJS
    module.exports = EventEmitter;
  }
  else {
    // Browser global.
    window.EventEmitter2 = EventEmitter;
  }
}();

/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(9)))

/***/ }),
/* 13 */,
/* 14 */,
/* 15 */
/***/ (function(module, exports) {

module.exports = require("serialport");

/***/ })
/******/ ]);