diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala
index 789eeb736bad386eecd36251364ad35b0f9a151d..34fe728fc7a5d44ccb270070295926458079783e 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/BigBlueButtonActor.scala
@@ -69,11 +69,24 @@ class BigBlueButtonActor(
 
   private def handleBbbCommonEnvCoreMsg(msg: BbbCommonEnvCoreMsg): Unit = {
     msg.core match {
-      case m: CreateMeetingReqMsg  => handleCreateMeetingReqMsg(m)
-      case m: RegisterUserReqMsg   => handleRegisterUserReqMsg(m)
-      case m: GetAllMeetingsReqMsg => handleGetAllMeetingsReqMsg(m)
-      case m: CheckAlivePingSysMsg => handleCheckAlivePingSysMsg(m)
-      case _                       => log.warning("Cannot handle " + msg.envelope.name)
+      case m: CreateMeetingReqMsg         => handleCreateMeetingReqMsg(m)
+      case m: RegisterUserReqMsg          => handleRegisterUserReqMsg(m)
+      case m: GetAllMeetingsReqMsg        => handleGetAllMeetingsReqMsg(m)
+      case m: CheckAlivePingSysMsg        => handleCheckAlivePingSysMsg(m)
+      case m: ValidateConnAuthTokenSysMsg => handleValidateConnAuthTokenSysMsg(m)
+      case _                              => log.warning("Cannot handle " + msg.envelope.name)
+    }
+  }
+
+  def handleValidateConnAuthTokenSysMsg(msg: ValidateConnAuthTokenSysMsg): Unit = {
+    RunningMeetings.findWithId(meetings, msg.body.meetingId) match {
+      case Some(meeting) =>
+        meeting.actorRef forward msg
+
+      case None =>
+        val event = MsgBuilder.buildValidateConnAuthTokenSysRespMsg(msg.body.meetingId, msg.body.userId,
+          false, msg.body.connId, msg.body.app)
+        outGW.send(event)
     }
   }
 
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/ValidateConnAuthTokenSysMsgHdlr.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/ValidateConnAuthTokenSysMsgHdlr.scala
new file mode 100755
index 0000000000000000000000000000000000000000..e440fa2a6c63e37cd576d2973545716f10991e46
--- /dev/null
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/apps/meeting/ValidateConnAuthTokenSysMsgHdlr.scala
@@ -0,0 +1,30 @@
+package org.bigbluebutton.core.apps.meeting
+
+import org.bigbluebutton.common2.msgs.ValidateConnAuthTokenSysMsg
+import org.bigbluebutton.core.models.RegisteredUsers
+import org.bigbluebutton.core.running.{ LiveMeeting, OutMsgRouter }
+import org.bigbluebutton.core2.message.senders.MsgBuilder
+
+trait ValidateConnAuthTokenSysMsgHdlr {
+  val liveMeeting: LiveMeeting
+  val outGW: OutMsgRouter
+
+  def handleValidateConnAuthTokenSysMsg(msg: ValidateConnAuthTokenSysMsg): Unit = {
+    val regUser = RegisteredUsers.getRegisteredUserWithToken(
+      msg.body.authToken,
+      msg.body.userId,
+      liveMeeting.registeredUsers
+    )
+
+    regUser match {
+      case Some(u) =>
+        val event = MsgBuilder.buildValidateConnAuthTokenSysRespMsg(msg.body.meetingId, msg.body.userId,
+          true, msg.body.connId, msg.body.app)
+        outGW.send(event)
+      case None =>
+        val event = MsgBuilder.buildValidateConnAuthTokenSysRespMsg(msg.body.meetingId, msg.body.userId,
+          false, msg.body.connId, msg.body.app)
+        outGW.send(event)
+    }
+  }
+}
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala
index 9a25bebf62c6b85e8de6e10ae3e2a1fa30c89f1c..f12364401be554b223ea65d9906e80028840b145 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/pubsub/senders/ReceivedJsonMsgHandlerActor.scala
@@ -68,6 +68,8 @@ class ReceivedJsonMsgHandlerActor(
         route[GetAllMeetingsReqMsg](meetingManagerChannel, envelope, jsonNode)
       case DestroyMeetingSysCmdMsg.NAME =>
         route[DestroyMeetingSysCmdMsg](meetingManagerChannel, envelope, jsonNode)
+      case ValidateConnAuthTokenSysMsg.NAME =>
+        route[ValidateConnAuthTokenSysMsg](meetingManagerChannel, envelope, jsonNode)
 
       // Guests
       case GetGuestsWaitingApprovalReqMsg.NAME =>
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
index c89e7c517a3fc51dcd620b637b1366aead0faaba..b081cd31f62c8537b3b224ecef0e1843357329a9 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core/running/MeetingActor.scala
@@ -78,6 +78,7 @@ class MeetingActor(
     with SendTimeRemainingUpdateHdlr
     with SendBreakoutTimeRemainingMsgHdlr
     with ChangeLockSettingsInMeetingCmdMsgHdlr
+    with ValidateConnAuthTokenSysMsgHdlr
     with SyncGetMeetingInfoRespMsgHdlr
     with ClientToServerLatencyTracerMsgHdlr {
 
@@ -137,8 +138,8 @@ class MeetingActor(
     MeetingStatus2x.unmuteMeeting(liveMeeting.status)
   }
 
-    // Set webcamsOnlyForModerator property in case we didn't after meeting creation
-    MeetingStatus2x.setWebcamsOnlyForModerator(liveMeeting.status, liveMeeting.props.usersProp.webcamsOnlyForModerator)
+  // Set webcamsOnlyForModerator property in case we didn't after meeting creation
+  MeetingStatus2x.setWebcamsOnlyForModerator(liveMeeting.status, liveMeeting.props.usersProp.webcamsOnlyForModerator)
 
   /*******************************************************************/
   //object FakeTestData extends FakeTestData
@@ -154,6 +155,7 @@ class MeetingActor(
     // its type is not BbbCommonEnvCoreMsg
     case m: RegisterUserReqMsg                => usersApp.handleRegisterUserReqMsg(m)
     case m: GetAllMeetingsReqMsg              => handleGetAllMeetingsReqMsg(m)
+    case m: ValidateConnAuthTokenSysMsg       => handleValidateConnAuthTokenSysMsg(m)
 
     // Meeting
     case m: DestroyMeetingSysCmdMsg           => handleDestroyMeetingSysCmdMsg(m)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala
index 988789427f52d9f5bae87d619b41879007572f51..d254d1324b3ce819a87918377c5660ef35836704 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/AnalyticsActor.scala
@@ -84,8 +84,11 @@ class AnalyticsActor extends Actor with ActorLogging {
       case m: SetCurrentPresentationPubMsg => logMessage(msg)
       case m: SetCurrentPresentationEvtMsg => logMessage(msg)
 
+      // System
       case m: ClientToServerLatencyTracerMsg => traceMessage(msg)
       case m: ServerToClientLatencyTracerMsg => traceMessage(msg)
+      case m: ValidateConnAuthTokenSysMsg => traceMessage(msg)
+      case m: ValidateConnAuthTokenSysRespMsg => traceMessage(msg)
 
       case _ => // ignore message
     }
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala
index 12baec89b184e799a3a4faa95ec346b13d5b4c42..8f33093297e8bd8353efa4dfde7b10f0dc2e76be 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/MeetingStatus2x.scala
@@ -72,7 +72,7 @@ class MeetingStatus2x {
   private var voiceRecordingFilename: String = ""
 
   private var extension = new MeetingExtensionProp
-  
+
   private var webcamsOnlyForModerator = false
 
   private def startRecordingVoice() {
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
index f8f96a7fc044151ea67721c3464c1401dea9d0de..876868bcb5beb0475e093bbec57ee31ed02f37ba 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/core2/message/senders/MsgBuilder.scala
@@ -1,7 +1,7 @@
 package org.bigbluebutton.core2.message.senders
 
 import org.bigbluebutton.common2.domain.DefaultProps
-import org.bigbluebutton.common2.msgs._
+import org.bigbluebutton.common2.msgs.{ BbbCommonEnvCoreMsg, BbbCoreEnvelope, BbbCoreHeaderWithMeetingId, MessageTypes, Routing, ValidateConnAuthTokenSysRespMsg, ValidateConnAuthTokenSysRespMsgBody, _ }
 import org.bigbluebutton.core.models.GuestWaiting
 
 object MsgBuilder {
@@ -63,6 +63,16 @@ object MsgBuilder {
     BbbCommonEnvCoreMsg(envelope, event)
   }
 
+  def buildValidateConnAuthTokenSysRespMsg(meetingId: String, userId: String,
+                                           authzed: Boolean, connId: String, app: String): BbbCommonEnvCoreMsg = {
+    val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
+    val envelope = BbbCoreEnvelope(ValidateConnAuthTokenSysRespMsg.NAME, routing)
+    val header = BbbCoreHeaderWithMeetingId(ValidateConnAuthTokenSysRespMsg.NAME, meetingId)
+    val body = ValidateConnAuthTokenSysRespMsgBody(meetingId, userId, connId, authzed, app)
+    val event = ValidateConnAuthTokenSysRespMsg(header, body)
+    BbbCommonEnvCoreMsg(envelope, event)
+  }
+
   def buildValidateAuthTokenRespMsg(meetingId: String, userId: String, authToken: String,
                                     valid: Boolean, waitForApproval: Boolean): BbbCommonEnvCoreMsg = {
     val routing = Routing.addMsgToClientRouting(MessageTypes.DIRECT, meetingId, userId)
diff --git a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala
index 8edac4e7df543de00786646d0198b55af181b49f..116a9dea9b9505ac8b9aab87e5dd2e22f98ab61f 100755
--- a/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala
+++ b/akka-bbb-apps/src/main/scala/org/bigbluebutton/endpoint/redis/RedisRecorderActor.scala
@@ -407,7 +407,7 @@ class RedisRecorderActor(val system: ActorSystem)
 
     record(msg.header.meetingId, ev.toMap)
   }
-  
+
   private def handleWebcamsOnlyForModeratorChangedEvtMsg(msg: WebcamsOnlyForModeratorChangedEvtMsg) {
     val ev = new WebcamsOnlyForModeratorRecordEvent()
     ev.setMeetingId(msg.header.meetingId)
diff --git a/bbb-client-check/html-template/index.html b/bbb-client-check/html-template/index.html
index 4fbb92fb91b27bfe764ce330fb78254a571ad923..56b1b7c3aa83cb74d035f4781ab81951e881d540 100755
--- a/bbb-client-check/html-template/index.html
+++ b/bbb-client-check/html-template/index.html
@@ -38,7 +38,6 @@
         <script type="text/javascript" src="resources/lib/api-bridge.js"></script>
         <script type="text/javascript" src="resources/lib/sip.js"></script>
         <script type="text/javascript" src="resources/lib/bbb_webrtc_bridge_sip.js"></script>
-        <script type="text/javascript" src="resources/lib/deployJava.js"></script>
         <script type="text/javascript" src="resources/lib/bbb_localization.js"></script>
         <script type="text/javascript" src="swfobject.js"></script>
         <script type="text/javascript">
@@ -66,7 +65,6 @@
         </script>
     </head>
     <body>
-        <div id="deployJavaPluginContainer" style="visibility:hidden; height:0px; "></div>
         <!-- SWFObject's dynamic embed method replaces this alternative HTML content with Flash content when enough 
              JavaScript and Flash plug-in support is available. The div is initially hidden so that it doesn't show
              when JavaScript is disabled.
diff --git a/bbb-client-check/html-template/index.template.html b/bbb-client-check/html-template/index.template.html
index f7583f2543529a98ccd9398970fc7bd5762c022b..9085653c92c47801ee55166ad1c2f85d22c2400b 100755
--- a/bbb-client-check/html-template/index.template.html
+++ b/bbb-client-check/html-template/index.template.html
@@ -37,7 +37,6 @@
         <script type="text/javascript" src="resources/lib/api-bridge.js"></script>
         <script type="text/javascript" src="resources/lib/sip.js"></script>
         <script type="text/javascript" src="resources/lib/bbb_webrtc_bridge_sip.js"></script>
-        <script type="text/javascript" src="resources/lib/deployJava.js"></script>
         <script type="text/javascript" src="resources/lib/bbb_localization.js"></script>
         <script type="text/javascript" src="swfobject.js"></script>
         <script type="text/javascript">
@@ -65,7 +64,6 @@
         </script>
     </head>
     <body>
-        <div id="deployJavaPluginContainer" style="visibility:hidden; height:0px; "></div>
         <!-- SWFObject's dynamic embed method replaces this alternative HTML content with Flash content when enough 
              JavaScript and Flash plug-in support is available. The div is initially hidden so that it doesn't show
              when JavaScript is disabled.
diff --git a/bbb-client-check/locale/en_US/resources.properties b/bbb-client-check/locale/en_US/resources.properties
index 852de1d304967899f80fde38b0756b14737eb7be..786fdd75f43969cec7d6fca58c5c26025ac98f0c 100755
--- a/bbb-client-check/locale/en_US/resources.properties
+++ b/bbb-client-check/locale/en_US/resources.properties
@@ -7,8 +7,6 @@ bbbsystemcheck.dataGridColumn.status = Status
 bbbsystemcheck.dataGridColumn.result = Result
 bbbsystemcheck.copyAllText = Copy all text
 bbbsystemcheck.result.undefined = Undefined
-bbbsystemcheck.result.javaEnabled.disabled = Java is disabled in your browser
-bbbsystemcheck.result.javaEnabled.notDetected = No Java detected
 bbbsystemcheck.result.browser.changeBrowser = Recommend you use Firefox or Chrome for better audio
 bbbsystemcheck.result.browser.browserOutOfDate = Your browser is out-of-date. Recommend you update to latest version.
 bbbsystemcheck.status.succeeded = Succeded
@@ -20,7 +18,6 @@ bbbsystemcheck.test.name.cookieEnabled = Cookie Enabled
 bbbsystemcheck.test.name.downloadSpeed = Download Speed
 bbbsystemcheck.test.name.flashVersion = Flash Version
 bbbsystemcheck.test.name.pepperFlash = Is Pepper Flash
-bbbsystemcheck.test.name.javaEnabled = Java Enabled
 bbbsystemcheck.test.name.language = Language
 bbbsystemcheck.test.name.ping = Ping
 bbbsystemcheck.test.name.screenSize = Screen Size
diff --git a/bbb-client-check/locale/pt_BR/resources.properties b/bbb-client-check/locale/pt_BR/resources.properties
index be2d6a47196e9bd49dc5a2370aa4a99126824a67..f6b6283f7c70c845d9cc8d18df4ec300ca4b6c32 100644
--- a/bbb-client-check/locale/pt_BR/resources.properties
+++ b/bbb-client-check/locale/pt_BR/resources.properties
@@ -7,8 +7,6 @@ bbbsystemcheck.dataGridColumn.status = Status
 bbbsystemcheck.dataGridColumn.result = Resultado
 bbbsystemcheck.copyAllText = Copiar resultados
 bbbsystemcheck.result.undefined = Indefinido
-bbbsystemcheck.result.javaEnabled.disabled = O Java está desabilitado em seu navegador
-bbbsystemcheck.result.javaEnabled.notDetected = Java não detectado
 bbbsystemcheck.result.browser.changeBrowser = Recomendamos o uso de Firefox ou Chrome para uma melhor qualidade de áudio
 bbbsystemcheck.result.browser.browserOutOfDate = Seu navegador está desatualizado. Recomendamos que você o atualize para uma versão mais nova.
 bbbsystemcheck.status.succeeded = Sucesso
@@ -20,7 +18,6 @@ bbbsystemcheck.test.name.cookieEnabled = Cookies habilitados
 bbbsystemcheck.test.name.downloadSpeed = Velocidade de download
 bbbsystemcheck.test.name.flashVersion = Versão do Adobe Flash Player
 bbbsystemcheck.test.name.pepperFlash = Pepper Flash
-bbbsystemcheck.test.name.javaEnabled = Java habilitado
 bbbsystemcheck.test.name.language = Idioma
 bbbsystemcheck.test.name.ping = Ping
 bbbsystemcheck.test.name.screenSize = Tamanho da tela
diff --git a/bbb-client-check/resources/lib/api-bridge.js b/bbb-client-check/resources/lib/api-bridge.js
index b4f064af2680c8dd154c0592e3f522659b58c51c..84c80f7c7f3117e52fc2e80e6f7a726cebbf5c7b 100644
--- a/bbb-client-check/resources/lib/api-bridge.js
+++ b/bbb-client-check/resources/lib/api-bridge.js
@@ -152,33 +152,6 @@
 		cookieEnabledInfo = navigator.cookieEnabled;
 		swfObj.cookieEnabled(cookieEnabledInfo);
 	}
-	
-	BBBClientCheck.javaEnabled = function(){
-		var result = {
-			enabled: navigator.javaEnabled(),
-			version: [],
-			minimum: '1.7.0_51+',
-			appropriate: false
-		};
-
-		if (result.enabled) {
-			result.version = getJavaVersion();
-			result.appropriate = isJavaVersionAppropriateForDeskshare(result.minimum);
-		}
-
-		console.log(result);
-
-		var swfObj = getSwfObj();
-		swfObj.javaEnabled(result);
-	}
-
-	function getJavaVersion() {
-		return deployJava.getJREs();
-	}
-
-	function isJavaVersionAppropriateForDeskshare(required) {
-		return deployJava.versionCheck(required);
-	}
 
 	BBBClientCheck.language = function(){ 
 		var languageInfo = '';
diff --git a/bbb-client-check/resources/lib/deployJava.js b/bbb-client-check/resources/lib/deployJava.js
deleted file mode 100644
index 8aa7a65aba8382bb8aa9ed24f3eee86a319050bf..0000000000000000000000000000000000000000
--- a/bbb-client-check/resources/lib/deployJava.js
+++ /dev/null
@@ -1 +0,0 @@
-var deployJava=function(){var l={core:["id","class","title","style"],i18n:["lang","dir"],events:["onclick","ondblclick","onmousedown","onmouseup","onmouseover","onmousemove","onmouseout","onkeypress","onkeydown","onkeyup"],applet:["codebase","code","name","archive","object","width","height","alt","align","hspace","vspace"],object:["classid","codebase","codetype","data","type","archive","declare","standby","height","width","usemap","name","tabindex","align","border","hspace","vspace"]};var b=l.object.concat(l.core,l.i18n,l.events);var m=l.applet.concat(l.core);function g(o){if(!d.debug){return}if(console.log){console.log(o)}else{alert(o)}}function k(p,o){if(p==null||p.length==0){return true}var r=p.charAt(p.length-1);if(r!="+"&&r!="*"&&(p.indexOf("_")!=-1&&r!="_")){p=p+"*";r="*"}p=p.substring(0,p.length-1);if(p.length>0){var q=p.charAt(p.length-1);if(q=="."||q=="_"){p=p.substring(0,p.length-1)}}if(r=="*"){return(o.indexOf(p)==0)}else{if(r=="+"){return p<=o}}return false}function e(){var o="//java.com/js/webstart.png";try{return document.location.protocol.indexOf("http")!=-1?o:"http:"+o}catch(p){return"http:"+o}}function n(p){var o="http://java.com/dt-redirect";if(p==null||p.length==0){return o}if(p.charAt(0)=="&"){p=p.substring(1,p.length)}return o+"?"+p}function j(q,p){var o=q.length;for(var r=0;r<o;r++){if(q[r]===p){return true}}return false}function c(o){return j(m,o.toLowerCase())}function i(o){return j(b,o.toLowerCase())}function a(o){if("MSIE"!=deployJava.browserName){return true}if(deployJava.compareVersionToPattern(deployJava.getPlugin().version,["10","0","0"],false,true)){return true}if(o==null){return false}return !k("1.6.0_33+",o)}var d={debug:null,version:"20120801",firefoxJavaVersion:null,myInterval:null,preInstallJREList:null,returnPage:null,brand:null,locale:null,installType:null,EAInstallEnabled:false,EarlyAccessURL:null,oldMimeType:"application/npruntime-scriptable-plugin;DeploymentToolkit",mimeType:"application/java-deployment-toolkit",launchButtonPNG:e(),browserName:null,browserName2:null,getJREs:function(){var t=new Array();if(this.isPluginInstalled()){var r=this.getPlugin();var o=r.jvms;for(var q=0;q<o.getLength();q++){t[q]=o.get(q).version}}else{var p=this.getBrowser();if(p=="MSIE"){if(this.testUsingActiveX("1.7.0")){t[0]="1.7.0"}else{if(this.testUsingActiveX("1.6.0")){t[0]="1.6.0"}else{if(this.testUsingActiveX("1.5.0")){t[0]="1.5.0"}else{if(this.testUsingActiveX("1.4.2")){t[0]="1.4.2"}else{if(this.testForMSVM()){t[0]="1.1"}}}}}}else{if(p=="Netscape Family"){this.getJPIVersionUsingMimeType();if(this.firefoxJavaVersion!=null){t[0]=this.firefoxJavaVersion}else{if(this.testUsingMimeTypes("1.7")){t[0]="1.7.0"}else{if(this.testUsingMimeTypes("1.6")){t[0]="1.6.0"}else{if(this.testUsingMimeTypes("1.5")){t[0]="1.5.0"}else{if(this.testUsingMimeTypes("1.4.2")){t[0]="1.4.2"}else{if(this.browserName2=="Safari"){if(this.testUsingPluginsArray("1.7.0")){t[0]="1.7.0"}else{if(this.testUsingPluginsArray("1.6")){t[0]="1.6.0"}else{if(this.testUsingPluginsArray("1.5")){t[0]="1.5.0"}else{if(this.testUsingPluginsArray("1.4.2")){t[0]="1.4.2"}}}}}}}}}}}}}if(this.debug){for(var q=0;q<t.length;++q){g("[getJREs()] We claim to have detected Java SE "+t[q])}}return t},installJRE:function(r,p){var o=false;if(this.isPluginInstalled()&&this.isAutoInstallEnabled(r)){var q=false;if(this.isCallbackSupported()){q=this.getPlugin().installJRE(r,p)}else{q=this.getPlugin().installJRE(r)}if(q){this.refresh();if(this.returnPage!=null){document.location=this.returnPage}}return q}else{return this.installLatestJRE()}},isAutoInstallEnabled:function(o){if(!this.isPluginInstalled()){return false}if(typeof o=="undefined"){o=null}return a(o)},isCallbackSupported:function(){return this.isPluginInstalled()&&this.compareVersionToPattern(this.getPlugin().version,["10","2","0"],false,true)},installLatestJRE:function(q){if(this.isPluginInstalled()&&this.isAutoInstallEnabled()){var r=false;if(this.isCallbackSupported()){r=this.getPlugin().installLatestJRE(q)}else{r=this.getPlugin().installLatestJRE()}if(r){this.refresh();if(this.returnPage!=null){document.location=this.returnPage}}return r}else{var p=this.getBrowser();var o=navigator.platform.toLowerCase();if((this.EAInstallEnabled=="true")&&(o.indexOf("win")!=-1)&&(this.EarlyAccessURL!=null)){this.preInstallJREList=this.getJREs();if(this.returnPage!=null){this.myInterval=setInterval("deployJava.poll()",3000)}location.href=this.EarlyAccessURL;return false}else{if(p=="MSIE"){return this.IEInstall()}else{if((p=="Netscape Family")&&(o.indexOf("win32")!=-1)){return this.FFInstall()}else{location.href=n(((this.returnPage!=null)?("&returnPage="+this.returnPage):"")+((this.locale!=null)?("&locale="+this.locale):"")+((this.brand!=null)?("&brand="+this.brand):""))}}return false}}},runApplet:function(p,u,r){if(r=="undefined"||r==null){r="1.1"}var t="^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:_(\\d+))?)?)?$";var o=r.match(t);if(this.returnPage==null){this.returnPage=document.location}if(o!=null){var q=this.getBrowser();if(q!="?"){if(this.versionCheck(r+"+")){this.writeAppletTag(p,u)}else{if(this.installJRE(r+"+")){this.refresh();location.href=document.location;this.writeAppletTag(p,u)}}}else{this.writeAppletTag(p,u)}}else{g("[runApplet()] Invalid minimumVersion argument to runApplet():"+r)}},writeAppletTag:function(r,w){var o="<"+"applet ";var q="";var t="<"+"/"+"applet"+">";var x=true;if(null==w||typeof w!="object"){w=new Object()}for(var p in r){if(!c(p)){w[p]=r[p]}else{o+=(" "+p+'="'+r[p]+'"');if(p=="code"){x=false}}}var v=false;for(var u in w){if(u=="codebase_lookup"){v=true}if(u=="object"||u=="java_object"||u=="java_code"){x=false}q+='<param name="'+u+'" value="'+w[u]+'"/>'}if(!v){q+='<param name="codebase_lookup" value="false"/>'}if(x){o+=(' code="dummy"')}o+=">";document.write(o+"\n"+q+"\n"+t)},versionCheck:function(p){var v=0;var x="^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:_(\\d+))?)?)?(\\*|\\+)?$";var y=p.match(x);if(y!=null){var r=false;var u=false;var q=new Array();for(var t=1;t<y.length;++t){if((typeof y[t]=="string")&&(y[t]!="")){q[v]=y[t];v++}}if(q[q.length-1]=="+"){u=true;r=false;q.length--}else{if(q[q.length-1]=="*"){u=false;r=true;q.length--}else{if(q.length<4){u=false;r=true}}}var w=this.getJREs();for(var t=0;t<w.length;++t){if(this.compareVersionToPattern(w[t],q,r,u)){return true}}return false}else{var o="Invalid versionPattern passed to versionCheck: "+p;g("[versionCheck()] "+o);alert(o);return false}},isWebStartInstalled:function(r){var q=this.getBrowser();if(q=="?"){return true}if(r=="undefined"||r==null){r="1.4.2"}var p=false;var t="^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:_(\\d+))?)?)?$";var o=r.match(t);if(o!=null){p=this.versionCheck(r+"+")}else{g("[isWebStartInstaller()] Invalid minimumVersion argument to isWebStartInstalled(): "+r);p=this.versionCheck("1.4.2+")}return p},getJPIVersionUsingMimeType:function(){for(var p=0;p<navigator.mimeTypes.length;++p){var q=navigator.mimeTypes[p].type;var o=q.match(/^application\/x-java-applet;jpi-version=(.*)$/);if(o!=null){this.firefoxJavaVersion=o[1];if("Opera"!=this.browserName2){break}}}},launchWebStartApplication:function(r){var o=navigator.userAgent.toLowerCase();this.getJPIVersionUsingMimeType();if(this.isWebStartInstalled("1.7.0")==false){if((this.installJRE("1.7.0+")==false)||((this.isWebStartInstalled("1.7.0")==false))){return false}}var u=null;if(document.documentURI){u=document.documentURI}if(u==null){u=document.URL}var p=this.getBrowser();var q;if(p=="MSIE"){q="<"+'object classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93" '+'width="0" height="0">'+"<"+'PARAM name="launchjnlp" value="'+r+'"'+">"+"<"+'PARAM name="docbase" value="'+u+'"'+">"+"<"+"/"+"object"+">"}else{if(p=="Netscape Family"){q="<"+'embed type="application/x-java-applet;jpi-version='+this.firefoxJavaVersion+'" '+'width="0" height="0" '+'launchjnlp="'+r+'"'+'docbase="'+u+'"'+" />"}}if(document.body=="undefined"||document.body==null){document.write(q);document.location=u}else{var t=document.createElement("div");t.id="div1";t.style.position="relative";t.style.left="-10000px";t.style.margin="0px auto";t.className="dynamicDiv";t.innerHTML=q;document.body.appendChild(t)}},createWebStartLaunchButtonEx:function(q,p){if(this.returnPage==null){this.returnPage=q}var o="javascript:deployJava.launchWebStartApplication('"+q+"');";document.write("<"+'a href="'+o+"\" onMouseOver=\"window.status=''; "+'return true;"><'+"img "+'src="'+this.launchButtonPNG+'" '+'border="0" /><'+"/"+"a"+">")},createWebStartLaunchButton:function(q,p){if(this.returnPage==null){this.returnPage=q}var o="javascript:"+"if (!deployJava.isWebStartInstalled(&quot;"+p+"&quot;)) {"+"if (deployJava.installLatestJRE()) {"+"if (deployJava.launch(&quot;"+q+"&quot;)) {}"+"}"+"} else {"+"if (deployJava.launch(&quot;"+q+"&quot;)) {}"+"}";document.write("<"+'a href="'+o+"\" onMouseOver=\"window.status=''; "+'return true;"><'+"img "+'src="'+this.launchButtonPNG+'" '+'border="0" /><'+"/"+"a"+">")},launch:function(o){document.location=o;return true},isPluginInstalled:function(){var o=this.getPlugin();if(o&&o.jvms){return true}else{return false}},isAutoUpdateEnabled:function(){if(this.isPluginInstalled()){return this.getPlugin().isAutoUpdateEnabled()}return false},setAutoUpdateEnabled:function(){if(this.isPluginInstalled()){return this.getPlugin().setAutoUpdateEnabled()}return false},setInstallerType:function(o){this.installType=o;if(this.isPluginInstalled()){return this.getPlugin().setInstallerType(o)}return false},setAdditionalPackages:function(o){if(this.isPluginInstalled()){return this.getPlugin().setAdditionalPackages(o)}return false},setEarlyAccess:function(o){this.EAInstallEnabled=o},isPlugin2:function(){if(this.isPluginInstalled()){if(this.versionCheck("1.6.0_10+")){try{return this.getPlugin().isPlugin2()}catch(o){}}}return false},allowPlugin:function(){this.getBrowser();var o=("Safari"!=this.browserName2&&"Opera"!=this.browserName2);return o},getPlugin:function(){this.refresh();var o=null;if(this.allowPlugin()){o=document.getElementById("deployJavaPlugin")}return o},compareVersionToPattern:function(v,p,r,t){if(v==undefined||p==undefined){return false}var w="^(\\d+)(?:\\.(\\d+)(?:\\.(\\d+)(?:_(\\d+))?)?)?$";var x=v.match(w);if(x!=null){var u=0;var y=new Array();for(var q=1;q<x.length;++q){if((typeof x[q]=="string")&&(x[q]!="")){y[u]=x[q];u++}}var o=Math.min(y.length,p.length);if(t){for(var q=0;q<o;++q){if(y[q]<p[q]){return false}else{if(y[q]>p[q]){return true}}}return true}else{for(var q=0;q<o;++q){if(y[q]!=p[q]){return false}}if(r){return true}else{return(y.length==p.length)}}}else{return false}},getBrowser:function(){if(this.browserName==null){var o=navigator.userAgent.toLowerCase();g("[getBrowser()] navigator.userAgent.toLowerCase() -> "+o);if((o.indexOf("msie")!=-1)&&(o.indexOf("opera")==-1)){this.browserName="MSIE";this.browserName2="MSIE"}else{if(o.indexOf("trident")!=-1||o.indexOf("Trident")!=-1){this.browserName="MSIE";this.browserName2="MSIE"}else{if(o.indexOf("iphone")!=-1){this.browserName="Netscape Family";this.browserName2="iPhone"}else{if((o.indexOf("firefox")!=-1)&&(o.indexOf("opera")==-1)){this.browserName="Netscape Family";this.browserName2="Firefox"}else{if(o.indexOf("chrome")!=-1){this.browserName="Netscape Family";this.browserName2="Chrome"}else{if(o.indexOf("safari")!=-1){this.browserName="Netscape Family";this.browserName2="Safari"}else{if((o.indexOf("mozilla")!=-1)&&(o.indexOf("opera")==-1)){this.browserName="Netscape Family";this.browserName2="Other"}else{if(o.indexOf("opera")!=-1){this.browserName="Netscape Family";this.browserName2="Opera"}else{this.browserName="?";this.browserName2="unknown"}}}}}}}}g("[getBrowser()] Detected browser name:"+this.browserName+", "+this.browserName2)}return this.browserName},testUsingActiveX:function(o){var q="JavaWebStart.isInstalled."+o+".0";if(typeof ActiveXObject=="undefined"||!ActiveXObject){g("[testUsingActiveX()] Browser claims to be IE, but no ActiveXObject object?");return false}try{return(new ActiveXObject(q)!=null)}catch(p){return false}},testForMSVM:function(){var p="{08B0E5C0-4FCB-11CF-AAA5-00401C608500}";if(typeof oClientCaps!="undefined"){var o=oClientCaps.getComponentVersion(p,"ComponentID");if((o=="")||(o=="5,0,5000,0")){return false}else{return true}}else{return false}},testUsingMimeTypes:function(p){if(!navigator.mimeTypes){g("[testUsingMimeTypes()] Browser claims to be Netscape family, but no mimeTypes[] array?");return false}for(var q=0;q<navigator.mimeTypes.length;++q){s=navigator.mimeTypes[q].type;var o=s.match(/^application\/x-java-applet\x3Bversion=(1\.8|1\.7|1\.6|1\.5|1\.4\.2)$/);if(o!=null){if(this.compareVersions(o[1],p)){return true}}}return false},testUsingPluginsArray:function(p){if((!navigator.plugins)||(!navigator.plugins.length)){return false}var o=navigator.platform.toLowerCase();for(var q=0;q<navigator.plugins.length;++q){s=navigator.plugins[q].description;if(s.search(/^Java Switchable Plug-in (Cocoa)/)!=-1){if(this.compareVersions("1.5.0",p)){return true}}else{if(s.search(/^Java/)!=-1){if(o.indexOf("win")!=-1){if(this.compareVersions("1.5.0",p)||this.compareVersions("1.6.0",p)){return true}}}}}if(this.compareVersions("1.5.0",p)){return true}return false},IEInstall:function(){location.href=n(((this.returnPage!=null)?("&returnPage="+this.returnPage):"")+((this.locale!=null)?("&locale="+this.locale):"")+((this.brand!=null)?("&brand="+this.brand):""));return false},done:function(p,o){},FFInstall:function(){location.href=n(((this.returnPage!=null)?("&returnPage="+this.returnPage):"")+((this.locale!=null)?("&locale="+this.locale):"")+((this.brand!=null)?("&brand="+this.brand):"")+((this.installType!=null)?("&type="+this.installType):""));return false},compareVersions:function(r,t){var p=r.split(".");var o=t.split(".");for(var q=0;q<p.length;++q){p[q]=Number(p[q])}for(var q=0;q<o.length;++q){o[q]=Number(o[q])}if(p.length==2){p[2]=0}if(p[0]>o[0]){return true}if(p[0]<o[0]){return false}if(p[1]>o[1]){return true}if(p[1]<o[1]){return false}if(p[2]>o[2]){return true}if(p[2]<o[2]){return false}return true},enableAlerts:function(){this.browserName=null;this.debug=true},poll:function(){this.refresh();var o=this.getJREs();if((this.preInstallJREList.length==0)&&(o.length!=0)){clearInterval(this.myInterval);if(this.returnPage!=null){location.href=this.returnPage}}if((this.preInstallJREList.length!=0)&&(o.length!=0)&&(this.preInstallJREList[0]!=o[0])){clearInterval(this.myInterval);if(this.returnPage!=null){location.href=this.returnPage}}},writePluginTag:function(){var o=this.getBrowser();if(o=="MSIE"){document.write("<"+'object classid="clsid:CAFEEFAC-DEC7-0000-0001-ABCDEFFEDCBA" '+'id="deployJavaPlugin" width="0" height="0">'+"<"+"/"+"object"+">")}else{if(o=="Netscape Family"&&this.allowPlugin()){this.writeEmbedTag()}}},refresh:function(){navigator.plugins.refresh(false);var o=this.getBrowser();if(o=="Netscape Family"&&this.allowPlugin()){var p=document.getElementById("deployJavaPlugin");if(p==null){this.writeEmbedTag()}}},writeEmbedTag:function(){var o=false;if(navigator.mimeTypes!=null){for(var p=0;p<navigator.mimeTypes.length;p++){if(navigator.mimeTypes[p].type==this.mimeType){if(navigator.mimeTypes[p].enabledPlugin){document.write("<"+'embed id="deployJavaPlugin" type="'+this.mimeType+'" hidden="true" />');o=true}}}if(!o){for(var p=0;p<navigator.mimeTypes.length;p++){if(navigator.mimeTypes[p].type==this.oldMimeType){if(navigator.mimeTypes[p].enabledPlugin){document.write("<"+'embed id="deployJavaPlugin" type="'+this.oldMimeType+'" hidden="true" />')}}}}}}};d.writePluginTag();if(d.locale==null){var h=null;if(h==null){try{h=navigator.userLanguage}catch(f){}}if(h==null){try{h=navigator.systemLanguage}catch(f){}}if(h==null){try{h=navigator.language}catch(f){}}if(h!=null){h.replace("-","_");d.locale=h}}return d}();
\ No newline at end of file
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/command/RequestBrowserInfoCommand.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/command/RequestBrowserInfoCommand.as
index 58766b11ec4fbc4ee9c92ffbbcee3c17ae09257d..94ec2e42333ca1d0604290aa528ac81c8b6866f8 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/command/RequestBrowserInfoCommand.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/command/RequestBrowserInfoCommand.as
@@ -43,7 +43,6 @@ package org.bigbluebutton.clientcheck.command
 			externalApiCalls.requestIsPepperFlash();
 			externalApiCalls.requestLanguage();
 			externalApiCalls.requestCookiesEnabled();
-			externalApiCalls.requestJavaEnabled();
 			externalApiCalls.requestIsWebRTCSupported();
 			externalApiCalls.requestWebRTCEchoAndSocketTest();
 
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/model/ISystemConfiguration.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/model/ISystemConfiguration.as
index e985ff257f44bd599e7602004aec2d2f09296d55..3f8a2aa7aa05b9998ce43a9db9dc751f8d009a09 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/model/ISystemConfiguration.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/model/ISystemConfiguration.as
@@ -24,7 +24,6 @@ package org.bigbluebutton.clientcheck.model
 	import org.bigbluebutton.clientcheck.model.test.DownloadBandwidthTest;
 	import org.bigbluebutton.clientcheck.model.test.FlashVersionTest;
 	import org.bigbluebutton.clientcheck.model.test.IsPepperFlashTest;
-	import org.bigbluebutton.clientcheck.model.test.JavaEnabledTest;
 	import org.bigbluebutton.clientcheck.model.test.LanguageTest;
 	import org.bigbluebutton.clientcheck.model.test.PingTest;
 	import org.bigbluebutton.clientcheck.model.test.ScreenSizeTest;
@@ -42,7 +41,6 @@ package org.bigbluebutton.clientcheck.model
 		function get flashVersion():FlashVersionTest;
 		function get isPepperFlash():IsPepperFlashTest;
 		function get cookieEnabled():CookieEnabledTest;
-		function get javaEnabled():JavaEnabledTest;
 		function get language():LanguageTest;
 		function get isWebRTCSupported():WebRTCSupportedTest;
 		function get webRTCEchoTest():WebRTCEchoTest;
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/model/SystemConfiguration.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/model/SystemConfiguration.as
index 94339846d7e80b68dd6cc7c0fa002d81070fbe00..7e40514c94f6081b66df4949eff18a6a695972c4 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/model/SystemConfiguration.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/model/SystemConfiguration.as
@@ -24,7 +24,6 @@ package org.bigbluebutton.clientcheck.model
 	import org.bigbluebutton.clientcheck.model.test.DownloadBandwidthTest;
 	import org.bigbluebutton.clientcheck.model.test.FlashVersionTest;
 	import org.bigbluebutton.clientcheck.model.test.IsPepperFlashTest;
-	import org.bigbluebutton.clientcheck.model.test.JavaEnabledTest;
 	import org.bigbluebutton.clientcheck.model.test.LanguageTest;
 	import org.bigbluebutton.clientcheck.model.test.PingTest;
 	import org.bigbluebutton.clientcheck.model.test.ScreenSizeTest;
@@ -42,7 +41,6 @@ package org.bigbluebutton.clientcheck.model
 		private var _flashVersion:FlashVersionTest=new FlashVersionTest;
 		private var _isPepperFlash:IsPepperFlashTest=new IsPepperFlashTest;
 		private var _cookieEnabled:CookieEnabledTest=new CookieEnabledTest;
-		private var _javaEnabled:JavaEnabledTest=new JavaEnabledTest;
 		private var _language:LanguageTest=new LanguageTest;
 		private var _isWebRTCSupported:WebRTCSupportedTest=new WebRTCSupportedTest;
 		private var _webRTCEchoTest:WebRTCEchoTest=new WebRTCEchoTest;
@@ -88,11 +86,6 @@ package org.bigbluebutton.clientcheck.model
 			return _cookieEnabled;
 		}
 
-		public function get javaEnabled():JavaEnabledTest
-		{
-			return _javaEnabled;
-		}
-
 		public function get language():LanguageTest
 		{
 			return _language
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/model/test/JavaEnabledTest.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/model/test/JavaEnabledTest.as
deleted file mode 100644
index 21daace595bf14c28af8c48c39d9373434cb336a..0000000000000000000000000000000000000000
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/model/test/JavaEnabledTest.as
+++ /dev/null
@@ -1,62 +0,0 @@
-/**
- * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
- * 
- * Copyright (c) 2014 BigBlueButton Inc. and by respective authors (see below).
- *
- * This program is free software; you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation; either version 3.0 of the License, or (at your option) any later
- * version.
- * 
- * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along
- * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-package org.bigbluebutton.clientcheck.model.test
-{
-	import org.osflash.signals.ISignal;
-	import org.osflash.signals.Signal;
-
-	import mx.resources.ResourceManager;
-
-	public class JavaEnabledTest implements ITestable
-	{
-		public static var JAVA_ENABLED:String=ResourceManager.getInstance().getString('resources', 'bbbsystemcheck.test.name.javaEnabled');
-
-		private var _testSuccessfull:Boolean;
-		private var _testResult:String;
-
-		private var _javaEnabledTestSuccessfullChangedSignal:ISignal=new Signal;
-
-		public function get testSuccessfull():Boolean
-		{
-			return _testSuccessfull;
-		}
-
-		public function set testSuccessfull(value:Boolean):void
-		{
-			_testSuccessfull=value;
-			javaEnabledTestSuccessfullChangedSignal.dispatch();
-		}
-
-		public function get testResult():String
-		{
-			return _testResult;
-		}
-
-		public function set testResult(value:String):void
-		{
-			_testResult=value;
-		}
-
-		public function get javaEnabledTestSuccessfullChangedSignal():ISignal
-		{
-			return _javaEnabledTestSuccessfullChangedSignal;
-		}
-	}
-}
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/ExternalApiCallbacks.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/ExternalApiCallbacks.as
index 3564a54f8d6e516bbf79f663791153e9a4d5e3bf..baa89acf731433d712abdb990dcd4b46a32e75ef 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/ExternalApiCallbacks.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/ExternalApiCallbacks.as
@@ -44,7 +44,6 @@ package org.bigbluebutton.clientcheck.service
 				ExternalInterface.addCallback("screenSize", screenSizeCallbackHandler);
 				ExternalInterface.addCallback("isPepperFlash", isPepperFlashCallbackHandler);
 				ExternalInterface.addCallback("cookieEnabled", cookieEnabledCallbackHandler);
-				ExternalInterface.addCallback("javaEnabled", javaEnabledCallbackHandler);
 				ExternalInterface.addCallback("language", languageCallbackHandler);
 				ExternalInterface.addCallback("isWebRTCSupported", isWebRTCSupportedCallbackHandler);
 				ExternalInterface.addCallback("webRTCEchoTest", webRTCEchoTestCallbackHandler);
@@ -88,21 +87,6 @@ package org.bigbluebutton.clientcheck.service
 			checkResult(value, systemConfiguration.language);
 		}
 
-		public function javaEnabledCallbackHandler(value:Object):void
-		{
-			var testResult:String;
-			if (!value.enabled) {
-				testResult = ResourceManager.getInstance().getString('resources', 'bbbsystemcheck.result.javaEnabled.disabled');
-			} else if (value.version.length == 0) {
-				testResult = ResourceManager.getInstance().getString('resources', 'bbbsystemcheck.result.javaEnabled.notDetected');
-			} else {
-				testResult = value.version.join(', ');
-			}
-
-			systemConfiguration.javaEnabled.testResult = testResult;
-			systemConfiguration.javaEnabled.testSuccessfull = value.appropriate;
-		}
-
 		public function isWebRTCSupportedCallbackHandler(value:String):void
 		{
 			checkResult(value, systemConfiguration.isWebRTCSupported);
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/ExternalApiCalls.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/ExternalApiCalls.as
index c6ad8bbf3537e9530cfebb9fa9a6a59bac35823c..3d58133dbf418918cecc5b71afe326aeadc48cf4 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/ExternalApiCalls.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/ExternalApiCalls.as
@@ -48,11 +48,6 @@ package org.bigbluebutton.clientcheck.service
 			ExternalInterface.call('BBBClientCheck.cookieEnabled');
 		}
 
-		public function requestJavaEnabled():void
-		{
-			ExternalInterface.call('BBBClientCheck.javaEnabled');
-		}
-
 		public function requestLanguage():void
 		{
 			ExternalInterface.call('BBBClientCheck.language');
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/IExternalApiCallbacks.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/IExternalApiCallbacks.as
index ab3642e2048a43f39cc4761a700a1fae617cf142..2901acf9cf91e708eefef9e138020da231dd0622 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/IExternalApiCallbacks.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/IExternalApiCallbacks.as
@@ -26,7 +26,6 @@ package org.bigbluebutton.clientcheck.service
 		function cookieEnabledCallbackHandler(value:String):void;
 		function isPepperFlashCallbackHandler(value:String):void;
 		function languageCallbackHandler(value:String):void;
-		function javaEnabledCallbackHandler(value:Object):void;
 		function screenSizeCallbackHandler(value:String):void;
 		function isWebRTCSupportedCallbackHandler(value:String):void;
 		function webRTCEchoTestCallbackHandler(success:Boolean, result:String):void;
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/IExternalApiCalls.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/IExternalApiCalls.as
index b16b2a5e65c64d2648f33bfa8d51a5a211647ee8..9fde5ce6df344fee62e0a68432db9e95af5f2077 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/service/IExternalApiCalls.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/service/IExternalApiCalls.as
@@ -27,7 +27,6 @@ package org.bigbluebutton.clientcheck.service
 		function requestScreenSize():void;
 		function requestIsPepperFlash():void;
 		function requestCookiesEnabled():void;
-		function requestJavaEnabled():void;
 		function requestLanguage():void;
 		function requestIsWebRTCSupported():void;
 		function requestWebRTCEchoAndSocketTest():void;
diff --git a/bbb-client-check/src/org/bigbluebutton/clientcheck/view/mainview/MainViewMediator.as b/bbb-client-check/src/org/bigbluebutton/clientcheck/view/mainview/MainViewMediator.as
index dc0e04977bab19966878c605e9f9a401dc1b75e3..5518ef947776d26a064408a8f8072e573a8dabb0 100644
--- a/bbb-client-check/src/org/bigbluebutton/clientcheck/view/mainview/MainViewMediator.as
+++ b/bbb-client-check/src/org/bigbluebutton/clientcheck/view/mainview/MainViewMediator.as
@@ -39,7 +39,6 @@ package org.bigbluebutton.clientcheck.view.mainview
 	import org.bigbluebutton.clientcheck.model.test.DownloadBandwidthTest;
 	import org.bigbluebutton.clientcheck.model.test.FlashVersionTest;
 	import org.bigbluebutton.clientcheck.model.test.IsPepperFlashTest;
-	import org.bigbluebutton.clientcheck.model.test.JavaEnabledTest;
 	import org.bigbluebutton.clientcheck.model.test.LanguageTest;
 	import org.bigbluebutton.clientcheck.model.test.PingTest;
 	import org.bigbluebutton.clientcheck.model.test.PortTest;
@@ -122,7 +121,6 @@ package org.bigbluebutton.clientcheck.view.mainview
 			systemConfiguration.isPepperFlash.pepperFlashTestSuccessfullChangedSignal.add(isPepperFlashChangedHandler);
 			systemConfiguration.cookieEnabled.cookieEnabledTestSuccessfullChangedSignal.add(cookieEnabledChangedHandler);
 			systemConfiguration.language.languageTestSuccessfullChangedSignal.add(languageChangedHandler);
-			systemConfiguration.javaEnabled.javaEnabledTestSuccessfullChangedSignal.add(javaEnabledChangedHandler);
 			systemConfiguration.isWebRTCSupported.webRTCSupportedTestSuccessfullChangedSignal.add(isWebRTCSupportedChangedHandler);
 			systemConfiguration.webRTCEchoTest.webRTCEchoTestSuccessfullChangedSignal.add(webRTCEchoTestChangedHandler);
 			systemConfiguration.webRTCSocketTest.webRTCSocketTestSuccessfullChangedSignal.add(webRTCSocketTestChangedHandler);
@@ -151,7 +149,6 @@ package org.bigbluebutton.clientcheck.view.mainview
 			dp.addData({Item: DownloadBandwidthTest.DOWNLOAD_SPEED, Result: null}, StatusENUM.LOADING);
 			dp.addData({Item: FlashVersionTest.FLASH_VERSION, Result: null}, StatusENUM.LOADING);
 			dp.addData({Item: IsPepperFlashTest.PEPPER_FLASH, Result: null}, StatusENUM.LOADING);
-			dp.addData({Item: JavaEnabledTest.JAVA_ENABLED, Result: null}, StatusENUM.LOADING);
 			dp.addData({Item: LanguageTest.LANGUAGE, Result: null}, StatusENUM.LOADING);
 			dp.addData({Item: PingTest.PING, Result: null}, StatusENUM.LOADING);
 			dp.addData({Item: ScreenSizeTest.SCREEN_SIZE, Result: null}, StatusENUM.LOADING);
@@ -275,12 +272,6 @@ package org.bigbluebutton.clientcheck.view.mainview
 			dp.updateData({Item: LanguageTest.LANGUAGE, Result: systemConfiguration.language.testResult}, status);
 		}
 
-		private function javaEnabledChangedHandler():void
-		{
-			var status:Object = (systemConfiguration.javaEnabled.testSuccessfull == true) ? StatusENUM.SUCCEED : StatusENUM.WARNING;
-			dp.updateData({Item: JavaEnabledTest.JAVA_ENABLED, Result: systemConfiguration.javaEnabled.testResult}, status);
-		}
-
 		private function isWebRTCSupportedChangedHandler():void
 		{
 			var status:Object = (systemConfiguration.isWebRTCSupported.testSuccessfull == true) ? StatusENUM.SUCCEED : StatusENUM.FAILED;
@@ -350,7 +341,6 @@ package org.bigbluebutton.clientcheck.view.mainview
 			systemConfiguration.webRTCEchoTest.webRTCEchoTestSuccessfullChangedSignal.remove(webRTCEchoTestChangedHandler);
 			systemConfiguration.webRTCSocketTest.webRTCSocketTestSuccessfullChangedSignal.remove(webRTCSocketTestChangedHandler);
 			systemConfiguration.language.languageTestSuccessfullChangedSignal.remove(languageChangedHandler);
-			systemConfiguration.javaEnabled.javaEnabledTestSuccessfullChangedSignal.remove(javaEnabledChangedHandler);
 			systemConfiguration.isWebRTCSupported.webRTCSupportedTestSuccessfullChangedSignal.remove(isWebRTCSupportedChangedHandler);
 			systemConfiguration.downloadBandwidthTest.downloadSpeedTestSuccessfullChangedSignal.remove(downloadSpeedTestChangedHandler);
 			systemConfiguration.uploadBandwidthTest.uploadSpeedTestSuccessfullChangedSignal.remove(uploadSpeedTestChangedHandler);
diff --git a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala
index 4dab761447eb7c0171d69167f8d66ce04b2573eb..7d583efb6d2b2de43ce30a0ce1ec2942a3749ef1 100755
--- a/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala
+++ b/bbb-common-message/src/main/scala/org/bigbluebutton/common2/msgs/SystemMsgs.scala
@@ -123,3 +123,15 @@ object CheckAlivePongSysMsg { val NAME = "CheckAlivePongSysMsg" }
 case class CheckAlivePongSysMsg(header: BbbCoreBaseHeader,
                                 body: CheckAlivePongSysMsgBody) extends BbbCoreMsg
 case class CheckAlivePongSysMsgBody(system: String, timestamp: Long)
+
+object ValidateConnAuthTokenSysMsg { val NAME = "ValidateConnAuthTokenSysMsg" }
+case class ValidateConnAuthTokenSysMsg(header: BbbCoreBaseHeader,
+                                       body: ValidateConnAuthTokenSysMsgBody) extends BbbCoreMsg
+case class ValidateConnAuthTokenSysMsgBody(meetingId: String, userId: String, authToken: String,
+                                           connId: String, app: String)
+
+object ValidateConnAuthTokenSysRespMsg { val NAME = "ValidateConnAuthTokenSysRespMsg" }
+case class ValidateConnAuthTokenSysRespMsg(header: BbbCoreHeaderWithMeetingId,
+                                           body: ValidateConnAuthTokenSysRespMsgBody) extends BbbCoreMsg
+case class ValidateConnAuthTokenSysRespMsgBody(meetingId: String, userId: String,
+                                               connId: String, authzed: Boolean, app: String)
diff --git a/bbb-screenshare/app/jws/lib/javacv-screenshare-0.0.1.jar b/bbb-screenshare/app/jws/lib/javacv-screenshare-0.0.1.jar
index 90fd2843fd81898e0bf1c2b82afa268d1847ca72..4dc89b841a7761594c4d0950d46d4159c253dca0 100755
Binary files a/bbb-screenshare/app/jws/lib/javacv-screenshare-0.0.1.jar and b/bbb-screenshare/app/jws/lib/javacv-screenshare-0.0.1.jar differ
diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/IScreenShareApplication.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/IScreenShareApplication.java
index a99e0e9aafec28fe8d57c34a71ca6fd60421538d..78728cd6fbafbf844cc59865a8bfbe852b32ccfe 100755
--- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/IScreenShareApplication.java
+++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/IScreenShareApplication.java
@@ -26,4 +26,5 @@ public interface IScreenShareApplication {
   void meetingHasEnded(String meetingId);
   void meetingCreated(String meetingId, Boolean record);
   void screenShareClientPongMessage(String meetingId, String userId, String streamId, Long timestamp);
+  void authorizeBroadcastStream(String meetingId, String streamId, String connId, String scope);
 }
diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/events/UnauthorizedBroadcastStreamEvent.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/events/UnauthorizedBroadcastStreamEvent.java
new file mode 100755
index 0000000000000000000000000000000000000000..7de53f296771129098b325933935dd71bd85545e
--- /dev/null
+++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/events/UnauthorizedBroadcastStreamEvent.java
@@ -0,0 +1,15 @@
+package org.bigbluebutton.app.screenshare.events;
+
+public class UnauthorizedBroadcastStreamEvent implements IEvent {
+	public final String meetingId;
+	public final String streamId;
+	public final String connId;
+	public final String scope;
+
+	public UnauthorizedBroadcastStreamEvent(String meetingId, String streamId, String connId, String scope) {
+		this.meetingId = meetingId;
+		this.streamId = streamId;
+		this.connId = connId;
+		this.scope = scope;
+	}
+}
diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/CloseConnectionMessage.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/CloseConnectionMessage.java
new file mode 100755
index 0000000000000000000000000000000000000000..dbcbd49dfbfbe265f0e4a10eaefb5803d9e4da15
--- /dev/null
+++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/CloseConnectionMessage.java
@@ -0,0 +1,16 @@
+package org.bigbluebutton.app.screenshare.red5;
+
+public class CloseConnectionMessage implements ClientMessage {
+
+	public final String meetingId;
+	public final String streamId;
+	public final String connId;
+	public final String scope;
+
+	public CloseConnectionMessage(String meetingId, String streamId, String connId, String scope) {
+		this.meetingId = meetingId;
+		this.streamId = streamId;
+		this.connId = connId;
+		this.scope = scope;
+	}
+}
diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/ConnectionInvokerService.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/ConnectionInvokerService.java
index 1b5db188969fec113f4f9a23b706e766795d8db7..12128c8a9114a525471e47af91b4b2aabb47327e 100755
--- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/ConnectionInvokerService.java
+++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/ConnectionInvokerService.java
@@ -18,11 +18,8 @@
  */
 package org.bigbluebutton.app.screenshare.red5;
 
-import java.util.Set;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.*;
 import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.concurrent.Executors;
 import java.util.concurrent.LinkedBlockingQueue;
@@ -36,6 +33,7 @@ import org.red5.server.api.so.ISharedObjectService;
 import org.red5.server.so.SharedObjectService;
 import org.red5.server.util.ScopeUtils;
 import org.slf4j.Logger;
+import com.google.gson.Gson;
 
 public class ConnectionInvokerService {
   private static Logger log = Red5LoggerFactory.getLogger(ConnectionInvokerService.class, "screenshare");
@@ -74,7 +72,7 @@ public class ConnectionInvokerService {
         }
       }
     };
-    exec.execute(sender);		
+    exec.execute(sender);
   }
 
   public void stop() {
@@ -96,8 +94,43 @@ public class ConnectionInvokerService {
       handlDisconnectClientMessage((DisconnectClientMessage) message);
     } else if (message instanceof DisconnectAllClientsMessage) {
       handleDisconnectAllClientsMessage((DisconnectAllClientsMessage) message);
+    } else if (message instanceof CloseConnectionMessage) {
+      handleCloseConnectionMessage((CloseConnectionMessage) message);
     }
-  }	
+  }
+
+  private void handleCloseConnectionMessage(CloseConnectionMessage msg) {
+		Map<String, Object> logData = new HashMap<String, Object>();
+		logData.put("meetingId", msg.meetingId);
+		logData.put("connId", msg.connId);
+		logData.put("streamId", msg.streamId);
+		logData.put("scope", msg.scope);
+		logData.put("event", "unauth_publish_stream_bbb_screenshare");
+		logData.put("description", "Unauthorized publish stream.");
+
+		Gson gson = new Gson();
+		String logStr =  gson.toJson(logData);
+		log.info(logStr);
+
+		IScope meetingScope = null;
+
+		if (bbbAppScope.getName().equals(msg.scope)) {
+			meetingScope = bbbAppScope;
+		} else {
+			meetingScope = getScope(msg.scope);
+		}
+
+		if (meetingScope != null) {
+			IConnection conn = getConnectionWithConnId(meetingScope, msg.connId);
+			if (conn != null) {
+				if (conn.isConnected()) {
+					log.info("Disconnecting connection. data={}", logStr);
+					conn.close();
+				}
+			}
+		}
+
+	}
 
   private void handleDisconnectAllClientsMessage(DisconnectAllClientsMessage msg) {
     IScope meetingScope = getScope(msg.getMeetingId());
@@ -123,9 +156,9 @@ public class ConnectionInvokerService {
           log.info("Disconnecting user=[{}] from meeting=[{}]", msg.getUserId(), msg.getMeetingId());
           conn.close();
         }
-      }				
-    }		
-  }	
+      }
+    }
+  }
 
   private void sendSharedObjectMessage(SharedObjectClientMessage msg) {
     System.out.println("*********** Request to send [" + msg.getMessageName() + "] using shared object.");
@@ -153,14 +186,14 @@ public class ConnectionInvokerService {
       public void run() {
         IScope meetingScope = getScope(msg.getMeetingID());
         if (meetingScope != null) {
-          log.debug("Found scope =[{}] for meeting=[{}]", meetingScope.getName(), msg.getMeetingID());
+          //log.debug("Found scope =[{}] for meeting=[{}]", meetingScope.getName(), msg.getMeetingID());
           IConnection conn = getConnection(meetingScope, msg.getUserID());
           if (conn != null) {
             if (conn.isConnected()) {
               List<Object> params = new ArrayList<Object>();
               params.add(msg.getMessageName());
               params.add(msg.getMessage());
-              log.debug("Sending message=[{}] to meeting=[{}]", msg.getMessageName(), msg.getMeetingID());
+              //log.debug("Sending message=[{}] to meeting=[{}]", msg.getMessageName(), msg.getMeetingID());
               ServiceUtils.invokeOnConnection(conn, "onMessageFromServer", params.toArray());
             } else {
               log.warn("Connection not connected for userid=[{}] in meeting=[{}]", msg.getUserID(), msg.getMeetingID());
@@ -191,6 +224,18 @@ public class ConnectionInvokerService {
     runExec.execute(sender);
   }
 
+	private IConnection getConnectionWithConnId(IScope scope, String connId) {
+		Set<IConnection> conns = scope.getClientConnections();
+		for (IConnection conn : conns) {
+			String connID = (String) conn.getSessionId();
+			if (connID != null && connID.equals(connId)) {
+				return conn;
+			}
+		}
+
+		return null;
+	}
+
   private IConnection getConnection(IScope scope, String userID) {
     Set<IConnection> conns = scope.getClientConnections();
     for (IConnection conn : conns) {
diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/EventListenerImp.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/EventListenerImp.java
index d862ee9d1edc2f080e6c288363fcba71d2e24052..eee8bc7272411dc163acd6332e480a05ba77ae8c 100755
--- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/EventListenerImp.java
+++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/EventListenerImp.java
@@ -27,10 +27,21 @@ public class EventListenerImp implements IEventListener {
         sendIsScreenSharingResponse((IsScreenSharingResponse) event);
     } else if (event instanceof ScreenShareClientPing) {
       sendScreenShareClientPing((ScreenShareClientPing) event);
+    } else if (event instanceof UnauthorizedBroadcastStreamEvent) {
+      sendUnauthorizedBroadcastStreamEvent((UnauthorizedBroadcastStreamEvent) event);
     }
 
   }
 
+  private void sendUnauthorizedBroadcastStreamEvent(UnauthorizedBroadcastStreamEvent event) {
+		if (log.isDebugEnabled()) {
+			log.debug("Sending CloseConnectionMessage to client, meetingId=" + event.meetingId + " streamId=" + event.streamId);
+		}
+
+		CloseConnectionMessage msg = new CloseConnectionMessage(event.meetingId, event.streamId, event.connId, event.scope);
+		sender.sendMessage(msg);
+	}
+
   private void sendScreenShareClientPing(ScreenShareClientPing event) {
     Map<String, Object> data = new HashMap<String, Object>();
     data.put("meetingId", event.meetingId);
diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppAdapter.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppAdapter.java
index ac7e46022893738bd814e29231c66dfb190c3844..47c47a57564cfb50d0b0a073163d98edd2af9d60 100755
--- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppAdapter.java
+++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppAdapter.java
@@ -140,6 +140,10 @@ public class Red5AppAdapter extends MultiThreadedApplicationAdapter {
     super.streamBroadcastStart(stream);
 
     log.info("streamBroadcastStart " + stream.getPublishedName() + "]");
+
+    String connId = conn.getSessionId();
+    String scopeName = stream.getScope().getName();
+
     String streamId = stream.getPublishedName();
     Matcher matcher = STREAM_ID_PATTERN.matcher(stream.getPublishedName());
     if (matcher.matches()) {
@@ -147,7 +151,11 @@ public class Red5AppAdapter extends MultiThreadedApplicationAdapter {
         String url = streamBaseUrl + "/" + meetingId + "/" + streamId;
         app.streamStarted(meetingId, streamId, url);
 
-	    boolean recordVideoStream = app.recordStream(meetingId, streamId);
+
+
+      app.authorizeBroadcastStream(meetingId, streamId, connId, scopeName);
+
+        boolean recordVideoStream = app.recordStream(meetingId, streamId);
 	    if (recordVideoStream) {
 	      recordStream(stream);
 	      ScreenshareStreamListener listener = new ScreenshareStreamListener(recordingService, recordingDirectory);
@@ -167,6 +175,7 @@ public class Red5AppAdapter extends MultiThreadedApplicationAdapter {
       log.info("ScreenShare broadcast started: data={}", logStr);
     } else {
     	log.error("Invalid streamid format [{}]", streamId);
+    	conn.close();
     }
   }
 
diff --git a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppService.java b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppService.java
index 240b8ceb679961c9cdbdc196a695317d5af2fa99..445078b1f5b9365f3f65eb92c767f14607e988b1 100755
--- a/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppService.java
+++ b/bbb-screenshare/app/src/main/java/org/bigbluebutton/app/screenshare/red5/Red5AppService.java
@@ -157,7 +157,14 @@ public class Red5AppService {
   public void screenShareClientPongMessage(Map<String, Object> msg) {
     String meetingId = Red5.getConnectionLocal().getScope().getName();
     String streamId = (String) msg.get("streamId");
-    Double timestamp = (Double) msg.get("timestamp");
+    Double timestamp;
+    if (msg.get("timestamp") instanceof Integer) {
+      Integer tempTimestamp = (Integer) msg.get("timestamp");
+      timestamp = tempTimestamp.doubleValue();
+    } else {
+      timestamp = (Double) msg.get("timestamp");
+    }
+
     String userId = (String) Red5.getConnectionLocal().getAttribute("USERID");
 
     //log.debug("Received screenShareClientPongMessage for meeting=[{}]", meetingId);
diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/ScreenShareApplication.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/ScreenShareApplication.scala
index e28ad314e7543101c739ea2f6d17b29f7352ad3d..f1ae74490c124a519bc8693ba71eea12e352a9ac 100755
--- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/ScreenShareApplication.scala
+++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/ScreenShareApplication.scala
@@ -219,6 +219,11 @@ class ScreenShareApplication(val bus: IEventsMessageBus, val jnlpFile: String,
     screenShareManager ! new StreamStartedMessage(meetingId, streamId, url)
   }
 
+  def authorizeBroadcastStream(meetingId: String, streamId: String, connId: String, scope: String): Unit = {
+
+		screenShareManager ! new AuthorizeBroadcastStreamMessage(meetingId, streamId, connId, scope)
+	}
+
   def streamStopped(meetingId: String, streamId: String) {
 //    if (logger.isDebugEnabled()) {
 //      logger.debug("Received stream stopped on meeting=[" + meetingId
diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/Screenshare.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/Screenshare.scala
index 8f73aae38414cb6183368d2a1e5a283ffb359b0d..6940a8b7c838df4fd6bad124b928da34cdb1c635 100755
--- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/Screenshare.scala
+++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/Screenshare.scala
@@ -90,8 +90,6 @@ class Screenshare(val sessionManager: ScreenshareManager,
 
   //private val sessions = new HashMap[String, ActiveSession]
 
-  private var activeSession:Option[ActiveSession] = None
-
   private val START = "START"
   private val PAUSE = "PAUSE"
   private val RUNNING = "RUNNING"
@@ -105,8 +103,14 @@ class Screenshare(val sessionManager: ScreenshareManager,
   // start-pause-stop
   private var streamIdCount = 0
 
+	// A screen sharing session that has lifecyle of start, pause, resume, and stop.
   private var screenShareSession: Option[String] = None
-  private var currentPresenterId: Option[String]  = None
+
+	// A broadcast stream session withing the screen share session.
+	private var activeSession:Option[ActiveSession] = None
+
+
+	private var currentPresenterId: Option[String]  = None
 
   private var width: Option[Int] = None
   private var height: Option[Int] = None
@@ -168,6 +172,8 @@ class Screenshare(val sessionManager: ScreenshareManager,
     case msg: MeetingEnded             => handleMeetingHasEnded(msg)
     case msg: SessionAuditMessage => handleSessionAuditMessage(msg)
     case msg: ClientPongMessage    => handleClientPongMessage(msg)
+    case msg: AuthorizeBroadcastStreamMessage => handleAuthorizeBroadcastStreamMessage(msg)
+
     case m: Any => log.warning("Session: Unknown message [{}]", m)
   }
 
@@ -284,9 +290,7 @@ class Screenshare(val sessionManager: ScreenshareManager,
       if (as.token == msg.token) {
         sender ! new ScreenShareInfoRequestReply(msg.meetingId, as.streamId, sss, as.tunnel)
       }
-
     }
-
   }
   
   private def handleIsStreamRecorded(msg: IsStreamRecorded) {
@@ -385,6 +389,21 @@ class Screenshare(val sessionManager: ScreenshareManager,
     }
   }
 
+  private def handleAuthorizeBroadcastStreamMessage(msg: AuthorizeBroadcastStreamMessage): Unit = {
+		if (log.isDebugEnabled) {
+			log.debug("handleAuthorizeBroadcastStreamMessage meetingId=" + msg.meetingId +
+			" streamId=" + msg.streamId + " connId=" + msg.connId + " scope=" + msg.scope)
+		}
+
+		activeSession match {
+			case Some(as) =>
+				if (as.streamId != msg.streamId) {
+					bus.send(new UnauthorizedBroadcastStreamEvent(msg.meetingId, msg.streamId, msg.connId, msg.scope))
+				}
+				case None => bus.send(new UnauthorizedBroadcastStreamEvent(msg.meetingId, msg.streamId, msg.connId, msg.scope))
+		}
+  }
+
   private def resetScreenShareSession() = {
     width = None
     height = None
diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/ScreenshareManager.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/ScreenshareManager.scala
index 5fbe4f31a5e9d4fcec37ed03c89c5d31e7975eea..e0c4229b6948b0ea1552e7252077f1645f803635 100755
--- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/ScreenshareManager.scala
+++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/ScreenshareManager.scala
@@ -18,11 +18,11 @@
  */
 package org.bigbluebutton.app.screenshare.server.sessions
 
-import akka.actor.{Actor, ActorLogging, ActorSystem, Props}
 import org.bigbluebutton.app.screenshare.StreamInfo
 import org.bigbluebutton.app.screenshare.server.sessions.Session.StopSession
+import akka.actor.{Actor, ActorLogging, ActorSystem, Props}
 import scala.collection.mutable.HashMap
-import org.bigbluebutton.app.screenshare.events.{IEventsMessageBus, IsScreenSharingResponse, ScreenShareRequestTokenFailedResponse}
+import org.bigbluebutton.app.screenshare.events.{IEventsMessageBus, IsScreenSharingResponse, ScreenShareRequestTokenFailedResponse, UnauthorizedBroadcastStreamEvent}
 import org.bigbluebutton.app.screenshare.server.sessions.messages._
 
 object ScreenshareManager {
@@ -57,6 +57,7 @@ class ScreenshareManager(val aSystem: ActorSystem, val bus: IEventsMessageBus)
     case msg: MeetingEnded             => handleMeetingHasEnded(msg)
     case msg: MeetingCreated              => handleMeetingCreated(msg)
     case msg: ClientPongMessage           => handleClientPongMessage(msg)
+    case msg: AuthorizeBroadcastStreamMessage => handleAuthorizeBroadcastStreamMessage(msg)
 
     case msg: Any => log.warning("Unknown message " + msg)
   }
@@ -205,6 +206,20 @@ class ScreenshareManager(val aSystem: ActorSystem, val bus: IEventsMessageBus)
     }
   }
 
+  private def handleAuthorizeBroadcastStreamMessage(msg: AuthorizeBroadcastStreamMessage): Unit = {
+		if (log.isDebugEnabled) {
+			log.debug("handleAuthorizeBroadcastStreamMessage meetingId=" + msg.meetingId +
+			" streamId=" + msg.streamId + " connId=" + msg.connId + " scope=" + msg.scope)
+		}
+
+		screenshares.get(msg.meetingId) match {
+			case Some(ss) =>
+				ss.actorRef forward msg
+			case None =>
+				bus.send(new UnauthorizedBroadcastStreamEvent(msg.meetingId, msg.streamId, msg.connId, msg.scope))
+		}
+  }
+
   private def handleStopShareRequestMessage(msg: StopShareRequestMessage) {
     if (log.isDebugEnabled) {
       log.debug("Received stop share request message for meeting=[" + msg.meetingId + "]")
diff --git a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/messages/IMessage.scala b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/messages/IMessage.scala
index 9819d807237dd969a5e531f3ee2dd47a9c227611..35025736e92045b31c88e3f08d8b5b38639ea763 100755
--- a/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/messages/IMessage.scala
+++ b/bbb-screenshare/app/src/main/scala/org/bigbluebutton/app/screenshare/server/sessions/messages/IMessage.scala
@@ -14,6 +14,8 @@ case class StopShareRequestMessage(meetingId: String, streamId: String)
 
 case class StreamStartedMessage(meetingId: String, streamId: String, url: String)
 
+case class AuthorizeBroadcastStreamMessage(meetingId: String, streamId: String, connId: String, scope: String)
+
 case class StreamStoppedMessage(meetingId: String, streamId: String)
 
 case class SharingStartedMessage(meetingId: String, streamId: String, width: Int, height: Int)
diff --git a/bbb-screenshare/jws/webstart/src/main/java/org/bigbluebutton/screenshare/client/javacv/FfmpegScreenshare.java b/bbb-screenshare/jws/webstart/src/main/java/org/bigbluebutton/screenshare/client/javacv/FfmpegScreenshare.java
index b98c0403e900fc089656f2ca2c4f85998fedf04f..e2d9f35a717962127f12873ec7dd708247d459a9 100755
--- a/bbb-screenshare/jws/webstart/src/main/java/org/bigbluebutton/screenshare/client/javacv/FfmpegScreenshare.java
+++ b/bbb-screenshare/jws/webstart/src/main/java/org/bigbluebutton/screenshare/client/javacv/FfmpegScreenshare.java
@@ -7,6 +7,8 @@ import static org.bytedeco.javacpp.avutil.AV_PIX_FMT_RGB0;
 import static org.bytedeco.javacpp.avutil.AV_PIX_FMT_YUV420P;
 import java.awt.AWTException;
 import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.concurrent.Executor;
@@ -114,6 +116,7 @@ public class FfmpegScreenshare {
       mainRecorder.start();
     } catch (Exception e) {
       System.out.println("Exception starting recorder. \n" + e.toString());
+      System.out.println(printStacktrace(e));
       listener.networkConnectionException(ExitCode.INTERNAL_ERROR, null);
     }
   }
@@ -166,6 +169,7 @@ public class FfmpegScreenshare {
       }
     } catch (Exception e1) {
       System.out.println("Exception grabbing image");
+      System.out.println(printStacktrace(e1));
       listener.networkConnectionException(ExitCode.INTERNAL_ERROR, null);
     }
 
@@ -476,6 +480,17 @@ private  FFmpegFrameRecorder setupMacOsXRecorder(String url, int width, int heig
     macGrabber.setOption("capture_mouse_clicks", "1");
     return macGrabber;
   }
+  
+  
+  private String printStacktrace(Exception exception) {
+	  StringWriter writer = new StringWriter();
+	  PrintWriter printWriter = new PrintWriter( writer );
+	  exception.printStackTrace( printWriter );
+	  printWriter.flush();
+
+	  String stackTrace = writer.toString();
+	  return stackTrace;
+  }
 
 }
 
diff --git a/bbb-video/build.gradle b/bbb-video/build.gradle
index eb7e4a69bf8e2e41dfce1b8ab081c67945cea78b..a6237c6ded6e95e9d81ab3185a543730adec9ddb 100755
--- a/bbb-video/build.gradle
+++ b/bbb-video/build.gradle
@@ -17,7 +17,7 @@ repositories {
   mavenLocal()
 }
 
-dependencies {	 
+dependencies {
   // Servlet
   providedCompile 'javax.servlet:servlet-api:2.5@jar'
 
@@ -26,17 +26,16 @@ dependencies {
   providedCompile 'org.apache.mina:mina-integration-beans:2.0.15@jar'
   providedCompile 'org.apache.mina:mina-integration-jmx:2.0.14@jar'
 
-  // Spring 
-  providedCompile 'org.springframework:spring-web:4.3.3.RELEASE@jar' 
+  // Spring
+  providedCompile 'org.springframework:spring-web:4.3.3.RELEASE@jar'
   providedCompile  'org.springframework:spring-beans:4.3.3.RELEASE@jar'
   providedCompile 'org.springframework:spring-context:4.3.3.RELEASE@jar'
   providedCompile 'org.springframework:spring-core:4.3.3.RELEASE@jar'
-	
-  // Red5
+
   providedCompile 'org.red5:red5-server:1.0.8-M13@jar'
   providedCompile 'org.red5:red5-server-common:1.0.8-M13@jar'
   providedCompile 'org.red5:red5-io:1.0.8-M13@jar'
-  
+
   // Logging
   providedCompile 'ch.qos.logback:logback-core:1.1.7@jar'
   providedCompile 'ch.qos.logback:logback-classic:1.1.7@jar'
@@ -44,24 +43,24 @@ dependencies {
   providedCompile 'org.slf4j:jcl-over-slf4j:1.7.21@jar'
   providedCompile 'org.slf4j:jul-to-slf4j:1.7.21@jar'
   providedCompile 'org.slf4j:slf4j-api:1.7.21@jar'
-	
+
   // Needed for the JVM shutdown hook but needs to be put into red5/lib dir.
   // Otherwise we get exception on aop utils class not found.
   providedCompile 'org.springframework:spring-aop:4.3.3.RELEASE@jar'
   compile 'aopalliance:aopalliance:1.0@jar'
-	
-  // Java Concurrency In Practice
-  providedCompile 'net.jcip:jcip-annotations:1.0@jar'
-        
+
   // Testing
-  //    compile 'org.testng:testng:5.8@jar' 
   compile 'org.easymock:easymock:2.4@jar'
-  
+
+  // Testing
+  testRuntime 'org.easymock:easymock:2.4@jar'
+
   //redis
-  compile 'redis.clients:jedis:2.0.0'
-  compile 'commons-pool:commons-pool:1.5.6'
+  compile 'redis.clients:jedis:2.9.0'
+  compile 'org.apache.commons:commons-pool2:2.3'
   compile 'com.google.code.gson:gson:2.5'
-	
+
+  compile 'org.apache.commons:commons-lang3:3.5'
   compile 'org.bigbluebutton:bbb-common-message_2.12:0.0.19-SNAPSHOT'
 }
 
diff --git a/bbb-video/src/main/java/org/bigbluebutton/app/video/ConnectionInvokerService.java b/bbb-video/src/main/java/org/bigbluebutton/app/video/ConnectionInvokerService.java
new file mode 100755
index 0000000000000000000000000000000000000000..1a06777f1c35871fbc38c422562d816ed1e29967
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/app/video/ConnectionInvokerService.java
@@ -0,0 +1,168 @@
+/**
+* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+* 
+* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
+*
+* This program is free software; you can redistribute it and/or modify it under the
+* terms of the GNU Lesser General Public License as published by the Free Software
+* Foundation; either version 3.0 of the License, or (at your option) any later
+* version.
+* 
+* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License along
+* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package org.bigbluebutton.app.video;
+
+import com.google.gson.Gson;
+import org.bigbluebutton.red5.pubsub.message.ClientMessage;
+import org.bigbluebutton.red5.pubsub.message.ValidateConnTokenRespMsg;
+import org.red5.logging.Red5LoggerFactory;
+import org.red5.server.api.IConnection;
+import org.red5.server.api.scope.IScope;
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.*;
+
+public class ConnectionInvokerService {
+  private static Logger log = Red5LoggerFactory.getLogger(ConnectionInvokerService.class, "video");
+
+  private final String CONN = "RED5-";
+  private static final int NTHREADS = 1;
+  private static final Executor exec = Executors.newFixedThreadPool(NTHREADS);
+  private static final ExecutorService runExec = Executors.newFixedThreadPool(3);
+
+  private BlockingQueue<ClientMessage> messages;
+  private volatile boolean sendMessages = false;
+  private IScope bbbAppScope;
+
+  private final long SEND_TIMEOUT = 5000000000L; // 5s
+
+  private Long lastMsgLengthLog = System.currentTimeMillis();
+
+  public ConnectionInvokerService() {
+    messages = new LinkedBlockingQueue<ClientMessage>();
+  }
+
+  public void setAppScope(IScope scope) {
+    bbbAppScope = scope;
+  }
+
+  public void start() {
+    sendMessages = true;
+    Runnable sender = new Runnable() {
+      public void run() {
+        while (sendMessages) {
+          ClientMessage message;
+          try {
+            if (System.currentTimeMillis() - lastMsgLengthLog > 60000) {
+              lastMsgLengthLog = System.currentTimeMillis();
+              log.info("Message queue length = " + messages.size());
+            }
+            message = messages.take();
+            if (log.isTraceEnabled()) {
+              log.trace("Took org.bigbluebutton.red5.pubsub.message from queue: " + message.getMessageName());
+            }
+            sendMessageToClient(message);
+            if (log.isTraceEnabled()) {
+              log.trace("Sent org.bigbluebutton.red5.pubsub.message to client: " + message.getMessageName());
+            }
+          } catch (Exception e) {
+            Marker sendingException = MarkerFactory.getMarker("SENDING_EXCEPTION");
+            log.error(sendingException, "Exception while sending org.bigbluebutton.red5.pubsub.message to client.", e);
+          }
+        }
+      }
+    };
+    exec.execute(sender);
+  }
+
+  public void stop() {
+    sendMessages = false;
+    runExec.shutdown();
+  }
+
+  public void sendMessage(final ClientMessage message) {
+    if (log.isTraceEnabled()) {
+      log.trace("Queue org.bigbluebutton.red5.pubsub.message: " + message.getMessageName());
+    }
+    messages.offer(message);
+  }
+
+  private void sendMessageToClient(ClientMessage message) {
+    if (message instanceof ValidateConnTokenRespMsg) {
+      handleValidateConnTokenRespMsg((ValidateConnTokenRespMsg) message);
+    }
+  }
+
+  private void handleValidateConnTokenRespMsg(ValidateConnTokenRespMsg msg) {
+    if (log.isTraceEnabled()) {
+      log.trace("Handle direct org.bigbluebutton.red5.pubsub.message: " + msg.getMessageName() + " conn=" + msg.connId);
+    }
+
+    IScope meetingScope = getScope(msg.meetingId);
+    if (meetingScope != null) {
+      String userId = msg.userId;
+      IConnection conn = getConnection(meetingScope, userId);
+      if (conn != null) {
+        if (conn.isConnected() && !msg.authzed) {
+          Map<String, Object> logData = new HashMap<String, Object>();
+          logData.put("meetingId", msg.meetingId);
+          logData.put("userId", userId);
+          logData.put("authzed", msg.authzed);
+          logData.put("app", "video");
+          logData.put("event", "close_unauthorized_connection");
+          logData.put("description", "Closing unauthorized connection.");
+
+          Gson gson = new Gson();
+          String logStr = gson.toJson(logData);
+
+          log.info("Closing unauthorized connection: data={}", logStr);
+          conn.close();
+        }
+      }
+    }
+  }
+
+  private IConnection getConnectionWithConnId(IScope scope, String connId) {
+    for (IConnection conn : scope.getClientConnections()) {
+      String connID = (String) conn.getSessionId();
+      if (connID != null && connID.equals(connId)) {
+        return conn;
+      }
+    }
+
+    log.warn("Failed to get connection for connId = " + connId);
+    return null;
+  }
+
+  private IConnection getConnection(IScope scope, String userId) {
+    for (IConnection conn : scope.getClientConnections()) {
+      String connID = (String) conn.getAttribute("USERID");
+      if (connID != null && connID.equals(userId)) {
+        return conn;
+      }
+    }
+
+    log.warn("Failed to get connection for userId = " + userId);
+    return null;
+  }
+
+  public IScope getScope(String meetingID) {
+    if (bbbAppScope != null) {
+      return bbbAppScope.getContext().resolveScope("video");
+    } else {
+      log.error("BigBlueButton Scope not initialized. No messages are going to the Flash client!");
+    }
+    
+    return null;
+  }
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/app/video/UserConnectionMapper.java b/bbb-video/src/main/java/org/bigbluebutton/app/video/UserConnectionMapper.java
new file mode 100755
index 0000000000000000000000000000000000000000..b2f2b143cce648be5155b3a87736a41615d560a8
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/app/video/UserConnectionMapper.java
@@ -0,0 +1,56 @@
+package org.bigbluebutton.app.video;
+
+import org.red5.server.api.IConnection;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+/**
+ * This class maintains the connections mapping of a user.
+ * This tracks the connections for a user to manage auto-reconnects.
+ * @author ralam
+ *
+ */
+public class UserConnectionMapper {
+
+    private ConcurrentMap<String, UserConnection> users = new ConcurrentHashMap<String, UserConnection>(8, 0.9f, 1);;
+
+    public synchronized Collection<UserConnection> getConnections() {
+        return users.values();
+    }
+
+    /**
+     * Adds a connection for a user.
+     * @param connId
+     */
+    public synchronized void addUserConnection(String connId, IConnection connection) {
+        UserConnection user = new UserConnection(connId, System.currentTimeMillis(), connection);
+        users.put(connId, user);
+    }
+
+    /**
+     * Removed a connection for a user. Returns true if the user doesn't have any
+     * connection left and thus can be removed.
+     * @param connId
+     * @return boolean - no more connections
+     */
+    public synchronized UserConnection userDisconnected(String connId) {
+        return users.remove(connId);
+    }
+
+    public class UserConnection {
+        public final String connId;
+        public final Long connectedOn;
+        public final IConnection connection;
+
+        public UserConnection(String connId, Long connectedOn, IConnection connection) {
+            this.connId = connId;
+            this.connectedOn = connectedOn;
+            this.connection = connection;
+        }
+
+    }
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java
index 89957e1d1ddd85f4042e5ae77a52071ce0cc0f66..60c3050a0e1b22e68dcc2106c0551cffde8fc87a 100755
--- a/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java
+++ b/bbb-video/src/main/java/org/bigbluebutton/app/video/VideoApplication.java
@@ -18,11 +18,13 @@
 */
 package org.bigbluebutton.app.video;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
 import java.util.concurrent.TimeUnit;
-
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
 import org.bigbluebutton.app.video.converter.H263Converter;
 import org.bigbluebutton.app.video.converter.VideoRotator;
 import org.bigbluebutton.red5.pubsub.MessagePublisher;
@@ -33,13 +35,14 @@ import org.red5.server.api.Red5;
 import org.red5.server.api.scope.IScope;
 import org.red5.server.api.stream.IBroadcastStream;
 import org.red5.server.api.stream.IPlayItem;
-import org.red5.server.api.stream.IServerStream;
 import org.red5.server.api.stream.IStreamListener;
 import org.red5.server.api.stream.ISubscriberStream;
 import org.red5.server.stream.ClientBroadcastStream;
 import org.slf4j.Logger;
 
 import com.google.gson.Gson;
+import org.springframework.util.StringUtils;
+
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -61,15 +64,56 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
 
 	private final Map<String, VideoRotator> videoRotators = new HashMap<String, VideoRotator>();
 
+	private ConnectionInvokerService connInvokerService;
+
+    private final UserConnectionMapper userConnections = new UserConnectionMapper();
+
     @Override
 	public boolean appStart(IScope app) {
 	    super.appStart(app);
 		log.info("BBB Video appStart");
+		connInvokerService.setAppScope(app);
+
+        portTestConnAudit();
+
 		return true;
 	}
 
+    private void portTestConnAudit() {
+        Runnable portConnAuditTask = () -> portTestConnAuditHelper();
+
+        ScheduledExecutorService executor = Executors.newScheduledThreadPool(1);
+        executor.scheduleAtFixedRate(portConnAuditTask, 0, 5, TimeUnit.SECONDS);
+    }
+
+    private IConnection getConnectionWithConnId(IScope scope, String connId) {
+        for (IConnection conn : scope.getClientConnections()) {
+            String connID = (String) conn.getSessionId();
+            if (connID != null && connID.equals(connId)) {
+                return conn;
+            }
+        }
+
+        log.warn("Failed to get connection for connId = " + connId);
+        return null;
+    }
+
+    private void portTestConnAuditHelper() {
+
+        Collection<UserConnectionMapper.UserConnection> usersConns = userConnections.getConnections();
+        for (UserConnectionMapper.UserConnection uconn : usersConns) {
+            log.debug("Checking port test connection {}", uconn.connId);
+            if (System.currentTimeMillis() - uconn.connectedOn > 10000) {
+                log.debug("Closing port test connection {}", uconn.connId);
+                uconn.connection.close();
+            }
+        }
+
+    }
+
     @Override
 	public boolean appConnect(IConnection conn, Object[] params) {
+		log.info("BBB Video appConnect");
 		return super.appConnect(conn, params);
 	}
 
@@ -77,69 +121,113 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
 	public boolean roomConnect(IConnection connection, Object[] params) {
 		log.info("BBB Video roomConnect");
 
-		if(params.length == 0) {
-			params = new Object[2];
-			params[0] = "UNKNOWN-MEETING-ID";
-			params[1] = "UNKNOWN-USER-ID";
+		if(params.length != 3) {
+			log.error("Invalid number of parameters. param length=" + params.length);
+			return false;
 		}
 
 		String meetingId = ((String) params[0]).toString();
 		String userId = ((String) params[1]).toString();
+		String authToken = ((String) params[2]).toString();
+
+
+      if (StringUtils.isEmpty(meetingId)) {
+          log.error("Invalid meetingId parameter.");
+          return false;
+      }
+
+      if (StringUtils.isEmpty(userId)) {
+          log.error("Invalid userId parameter.");
+          return false;
+      }
+
+      if (StringUtils.isEmpty(authToken)) {
+          log.error("Invalid authToken parameter.");
+          return false;
+      }
 
 		Red5.getConnectionLocal().setAttribute("MEETING_ID", meetingId);
 		Red5.getConnectionLocal().setAttribute("USERID", userId);
+	  	Red5.getConnectionLocal().setAttribute("AUTH_TOKEN", authToken);
 
 		String connType = getConnectionType(Red5.getConnectionLocal().getType());
 		String sessionId = Red5.getConnectionLocal().getSessionId();
-		/**
-		* Find if there are any other connections owned by this user. If we find one,
-		* that means that the connection is old and the user reconnected. Clear the
-		* userId attribute so that messages would not be sent in the defunct connection.
-		*/
-		Set<IConnection> conns = Red5.getConnectionLocal().getScope().getClientConnections();
-		for (IConnection conn : conns) {
-			String connUserId = (String) conn.getAttribute("USERID");
-			String connSessionId = conn.getSessionId();
-			String clientId = conn.getClient().getId();
-			String remoteHost = conn.getRemoteAddress();
-			int remotePort = conn.getRemotePort();
-			if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) {
-				conn.removeAttribute("USERID");
-				Map<String, Object> logData = new HashMap<String, Object>();
-				logData.put("meetingId", meetingId);
-				logData.put("userId", userId);
-				logData.put("oldConnId", connSessionId);
-				logData.put("newConnId", sessionId);
-				logData.put("clientId", clientId);
-				logData.put("remoteAddress", remoteHost + ":" + remotePort);
-				logData.put("event", "removing_defunct_connection");
-				logData.put("description", "Removing defunct connection BBB Video.");
-
-				Gson gson = new Gson();
-				String logStr =  gson.toJson(logData);
-
-				log.info("Removing defunct connection: data={}", logStr);
-			  }
-		  }
-
-	  String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
-	  int remotePort = Red5.getConnectionLocal().getRemotePort();
-	  String clientId = Red5.getConnectionLocal().getClient().getId();
-
-		Map<String, Object> logData = new HashMap<String, Object>();
-		logData.put("meetingId", meetingId);
-		logData.put("userId", userId);
-		logData.put("connType", connType);
-		logData.put("connId", sessionId);
-	  logData.put("clientId", clientId);
-	  logData.put("remoteAddress", remoteHost + ":" + remotePort);
-		logData.put("event", "user_joining_bbb_video");
-		logData.put("description", "User joining BBB Video.");
-
-		Gson gson = new Gson();
-		String logStr =  gson.toJson(logData);
-
-		log.info("User joining bbb-video: data={}", logStr);
+
+		if (userId.startsWith("portTestDummyUserId")) {
+            userConnections.addUserConnection(sessionId, connection);
+
+            String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
+            int remotePort = Red5.getConnectionLocal().getRemotePort();
+            String clientId = Red5.getConnectionLocal().getClient().getId();
+
+            Map<String, Object> logData = new HashMap<String, Object>();
+            logData.put("meetingId", meetingId);
+            logData.put("userId", userId);
+            logData.put("connType", connType);
+            logData.put("connId", sessionId);
+            logData.put("clientId", clientId);
+            logData.put("remoteAddress", remoteHost + ":" + remotePort);
+            logData.put("event", "port_test_connection_bbb_video");
+            logData.put("description", "Keeping track of port test connection.");
+
+            Gson gson = new Gson();
+            String logStr =  gson.toJson(logData);
+
+            log.info(logStr);
+        } else {
+            log.info("BBB Video validateConnAuthToken");
+            publisher.validateConnAuthToken(meetingId, userId, authToken, sessionId);
+
+            /**
+             * Find if there are any other connections owned by this user. If we find one,
+             * that means that the connection is old and the user reconnected. Clear the
+             * userId attribute so that messages would not be sent in the defunct connection.
+             */
+            Set<IConnection> conns = Red5.getConnectionLocal().getScope().getClientConnections();
+            for (IConnection conn : conns) {
+                String connUserId = (String) conn.getAttribute("USERID");
+                String connSessionId = conn.getSessionId();
+                String clientId = conn.getClient().getId();
+                String remoteHost = conn.getRemoteAddress();
+                int remotePort = conn.getRemotePort();
+                if (connUserId != null && connUserId.equals(userId) && !connSessionId.equals(sessionId)) {
+                    conn.removeAttribute("USERID");
+                    Map<String, Object> logData = new HashMap<String, Object>();
+                    logData.put("meetingId", meetingId);
+                    logData.put("userId", userId);
+                    logData.put("oldConnId", connSessionId);
+                    logData.put("newConnId", sessionId);
+                    logData.put("clientId", clientId);
+                    logData.put("remoteAddress", remoteHost + ":" + remotePort);
+                    logData.put("event", "removing_defunct_connection");
+                    logData.put("description", "Removing defunct connection BBB Video.");
+
+                    Gson gson = new Gson();
+                    String logStr =  gson.toJson(logData);
+
+                    log.info("Removing defunct connection: data={}", logStr);
+                }
+            }
+
+            String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
+            int remotePort = Red5.getConnectionLocal().getRemotePort();
+            String clientId = Red5.getConnectionLocal().getClient().getId();
+
+            Map<String, Object> logData = new HashMap<String, Object>();
+            logData.put("meetingId", meetingId);
+            logData.put("userId", userId);
+            logData.put("connType", connType);
+            logData.put("connId", sessionId);
+            logData.put("clientId", clientId);
+            logData.put("remoteAddress", remoteHost + ":" + remotePort);
+            logData.put("event", "user_joining_bbb_video");
+            logData.put("description", "User joining BBB Video.");
+
+            Gson gson = new Gson();
+            String logStr =  gson.toJson(logData);
+
+            log.info("User joining bbb-video: data={}", logStr);
+        }
 
 		return super.roomConnect(connection, params);
 	}
@@ -178,19 +266,37 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
 		
 		String connType = getConnectionType(Red5.getConnectionLocal().getType());
 		String connId = Red5.getConnectionLocal().getSessionId();
-		
-		Map<String, Object> logData = new HashMap<String, Object>();
-		logData.put("meetingId", getMeetingId());
-		logData.put("userId", getUserId());
-		logData.put("connType", connType);
-		logData.put("connId", connId);
-		logData.put("event", "user_leaving_bbb_video");
-		logData.put("description", "User leaving BBB Video.");
-		
-		Gson gson = new Gson();
-		String logStr =  gson.toJson(logData);
-		
-		log.info("User leaving bbb-video: data={}", logStr);
+
+      UserConnectionMapper.UserConnection uconn = userConnections.userDisconnected(connId);
+      if (uconn != null) {
+          Map<String, Object> logData = new HashMap<String, Object>();
+          logData.put("meetingId", getMeetingId());
+          logData.put("userId", getUserId());
+          logData.put("connType", connType);
+          logData.put("connId", connId);
+          logData.put("event", "removing_port_test_conn_bbb_video");
+          logData.put("description", "Removing port test connection BBB Video.");
+
+          Gson gson = new Gson();
+          String logStr =  gson.toJson(logData);
+
+          log.info(logStr);
+      } else {
+          Map<String, Object> logData = new HashMap<String, Object>();
+          logData.put("meetingId", getMeetingId());
+          logData.put("userId", getUserId());
+          logData.put("connType", connType);
+          logData.put("connId", connId);
+          logData.put("event", "user_leaving_bbb_video");
+          logData.put("description", "User leaving BBB Video.");
+
+          Gson gson = new Gson();
+          String logStr =  gson.toJson(logData);
+
+          log.info("User leaving bbb-video: data={}", logStr);
+      }
+
+
 		
 		super.roomDisconnect(conn);
 	}
@@ -234,7 +340,34 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
 
     @Override
     public void streamBroadcastStart(IBroadcastStream stream) {
-    	IConnection conn = Red5.getConnectionLocal();  
+    	IConnection conn = Red5.getConnectionLocal();
+    	String contextName = stream.getScope().getName();
+
+    	if ("video".equals(contextName)) {
+            /**
+             * Prevent publishing into the /video context as all our webcams are published
+             * into /video/<meetingId> context. (ralam jan 22, 2018)
+             */
+
+            String connType = getConnectionType(Red5.getConnectionLocal().getType());
+            String connId = Red5.getConnectionLocal().getSessionId();
+            Map<String, Object> logData = new HashMap<String, Object>();
+            logData.put("meetingId", getMeetingId());
+            logData.put("userId", getUserId());
+            logData.put("connType", connType);
+            logData.put("connId", connId);
+            logData.put("stream", stream.getPublishedName());
+            logData.put("context", contextName);
+            logData.put("event", "unauth_publish_stream_bbb_video");
+            logData.put("description", "Publishing stream in app context.");
+
+            Gson gson = new Gson();
+            String logStr =  gson.toJson(logData);
+    	    log.error(logStr);
+    	    conn.close();
+    	    return;
+        }
+
     	super.streamBroadcastStart(stream);
     	log.info("streamBroadcastStart " + stream.getPublishedName() + " " + System.currentTimeMillis() + " " + conn.getScope().getName());
 
@@ -262,8 +395,6 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
 
 				recordStream(stream);
 			}
-
-
     }
 
     private Long genTimestamp() {
@@ -481,4 +612,8 @@ public class VideoApplication extends MultiThreadedApplicationAdapter {
             }
         }
     }
+
+	public void setConnInvokerService(ConnectionInvokerService connInvokerService) {
+		this.connInvokerService = connInvokerService;
+	}
 }
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/Constants.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/Constants.java
old mode 100644
new mode 100755
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/GenericObjectPoolConfigWrapper.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/GenericObjectPoolConfigWrapper.java
deleted file mode 100755
index 0ed93505382b95ba3f10076f2ab28fd4f9441579..0000000000000000000000000000000000000000
--- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/GenericObjectPoolConfigWrapper.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
-* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
-* 
-* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
-*
-* This program is free software; you can redistribute it and/or modify it under the
-* terms of the GNU Lesser General Public License as published by the Free Software
-* Foundation; either version 3.0 of the License, or (at your option) any later
-* version.
-* 
-* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
-* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License along
-* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-*
-*/
-package org.bigbluebutton.red5.pubsub;
-
-import org.apache.commons.pool.impl.GenericObjectPool;
-
-public class GenericObjectPoolConfigWrapper {
-	
-	private final GenericObjectPool.Config config;
- 
-    public GenericObjectPoolConfigWrapper() {
-        this.config = new GenericObjectPool.Config();
-    }
- 
-    public GenericObjectPool.Config getConfig() {
-        return config;
-    }
- 
-    public int getMaxIdle() {
-        return this.config.maxIdle;
-    }
- 
-    public void setMaxIdle(int maxIdle) {
-        this.config.maxIdle = maxIdle;
-    }
- 
-    public int getMinIdle() {
-        return this.config.minIdle;
-    }
- 
-    public void setMinIdle(int minIdle) {
-        this.config.minIdle = minIdle;
-    }
- 
-    public int getMaxActive() {
-        return this.config.maxActive;
-    }
- 
-    public void setMaxActive(int maxActive) {
-        this.config.maxActive = maxActive;
-    }
- 
-    public long getMaxWait() {
-        return this.config.maxWait;
-    }
- 
-    public void setMaxWait(long maxWait) {
-        this.config.maxWait = maxWait;
-    }
- 
-    public byte getWhenExhaustedAction() {
-        return this.config.whenExhaustedAction;
-    }
- 
-    public void setWhenExhaustedAction(byte whenExhaustedAction) {
-        this.config.whenExhaustedAction = whenExhaustedAction;
-    }
- 
-    public boolean isTestOnBorrow() {
-        return this.config.testOnBorrow;
-    }
- 
-    public void setTestOnBorrow(boolean testOnBorrow) {
-        this.config.testOnBorrow = testOnBorrow;
-    }
- 
-    public boolean isTestOnReturn() {
-        return this.config.testOnReturn;
-    }
- 
-    public void setTestOnReturn(boolean testOnReturn) {
-        this.config.testOnReturn = testOnReturn;
-    }
- 
-    public boolean isTestWhileIdle() {
-        return this.config.testWhileIdle;
-    }
- 
-    public void setTestWhileIdle(boolean testWhileIdle) {
-        this.config.testWhileIdle = testWhileIdle;
-    }
- 
-    public long getTimeBetweenEvictionRunsMillis() {
-        return this.config.timeBetweenEvictionRunsMillis;
-    }
- 
-    public void setTimeBetweenEvictionRunsMillis(
-            long timeBetweenEvictionRunsMillis) {
-        this.config.timeBetweenEvictionRunsMillis =
-                timeBetweenEvictionRunsMillis;
-    }
- 
-    public int getNumTestsPerEvictionRun() {
-        return this.config.numTestsPerEvictionRun;
-    }
- 
-    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
-        this.config.numTestsPerEvictionRun = numTestsPerEvictionRun;
-    }
- 
-    public long getMinEvictableIdleTimeMillis() {
-        return this.config.minEvictableIdleTimeMillis;
-    }
- 
-    public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
-        this.config.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
-    }
- 
-    public long getSoftMinEvictableIdleTimeMillis() {
-        return this.config.softMinEvictableIdleTimeMillis;
-    }
- 
-    public void setSoftMinEvictableIdleTimeMillis(
-            long softMinEvictableIdleTimeMillis) {
-        this.config.softMinEvictableIdleTimeMillis =
-                softMinEvictableIdleTimeMillis;
-    }
- 
-    public boolean isLifo() {
-        return this.config.lifo;
-    }
- 
-    public void setLifo(boolean lifo) {
-        this.config.lifo = lifo;
-    }
-}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MeetingMessageHandler.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MeetingMessageHandler.java
new file mode 100755
index 0000000000000000000000000000000000000000..e6fb817ee1054b43b5bb60a2cd886ed03b89ce08
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MeetingMessageHandler.java
@@ -0,0 +1,75 @@
+package org.bigbluebutton.red5.pubsub;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.bigbluebutton.app.video.ConnectionInvokerService;
+import org.bigbluebutton.red5.pubsub.message.ValidateConnTokenRespMsg;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+
+public class MeetingMessageHandler implements MessageHandler {
+    private static Logger log = Red5LoggerFactory.getLogger(MeetingMessageHandler.class, "video");
+
+    private final String HEADER = "header";
+    private final String NAME = "name";
+    private final String BODY = "body";
+    private final String MEETING_ID = "meetingId";
+    private final String TIMESTAMP = "timestamp";
+    private final String ENVELOPE = "envelope";
+    private final String CORE = "core";
+
+    private final String USERID = "userId";
+    private final String AUTHZED = "authzed";
+    private final String CONN = "connId";
+    private final String APP = "app";
+    private final String VIDEO_APP = "VIDEO";
+
+    private final String RecordingChapterBreakSysMsg = "RecordingChapterBreakSysMsg";
+    private final String ValidateConnAuthTokenSysRespMsg = "ValidateConnAuthTokenSysRespMsg";
+
+    private ConnectionInvokerService connInvokerService;
+
+    public void handleMessage(String pattern, String channel, String message) {
+        JsonParser parser = new JsonParser();
+        JsonObject obj = (JsonObject) parser.parse(message);
+
+        if (obj.has(ENVELOPE) && obj.has(CORE)) {
+            JsonObject core = obj.getAsJsonObject(CORE);
+            JsonObject header = core.getAsJsonObject(HEADER);
+            if (header.has(NAME)) {
+                String name = header.get(NAME).getAsString();
+                handle(name, core.getAsJsonObject(BODY));
+            }
+        }
+    }
+
+    private void handle(String name, JsonObject body) {
+        if (ValidateConnAuthTokenSysRespMsg.equals(name)) {
+            Gson gson = new Gson();
+            String logStr = gson.toJson(body);
+
+            log.debug("HANDLE: {}", logStr);
+            if (body.has(MEETING_ID) && body.has(USERID)
+                    && body.has(AUTHZED) && body.has(CONN) && body.has(APP)) {
+                String meetingId = body.get(MEETING_ID).getAsString();
+                String userId = body.get(USERID).getAsString();
+                Boolean authzed = body.get(AUTHZED).getAsBoolean();
+                String conn = body.get(CONN).getAsString();
+                String app = body.get(APP).getAsString();
+
+                log.debug("PROCESS: {}", name);
+                if (VIDEO_APP.equals(app)) {
+                    ValidateConnTokenRespMsg vctrm = new ValidateConnTokenRespMsg(meetingId, userId, authzed, conn);
+                    connInvokerService.sendMessage(vctrm);
+                }
+            } else {
+                log.debug("INVALID MSG FORMAT: {}", logStr);
+            }
+        }
+    }
+
+    public void setConnInvokerService(ConnectionInvokerService connInvokerService) {
+        this.connInvokerService = connInvokerService;
+    }
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageDistributor.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageDistributor.java
new file mode 100755
index 0000000000000000000000000000000000000000..b51ed206c8f6ea6b5da5e3681709dbfe103f6f3b
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageDistributor.java
@@ -0,0 +1,25 @@
+package org.bigbluebutton.red5.pubsub;
+
+import java.util.Set;
+
+public class MessageDistributor {
+    private ReceivedMessageHandler handler;
+    private Set<MessageHandler> listeners;
+
+    public void setMessageListeners(Set<MessageHandler> listeners) {
+        this.listeners = listeners;
+    }
+
+    public void setMessageHandler(ReceivedMessageHandler handler) {
+        this.handler = handler;
+        if (handler != null) {
+            handler.setMessageDistributor(this);
+        }
+    }
+
+    public void notifyListeners(String pattern, String channel, String message) {
+        for (MessageHandler listener : listeners) {
+            listener.handleMessage(pattern, channel, message);
+        }
+    }
+}
\ No newline at end of file
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageHandler.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageHandler.java
new file mode 100755
index 0000000000000000000000000000000000000000..8f197312c290d0ef21e0baed37478d9d7bfb94e3
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageHandler.java
@@ -0,0 +1,5 @@
+package org.bigbluebutton.red5.pubsub;
+
+public interface MessageHandler {
+    void handleMessage(String pattern, String channel, String message);
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java
index 5b6de28e9828ec66f29d209317d1d7629d61d824..ed14c008381cf9dbe22c2f3aea6cedef2c38365c 100755
--- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagePublisher.java
@@ -1,13 +1,14 @@
 package org.bigbluebutton.red5.pubsub;
 
-import org.bigbluebutton.common.messages.MessagingConstants;
-import org.bigbluebutton.common.messages.UserSharedWebcamMessage;
-import org.bigbluebutton.common.messages.UserUnshareWebcamRequestMessage;
 
-import java.util.HashMap;
-import java.util.Map;
+//import org.bigbluebutton.common.messages.UserSharedWebcamMessage;
+//import org.bigbluebutton.common.messages.UserUnshareWebcamRequestMessage;
 
 import com.google.gson.Gson;
+import org.bigbluebutton.common2.msgs.*;
+
+import java.util.HashMap;
+import java.util.Map;
 
 public class MessagePublisher {
 
@@ -16,8 +17,42 @@ public class MessagePublisher {
 	public void setMessageSender(MessageSender sender) {
 		this.sender = sender;
 	}
-	
-	// Polling 
+
+	private Map<String, Object> buildEnvelope(String name, Map<String, String> routing) {
+		Map<String, Object> envelope = new HashMap<String, Object>();
+		envelope.put("name", name);
+		envelope.put("routing", routing);
+		return envelope;
+	}
+
+	private Map<String, String> buildRouting() {
+		Map<String, String> routing = new HashMap<String, String>();
+		routing.put("msgType", "SYSTEM");
+		routing.put("sender", "bbb-video");
+		return routing;
+	}
+
+	public void validateConnAuthToken(String meetingId, String userId, String authToken, String connId) {
+		BbbCoreBaseHeader header = new BbbCoreBaseHeader("ValidateConnAuthTokenSysMsg");
+		ValidateConnAuthTokenSysMsgBody body = new ValidateConnAuthTokenSysMsgBody(meetingId,
+				userId, authToken, connId, "VIDEO");
+		ValidateConnAuthTokenSysMsg msg = new ValidateConnAuthTokenSysMsg(header, body);
+
+		Map<String, String> routing = buildRouting();
+		Map<String, Object> envelope = buildEnvelope("ValidateConnAuthTokenSysMsg", routing);
+
+		Map<String, Object> fullmsg = new HashMap<String, Object>();
+		fullmsg.put("envelope", envelope);
+		fullmsg.put("core", msg);
+
+		Gson gson = new Gson();
+		String json = gson.toJson(fullmsg);
+
+		sender.send("to-akka-apps-redis-channel", json);
+	}
+
+	// Polling
+	/*
 	public void userSharedWebcamMessage(String meetingId, String userId, String streamId) {
 		UserSharedWebcamMessage msg = new UserSharedWebcamMessage(meetingId, userId, streamId);
 		sender.send(MessagingConstants.TO_USERS_CHANNEL, msg.toJson());
@@ -27,6 +62,7 @@ public class MessagePublisher {
 		UserUnshareWebcamRequestMessage msg = new UserUnshareWebcamRequestMessage(meetingId, userId, streamId);
 		sender.send(MessagingConstants.TO_USERS_CHANNEL, msg.toJson());
 	}
+	*/
 	
 	public void startRotateLeftTranscoderRequest(String meetingId, String transcoderId, String streamName, String ipAddress) {
 		Map<String, String> params = new HashMap<String, String>();
@@ -114,4 +150,4 @@ public class MessagePublisher {
 		header.put(Constants.MEETING_ID, meetingId);
 		return header;
 	}
-}
\ No newline at end of file
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageReceiver.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageReceiver.java
new file mode 100755
index 0000000000000000000000000000000000000000..e0435bd5b941c8d1c7ab97ad529b427827510711
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageReceiver.java
@@ -0,0 +1,123 @@
+package org.bigbluebutton.red5.pubsub;
+
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+import redis.clients.jedis.Jedis;
+import redis.clients.jedis.JedisPubSub;
+import redis.clients.jedis.exceptions.JedisConnectionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+
+public class MessageReceiver {
+    private static Logger log = Red5LoggerFactory.getLogger(MessageReceiver.class, "video");
+
+    private ReceivedMessageHandler handler;
+
+    private Jedis jedis;
+    private volatile boolean receiveMessage = false;
+
+    private final Executor msgReceiverExec = Executors.newSingleThreadExecutor();
+    private final Executor runExec = Executors.newSingleThreadExecutor();
+
+    private final String FROM_BBB_APPS_PATTERN = "from-akka-apps-redis-channel";
+
+    private String host;
+    private int port;
+
+    public void stop() {
+        receiveMessage = false;
+    }
+
+    public void start() {
+        log.info("Ready to receive messages from Redis pubsub.");
+        try {
+            receiveMessage = true;
+            jedis = new Jedis(host, port);
+            // Set the name of this client to be able to distinguish when doing
+            // CLIENT LIST on redis-cli
+            jedis.clientSetname("BbbRed5VideoSub");
+
+            Runnable messageReceiver = new Runnable() {
+                public void run() {
+                    if (receiveMessage) {
+                        try {
+                            jedis.subscribe(new PubSubListener(), FROM_BBB_APPS_PATTERN);
+                        } catch(JedisConnectionException ex) {
+                            log.warn("Exception on Jedis connection. Resubscribing to pubsub.");
+                            start();
+                        } catch (Exception e) {
+                            log.error("Error resubscribing to channels: " + e.getMessage());
+                        }
+                    }
+                }
+            };
+            msgReceiverExec.execute(messageReceiver);
+        } catch (Exception e) {
+            log.error("Error subscribing to channels: " + e.getMessage());
+        }
+    }
+
+    public void setHost(String host){
+        this.host = host;
+    }
+
+    public void setPort(int port) {
+        this.port = port;
+    }
+
+    public void setMessageHandler(ReceivedMessageHandler handler) {
+        this.handler = handler;
+    }
+
+    private class PubSubListener extends JedisPubSub {
+
+        public PubSubListener() {
+            super();
+        }
+
+        @Override
+        public void onMessage(String channel, String message) {
+            // Not used.
+            Runnable task = new Runnable() {
+                public void run() {
+                    handler.handleMessage("", channel, message);
+                }
+            };
+
+            runExec.execute(task);
+        }
+
+        @Override
+        public void onPMessage(final String pattern, final String channel, final String message) {
+            System.out.println("RECEIVED onPMessage" + channel + " org.bigbluebutton.red5.pubsub.message=\n" + message);
+            Runnable task = new Runnable() {
+                public void run() {
+                    handler.handleMessage(pattern, channel, message);
+                }
+            };
+
+            runExec.execute(task);
+        }
+
+        @Override
+        public void onPSubscribe(String pattern, int subscribedChannels) {
+            log.debug("Subscribed to the pattern: " + pattern);
+        }
+
+        @Override
+        public void onPUnsubscribe(String pattern, int subscribedChannels) {
+            // Not used.
+        }
+
+        @Override
+        public void onSubscribe(String channel, int subscribedChannels) {
+            // Not used.
+        }
+
+        @Override
+        public void onUnsubscribe(String channel, int subscribedChannels) {
+            // Not used.
+        }
+    }
+}
+
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageSender.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageSender.java
index 74003393f434496d7aa7f8c8d823f68f56253b04..e5dbe23501afd048e777a5d53c0b236f5f74f0eb 100755
--- a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageSender.java
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessageSender.java
@@ -1,13 +1,16 @@
 package org.bigbluebutton.red5.pubsub;
 
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.Executors;
-import java.util.concurrent.LinkedBlockingQueue;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import redis.clients.jedis.Jedis;
 import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.Protocol;
+
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
 
 public class MessageSender {
 	private static Logger log = Red5LoggerFactory.getLogger(MessageSender.class, "bigbluebutton");
@@ -18,27 +21,48 @@ public class MessageSender {
 	private final Executor msgSenderExec = Executors.newSingleThreadExecutor();
 	private final Executor runExec = Executors.newSingleThreadExecutor();
 	private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>();
-	
+	private String host;
+	private int port;
+
 	public void stop() {
 		sendMessage = false;
+		redisPool.destroy();
 	}
 	
 	public void start() {	
-		log.info("Redis message publisher starting!");
+
+		GenericObjectPoolConfig config = new GenericObjectPoolConfig();
+		config.setMaxTotal(32);
+		config.setMaxIdle(8);
+		config.setMinIdle(1);
+		config.setTestOnBorrow(true);
+		config.setTestOnReturn(true);
+		config.setTestWhileIdle(true);
+		config.setNumTestsPerEvictionRun(12);
+		config.setMaxWaitMillis(5000);
+		config.setTimeBetweenEvictionRunsMillis(60000);
+		config.setBlockWhenExhausted(true);
+
+		// Set the name of this client to be able to distinguish when doing
+		// CLIENT LIST on redis-cli
+		redisPool = new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, null,
+				Protocol.DEFAULT_DATABASE, "BbbRed5VideoPub");
+
+		log.info("Redis org.bigbluebutton.red5.pubsub.message publisher starting!");
 		try {
 			sendMessage = true;
 			
 			Runnable messageSender = new Runnable() {
-			    public void run() {
-			    	while (sendMessage) {
-				    	try {
+				public void run() {
+					while (sendMessage) {
+						try {
 							MessageToSend msg = messages.take();
 							publish(msg.getChannel(), msg.getMessage());
 						} catch (InterruptedException e) {
-							log.warn("Failed to get message from queue.");
-						}    			    		
-			    	}
-			    }
+							log.warn("Failed to get org.bigbluebutton.red5.pubsub.message from queue.");
+						}
+					}
+				}
 			};
 			msgSenderExec.execute(messageSender);
 		} catch (Exception e) {
@@ -53,22 +77,27 @@ public class MessageSender {
 	
 	private void publish(final String channel, final String message) {
 		Runnable task = new Runnable() {
-		    public void run() {
-		  		Jedis jedis = redisPool.getResource();
-		  		try {
-		  			jedis.publish(channel, message);
-		  		} catch(Exception e){
-		  			log.warn("Cannot publish the message to redis", e);
-		  		} finally {
-		  			redisPool.returnResource(jedis);
-		  		}	    	
-		    }
+			public void run() {
+				Jedis jedis = redisPool.getResource();
+				try {
+					jedis.publish(channel, message);
+				} catch(Exception e){
+					log.warn("Cannot publish the org.bigbluebutton.red5.pubsub.message to redis", e);
+				} finally {
+					redisPool.returnResource(jedis);
+				}
+			}
 		};
 		
 		runExec.execute(task);
 	}
-	
-	public void setRedisPool(JedisPool redisPool){
-		this.redisPool = redisPool;
+
+
+	public void setHost(String host){
+		this.host = host;
+	}
+
+	public void setPort(int port) {
+		this.port = port;
 	}
 }
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagingConstants.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagingConstants.java
new file mode 100755
index 0000000000000000000000000000000000000000..381f800f2a0cd70a9ed183aa483dcc36154184e8
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/MessagingConstants.java
@@ -0,0 +1,81 @@
+/**
+ * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+ *
+ * Copyright (c) 2014 BigBlueButton Inc. and by respective authors (see below).
+ *
+ * This program is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation; either version 3.0 of the License, or (at your option) any later
+ * version.
+ *
+ * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package org.bigbluebutton.red5.pubsub;
+
+public class MessagingConstants {
+
+  public static final String FROM_BBB_APPS_CHANNEL = "bigbluebutton:from-bbb-apps";
+  public static final String FROM_BBB_APPS_PATTERN = FROM_BBB_APPS_CHANNEL + ":*";
+  public static final String FROM_SYSTEM_CHANNEL = FROM_BBB_APPS_CHANNEL + ":system";
+  public static final String FROM_MEETING_CHANNEL = FROM_BBB_APPS_CHANNEL + ":meeting";
+  public static final String FROM_PRESENTATION_CHANNEL = FROM_BBB_APPS_CHANNEL + ":presentation";
+  public static final String FROM_POLLING_CHANNEL = FROM_BBB_APPS_CHANNEL + ":polling";
+  public static final String FROM_USERS_CHANNEL = FROM_BBB_APPS_CHANNEL + ":users";
+  public static final String FROM_WHITEBOARD_CHANNEL = FROM_BBB_APPS_CHANNEL + ":whiteboard";
+  public static final String FROM_DESK_SHARE_CHANNEL = FROM_BBB_APPS_CHANNEL + ":deskshare";
+
+  public static final String TO_BBB_APPS_CHANNEL = "bigbluebutton:to-bbb-apps";
+  public static final String TO_BBB_APPS_PATTERN = TO_BBB_APPS_CHANNEL + ":*";
+  public static final String TO_MEETING_CHANNEL = TO_BBB_APPS_CHANNEL + ":meeting";
+  public static final String TO_SYSTEM_CHANNEL = TO_BBB_APPS_CHANNEL + ":system";
+  public static final String TO_PRESENTATION_CHANNEL = TO_BBB_APPS_CHANNEL + ":presentation";
+  public static final String TO_POLLING_CHANNEL = TO_BBB_APPS_CHANNEL + ":polling";
+  public static final String TO_USERS_CHANNEL = TO_BBB_APPS_CHANNEL + ":users";
+  public static final String TO_VOICE_CHANNEL = TO_BBB_APPS_CHANNEL + ":voice";
+  public static final String TO_WHITEBOARD_CHANNEL = TO_BBB_APPS_CHANNEL + ":whiteboard";
+
+  public static final String BBB_APPS_KEEP_ALIVE_CHANNEL = "bigbluebutton:from-bbb-apps:keepalive";
+
+  public static final String TO_BBB_HTML5_CHANNEL = "bigbluebutton:to-bbb-html5";
+
+  public static final String TO_VOICE_CONF_CHANNEL = "bigbluebutton:to-voice-conf";
+  public static final String TO_VOICE_CONF_PATTERN = TO_VOICE_CONF_CHANNEL + ":*";
+  public static final String TO_VOICE_CONF_SYSTEM_CHAN = TO_VOICE_CONF_CHANNEL + ":system";
+  public static final String FROM_VOICE_CONF_CHANNEL = "bigbluebutton:from-voice-conf";
+  public static final String FROM_VOICE_CONF_PATTERN = FROM_VOICE_CONF_CHANNEL + ":*";
+  public static final String FROM_VOICE_CONF_SYSTEM_CHAN = FROM_VOICE_CONF_CHANNEL + ":system";
+
+  public static final String FROM_BBB_RECORDING_CHANNEL  = "bigbluebutton:from-rap";
+
+  public static final String TO_BBB_TRANSCODE_CHANNEL = "bigbluebutton:to-bbb-transcode";
+  public static final String TO_BBB_TRANSCODE_PATTERN = TO_BBB_TRANSCODE_CHANNEL + ":*";
+  public static final String TO_BBB_TRANSCODE_SYSTEM_CHAN = TO_BBB_TRANSCODE_CHANNEL + ":system";
+  public static final String FROM_BBB_TRANSCODE_CHANNEL = "bigbluebutton:from-bbb-transcode";
+  public static final String FROM_BBB_TRANSCODE_PATTERN = FROM_BBB_TRANSCODE_CHANNEL + ":*";
+  public static final String FROM_BBB_TRANSCODE_SYSTEM_CHAN = FROM_BBB_TRANSCODE_CHANNEL + ":system";
+
+
+  public static final String DESTROY_MEETING_REQUEST_EVENT = "DestroyMeetingRequestEvent";
+  public static final String CREATE_MEETING_REQUEST_EVENT = "CreateMeetingRequestEvent";
+  public static final String END_MEETING_REQUEST_EVENT = "EndMeetingRequestEvent";
+  public static final String MEETING_STARTED_EVENT = "meeting_created_message";
+  public static final String MEETING_ENDED_EVENT = "meeting_ended_event";
+  public static final String MEETING_DESTROYED_EVENT = "meeting_destroyed_event";
+  public static final String USER_JOINED_EVENT = "UserJoinedEvent";
+  public static final String USER_LEFT_EVENT = "UserLeftEvent";
+  public static final String USER_LEFT_VOICE_REQUEST = "user_left_voice_request";
+  public static final String USER_STATUS_CHANGE_EVENT = "UserStatusChangeEvent";
+  public static final String USER_ROLE_CHANGE_EVENT = "UserRoleChangeEvent";
+  public static final String SEND_POLLS_EVENT = "SendPollsEvent";
+  public static final String RECORD_STATUS_EVENT = "RecordStatusEvent";
+  public static final String SEND_PUBLIC_CHAT_MESSAGE_REQUEST = "send_public_chat_message_request";
+  public static final String SEND_PRIVATE_CHAT_MESSAGE_REQUEST = "send_private_chat_message_request";
+  public static final String MUTE_USER_REQUEST = "mute_user_request";
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessage.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessage.java
new file mode 100755
index 0000000000000000000000000000000000000000..41c775f739fc95f8e0c827ff1aa4a2adf6976ee5
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessage.java
@@ -0,0 +1,25 @@
+package org.bigbluebutton.red5.pubsub;
+
+public class ReceivedMessage {
+    private final String pattern;
+    private final String channel;
+    private final String message;
+
+    public ReceivedMessage(String pattern, String channel, String message) {
+        this.pattern = pattern;
+        this.channel = channel;
+        this.message = message;
+    }
+
+    public String getPattern() {
+        return pattern;
+    }
+
+    public String getChannel() {
+        return channel;
+    }
+
+    public String getMessage() {
+        return message;
+    }
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessageHandler.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessageHandler.java
new file mode 100755
index 0000000000000000000000000000000000000000..b7473dd3f849111163441ff33fdb7cce587dabc7
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/ReceivedMessageHandler.java
@@ -0,0 +1,72 @@
+package org.bigbluebutton.red5.pubsub;
+
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+
+public class ReceivedMessageHandler {
+    private static Logger log = Red5LoggerFactory.getLogger(ReceivedMessageHandler.class, "video");
+
+    private BlockingQueue<ReceivedMessage> receivedMessages = new LinkedBlockingQueue<ReceivedMessage>();
+
+    private volatile boolean processMessage = false;
+
+    private final Executor msgProcessorExec = Executors.newSingleThreadExecutor();
+    private final Executor runExec = Executors.newSingleThreadExecutor();
+
+    private MessageDistributor handler;
+
+    public void stop() {
+        processMessage = false;
+    }
+
+    public void start() {
+        log.info("Ready to handle messages from Redis pubsub!");
+
+        try {
+            processMessage = true;
+
+            Runnable messageProcessor = new Runnable() {
+                public void run() {
+                    while (processMessage) {
+                        try {
+                            ReceivedMessage msg = receivedMessages.take();
+                            processMessage(msg);
+                        } catch (InterruptedException e) {
+                            log.warn("Error while taking received org.bigbluebutton.red5.pubsub.message from queue.");
+                        }
+                    }
+                }
+            };
+            msgProcessorExec.execute(messageProcessor);
+        } catch (Exception e) {
+            log.error("Error subscribing to channels: " + e.getMessage());
+        }
+    }
+
+    private void processMessage(final ReceivedMessage msg) {
+        Runnable task = new Runnable() {
+            public void run() {
+                if (handler != null) {
+                    handler.notifyListeners(msg.getPattern(), msg.getChannel(), msg.getMessage());
+                } else {
+                    log.warn("No listeners interested in messages from Redis!");
+                }
+            }
+        };
+
+        runExec.execute(task);
+    }
+
+    public void handleMessage(String pattern, String channel, String message) {
+        ReceivedMessage rm = new ReceivedMessage(pattern, channel, message);
+        receivedMessages.add(rm);
+    }
+
+    public void setMessageDistributor(MessageDistributor h) {
+        this.handler = h;
+    }
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/ClientMessage.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/ClientMessage.java
new file mode 100755
index 0000000000000000000000000000000000000000..e96c2a079691bc8e58b1e2f024c3d96397ecd372
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/ClientMessage.java
@@ -0,0 +1,25 @@
+/**
+* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+* 
+* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
+*
+* This program is free software; you can redistribute it and/or modify it under the
+* terms of the GNU Lesser General Public License as published by the Free Software
+* Foundation; either version 3.0 of the License, or (at your option) any later
+* version.
+* 
+* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License along
+* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package org.bigbluebutton.red5.pubsub.message;
+
+
+public interface ClientMessage {
+
+    String getMessageName();
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/RecordChapterBreakMessage.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/RecordChapterBreakMessage.java
new file mode 100755
index 0000000000000000000000000000000000000000..1a50454b45af432099eb8c3b55091b5599e33266
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/RecordChapterBreakMessage.java
@@ -0,0 +1,11 @@
+package org.bigbluebutton.red5.pubsub.message;
+
+public class RecordChapterBreakMessage {
+    public final String meetingId;
+    public final Long timestamp;
+
+    public RecordChapterBreakMessage(String meetingId, Long timestamp) {
+        this.meetingId = meetingId;
+        this.timestamp = timestamp;
+    }
+}
diff --git a/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/ValidateConnTokenRespMsg.java b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/ValidateConnTokenRespMsg.java
new file mode 100755
index 0000000000000000000000000000000000000000..7e0eab561c7b797b73735b64bf0c851bc060cc7a
--- /dev/null
+++ b/bbb-video/src/main/java/org/bigbluebutton/red5/pubsub/message/ValidateConnTokenRespMsg.java
@@ -0,0 +1,20 @@
+package org.bigbluebutton.red5.pubsub.message;
+
+public class ValidateConnTokenRespMsg implements ClientMessage {
+
+    public final String meetingId;
+    public final String connId;
+    public final String userId;
+    public final Boolean authzed;
+
+    public ValidateConnTokenRespMsg(String meetingId, String userId, Boolean authzed, String connId) {
+        this.meetingId = meetingId;
+        this.connId = connId;
+        this.authzed = authzed;
+        this.userId = userId;
+    }
+
+    public String getMessageName() {
+        return "ValidateConnAuthTokenSysRespMsg";
+    }
+}
diff --git a/bbb-video/src/main/webapp/WEB-INF/red5-web.xml b/bbb-video/src/main/webapp/WEB-INF/red5-web.xml
index 1ea5e9f5b363741d2198517b5ef9681e74ff3bd7..c74c783e23173b6bb8f34bea849d9c8582f472b5 100755
--- a/bbb-video/src/main/webapp/WEB-INF/red5-web.xml
+++ b/bbb-video/src/main/webapp/WEB-INF/red5-web.xml
@@ -49,8 +49,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	   <property name="packetTimeout" value="10000"/>
 		<property name="eventRecordingService" ref="redisRecorder"/>
 		<property name="messagePublisher" ref="redisPublisher"/>
+		<property name="connInvokerService" ref="connInvokerService"/>
 	</bean>
 
+	<bean id="connInvokerService" class="org.bigbluebutton.app.video.ConnectionInvokerService"
+		  init-method="start" destroy-method="stop"/>
+
     <bean id="redisPublisher" class="org.bigbluebutton.red5.pubsub.MessagePublisher">
         <property name="messageSender" ref="redisSender"/>
     </bean>
@@ -59,12 +63,35 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         <constructor-arg index="0" value="${redis.host}"/>
         <constructor-arg index="1" value="${redis.port}"/>
         <constructor-arg index="2" value="${redis.keyExpiry}"/>
-    </bean>	
-    
-    <bean id="redisSender" class="org.bigbluebutton.red5.pubsub.MessageSender" 
-                    init-method="start" destroy-method="stop">
-      <property name="redisPool"> <ref bean="redisPool"/></property>
     </bean>
-    
-    <import resource="bbb-redis-pool.xml"/>
+
+	<bean id="messageReceiver" class="org.bigbluebutton.red5.pubsub.MessageReceiver"
+		  init-method="start" destroy-method="stop">
+		<property name="host" value="${redis.host}"/>
+		<property name="port" value="${redis.port}"/>
+		<property name="messageHandler" ref="receivedMessageHandler"/>
+	</bean>
+
+	<bean id="messageDistributor" class="org.bigbluebutton.red5.pubsub.MessageDistributor">
+		<property name="messageHandler" ref="receivedMessageHandler"/>
+		<property name="messageListeners">
+			<set>
+				<ref bean="meetingMessageHandler" />
+			</set>
+		</property>
+	</bean>
+
+	<bean id="meetingMessageHandler" class="org.bigbluebutton.red5.pubsub.MeetingMessageHandler">
+		<property name="connInvokerService" ref="connInvokerService"/>
+	</bean>
+
+	<bean id="receivedMessageHandler" class="org.bigbluebutton.red5.pubsub.ReceivedMessageHandler"
+		  init-method="start" destroy-method="stop">
+	</bean>
+
+	<bean id="redisSender" class="org.bigbluebutton.red5.pubsub.MessageSender"
+		  init-method="start" destroy-method="stop">
+		<property name="host" value="${redis.host}"/>
+		<property name="port" value="${redis.port}"/>
+	</bean>
 </beans>
diff --git a/bbb-voice/build.gradle b/bbb-voice/build.gradle
index c7e57db98cd6003ecdc06e74cc12b8021dd92fe5..f58d7d1375cb526ae99116a2050f7e13c92a3bb5 100755
--- a/bbb-voice/build.gradle
+++ b/bbb-voice/build.gradle
@@ -55,11 +55,14 @@ dependencies {
   
   // Testing
   testRuntime 'org.easymock:easymock:2.4@jar'
-	    
-  // Redis pubsub
-  compile "redis.clients:jedis:2.1.0"
-  compile 'commons-pool:commons-pool:1.5.6'
+
+  //redis
+  compile 'redis.clients:jedis:2.9.0'
+  compile 'org.apache.commons:commons-pool2:2.3'
   compile 'com.google.code.gson:gson:2.5'
+
+  compile 'org.apache.commons:commons-lang3:3.5'
+  compile 'org.bigbluebutton:bbb-common-message_2.12:0.0.19-SNAPSHOT'
   
 }
 
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/GenericObjectPoolConfigWrapper.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/GenericObjectPoolConfigWrapper.java
deleted file mode 100755
index 47f3380f18929630792389aba30428bad3280bdc..0000000000000000000000000000000000000000
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/GenericObjectPoolConfigWrapper.java
+++ /dev/null
@@ -1,142 +0,0 @@
-/**
-* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
-* 
-* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
-*
-* This program is free software; you can redistribute it and/or modify it under the
-* terms of the GNU Lesser General Public License as published by the Free Software
-* Foundation; either version 3.0 of the License, or (at your option) any later
-* version.
-* 
-* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
-* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License along
-* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-*
-*/
-package org.bigbluebutton.voiceconf.messaging;
-
-import org.apache.commons.pool.impl.GenericObjectPool;
-
-public class GenericObjectPoolConfigWrapper {
-	
-	private final GenericObjectPool.Config config;
- 
-    public GenericObjectPoolConfigWrapper() {
-        this.config = new GenericObjectPool.Config();
-    }
- 
-    public GenericObjectPool.Config getConfig() {
-        return config;
-    }
- 
-    public int getMaxIdle() {
-        return this.config.maxIdle;
-    }
- 
-    public void setMaxIdle(int maxIdle) {
-        this.config.maxIdle = maxIdle;
-    }
- 
-    public int getMinIdle() {
-        return this.config.minIdle;
-    }
- 
-    public void setMinIdle(int minIdle) {
-        this.config.minIdle = minIdle;
-    }
- 
-    public int getMaxActive() {
-        return this.config.maxActive;
-    }
- 
-    public void setMaxActive(int maxActive) {
-        this.config.maxActive = maxActive;
-    }
- 
-    public long getMaxWait() {
-        return this.config.maxWait;
-    }
- 
-    public void setMaxWait(long maxWait) {
-        this.config.maxWait = maxWait;
-    }
- 
-    public byte getWhenExhaustedAction() {
-        return this.config.whenExhaustedAction;
-    }
- 
-    public void setWhenExhaustedAction(byte whenExhaustedAction) {
-        this.config.whenExhaustedAction = whenExhaustedAction;
-    }
- 
-    public boolean isTestOnBorrow() {
-        return this.config.testOnBorrow;
-    }
- 
-    public void setTestOnBorrow(boolean testOnBorrow) {
-        this.config.testOnBorrow = testOnBorrow;
-    }
- 
-    public boolean isTestOnReturn() {
-        return this.config.testOnReturn;
-    }
- 
-    public void setTestOnReturn(boolean testOnReturn) {
-        this.config.testOnReturn = testOnReturn;
-    }
- 
-    public boolean isTestWhileIdle() {
-        return this.config.testWhileIdle;
-    }
- 
-    public void setTestWhileIdle(boolean testWhileIdle) {
-        this.config.testWhileIdle = testWhileIdle;
-    }
- 
-    public long getTimeBetweenEvictionRunsMillis() {
-        return this.config.timeBetweenEvictionRunsMillis;
-    }
- 
-    public void setTimeBetweenEvictionRunsMillis(
-            long timeBetweenEvictionRunsMillis) {
-        this.config.timeBetweenEvictionRunsMillis =
-                timeBetweenEvictionRunsMillis;
-    }
- 
-    public int getNumTestsPerEvictionRun() {
-        return this.config.numTestsPerEvictionRun;
-    }
- 
-    public void setNumTestsPerEvictionRun(int numTestsPerEvictionRun) {
-        this.config.numTestsPerEvictionRun = numTestsPerEvictionRun;
-    }
- 
-    public long getMinEvictableIdleTimeMillis() {
-        return this.config.minEvictableIdleTimeMillis;
-    }
- 
-    public void setMinEvictableIdleTimeMillis(long minEvictableIdleTimeMillis) {
-        this.config.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
-    }
- 
-    public long getSoftMinEvictableIdleTimeMillis() {
-        return this.config.softMinEvictableIdleTimeMillis;
-    }
- 
-    public void setSoftMinEvictableIdleTimeMillis(
-            long softMinEvictableIdleTimeMillis) {
-        this.config.softMinEvictableIdleTimeMillis =
-                softMinEvictableIdleTimeMillis;
-    }
- 
-    public boolean isLifo() {
-        return this.config.lifo;
-    }
- 
-    public void setLifo(boolean lifo) {
-        this.config.lifo = lifo;
-    }
-}
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/IMessagingService.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/IMessagingService.java
index 72e5905e545218c5fa0673307540aaa56c782790..f3498c6601e75236e53973a94efe8f7789d335b3 100755
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/IMessagingService.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/IMessagingService.java
@@ -1,6 +1,7 @@
 package org.bigbluebutton.voiceconf.messaging;
 
 public interface IMessagingService {
+	void validateConnAuthToken(String meetingId, String userId, String authToken, String connId);
 	void userConnectedToGlobalAudio(String voiceConf, String callerIdName);
 	void userDisconnectedFromGlobalAudio(String voiceConf, String callerIdName);
 }
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MeetingMessageHandler.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MeetingMessageHandler.java
new file mode 100755
index 0000000000000000000000000000000000000000..04623357859b93ae1dcb41d49aff0bc66994cbe4
--- /dev/null
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MeetingMessageHandler.java
@@ -0,0 +1,74 @@
+package org.bigbluebutton.voiceconf.messaging;
+
+import com.google.gson.Gson;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import org.bigbluebutton.voiceconf.messaging.messages.ValidateConnTokenRespMsg;
+import org.bigbluebutton.voiceconf.red5.ConnectionInvokerService;
+import org.red5.logging.Red5LoggerFactory;
+import org.slf4j.Logger;
+
+public class MeetingMessageHandler implements MessageHandler {
+    private static Logger log = Red5LoggerFactory.getLogger(MeetingMessageHandler.class, "video");
+
+    private final String HEADER = "header";
+    private final String NAME = "name";
+    private final String BODY = "body";
+    private final String MEETING_ID = "meetingId";
+    private final String TIMESTAMP = "timestamp";
+    private final String ENVELOPE = "envelope";
+    private final String CORE = "core";
+
+    private final String USERID = "userId";
+    private final String AUTHZED = "authzed";
+    private final String CONN = "connId";
+    private final String APP = "app";
+    private final String VOICE_APP = "VOICE";
+
+    private final String ValidateConnAuthTokenSysRespMsg = "ValidateConnAuthTokenSysRespMsg";
+
+    private ConnectionInvokerService connInvokerService;
+
+    public void handleMessage(String pattern, String channel, String message) {
+        JsonParser parser = new JsonParser();
+        JsonObject obj = (JsonObject) parser.parse(message);
+
+        if (obj.has(ENVELOPE) && obj.has(CORE)) {
+            JsonObject core = obj.getAsJsonObject(CORE);
+            JsonObject header = core.getAsJsonObject(HEADER);
+            if (header.has(NAME)) {
+                String name = header.get(NAME).getAsString();
+                handle(name, core.getAsJsonObject(BODY));
+            }
+        }
+    }
+
+    private void handle(String name, JsonObject body) {
+        if (ValidateConnAuthTokenSysRespMsg.equals(name)) {
+            Gson gson = new Gson();
+            String logStr = gson.toJson(body);
+
+            log.debug("HANDLE: {}", logStr);
+            if (body.has(MEETING_ID) && body.has(USERID)
+                    && body.has(AUTHZED) && body.has(CONN) && body.has(APP)) {
+                String meetingId = body.get(MEETING_ID).getAsString();
+                String userId = body.get(USERID).getAsString();
+                Boolean authzed = body.get(AUTHZED).getAsBoolean();
+                String conn = body.get(CONN).getAsString();
+                String app = body.get(APP).getAsString();
+
+                log.debug("PROCESS: {}", name);
+                if (VOICE_APP.equals(app)) {
+                    ValidateConnTokenRespMsg vctrm = new ValidateConnTokenRespMsg(meetingId, userId, authzed, conn);
+                    connInvokerService.sendMessage(vctrm);
+                }
+            } else {
+                log.debug("INVALID MSG FORMAT: {}", logStr);
+            }
+        }
+    }
+
+    public void setConnInvokerService(ConnectionInvokerService connInvokerService) {
+        this.connInvokerService = connInvokerService;
+    }
+}
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageReceiver.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageReceiver.java
index 5c170fc7a78c79b1f12eadb3da20bec860db64b2..9033abe06a9a511d90f42520cf8c5daae97b5df6 100755
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageReceiver.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageReceiver.java
@@ -7,62 +7,97 @@ import org.slf4j.Logger;
 import redis.clients.jedis.Jedis;
 import redis.clients.jedis.JedisPool;
 import redis.clients.jedis.JedisPubSub;
+import redis.clients.jedis.exceptions.JedisConnectionException;
 
 public class MessageReceiver {
 	private static Logger log = Red5LoggerFactory.getLogger(MessageReceiver.class, "bigbluebutton");
-	
+
 	private ReceivedMessageHandler handler;
-	
-	private JedisPool redisPool;
+
+	private Jedis jedis;
 	private volatile boolean receiveMessage = false;
-	
+
 	private final Executor msgReceiverExec = Executors.newSingleThreadExecutor();
+	private final Executor runExec = Executors.newSingleThreadExecutor();
+
+	private final String FROM_BBB_APPS_PATTERN = "from-akka-apps-redis-channel";
+
+	private String host;
+	private int port;
 
 	public void stop() {
 		receiveMessage = false;
 	}
-	
+
 	public void start() {
 		log.info("Ready to receive messages from Redis pubsub.");
 		try {
 			receiveMessage = true;
-			final Jedis jedis = redisPool.getResource();
-			
+			jedis = new Jedis(host, port);
+			// Set the name of this client to be able to distinguish when doing
+			// CLIENT LIST on redis-cli
+			jedis.clientSetname("BbbRed5VoiceSub");
+
 			Runnable messageReceiver = new Runnable() {
-			    public void run() {
-			    	if (receiveMessage) {
-			    		jedis.psubscribe(new PubSubListener(), MessagingConstants.TO_AKKA_APPS_CHANNEL);
-			    	}
-			    }
+				public void run() {
+					if (receiveMessage) {
+						try {
+							jedis.subscribe(new PubSubListener(), FROM_BBB_APPS_PATTERN);
+						} catch(JedisConnectionException ex) {
+							log.warn("Exception on Jedis connection. Resubscribing to pubsub.");
+							start();
+						} catch (Exception e) {
+							log.error("Error resubscribing to channels: " + e.getMessage());
+						}
+					}
+				}
 			};
 			msgReceiverExec.execute(messageReceiver);
 		} catch (Exception e) {
 			log.error("Error subscribing to channels: " + e.getMessage());
-		}			
+		}
 	}
-	
-	public void setRedisPool(JedisPool redisPool){
-		this.redisPool = redisPool;
+
+	public void setHost(String host){
+		this.host = host;
 	}
-	
+
+	public void setPort(int port) {
+		this.port = port;
+	}
+
 	public void setMessageHandler(ReceivedMessageHandler handler) {
 		this.handler = handler;
 	}
-	
+
 	private class PubSubListener extends JedisPubSub {
-		
+
 		public PubSubListener() {
-			super();			
+			super();
 		}
 
 		@Override
 		public void onMessage(String channel, String message) {
 			// Not used.
+			Runnable task = new Runnable() {
+				public void run() {
+					handler.handleMessage("", channel, message);
+				}
+			};
+
+			runExec.execute(task);
 		}
 
 		@Override
-		public void onPMessage(String pattern, String channel, String message) {
-			handler.handleMessage(pattern, channel, message);			
+		public void onPMessage(final String pattern, final String channel, final String message) {
+			System.out.println("RECEIVED onPMessage" + channel + "\n" + message);
+			Runnable task = new Runnable() {
+				public void run() {
+					handler.handleMessage(pattern, channel, message);
+				}
+			};
+
+			runExec.execute(task);
 		}
 
 		@Override
@@ -83,6 +118,6 @@ public class MessageReceiver {
 		@Override
 		public void onUnsubscribe(String channel, int subscribedChannels) {
 			// Not used.
-		}		
+		}
 	}
 }
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageSender.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageSender.java
index 109f00ca0f70789cdf42b8ea31a51e65487b4731..67869c13367f6892a4a7b3e0cf82fcd393844227 100755
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageSender.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/MessageSender.java
@@ -8,60 +8,95 @@ import org.red5.logging.Red5LoggerFactory;
 import org.slf4j.Logger;
 import redis.clients.jedis.Jedis;
 import redis.clients.jedis.JedisPool;
+import redis.clients.jedis.Protocol;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
 
 public class MessageSender {
 	private static Logger log = Red5LoggerFactory.getLogger(MessageSender.class, "bigbluebutton");
-	
+
 	private JedisPool redisPool;
 	private volatile boolean sendMessage = false;
-	
+
 	private final Executor msgSenderExec = Executors.newSingleThreadExecutor();
+	private final Executor runExec = Executors.newSingleThreadExecutor();
 	private BlockingQueue<MessageToSend> messages = new LinkedBlockingQueue<MessageToSend>();
-	
+	private String host;
+	private int port;
+
 	public void stop() {
 		sendMessage = false;
+		redisPool.destroy();
 	}
-	
-	public void start() {	
-		log.info("Redis message publisher starting!");
+
+	public void start() {
+
+		GenericObjectPoolConfig config = new GenericObjectPoolConfig();
+		config.setMaxTotal(32);
+		config.setMaxIdle(8);
+		config.setMinIdle(1);
+		config.setTestOnBorrow(true);
+		config.setTestOnReturn(true);
+		config.setTestWhileIdle(true);
+		config.setNumTestsPerEvictionRun(12);
+		config.setMaxWaitMillis(5000);
+		config.setTimeBetweenEvictionRunsMillis(60000);
+		config.setBlockWhenExhausted(true);
+
+		// Set the name of this client to be able to distinguish when doing
+		// CLIENT LIST on redis-cli
+		redisPool = new JedisPool(config, host, port, Protocol.DEFAULT_TIMEOUT, null,
+				Protocol.DEFAULT_DATABASE, "BbbRed5VoicePub");
+
+		log.info("Redis org.bigbluebutton.red5.pubsub.message publisher starting!");
 		try {
 			sendMessage = true;
-			
+
 			Runnable messageSender = new Runnable() {
-			    public void run() {
-			    	while (sendMessage) {
-				    	try {
+				public void run() {
+					while (sendMessage) {
+						try {
 							MessageToSend msg = messages.take();
 							publish(msg.getChannel(), msg.getMessage());
 						} catch (InterruptedException e) {
-							log.warn("Failed to get message from queue.");
-						}    			    		
-			    	}
-			    }
+							log.warn("Failed to get org.bigbluebutton.red5.pubsub.message from queue.");
+						}
+					}
+				}
 			};
 			msgSenderExec.execute(messageSender);
 		} catch (Exception e) {
 			log.error("Error subscribing to channels: " + e.getMessage());
-		}			
+		}
 	}
-	
+
 	public void send(String channel, String message) {
 		MessageToSend msg = new MessageToSend(channel, message);
 		messages.add(msg);
 	}
-	
-	private void publish(String channel, String message) {
-		Jedis jedis = redisPool.getResource();
-		try {
-			jedis.publish(channel, message);
-		} catch(Exception e){
-			log.warn("Cannot publish the message to redis", e);
-		} finally {
-			redisPool.returnResource(jedis);
-		}
+
+	private void publish(final String channel, final String message) {
+		Runnable task = new Runnable() {
+			public void run() {
+				Jedis jedis = redisPool.getResource();
+				try {
+					jedis.publish(channel, message);
+				} catch(Exception e){
+					log.warn("Cannot publish the org.bigbluebutton.red5.pubsub.message to redis", e);
+				} finally {
+					redisPool.returnResource(jedis);
+				}
+			}
+		};
+
+		runExec.execute(task);
 	}
-	
-	public void setRedisPool(JedisPool redisPool){
-		this.redisPool = redisPool;
+
+
+	public void setHost(String host){
+		this.host = host;
+	}
+
+	public void setPort(int port) {
+		this.port = port;
 	}
 }
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/RedisMessagingService.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/RedisMessagingService.java
index eda175c0843995b354683524c03237c4f6b8e549..11da04a9f7c525a296437691cacb8284b2a82f91 100755
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/RedisMessagingService.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/RedisMessagingService.java
@@ -1,7 +1,11 @@
 package org.bigbluebutton.voiceconf.messaging;
 
+import java.util.HashMap;
+import java.util.Map;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import org.bigbluebutton.common2.msgs.*;
+import com.google.gson.Gson;
 import org.bigbluebutton.voiceconf.messaging.messages.UserConnectedToGlobalAudio;
 import org.bigbluebutton.voiceconf.messaging.messages.UserDisconnectedFromGlobalAudio;
 import org.red5.logging.Red5LoggerFactory;
@@ -13,7 +17,40 @@ public class RedisMessagingService implements IMessagingService {
   private static final Pattern CALLERNAME_PATTERN = Pattern.compile("(.*)-bbbID-(.*)$");
   
 	private MessageSender sender;
-	
+
+	private Map<String, Object> buildEnvelope(String name, Map<String, String> routing) {
+		Map<String, Object> envelope = new HashMap<String, Object>();
+		envelope.put("name", name);
+		envelope.put("routing", routing);
+		return envelope;
+	}
+
+	private Map<String, String> buildRouting() {
+		Map<String, String> routing = new HashMap<String, String>();
+		routing.put("msgType", "SYSTEM");
+		routing.put("sender", "bbb-voice");
+		return routing;
+	}
+
+	public void validateConnAuthToken(String meetingId, String userId, String authToken, String connId) {
+		BbbCoreBaseHeader header = new BbbCoreBaseHeader("ValidateConnAuthTokenSysMsg");
+		ValidateConnAuthTokenSysMsgBody body = new ValidateConnAuthTokenSysMsgBody(meetingId,
+				userId, authToken, connId, "VOICE");
+		ValidateConnAuthTokenSysMsg msg = new ValidateConnAuthTokenSysMsg(header, body);
+
+		Map<String, String> routing = buildRouting();
+		Map<String, Object> envelope = buildEnvelope("ValidateConnAuthTokenSysMsg", routing);
+
+		Map<String, Object> fullmsg = new HashMap<String, Object>();
+		fullmsg.put("envelope", envelope);
+		fullmsg.put("core", msg);
+
+		Gson gson = new Gson();
+		String json = gson.toJson(fullmsg);
+
+		sender.send("to-akka-apps-redis-channel", json);
+	}
+
 	@Override
 	public void userConnectedToGlobalAudio(String voiceConf, String callerIdName) {
 		
@@ -33,7 +70,7 @@ public class RedisMessagingService implements IMessagingService {
 	@Override
 	public void userDisconnectedFromGlobalAudio(String voiceConf, String callerIdName) {
 	  	Matcher matcher = CALLERNAME_PATTERN.matcher(callerIdName);
-	    if (matcher.matches()) {			
+	    if (matcher.matches()) {
 		    String userid = matcher.group(1).trim();
 		    String name = matcher.group(2).trim();
 				String json = new UserDisconnectedFromGlobalAudio(voiceConf, userid, name).toJson();
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/messages/ClientMessage.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/messages/ClientMessage.java
new file mode 100755
index 0000000000000000000000000000000000000000..ad1f609159f1ecc1f835d934dd1f258d1a53234c
--- /dev/null
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/messages/ClientMessage.java
@@ -0,0 +1,25 @@
+/**
+* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+* 
+* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
+*
+* This program is free software; you can redistribute it and/or modify it under the
+* terms of the GNU Lesser General Public License as published by the Free Software
+* Foundation; either version 3.0 of the License, or (at your option) any later
+* version.
+* 
+* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License along
+* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package org.bigbluebutton.voiceconf.messaging.messages;
+
+
+public interface ClientMessage {
+
+    String getMessageName();
+}
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/messages/ValidateConnTokenRespMsg.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/messages/ValidateConnTokenRespMsg.java
new file mode 100755
index 0000000000000000000000000000000000000000..922d7adc00196d013a3a9f9b06ff1d9a3ebfadc9
--- /dev/null
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/messaging/messages/ValidateConnTokenRespMsg.java
@@ -0,0 +1,20 @@
+package org.bigbluebutton.voiceconf.messaging.messages;
+
+public class ValidateConnTokenRespMsg implements ClientMessage {
+
+    public final String meetingId;
+    public final String connId;
+    public final String userId;
+    public final Boolean authzed;
+
+    public ValidateConnTokenRespMsg(String meetingId, String userId, Boolean authzed, String connId) {
+        this.meetingId = meetingId;
+        this.connId = connId;
+        this.authzed = authzed;
+        this.userId = userId;
+    }
+
+    public String getMessageName() {
+        return "ValidateConnAuthTokenSysRespMsg";
+    }
+}
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/Application.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/Application.java
index 9932ddd96329d025e91b701d120c5d9f5aa5f425..f7c16faf587a79e7a9431c5cf319dbc4f8317808 100755
--- a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/Application.java
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/Application.java
@@ -21,6 +21,8 @@ package org.bigbluebutton.voiceconf.red5;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Set;
+
+import org.bigbluebutton.voiceconf.messaging.IMessagingService;
 import org.slf4j.Logger;
 import org.bigbluebutton.voiceconf.sip.PeerNotFoundException;
 import org.bigbluebutton.voiceconf.sip.SipPeerManager;
@@ -33,6 +35,7 @@ import org.red5.server.api.service.IServiceCapableConnection;
 import org.red5.server.api.stream.IBroadcastStream;
 import org.red5.server.stream.ClientBroadcastStream;
 import com.google.gson.Gson;
+import org.springframework.util.StringUtils;
 
 public class Application extends MultiThreadedApplicationAdapter {
 	private static Logger log = Red5LoggerFactory.getLogger(Application.class, "sip");
@@ -48,7 +51,10 @@ public class Application extends MultiThreadedApplicationAdapter {
 	private String password = "secret";
 	private String username;
 	private CallStreamFactory callStreamFactory;
-	
+
+	private ConnectionInvokerService connInvokerService;
+	private IMessagingService messagingService;
+
     @Override
     public boolean appStart(IScope scope) {
     	log.debug("VoiceConferenceApplication appStart[" + scope.getName() + "]");
@@ -64,6 +70,8 @@ public class Application extends MultiThreadedApplicationAdapter {
       	// TODO Auto-generated catch block
       	e.printStackTrace();
       }
+
+		connInvokerService.setAppScope(scope);
       return super.appStart(scope);
     }
 
@@ -74,89 +82,119 @@ public class Application extends MultiThreadedApplicationAdapter {
         super.appStop(scope);
     }
 
-    @Override
-    public boolean appConnect(IConnection conn, Object[] params) {
-    	String meetingId = ((String) params[0]).toString();
-    	String userId = ((String) params[1]).toString();
-      String username = ((String) params[2]).toString();
-      String clientId = Red5.getConnectionLocal().getClient().getId();
-      String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
-      int remotePort = Red5.getConnectionLocal().getRemotePort();
-        
-      if ((userId == null) || ("".equals(userId))) userId = "unknown-userid";
-      if ((username == null) || ("".equals(username))) username = "UNKNOWN-CALLER";
-      Red5.getConnectionLocal().setAttribute("MEETING_ID", meetingId);
-      Red5.getConnectionLocal().setAttribute("USERID", userId);
-      Red5.getConnectionLocal().setAttribute("USERNAME", username);
-        
-      log.info("{} [clientid={}] has connected to the voice conf app.", username + "[uid=" + userId + "]", clientId);
-      log.info("[clientid={}] connected from {}.", clientId, remoteHost + ":" + remotePort);
-      
-  		String connType = getConnectionType(Red5.getConnectionLocal().getType());
-  		String userFullname = username;
-  		String connId = Red5.getConnectionLocal().getSessionId();
-  		
-  		Map<String, Object> logData = new HashMap<String, Object>();
-  		logData.put("meetingId", meetingId);
-  		logData.put("connType", connType);
-  		logData.put("connId", connId);
-  		logData.put("userId", userId);
-  		logData.put("username", userFullname);
-  		logData.put("event", "user_joining_bbb_voice");
-  		logData.put("description", "User joining BBB Voice.");
-  		
-  		Gson gson = new Gson();
-      String logStr =  gson.toJson(logData);
-  		
-  		log.info("User joining bbb-voice: data={}", logStr);
-      
-      clientConnManager.createClient(clientId, userId, username, (IServiceCapableConnection) Red5.getConnectionLocal());
-      return super.appConnect(conn, params);
-    }
-    
-  	private String getConnectionType(String connType) {
-  		if ("persistent".equals(connType.toLowerCase())) {
-  			return "RTMP";
-  		} else if("polling".equals(connType.toLowerCase())) {
-  			return "RTMPT";
-  		} else {
-  			return connType.toUpperCase();
-  		}
-  	}
+	@Override
+	public boolean appConnect(IConnection conn, Object[] params) {
 
-    @Override
-    public void appDisconnect(IConnection conn) {
-    	String clientId = Red5.getConnectionLocal().getClient().getId();
-    	String userId = getUserId();
-    	String username = getUsername();
-    	
-      String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
-      int remotePort = Red5.getConnectionLocal().getRemotePort();    	
-    	log.info("[clientid={}] disconnnected from {}.", clientId, remoteHost + ":" + remotePort);
-      log.debug("{} [clientid={}] is leaving the voice conf app. Removing from ConnectionManager.", username + "[uid=" + userId + "]", clientId);
-    	
-  		String connType = getConnectionType(Red5.getConnectionLocal().getType());
-  		String userFullname = username;
-  		String connId = Red5.getConnectionLocal().getSessionId();
-  		
-  		Map<String, Object> logData = new HashMap<String, Object>();
-  		logData.put("meetingId", getMeetingId());
-  		logData.put("connType", connType);
-  		logData.put("connId", connId);
-  		logData.put("userId", userId);
-  		logData.put("username", userFullname);
-  		logData.put("event", "user_leaving_bbb_voice");
-  		logData.put("description", "User leaving BBB Voice.");
-  		
-  		Gson gson = new Gson();
-      String logStr =  gson.toJson(logData);
-  		
-  		log.info("User leaving bbb-voice: data={}", logStr);
-      
-      clientConnManager.removeClient(clientId);
-
-      String peerId = (String) Red5.getConnectionLocal().getAttribute("VOICE_CONF_PEER");
-      if (peerId != null) {
+		if(params.length != 4) {
+			log.error("Invalid number of parameters. param length=" + params.length);
+			return false;
+		}
+
+		String meetingId = ((String) params[0]).toString();
+		String userId = ((String) params[1]).toString();
+		String username = ((String) params[2]).toString();
+		String authToken = ((String) params[3]).toString();
+
+		if (StringUtils.isEmpty(meetingId)) {
+			log.error("Invalid meetingId parameter.");
+			return false;
+		}
+
+		if (StringUtils.isEmpty(userId)) {
+			log.error("Invalid userId parameter.");
+			return false;
+		}
+
+		if (StringUtils.isEmpty(username)) {
+			log.error("Invalid username parameter.");
+			return false;
+		}
+
+		if (StringUtils.isEmpty(authToken)) {
+			log.error("Invalid authToken parameter.");
+			return false;
+		}
+
+		String clientId = Red5.getConnectionLocal().getClient().getId();
+		String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
+		int remotePort = Red5.getConnectionLocal().getRemotePort();
+
+		Red5.getConnectionLocal().setAttribute("MEETING_ID", meetingId);
+		Red5.getConnectionLocal().setAttribute("USERID", userId);
+		Red5.getConnectionLocal().setAttribute("USERNAME", username);
+
+		log.info("{} [clientid={}] has connected to the voice conf app.", username + "[uid=" + userId + "]", clientId);
+		log.info("[clientid={}] connected from {}.", clientId, remoteHost + ":" + remotePort);
+
+		String connType = getConnectionType(Red5.getConnectionLocal().getType());
+		String userFullname = username;
+		String connId = Red5.getConnectionLocal().getSessionId();
+
+		log.info("BBB Voice validateConnAuthToken");
+		messagingService.validateConnAuthToken(meetingId, userId, authToken, connId);
+
+		Map<String, Object> logData = new HashMap<String, Object>();
+		logData.put("meetingId", meetingId);
+		logData.put("connType", connType);
+		logData.put("connId", connId);
+		logData.put("userId", userId);
+		logData.put("username", userFullname);
+		logData.put("event", "user_joining_bbb_voice");
+		logData.put("description", "User joining BBB Voice.");
+
+		Gson gson = new Gson();
+		String logStr =  gson.toJson(logData);
+
+		log.info("User joining bbb-voice: data={}", logStr);
+
+		clientConnManager.createClient(clientId, userId, username, (IServiceCapableConnection) Red5.getConnectionLocal());
+		return super.appConnect(conn, params);
+	}
+
+	private String getConnectionType(String connType) {
+		if ("persistent".equals(connType.toLowerCase())) {
+			return "RTMP";
+		} else if("polling".equals(connType.toLowerCase())) {
+			return "RTMPT";
+		} else {
+			return connType.toUpperCase();
+		}
+	}
+
+	@Override
+	public void appDisconnect(IConnection conn) {
+		String clientId = Red5.getConnectionLocal().getClient().getId();
+		String userId = getUserId();
+		String username = getUsername();
+
+		String remoteHost = Red5.getConnectionLocal().getRemoteAddress();
+		int remotePort = Red5.getConnectionLocal().getRemotePort();
+		log.info("[clientid={}] disconnnected from {}.", clientId, remoteHost + ":" + remotePort);
+		log.debug("{} [clientid={}] is leaving the voice conf app. Removing from ConnectionManager.", username + "[uid=" + userId + "]", clientId);
+
+		String connType = getConnectionType(Red5.getConnectionLocal().getType());
+		String userFullname = username;
+		String connId = Red5.getConnectionLocal().getSessionId();
+
+		Map<String, Object> logData = new HashMap<String, Object>();
+		logData.put("meetingId", getMeetingId());
+		logData.put("connType", connType);
+		logData.put("connId", connId);
+		logData.put("userId", userId);
+		logData.put("username", userFullname);
+		logData.put("event", "user_leaving_bbb_voice");
+		logData.put("description", "User leaving BBB Voice.");
+
+		Gson gson = new Gson();
+		String logStr =  gson.toJson(logData);
+
+		log.info("User leaving bbb-voice: data={}", logStr);
+
+		clientConnManager.removeClient(clientId);
+
+		String peerId = (String) Red5.getConnectionLocal().getAttribute("VOICE_CONF_PEER");
+
+		if (peerId != null) {
 				try {
 					log.debug("Forcing hang up {} [clientid={}] in case the user is still in the conference.", username + "[uid=" + userId + "]", clientId);
 					sipPeerManager.hangup(peerId, clientId);
@@ -164,9 +202,9 @@ public class Application extends MultiThreadedApplicationAdapter {
 					// TODO Auto-generated catch block
 					e.printStackTrace();
 				}
-      }
-      super.appDisconnect(conn);
-    }
+		}
+		super.appDisconnect(conn);
+	}
     
     @Override
     public void streamPublishStart(IBroadcastStream stream) {
@@ -279,4 +317,12 @@ public class Application extends MultiThreadedApplicationAdapter {
 		if ((username == null) || ("".equals(username))) username = "UNKNOWN-CALLER";
 		return username;
 	}
+
+	public void setConnInvokerService(ConnectionInvokerService connInvokerService) {
+		this.connInvokerService = connInvokerService;
+	}
+
+	public void setMessagingService(IMessagingService service) {
+		messagingService = service;
+	}
 }
diff --git a/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/ConnectionInvokerService.java b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/ConnectionInvokerService.java
new file mode 100755
index 0000000000000000000000000000000000000000..61ddb21852f9c50f85f8c920782a6184ebd70a9a
--- /dev/null
+++ b/bbb-voice/src/main/java/org/bigbluebutton/voiceconf/red5/ConnectionInvokerService.java
@@ -0,0 +1,168 @@
+/**
+* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+* 
+* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
+*
+* This program is free software; you can redistribute it and/or modify it under the
+* terms of the GNU Lesser General Public License as published by the Free Software
+* Foundation; either version 3.0 of the License, or (at your option) any later
+* version.
+* 
+* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public License along
+* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+*
+*/
+package org.bigbluebutton.voiceconf.red5;
+
+import com.google.gson.Gson;
+import org.bigbluebutton.voiceconf.messaging.messages.ClientMessage;
+import org.bigbluebutton.voiceconf.messaging.messages.ValidateConnTokenRespMsg;
+import org.red5.logging.Red5LoggerFactory;
+import org.red5.server.api.IConnection;
+import org.red5.server.api.scope.IScope;
+import org.slf4j.Logger;
+import org.slf4j.Marker;
+import org.slf4j.MarkerFactory;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.*;
+
+public class ConnectionInvokerService {
+  private static Logger log = Red5LoggerFactory.getLogger(ConnectionInvokerService.class, "video");
+
+  private final String CONN = "RED5-";
+  private static final int NTHREADS = 1;
+  private static final Executor exec = Executors.newFixedThreadPool(NTHREADS);
+  private static final ExecutorService runExec = Executors.newFixedThreadPool(3);
+
+  private BlockingQueue<ClientMessage> messages;
+  private volatile boolean sendMessages = false;
+  private IScope bbbAppScope;
+
+  private final long SEND_TIMEOUT = 5000000000L; // 5s
+
+  private Long lastMsgLengthLog = System.currentTimeMillis();
+
+  public ConnectionInvokerService() {
+    messages = new LinkedBlockingQueue<ClientMessage>();
+  }
+
+  public void setAppScope(IScope scope) {
+    bbbAppScope = scope;
+  }
+
+  public void start() {
+    sendMessages = true;
+    Runnable sender = new Runnable() {
+      public void run() {
+        while (sendMessages) {
+          ClientMessage message;
+          try {
+            if (System.currentTimeMillis() - lastMsgLengthLog > 60000) {
+              lastMsgLengthLog = System.currentTimeMillis();
+              log.info("Message queue length = " + messages.size());
+            }
+            message = messages.take();
+            if (log.isTraceEnabled()) {
+              log.trace("Took org.bigbluebutton.red5.pubsub.message from queue: " + message.getMessageName());
+            }
+            sendMessageToClient(message);
+            if (log.isTraceEnabled()) {
+              log.trace("Sent org.bigbluebutton.red5.pubsub.message to client: " + message.getMessageName());
+            }
+          } catch (Exception e) {
+            Marker sendingException = MarkerFactory.getMarker("SENDING_EXCEPTION");
+            log.error(sendingException, "Exception while sending org.bigbluebutton.red5.pubsub.message to client.", e);
+          }
+        }
+      }
+    };
+    exec.execute(sender);
+  }
+
+  public void stop() {
+    sendMessages = false;
+    runExec.shutdown();
+  }
+
+  public void sendMessage(final ClientMessage message) {
+    if (log.isTraceEnabled()) {
+      log.trace("Queue org.bigbluebutton.red5.pubsub.message: " + message.getMessageName());
+    }
+    messages.offer(message);
+  }
+
+  private void sendMessageToClient(ClientMessage message) {
+    if (message instanceof ValidateConnTokenRespMsg) {
+      handleValidateConnTokenRespMsg((ValidateConnTokenRespMsg) message);
+    }
+  }
+
+  private void handleValidateConnTokenRespMsg(ValidateConnTokenRespMsg msg) {
+    if (log.isTraceEnabled()) {
+      log.trace("Handle direct org.bigbluebutton.red5.pubsub.message: " + msg.getMessageName() + " conn=" + msg.connId);
+    }
+
+    IScope meetingScope = getScope(msg.meetingId);
+    if (meetingScope != null) {
+      String userId = msg.userId;
+      IConnection conn = getConnection(meetingScope, userId);
+      if (conn != null) {
+        if (conn.isConnected() && !msg.authzed) {
+          Map<String, Object> logData = new HashMap<String, Object>();
+          logData.put("meetingId", msg.meetingId);
+          logData.put("userId", userId);
+          logData.put("authzed", msg.authzed);
+          logData.put("app", "video");
+          logData.put("event", "close_unauthorized_connection");
+          logData.put("description", "Closing unauthorized connection.");
+
+          Gson gson = new Gson();
+          String logStr = gson.toJson(logData);
+
+          log.info("Closing unauthorized connection: data={}", logStr);
+          conn.close();
+        }
+      }
+    }
+  }
+
+  private IConnection getConnectionWithConnId(IScope scope, String connId) {
+    for (IConnection conn : scope.getClientConnections()) {
+      String connID = (String) conn.getSessionId();
+      if (connID != null && connID.equals(connId)) {
+        return conn;
+      }
+    }
+
+    log.warn("Failed to get connection for connId = " + connId);
+    return null;
+  }
+
+  private IConnection getConnection(IScope scope, String userId) {
+    for (IConnection conn : scope.getClientConnections()) {
+      String connID = (String) conn.getAttribute("USERID");
+      if (connID != null && connID.equals(userId)) {
+        return conn;
+      }
+    }
+
+    log.warn("Failed to get connection for userId = " + userId);
+    return null;
+  }
+
+  public IScope getScope(String meetingID) {
+    if (bbbAppScope != null) {
+      return bbbAppScope.getContext().resolveScope("video");
+    } else {
+      log.error("BigBlueButton Scope not initialized. No messages are going to the Flash client!");
+    }
+    
+    return null;
+  }
+}
diff --git a/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-messaging.xml b/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-messaging.xml
index 536588174e35f21fe0cebeb10b45bf050919758f..fe19d06cc39a355141fc0d48cf604f7b9f8913bb 100755
--- a/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-messaging.xml
+++ b/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-messaging.xml
@@ -27,32 +27,39 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			http://www.springframework.org/schema/util/spring-util-2.0.xsd
 			">
 	
-  <bean id="messagingService" class="org.bigbluebutton.voiceconf.messaging.RedisMessagingService">
-      <property name="redisMessageSender"> <ref bean="redisMessageSender"/></property>
-  </bean>
-      	
-    <bean id="redisMessageSender" class="org.bigbluebutton.voiceconf.messaging.MessageSender" 
-                    init-method="start" destroy-method="stop">
-    	<property name="redisPool"> <ref bean="redisPool"/></property>
-  	</bean>
-<!--
-    <bean id="redisMessageReceiver" class="org.bigbluebutton.voiceconf.messaging.MessageReceiver" 
-                    init-method="start" destroy-method="stop">
-    	<property name="redisPool"> <ref bean="redisPool"/></property>
-    	<property name="messageHandler"> <ref local="redisMessageHandler"/> </property>
-  	</bean>
-
-    <bean id="redisMessageHandler" class="org.bigbluebutton.voiceconf.messaging.ReceivedMessageHandler" 
-                    init-method="start" destroy-method="stop">
-      <property name="messageDistributor"><ref bean="redisMessageDistributor" /></property>
-    </bean>
-  	
-  	<bean id="redisMessageDistributor" class="org.bigbluebutton.voiceconf.messaging.MessageDistributor">
-  	     <property name="messageHandler"> <ref local="redisMessageHandler"/> </property>
-  	     <property name="messageListeners">
-            <set>
-            </set>
-        </property> 
-  	</bean>	  	
---> 
+	<bean id="messagingService" class="org.bigbluebutton.voiceconf.messaging.RedisMessagingService">
+		<property name="redisMessageSender"> <ref bean="redisMessageSender"/></property>
+	</bean>
+
+	<bean id="redisMessageSender" class="org.bigbluebutton.voiceconf.messaging.MessageSender"
+		  init-method="start" destroy-method="stop">
+		<property name="host" value="${redis.host}"/>
+		<property name="port" value="${redis.port}"/>
+	</bean>
+
+	<bean id="meetingMessageHandler" class="org.bigbluebutton.voiceconf.messaging.MeetingMessageHandler">
+		<property name="connInvokerService" ref="connInvokerService"/>
+	</bean>
+
+	<bean id="redisMessageReceiver" class="org.bigbluebutton.voiceconf.messaging.MessageReceiver"
+		  init-method="start" destroy-method="stop">
+		<property name="host" value="${redis.host}"/>
+		<property name="port" value="${redis.port}"/>
+		<property name="messageHandler"> <ref local="redisMessageHandler"/> </property>
+	</bean>
+
+	<bean id="redisMessageHandler" class="org.bigbluebutton.voiceconf.messaging.ReceivedMessageHandler"
+		  init-method="start" destroy-method="stop">
+		<property name="messageDistributor"><ref bean="redisMessageDistributor" /></property>
+	</bean>
+
+	<bean id="redisMessageDistributor" class="org.bigbluebutton.voiceconf.messaging.MessageDistributor">
+		<property name="messageHandler"> <ref local="redisMessageHandler"/> </property>
+		<property name="messageListeners">
+			<set>
+				<ref bean="meetingMessageHandler" />
+			</set>
+		</property>
+	</bean>
+
 </beans>
diff --git a/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-pool.xml b/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-pool.xml
deleted file mode 100755
index b30253c68270271b8aaadb17a0606a4a09352027..0000000000000000000000000000000000000000
--- a/bbb-voice/src/main/webapp/WEB-INF/bbb-redis-pool.xml
+++ /dev/null
@@ -1,66 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
-
-BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
-
-Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
-
-This program is free software; you can redistribute it and/or modify it under the
-terms of the GNU Lesser General Public License as published by the Free Software
-Foundation; either version 3.0 of the License, or (at your option) any later
-version.
-
-BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
-WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License along
-with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-
--->
-<beans xmlns="http://www.springframework.org/schema/beans"
-	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-	xmlns:util="http://www.springframework.org/schema/util"
-	xsi:schemaLocation="http://www.springframework.org/schema/beans
-			http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
-			http://www.springframework.org/schema/util 
-			http://www.springframework.org/schema/util/spring-util-2.0.xsd
-			">
-  	
-    <bean id="redisPool" class="redis.clients.jedis.JedisPool">
-    	<constructor-arg index="0">
-    		<bean factory-bean="config" factory-method="getConfig" />
-  		</constructor-arg>
-        <constructor-arg index="1" value="${redis.host}"/>
-        <constructor-arg index="2" value="${redis.port}"/>
-    </bean>
-	    
-    <bean id="config" class="org.bigbluebutton.voiceconf.messaging.GenericObjectPoolConfigWrapper">
-	  <!-- Action to take when trying to acquire a connection and all connections are taken -->
-	  <property name="whenExhaustedAction">
-	    <!-- Fail-fast behaviour, we don't like to keep the kids waiting -->
-	    <util:constant static-field="org.apache.commons.pool.impl.GenericObjectPool.WHEN_EXHAUSTED_FAIL" />
-	    <!-- Default behaviour, block the caller until a resource becomes available -->
-	    <!--<util:constant static-field="org.apache.commons.pool.impl.GenericObjectPool.WHEN_EXHAUSTED_BLOCK" />-->
-	  </property>
-	  <!-- Maximum active connections to Redis instance -->
-	  <property name="maxActive" value="12" />
-	  <!-- Number of connections to Redis that just sit there and do nothing -->
-	  <property name="maxIdle" value="6" />
-	  <!-- Minimum number of idle connections to Redis - these can be seen as always open and ready to serve -->
-	  <property name="minIdle" value="1" />
-	  <!-- Tests whether connection is dead when connection retrieval method is called -->
-	  <property name="testOnBorrow" value="true" />
-	  <!-- Tests whether connection is dead when returning a connection to the pool -->
-	  <property name="testOnReturn" value="true" />
-	  <!-- Tests whether connections are dead during idle periods -->
-	  <property name="testWhileIdle" value="true" />
-	  <!-- Maximum number of connections to test in each idle check -->
-	  <property name="numTestsPerEvictionRun" value="12" />
-	  <!-- Idle connection checking period -->
-	  <property name="timeBetweenEvictionRunsMillis" value="60000" />
-	  <!-- Maximum time, in milliseconds, to wait for a resource when exausted action is set to WHEN_EXAUSTED_BLOCK -->
-	  <property name="maxWait" value="5000" />
-	</bean>
-    
-</beans>
diff --git a/bbb-voice/src/main/webapp/WEB-INF/red5-web.xml b/bbb-voice/src/main/webapp/WEB-INF/red5-web.xml
index df02df9dcc0c989cb4bdf55970cf307973205fba..12f3bb8eebe8e7b6c2f0778a9aabf5983d045e08 100755
--- a/bbb-voice/src/main/webapp/WEB-INF/red5-web.xml
+++ b/bbb-voice/src/main/webapp/WEB-INF/red5-web.xml
@@ -28,12 +28,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                            http://www.springframework.org/schema/lang/spring-lang-2.0.xsd">
 
 	<bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
-	    <property name="locations">
-	    	<list>
-	    	 	<value>/WEB-INF/red5-web.properties</value>
-	    	 	<value>/WEB-INF/bigbluebutton-sip.properties</value>
-	    	</list>
-	    </property>
+		<property name="locations">
+			<list>
+				<value>/WEB-INF/red5-web.properties</value>
+				<value>/WEB-INF/bigbluebutton-sip.properties</value>
+			</list>
+		</property>
 	</bean>
 	
 	
@@ -60,12 +60,17 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 		<property name="stopAudioPort" value="${stopAudioPort}" />
 		<property name="sipPeerManager" ref="sipPeerManager"/>
 		<property name="clientConnectionManager" ref="clientConnectionManager"/>
+		<property name="connInvokerService" ref="connInvokerService"/>
+		<property name="messagingService" ref="messagingService"/>
+	</bean>
+
+	<bean id="voiceconf.service" class="org.bigbluebutton.voiceconf.red5.Service">
+		<property name="sipPeerManager" ref="sipPeerManager"/>
 	</bean>
 
-    <bean id="voiceconf.service" class="org.bigbluebutton.voiceconf.red5.Service">
-        <property name="sipPeerManager" ref="sipPeerManager"/>
-    </bean>
-    	
+	<bean id="connInvokerService" class="org.bigbluebutton.voiceconf.red5.ConnectionInvokerService"
+		  init-method="start" destroy-method="stop"/>
+
 	<bean id="sipPeerManager" class="org.bigbluebutton.voiceconf.sip.SipPeerManager">
 		<property name="sipStackDebugLevel" value="${sipStackDebugLevel}"/>
 		<property name="sipRemotePort" value="${freeswitch.port}"/>
@@ -75,7 +80,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	
 	<bean id="clientConnectionManager" class="org.bigbluebutton.voiceconf.red5.ClientConnectionManager"/>
 
-  <import resource="bbb-redis-pool.xml"/>
-  <import resource="bbb-redis-messaging.xml"/>
-          
+	<import resource="bbb-redis-messaging.xml"/>
+
 </beans>
diff --git a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java
index 9cbb0b249a21a663a434a373c2402d8ecc00db30..bc6527693527ed7d43303de05d42e8522e617f37 100755
--- a/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java
+++ b/bigbluebutton-apps/src/main/java/org/bigbluebutton/red5/BigBlueButtonApplication.java
@@ -36,6 +36,7 @@ import org.red5.server.api.IClient;
 import org.red5.server.api.IConnection;
 import org.red5.server.api.Red5;
 import org.red5.server.api.scope.IScope;
+import org.red5.server.api.stream.IBroadcastStream;
 import org.slf4j.Logger;
 
 import com.google.gson.Gson;
@@ -137,6 +138,12 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
     	
 	@Override
 	public boolean roomConnect(IConnection connection, Object[] params) {
+
+		if(params.length != 10) {
+			log.error("Invalid number of parameters. param length=" + params.length);
+			return false;
+		}
+
 		String username = ((String) params[0]).toString();
 		String role = ((String) params[1]).toString();
 		String room = ((String)params[2]).toString();
@@ -259,6 +266,33 @@ public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter {
 		super.roomDisconnect(conn);
 	}
 
+	@Override
+	public void streamBroadcastStart(IBroadcastStream stream) {
+		IConnection conn = Red5.getConnectionLocal();
+		String contextName = stream.getScope().getName();
+
+		/**
+		 * There shouldn't be any broadcast stream in this scope.
+		 */
+
+		String connType = getConnectionType(Red5.getConnectionLocal().getType());
+		String connId = Red5.getConnectionLocal().getSessionId();
+		Map<String, Object> logData = new HashMap<String, Object>();
+		logData.put("connType", connType);
+		logData.put("connId", connId);
+		logData.put("stream", stream.getPublishedName());
+		logData.put("context", contextName);
+		logData.put("event", "unauth_publish_stream_bbb_apps");
+		logData.put("description", "Publishing stream in app context.");
+
+		Gson gson = new Gson();
+		String logStr =  gson.toJson(logData);
+		log.error(logStr);
+		conn.close();
+
+	}
+
+
 	public void onMessageFromClient(String json) {
 		//System.out.println("onMessageFromClient \n" + json);
 		if (json.length() < maxMessageLength) {
diff --git a/bigbluebutton-client/branding/default/style/css/V2Theme.css b/bigbluebutton-client/branding/default/style/css/V2Theme.css
index fa19ec2c9bca0d50e2b1443e159e8b1f3d412f6b..adc9f8c3151d22e04cf49b0bc3192b1a72fb44e6 100755
--- a/bigbluebutton-client/branding/default/style/css/V2Theme.css
+++ b/bigbluebutton-client/branding/default/style/css/V2Theme.css
@@ -647,6 +647,10 @@ chat|AddChatTabBox {
 
 chat|ChatMessageRenderer {
 	moderatorIcon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_User_Chat_Moderator");
+	verticalAlign : top;
+	verticalGap   : 0;
+	paddingBottom : 0;
+	paddingTop    : 0;
 }
 
 .chatMessageListStyle {
@@ -881,6 +885,22 @@ layout|LoadButton {
 	icon : Embed(source="assets/swf/v2_skin.swf", symbol="Icon_Send_Layout_RTL");
 }
 
+/*
+//------------------------------
+//  LoadingBar
+//------------------------------
+*/
+
+views|LoadingBar {
+	textAlign       : center;
+	horizontalAlign : center;
+}
+
+.loadingBarLabel {
+	color       : #8A9AA7;
+	fontWeight  : bold;
+}
+
 /*
 //------------------------------
 //  Logout Window
diff --git a/bigbluebutton-client/build.xml b/bigbluebutton-client/build.xml
index 49afe82cf197a7a0e7d9255be4b33bade178157e..6a04e076277bb73b83234aeb2184e3652046db0d 100755
--- a/bigbluebutton-client/build.xml
+++ b/bigbluebutton-client/build.xml
@@ -411,6 +411,9 @@
 		<copy todir="${OUTPUT_DIR}/swfobject/">
 			<fileset dir="${PROD_RESOURCES_DIR}/swfobject" />
 		</copy>
+		<copy todir="${OUTPUT_DIR}/logos/">
+			<fileset dir="${PROD_RESOURCES_DIR}/logos" />
+		</copy>
 		<copy todir="${OUTPUT_DIR}/lib/">
 			<fileset dir="${PROD_RESOURCES_DIR}/lib" />
 		</copy>
@@ -423,7 +426,6 @@
 		<copy file="${PROD_RESOURCES_DIR}/get_flash_player.gif" todir="${OUTPUT_DIR}" overwrite="true" />
 		<copy file="${PROD_RESOURCES_DIR}/bbb.gif" todir="${OUTPUT_DIR}" overwrite="true" />
 		<copy file="${PROD_RESOURCES_DIR}/avatar.png" todir="${OUTPUT_DIR}" overwrite="true" />
-		<copy file="${PROD_RESOURCES_DIR}/logo.swf" todir="${OUTPUT_DIR}" overwrite="true" />
 		<copy file="${PROD_RESOURCES_DIR}/background.jpg" todir="${OUTPUT_DIR}" overwrite="true" />
 		<copy file="${PROD_RESOURCES_DIR}/locales.xml" todir="${OUTPUT_DIR}/conf" overwrite="true" />
 		<copy file="${PROD_RESOURCES_DIR}/expressInstall.swf" todir="${OUTPUT_DIR}" overwrite="true" />
diff --git a/bigbluebutton-client/locale/en_US/bbbResources.properties b/bigbluebutton-client/locale/en_US/bbbResources.properties
index 05bf051314b80e45b73ffdb1d8bbd1f268a39e81..563eea1a48016895ac3fc3f2cbb011c7b40116ec 100755
--- a/bigbluebutton-client/locale/en_US/bbbResources.properties
+++ b/bigbluebutton-client/locale/en_US/bbbResources.properties
@@ -2,7 +2,7 @@ bbb.mainshell.locale.version = 0.9.0
 bbb.mainshell.statusProgress.connecting = Connecting to the server
 bbb.mainshell.statusProgress.loading = Loading
 bbb.mainshell.statusProgress.cannotConnectServer = Sorry, we cannot connect to the server.
-bbb.mainshell.copyrightLabel2 = (c) 2017 <a href='event:http://www.bigbluebutton.org/' target='_blank'><u>BigBlueButton Inc.</u></a> (build {0})
+bbb.mainshell.copyrightLabel2 = (c) 2018 <a href='event:http://www.bigbluebutton.org/' target='_blank'><u>BigBlueButton Inc.</u></a> (build {0})
 bbb.mainshell.logBtn.toolTip = Open Log Window
 bbb.mainshell.meetingNotFound = Meeting Not Found
 bbb.mainshell.invalidAuthToken = Invalid Authentication Token
@@ -765,7 +765,7 @@ bbb.polling.publishButton.label = Publish
 bbb.polling.closeButton.label = Close
 bbb.polling.customPollOption.label = Custom Poll...
 bbb.polling.pollModal.title = Live Poll Results
-bbb.polling.pollModal.hint = Leave this window open to allow students to respond to the poll. Selecting the Publish or Close button will end the poll.
+bbb.polling.pollModal.hint = Leave this window open to allow others to respond to the poll. Selecting the Publish or Close button will end the poll.
 bbb.polling.customChoices.title = Enter Polling Choices
 bbb.polling.respondersLabel.novotes = Waiting for responses
 bbb.polling.respondersLabel.text = {0} Users Responded
@@ -818,7 +818,7 @@ bbb.lockSettings.moderatorLocking = Moderator locking
 bbb.lockSettings.privateChat = Private Chat
 bbb.lockSettings.publicChat = Public Chat
 bbb.lockSettings.webcam = Webcam
-bbb.lockSettings.webcamsOnlyForModerator = Hide other viewer's webcams
+bbb.lockSettings.webcamsOnlyForModerator = See other viewer's webcams
 bbb.lockSettings.microphone = Microphone
 bbb.lockSettings.layout = Layout
 bbb.lockSettings.title=Lock Viewers
diff --git a/bigbluebutton-client/resources/config.xml.template b/bigbluebutton-client/resources/config.xml.template
index 7be9c348757467430ed9bfb942dc2ed8d85c8d90..084f76ef1bc6b4ee29eec2e4476ca92b947f6f02 100755
--- a/bigbluebutton-client/resources/config.xml.template
+++ b/bigbluebutton-client/resources/config.xml.template
@@ -4,12 +4,12 @@
     <version>VERSION</version>
     <help url="http://HOST/help.html"/>
     <javaTest url="http://HOST/testjava.html"/>
-    <porttest host="HOST" application="video/portTest" timeout="10000"/>
-    <bwMon server="HOST" application="video/bwTest"/>
+    <porttest host="rtmp://HOST" application="video/portTest" timeout="10000"/>
+    <bwMon server="rtmp://HOST" application="video/bwTest"/>
     <application uri="rtmp://HOST/bigbluebutton" host="http://HOST/bigbluebutton/api/enter"/>
     <language userSelectionEnabled="true" rtlEnabled="false"/>
     <skinning url="http://HOST/client/branding/css/V2Theme.css.swf?v=VERSION" />
-    <branding logo="logo.swf" copyright="&#169; 2017 &lt;u&gt;&lt;a href=&quot;http://HOST/home.html&quot; target=&quot;_blank&quot;&gt;BigBlueButton Inc.&lt;/a&gt;&lt;/u&gt; (build {0})" background="" toolbarColor="" showQuote="true"/>
+    <branding logo="logos/logo.swf" copyright="&#169; 2017 &lt;u&gt;&lt;a href=&quot;http://HOST/home.html&quot; target=&quot;_blank&quot;&gt;BigBlueButton Inc.&lt;/a&gt;&lt;/u&gt; (build {0})" background="" toolbarColor="" showQuote="true"/>
     <shortcutKeys showButton="true" />
     <browserVersions chrome="CHROME_VERSION" firefox="FIREFOX_VERSION" flash="FLASH_VERSION"/>
     <layout showLogButton="false" defaultLayout="bbb.layout.name.defaultlayout"
diff --git a/bigbluebutton-client/resources/prod/logo.swf b/bigbluebutton-client/resources/prod/logos/logo.swf
similarity index 100%
rename from bigbluebutton-client/resources/prod/logo.swf
rename to bigbluebutton-client/resources/prod/logos/logo.swf
diff --git a/bigbluebutton-client/src/BigBlueButtonMainContainer.mxml b/bigbluebutton-client/src/BigBlueButtonMainContainer.mxml
index f89ef629dc3706db318bd3577de27109d486a935..99c2306d57b9f22c544d99b8e1426ab10ca412d8 100644
--- a/bigbluebutton-client/src/BigBlueButtonMainContainer.mxml
+++ b/bigbluebutton-client/src/BigBlueButtonMainContainer.mxml
@@ -90,7 +90,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	  }
 	
 	  private function getSessionToken():String {
-		  return BBB.getSessionTokenUtil().getSessionToken();
+		  return BBB.getQueryStringParameters().getSessionToken();
 	  }
 
       private function timerHandler(e:TimerEvent):void{
diff --git a/bigbluebutton-client/src/RTMPConnCheck.mxml b/bigbluebutton-client/src/RTMPConnCheck.mxml
index c089ec54707d95e556450bd3673da1611f7e84e8..1b965d9c62f8c7fc74211ee836e0e91d3065ae58 100755
--- a/bigbluebutton-client/src/RTMPConnCheck.mxml
+++ b/bigbluebutton-client/src/RTMPConnCheck.mxml
@@ -46,8 +46,8 @@
         rtmp = testRTMP;
         
         netConnection = new NetConnection();
-	netConnection.proxyType = "best";
-        netConnection.client = this;
+				netConnection.proxyType = "best";
+				netConnection.objectEncoding = ObjectEncoding.AMF3;
         
         netConnection.addEventListener(NetStatusEvent.NET_STATUS, connectionHandler);
         var connStr:String = (rtmp ? "rtmp:" : "rtmpt:") + "//" + server + "/" + application;
diff --git a/bigbluebutton-client/src/ScreenshareModule.mxml b/bigbluebutton-client/src/ScreenshareModule.mxml
index 070d39731afdcc996474538c690094f791f9e74a..99d8694944c8359af8b519b555a9f890443dd931 100755
--- a/bigbluebutton-client/src/ScreenshareModule.mxml
+++ b/bigbluebutton-client/src/ScreenshareModule.mxml
@@ -41,8 +41,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       private static const LOGGER:ILogger = getClassLogger(ScreenshareModule);
       
       private var _moduleName:String = "Desk Share";
-      private var _attributes:Object;
-      
+
       private var globalDispatcher:Dispatcher = new Dispatcher();;
       
       private function onCreationComplete():void{
@@ -53,34 +52,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         return _moduleName;
       }
       
-      public function get uri():String{
-        return _attributes.uri;
-      }
-      
-      public function get username():String{
-        return _attributes.username;
-      }
-      
-      public function get mode():String{
-        if (_attributes.mode == null){
-          _attributes.mode = "LIVE";
-          LOGGER.debug("Setting DeskShare mode: " + _attributes.mode);
-        }
-        LOGGER.debug("DeskShare mode: " + _attributes.mode);
-        return _attributes.mode;
-      }
-      
-      public function get userid():Number{
-        return _attributes.userid as Number;
-      }
-      
-      public function get role():String{
-        return _attributes.userrole as String;
-      }
-      
       public function start(attributes:Object):void{
-        LOGGER.debug("desk share attr: " + attributes.username);
-        _attributes = attributes;
+        LOGGER.debug("desk share attr: " + attributes.username)
         
         var startEvent:ModuleEvent = new ModuleEvent(ModuleEvent.START);
         startEvent.module = this;
@@ -93,27 +66,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         globalDispatcher.dispatchEvent(stopEvent);
       }
       
-      public function getRoom():String{
-        return _attributes.room;
-      }
-      
-      public function getRed5ServerUri():String{
-        return _attributes.uri;
-      }
-      
-      public function getCaptureServerUri():String{
-        var uri:String = _attributes.uri;
-        uri = uri.split("/")[2];
-        return uri;
-      }
-      
-      public function tunnel():Boolean {
-        if (_attributes.protocol == "RTMPT") {
-          LOGGER.debug("Use tunneling for desktop sharing");
-          return true;
-        }
-        return false;
-      }
     ]]>
   </fx:Script>
   
diff --git a/bigbluebutton-client/src/ScreenshareStandalone.mxml b/bigbluebutton-client/src/ScreenshareStandalone.mxml
index 77adf063a559528ef61a8faa568fc5e840bc6fcd..6510fd8e736a082d8b54e9afefe259036f9df04a 100755
--- a/bigbluebutton-client/src/ScreenshareStandalone.mxml
+++ b/bigbluebutton-client/src/ScreenshareStandalone.mxml
@@ -38,15 +38,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
   
   <fx:Script>
     <![CDATA[
-      	
-      import mx.core.UIComponent;
-      
-      import org.bigbluebutton.modules.screenshare.events.AppletStartedEvent;
-      import org.bigbluebutton.modules.screenshare.events.CursorEvent;
-      import org.bigbluebutton.modules.screenshare.events.ViewStreamEvent;
-      import org.bigbluebutton.modules.screenshare.services.ScreenshareService;
-      import org.bigbluebutton.modules.screenshare.services.red5.ConnectionEvent;
-      import org.bigbluebutton.util.QueryStringParameters;
+		import mx.core.UIComponent;
+		
+		import org.bigbluebutton.core.BBB;
+		import org.bigbluebutton.modules.screenshare.events.AppletStartedEvent;
+		import org.bigbluebutton.modules.screenshare.events.CursorEvent;
+		import org.bigbluebutton.modules.screenshare.events.ViewStreamEvent;
+		import org.bigbluebutton.modules.screenshare.services.ScreenshareService;
+		import org.bigbluebutton.modules.screenshare.services.red5.ConnectionEvent;
+		import org.bigbluebutton.util.QueryStringParameters;
       
       private var videoHolder:UIComponent;
       
@@ -67,12 +67,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       private var videoHeight:int;
       
       private function onCreationComplete():void {			
-        var p:QueryStringParameters = new QueryStringParameters();
+        var p:QueryStringParameters = BBB.getQueryStringParameters();
         p.collectParameters();
         logoutURL = p.getParameter("LOGOUTURL");
         host = p.getParameter("HOST");
         room = p.getParameter("ROOM");
-        service.connect(host, room);
+        service.connect();
         
         cursor.graphics.lineStyle(6, 0xFF0000, 0.6);
         cursor.graphics.drawCircle(0,0,3);				
diff --git a/bigbluebutton-client/src/VideoconfModule.mxml b/bigbluebutton-client/src/VideoconfModule.mxml
old mode 100644
new mode 100755
index c7367b841a574aca7d9f13e44878b5cf30670e18..3ae30df882bff954a011f3646084c0b5ad7b8bbb
--- a/bigbluebutton-client/src/VideoconfModule.mxml
+++ b/bigbluebutton-client/src/VideoconfModule.mxml
@@ -44,38 +44,12 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				return _moduleName;
 			}
 		
-			public function get uri():String {
-				return _attributes.uri + "/" + _attributes.room;
-			}
-			
-			public function get username():String {
-				return _attributes.username;
-			}
-					
-			public function get mode():String {
-				if (_attributes.mode == null) {					
-					//_attributes.mode = "PLAYBACK"
-					_attributes.mode = "LIVE"
-					LOGGER.debug('Setting NotesModule mode: {0}', [_attributes.mode]);
-				}
-				LOGGER.debug('VideoconfVModule mode: {0}', [_attributes.mode]);
-				return _attributes.mode;
-			}
-						
-			public function get userid():String {
-				return _attributes.userid as String;
-			}
-			
-			public function get role():String {
-				return _attributes.userrole as String;
-			}
 			
 			public function start(attributes:Object):void {
 				LOGGER.debug("Starting Video Module");
 				_attributes = attributes;
 				var globalDispatcher:Dispatcher = new Dispatcher();
 				var event:VideoModuleStartEvent = new VideoModuleStartEvent(VideoModuleStartEvent.START);
-				event.uri = uri;
 				globalDispatcher.dispatchEvent(event);
 			}
 			
diff --git a/bigbluebutton-client/src/WebcamViewStandalone.mxml b/bigbluebutton-client/src/WebcamViewStandalone.mxml
index f4aed07026af7587d8a790d1584a7cb7fcf052a8..eff0054bbf9a380acb4157bdd6ff4661a167a9c7 100755
--- a/bigbluebutton-client/src/WebcamViewStandalone.mxml
+++ b/bigbluebutton-client/src/WebcamViewStandalone.mxml
@@ -102,7 +102,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       
       private function connect(url:String):void {
         nc = new NetConnection();
-	nc.proxyType = "best";
+				nc.proxyType = "best";
+				nc.objectEncoding = ObjectEncoding.AMF3;
         nc.client = this;
         nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
         nc.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/BBB.as b/bigbluebutton-client/src/org/bigbluebutton/core/BBB.as
index 8b35594cc05aff4b9ee24e380ed7e973a1b41203..a9400a187dd23417ac2fa2681a7d15f8fe0ad680 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/core/BBB.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/BBB.as
@@ -19,16 +19,16 @@
 package org.bigbluebutton.core {
 
 	import flash.system.Capabilities;
-	
+
 	import mx.core.FlexGlobals;
 	import mx.utils.URLUtil;
-	
+
 	import org.bigbluebutton.core.managers.ConfigManager2;
 	import org.bigbluebutton.core.managers.ConnectionManager;
 	import org.bigbluebutton.core.managers.VideoProfileManager;
 	import org.bigbluebutton.core.model.LiveMeeting;
 	import org.bigbluebutton.core.model.VideoProfile;
-	import org.bigbluebutton.util.SessionTokenUtil;
+	import org.bigbluebutton.util.QueryStringParameters;
 
 	public class BBB {
 		private static var configManager:ConfigManager2 = null;
@@ -37,13 +37,13 @@ package org.bigbluebutton.core {
 
 		private static var videoProfileManager:VideoProfileManager = null;
 
-		private static var sessionTokenUtil:SessionTokenUtil = null;
+		private static var queryStringParameters:QueryStringParameters = null;
 
-		public static function getSessionTokenUtil():SessionTokenUtil {
-			if (sessionTokenUtil == null) {
-				sessionTokenUtil = new SessionTokenUtil();
+		public static function getQueryStringParameters():QueryStringParameters {
+			if (queryStringParameters == null) {
+				queryStringParameters = new QueryStringParameters();
 			}
-			return sessionTokenUtil;
+			return queryStringParameters;
 		}
 
 		public static function getConfigManager():ConfigManager2 {
@@ -119,7 +119,7 @@ package org.bigbluebutton.core {
 		}
 
 		public static function getSignoutURL():String {
-			var sessionToken:String = BBB.sessionTokenUtil.getSessionToken();
+			var sessionToken:String = getQueryStringParameters().getSessionToken();
 			var logoutUrl:String = getBaseURL();
 			if (sessionToken != "") {
 				logoutUrl += "/bigbluebutton/api/signOut?sessionToken=" + sessionToken;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/UsersUtil.as b/bigbluebutton-client/src/org/bigbluebutton/core/UsersUtil.as
index 56244babe415790d7ce7116324009f96f2a36da1..702c192a37287d881dc6e05e2de44ddd2010faa5 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/core/UsersUtil.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/UsersUtil.as
@@ -33,7 +33,6 @@ package org.bigbluebutton.core
   import org.bigbluebutton.core.vo.LockSettingsVO;
   import org.bigbluebutton.main.model.options.LockOptions;
   import org.bigbluebutton.main.model.users.BreakoutRoom;
-  import org.bigbluebutton.util.SessionTokenUtil;
   
   public class UsersUtil
   {
@@ -313,8 +312,7 @@ package org.bigbluebutton.core
     }
     
     public static function getUserSession():String {
-        var sessionUtil:SessionTokenUtil = new SessionTokenUtil()
-        return sessionUtil.getSessionToken();
+        return BBB.getQueryStringParameters().getSessionToken();
     }
     
     public static function applyLockSettings():void {
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/managers/ConfigManager2.as b/bigbluebutton-client/src/org/bigbluebutton/core/managers/ConfigManager2.as
index d1ba4c13eb16bed92496e29c0032733deebb8cbd..c220ffdb158d79dc0c734b220b3286b38b27ee19 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/core/managers/ConfigManager2.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/managers/ConfigManager2.as
@@ -32,11 +32,11 @@ package org.bigbluebutton.core.managers {
     import org.as3commons.logging.api.ILogger;
     import org.as3commons.logging.api.getClassLogger;
     import org.bigbluebutton.common.LogUtil;
+    import org.bigbluebutton.core.BBB;
     import org.bigbluebutton.core.model.Config;
     import org.bigbluebutton.main.events.ConfigLoadedEvent;
     import org.bigbluebutton.main.events.MeetingNotFoundEvent;
     import org.bigbluebutton.main.model.modules.ModuleDescriptor;
-    import org.bigbluebutton.util.QueryStringParameters;
 
     public class ConfigManager2 {
         private static const LOGGER:ILogger = getClassLogger(ConfigManager2);
@@ -46,9 +46,7 @@ package org.bigbluebutton.core.managers {
         private var _config:Config = null;
         
         public function loadConfig():void {
-            var p:QueryStringParameters = new QueryStringParameters();
-            p.collectParameters();
-            var sessionToken:String = p.getParameter("sessionToken");
+            var sessionToken:String = BBB.getQueryStringParameters().getSessionToken();
 
             var reqVars:URLVariables = new URLVariables();
             reqVars.sessionToken = sessionToken;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/managers/ConnectionManager.as b/bigbluebutton-client/src/org/bigbluebutton/core/managers/ConnectionManager.as
index c768b9f745280d04b5a77e6058e402726fa03c7b..aede051109c9c4851804c9fbe92145548173de83 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/core/managers/ConnectionManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/managers/ConnectionManager.as
@@ -18,16 +18,18 @@
  */
 package org.bigbluebutton.core.managers {
     import flash.net.NetConnection;
-    
+    import org.bigbluebutton.core.Options;
+    import org.bigbluebutton.main.model.options.PortTestOptions;
     import org.bigbluebutton.main.model.users.IMessageListener;
     import org.bigbluebutton.main.model.users.NetConnectionDelegate;
 
     public class ConnectionManager {
         private var connDelegate:NetConnectionDelegate;
 
-        [Bindable]
-        public var isTunnelling:Boolean = false;
+        private var _isTunnelling:Boolean = false;
 
+				private var portTestOptions : PortTestOptions;
+				
         public function ConnectionManager() {
             connDelegate = new NetConnectionDelegate();
         }
@@ -45,6 +47,30 @@ package org.bigbluebutton.core.managers {
             connDelegate.disconnect(onUserAction);
         }
 
+				public function initPortTestOption():void {
+					portTestOptions = Options.getOptions(PortTestOptions) as PortTestOptions;
+				}
+				
+				public function useProtocol(tunnel:Boolean):void {
+					_isTunnelling = tunnel;
+				}
+				
+				public function get isTunnelling():Boolean {
+					return _isTunnelling;
+				}
+				
+				public function get portTestHost():String {
+					return portTestOptions.host;
+				}
+				
+				public function get portTestApplication():String {
+					return portTestOptions.application;
+				}
+				
+				public function get portTestTimeout():Number {
+					return portTestOptions.timeout;
+				}
+				
         public function addMessageListener(listener:IMessageListener):void {
             connDelegate.addMessageListener(listener);
         }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/model/BandwidthMonOptions.as b/bigbluebutton-client/src/org/bigbluebutton/core/model/BandwidthMonOptions.as
new file mode 100755
index 0000000000000000000000000000000000000000..1a51b6937491752603152a591e208270f0416750
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/model/BandwidthMonOptions.as
@@ -0,0 +1,18 @@
+package org.bigbluebutton.core.model
+{
+	import org.bigbluebutton.core.Options;
+	
+	public class BandwidthMonOptions extends Options
+	{
+		[Bindable]
+		public var server:String = "";
+		
+		[Bindable]
+		public var application:String = "";
+		
+		public function BandwidthMonOptions()
+		{
+			name = "bwMon";
+		}
+	}
+}
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/core/services/BandwidthMonitor.as b/bigbluebutton-client/src/org/bigbluebutton/core/services/BandwidthMonitor.as
old mode 100644
new mode 100755
index a9b330ef3174b282cd93fbc757703c2269091c10..68863b9afcefd9fe672d4a4c26083e27495ea0cc
--- a/bigbluebutton-client/src/org/bigbluebutton/core/services/BandwidthMonitor.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/core/services/BandwidthMonitor.as
@@ -25,7 +25,11 @@ package org.bigbluebutton.core.services
   
   import org.as3commons.logging.api.ILogger;
   import org.as3commons.logging.api.getClassLogger;
+  import org.bigbluebutton.core.BBB;
+  import org.bigbluebutton.core.Options;
+  import org.bigbluebutton.core.model.BandwidthMonOptions;
   import org.bigbluebutton.main.model.NetworkStatsData;
+  import org.bigbluebutton.util.ConnUtil;
   import org.red5.flash.bwcheck.ClientServerBandwidth;
   import org.red5.flash.bwcheck.ServerClientBandwidth;
   import org.red5.flash.bwcheck.events.BandwidthDetectEvent;
@@ -35,8 +39,6 @@ package org.bigbluebutton.core.services
     public static const INTERVAL_BETWEEN_CHECKS:int = 30000; // in ms
 
     private static var _instance:BandwidthMonitor = null;
-    private var _serverURL:String = "localhost";
-    private var _serverApplication:String = "video";
     private var _clientServerService:String = "checkBandwidthUp";
     private var _serverClientService:String = "checkBandwidth";
     private var _pendingClientToServer:Boolean;
@@ -83,26 +85,43 @@ package org.bigbluebutton.core.services
         }
         return _instance;
     }
-
-    public function set serverURL(url:String):void {
-        if (_nc.connected)
-            _nc.close();
-        _serverURL = url;
-    }
-    
-    public function set serverApplication(app:String):void {
-        if (_nc.connected)
-            _nc.close();
-        _serverApplication = app;
-    }
-
+		
     public function start():void {
       connect();
     }
        
     private function connect():void {
         if (!_nc.connected && !_connecting) {
-            _nc.connect("rtmp://" + _serverURL + "/" + _serverApplication);
+					var bwMonOption:BandwidthMonOptions = Options.getOptions(BandwidthMonOptions) as BandwidthMonOptions;
+					
+					var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)/;
+					var result:Array = pattern.exec(bwMonOption.server);
+					
+					var bwMonUrl: String;
+					var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS;
+					if (BBB.initConnectionManager().isTunnelling) {
+						var tunnelProtocol: String = ConnUtil.RTMPT;
+						
+						if (useRTMPS) {
+							_nc.proxyType = ConnUtil.PROXY_NONE;
+							tunnelProtocol = ConnUtil.RTMPS;
+						}
+						
+						
+						bwMonUrl = tunnelProtocol + "://" + result.server + "/" + bwMonOption.application;
+						LOGGER.debug("BW MON CONNECT tunnel = TRUE " + "url=" +  bwMonUrl);
+					} else {
+						var nativeProtocol: String = ConnUtil.RTMP;
+						if (useRTMPS) {
+							_nc.proxyType = ConnUtil.PROXY_BEST;
+							nativeProtocol = ConnUtil.RTMPS;
+						}
+						
+						bwMonUrl = nativeProtocol + "://" + result.server + "/" + bwMonOption.application;
+						LOGGER.debug("BBB MON CONNECT tunnel = FALSE " + "url=" +  bwMonUrl);
+					}
+					
+            _nc.connect(bwMonUrl);
             _connecting = true;
         }
     }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/api/ExternalApiCallbacks.as b/bigbluebutton-client/src/org/bigbluebutton/main/api/ExternalApiCallbacks.as
index aab02604af82012476fcea6b7c0d445182577656..7a70b20fb9cdbbbe5e15b630037d5809e5bea094 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/api/ExternalApiCallbacks.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/api/ExternalApiCallbacks.as
@@ -264,7 +264,7 @@ package org.bigbluebutton.main.api
     }
     
     private function handleGetSessionToken():String {
-      return BBB.getSessionTokenUtil().getSessionToken();
+      return BBB.getQueryStringParameters().getSessionToken();
     }
     
     
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as
index 501e118685ca4af6e7fb0e5077078ba6a0ed4527..394535646c489219e18da175be0439443981bfa4 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTest.as
@@ -18,16 +18,17 @@
 */
 package org.bigbluebutton.main.model
 {
-	 
 	import flash.events.NetStatusEvent;
 	import flash.events.TimerEvent;
 	import flash.net.NetConnection;
 	import flash.net.ObjectEncoding;
+	import flash.utils.Dictionary;
 	import flash.utils.Timer;
-    import flash.utils.Dictionary;
-    import org.bigbluebutton.core.UsersUtil;
+	
 	import org.as3commons.logging.api.ILogger;
 	import org.as3commons.logging.api.getClassLogger;
+	import org.bigbluebutton.core.UsersUtil;
+	import org.bigbluebutton.util.ConnUtil;
 	
 	[Bindable]
 	/**
@@ -93,11 +94,6 @@ package org.bigbluebutton.main.model
     
     private var closeConnectionTimer:Timer;
 		
-		/**
-		* Set default encoding to AMF0 so FMS also understands.
-		*/		
-		NetConnection.defaultObjectEncoding = ObjectEncoding.AMF0;
-		
 		/**
 		 * Create new port test and connect to the RTMP server.
 		 * 
@@ -123,12 +119,12 @@ package org.bigbluebutton.main.model
 			} else {
 				this.port = port;
 			}
-			// Construct URI.
-      if (tunnel) {
-        this.baseURI = "rtmpt://" + this.hostname + "/" + this.application;
-      } else {
-        this.baseURI = "rtmp://" + this.hostname + this.port + "/" + this.application;
-      }
+		}
+		
+		private function parseRTMPConn(appURL: String):Array {
+			var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)/;
+			var result:Array = pattern.exec(appURL);
+			return result;
 		}
 		
 		/**
@@ -137,8 +133,34 @@ package org.bigbluebutton.main.model
 		public function connect():void {
 			nc = new NetConnection();
 			nc.client = this;
-      nc.proxyType = "best";
 
+			LOGGER.debug("Connecting PORT TEST hostname= " + this.hostname);
+			var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)/;
+			var result:Array = pattern.exec(this.hostname);
+			var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS;
+			
+			// Construct URI.
+			if (tunnel) {
+				LOGGER.debug("Connecting PORT TEST tunnel= " + tunnel);
+				var tunnelProtocol: String = ConnUtil.RTMPT;
+				if (useRTMPS) {
+					tunnelProtocol = ConnUtil.RTMPS;
+					nc.proxyType = ConnUtil.PROXY_NONE;
+				}
+				this.baseURI = tunnelProtocol + "://" + result.server + "/" + this.application;
+				
+			} else {
+				LOGGER.debug("Connecting PORT TEST tunnel= " + tunnel);
+				var nativeProtocol: String = ConnUtil.RTMP;
+				if (useRTMPS) {
+					nativeProtocol = ConnUtil.RTMPS;
+					nc.proxyType = ConnUtil.PROXY_BEST;
+				}
+				this.baseURI = nativeProtocol + "://" + result.server + "/" + this.application;
+			}
+			
+      
+			nc.objectEncoding = ObjectEncoding.AMF3;
 			nc.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
 			// connect to server
 			try {
@@ -153,8 +175,12 @@ package org.bigbluebutton.main.model
         connectionTimer.start();
         
         var curTime:Number = new Date().getTime();
+				
+				LOGGER.debug("Connecting PORT TEST = " + this.baseURI);
 				// Create connection with the server.
-				nc.connect( this.baseURI, "portTestMeetingId-" + curTime, "portTestDummyUserId-" + curTime);
+				nc.connect( this.baseURI, "portTestMeetingId-" + curTime, 
+					"portTestDummyUserId-" + curTime, "portTestDummyAuthToken");
+							
 				status = "Connecting...";
 			} catch( e : ArgumentError ) {
 				// Invalid parameters.
@@ -171,7 +197,7 @@ package org.bigbluebutton.main.model
             logData.tags = ["initialization", "port-test", "connection"];
             logData.message = "Port testing connection timedout.";
             LOGGER.info(JSON.stringify(logData));
-
+						LOGGER.debug("Connect FAILED PORT TEST = " + this.baseURI);
 			status = "FAILED";
 			_connectionListener(status, tunnel, hostname, port, application);
             closeConnection();
@@ -228,11 +254,13 @@ package org.bigbluebutton.main.model
         logData.connection = this.baseURI;
         logData.tags = ["initialization", "port-test", "connection"];
 
+				LOGGER.debug("Connect SUCCESS PORT TEST connected= " + nc.connected);
+				
         if ( statusCode == "NetConnection.Connect.Success" ) {
             status = "SUCCESS";
             logData.message = "Port test successfully connected.";
             LOGGER.info(JSON.stringify(logData));
-
+						LOGGER.debug("Connect SUCCESS PORT TEST = " + this.baseURI);
             _connectionListener(status, tunnel, hostname, port, application);
         } else if ( statusCode == "NetConnection.Connect.Rejected" ||
                     statusCode == "NetConnection.Connect.Failed" || 
@@ -240,7 +268,7 @@ package org.bigbluebutton.main.model
             logData.statusCode = statusCode;            
             logData.message = "Port test failed to connect.";
             LOGGER.info(JSON.stringify(logData));
-            
+						LOGGER.debug("Connect FAILED (2) PORT TEST = " + this.baseURI);
             status = "FAILED";
             _connectionListener(status, tunnel, hostname, port, application);
             
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTestProxy.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTestProxy.as
old mode 100644
new mode 100755
index 99fec41b9396d2af2c7fad824ce059a95f50bb02..6f3037d30d2437891b3a24e9e3f4bd7c784cb54d
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTestProxy.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/PortTestProxy.as
@@ -36,7 +36,9 @@ package org.bigbluebutton.main.model {
             this.modulesDispatcher = modulesDispatcher;
         }
 
-        public function connect(tunnel:Boolean, hostname:String = "", port:String = "", application:String = "", testTimeout:Number = 10000):void {
+        public function connect( tunnel:Boolean, hostname:String = "", 
+																port:String = "", application:String = "", 
+																testTimeout:Number = 10000):void {
             this.tunnel = tunnel;
             portTest = new PortTest(tunnel, hostname, port, application, testTimeout);
             portTest.addConnectionSuccessListener(connectionListener);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/ModuleManager.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/ModuleManager.as
index 5031062b7f1edca66d8bbdf284e6e5dfc0da25f2..6d63ea4752bad57d7620425f0504f48572444eac 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/ModuleManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/ModuleManager.as
@@ -22,16 +22,12 @@ package org.bigbluebutton.main.model.modules
 	
 	import flash.system.ApplicationDomain;
 	import flash.utils.Dictionary;
-	
 	import mx.collections.ArrayCollection;
-	
 	import org.as3commons.logging.api.ILogger;
 	import org.as3commons.logging.api.getClassLogger;
 	import org.bigbluebutton.common.IBigBlueButtonModule;
 	import org.bigbluebutton.core.BBB;
-	import org.bigbluebutton.core.Options;
 	import org.bigbluebutton.main.events.AppVersionEvent;
-	import org.bigbluebutton.main.model.options.PortTestOptions;
 	
 	public class ModuleManager
 	{
@@ -48,11 +44,11 @@ package org.bigbluebutton.main.model.modules
 		
 		private var modulesDispatcher:ModulesDispatcher;
 		
-		private var portTestOptions : PortTestOptions;
+		
 		
 		public function ModuleManager(modulesDispatcher: ModulesDispatcher)
 		{
-            this.modulesDispatcher = modulesDispatcher;
+      this.modulesDispatcher = modulesDispatcher;
 			_applicationDomain = new ApplicationDomain(ApplicationDomain.currentDomain);
 		}
 				
@@ -66,8 +62,8 @@ package org.bigbluebutton.main.model.modules
 			var resolver:DependancyResolver = new DependancyResolver();
 			sorted = resolver.buildDependencyTree(modules);
 			
-			portTestOptions = Options.getOptions(PortTestOptions) as PortTestOptions;
-			
+			BBB.initConnectionManager().initPortTestOption();
+
 			modulesDispatcher.sendPortTestEvent();
 		}
 		
@@ -75,23 +71,7 @@ package org.bigbluebutton.main.model.modules
 			BBB.getConfigManager();
 			BBB.loadConfig();
 		}
-		
-		public function useProtocol(tunnel:Boolean):void {
-      BBB.initConnectionManager().isTunnelling = tunnel;			
-		}
-		
-		public function get portTestHost():String {
-			return portTestOptions.host;
-		}
-		
-		public function get portTestApplication():String {
-			return portTestOptions.application;
-		}
-		
-		public function get portTestTimeout():Number {
-			return portTestOptions.timeout;
-		}
-		
+
 		private function getModule(name:String):ModuleDescriptor {
 			return BBB.getConfigManager().getModuleFor(name);	
 		}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/ModulesProxy.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/ModulesProxy.as
index ab37b817a91820531185a8e65e1ae3f0b30c789c..49d7b7cb2f755ee18647802b1be28dc6b1c3b289 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/ModulesProxy.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/modules/ModulesProxy.as
@@ -20,8 +20,9 @@ package org.bigbluebutton.main.model.modules
 {
 	import org.as3commons.logging.api.ILogger;
 	import org.as3commons.logging.api.getClassLogger;
+	import org.bigbluebutton.core.BBB;
 	import org.bigbluebutton.core.UsersUtil;
-	import org.bigbluebutton.main.model.PortTestProxy;
+	import org.bigbluebutton.main.model.PortTestProxy;
 	
 	public class ModulesProxy {
 		private static const LOGGER:ILogger = getClassLogger(ModulesProxy);      
@@ -49,7 +50,7 @@ package org.bigbluebutton.main.model.modules
             logData.message = "Successfully tested connection to server.";
             LOGGER.info(JSON.stringify(logData));
                 
-			modulesManager.useProtocol(tunnel);
+						BBB.initConnectionManager().useProtocol(tunnel);
 			modulesManager.startUserServices();
 		}
 						
@@ -58,15 +59,15 @@ package org.bigbluebutton.main.model.modules
 		}
 		
 		public function getPortTestHost():String {
-			return modulesManager.portTestHost;
+			return BBB.initConnectionManager().portTestHost;
 		}
 		
 		public function getPortTestApplication():String {
-			return modulesManager.portTestApplication;
+			return BBB.initConnectionManager().portTestApplication;
 		}
 
 		public function getPortTestTimeout():Number {
-			return modulesManager.portTestTimeout;
+			return BBB.initConnectionManager().portTestTimeout;
 		}
 		
 		public function handleConfigLoaded():void {
@@ -78,13 +79,13 @@ package org.bigbluebutton.main.model.modules
 		}
 		
 		public function testRTMP():void{
-			portTestProxy.connect(false /*"RTMP"*/, getPortTestHost(), "1935", getPortTestApplication(), getPortTestTimeout());
+			portTestProxy.connect(false /*tunnel*/, getPortTestHost(), "", getPortTestApplication(), getPortTestTimeout());
 		}
 
 		public function testRTMPT(tunnel:Boolean):void {
 			if (!tunnel) {
 				// Try to test using rtmpt as rtmp failed.
-				portTestProxy.connect(true /*"RTMPT"*/, getPortTestHost(), "", getPortTestApplication(), getPortTestTimeout());
+				portTestProxy.connect(true /*tunnel*/, getPortTestHost(), "", getPortTestApplication(), getPortTestTimeout());
 			} else {
 				modulesDispatcher.sendTunnelingFailedEvent(getPortTestHost(), getPortTestApplication());
 			}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/options/PortTestOptions.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/options/PortTestOptions.as
old mode 100644
new mode 100755
index 9292f3edabba8d52374db0caf1b1088d946ce050..eb9a9c235f1d5c2b5d9553ef87905fa93025b748
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/options/PortTestOptions.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/options/PortTestOptions.as
@@ -29,7 +29,7 @@ package org.bigbluebutton.main.model.options {
 
 		[Bindable]
 		public var timeout:int = 10000;
-
+		
 		public function PortTestOptions() {
 			name = "porttest";
 		}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as
index 299422437666858902a6a3c0dea3a77cfe62f6d7..d00494909bd715a148bf47dd892ee6421ce117d1 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/Conference.as
@@ -394,7 +394,7 @@ package org.bigbluebutton.main.model.users {
         var p:Object = getUserIndex(userID);
         if (p != null) {
           var u:BBBUser = p.participant as BBBUser;
-          if(u.avatarURL == null || u.avatarURL == ""){
+          if(StringUtils.isEmpty(u.avatarURL)){
             return LiveMeeting.inst().me.avatarURL;
           }
           return u.avatarURL;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/JoinService.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/JoinService.as
index a1a195cb3fd9d1730f1e3f8b858e38004f11dceb..405042d0ec43525ff9740e24ef8784aa99f77ed7 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/JoinService.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/JoinService.as
@@ -30,10 +30,10 @@ package org.bigbluebutton.main.model.users
   
   import org.as3commons.logging.api.ILogger;
   import org.as3commons.logging.api.getClassLogger;
+  import org.bigbluebutton.core.BBB;
   import org.bigbluebutton.core.UsersUtil;
   import org.bigbluebutton.main.events.MeetingNotFoundEvent;
-  import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
-  import org.bigbluebutton.util.QueryStringParameters;
+  import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
   
   public class JoinService
   {  
@@ -50,9 +50,7 @@ package org.bigbluebutton.main.model.users
     }
     
     public function load(url:String):void {
-      var p:QueryStringParameters = new QueryStringParameters();
-      p.collectParameters();
-      var sessionToken:String = p.getParameter("sessionToken");
+      var sessionToken:String = BBB.getQueryStringParameters().getSessionToken();
       
       reqVars.sessionToken = sessionToken;
       
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as
index 5132ce2eff25522335d5c29a4c1169a9677162f1..a5c2f1a6f12066a10d50e75c36bdd1830619dd10 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/model/users/NetConnectionDelegate.as
@@ -26,6 +26,7 @@ package org.bigbluebutton.main.model.users
 	import flash.events.SecurityErrorEvent;
 	import flash.events.TimerEvent;
 	import flash.net.NetConnection;
+	import flash.net.ObjectEncoding;
 	import flash.net.Responder;
 	import flash.utils.Timer;
 	
@@ -41,13 +42,13 @@ package org.bigbluebutton.main.model.users
 	import org.bigbluebutton.core.events.TokenValidReconnectEvent;
 	import org.bigbluebutton.core.managers.ReconnectionManager;
 	import org.bigbluebutton.core.model.LiveMeeting;
-	import org.bigbluebutton.core.services.BandwidthMonitor;
 	import org.bigbluebutton.main.events.BBBEvent;
 	import org.bigbluebutton.main.events.InvalidAuthTokenEvent;
 	import org.bigbluebutton.main.model.options.ApplicationOptions;
 	import org.bigbluebutton.main.model.users.events.ConnectionFailedEvent;
-	import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
-
+	import org.bigbluebutton.main.model.users.events.UsersConnectionEvent;
+	import org.bigbluebutton.util.ConnUtil;
+	
     public class NetConnectionDelegate {
         private static const LOGGER:ILogger = getClassLogger(NetConnectionDelegate);
 
@@ -78,7 +79,7 @@ package org.bigbluebutton.main.model.users
         public function NetConnectionDelegate():void {
             dispatcher = new Dispatcher();
             _netConnection = new NetConnection();
-            _netConnection.proxyType = "best";
+						_netConnection.objectEncoding = ObjectEncoding.AMF3;
             _netConnection.client = this;
             _netConnection.addEventListener( NetStatusEvent.NET_STATUS, netStatus );
             _netConnection.addEventListener( AsyncErrorEvent.ASYNC_ERROR, netASyncError );
@@ -218,8 +219,6 @@ package org.bigbluebutton.main.model.users
 
             var message: ValidateAuthTokenReqMsg = new ValidateAuthTokenReqMsg(body);
 
-            LOGGER.debug("******* msg \n" + JSON.stringify(message));
-
             sendMessage2x(
                 // result - On successful result
                 function(result:Object):void { 
@@ -402,18 +401,31 @@ package org.bigbluebutton.main.model.users
                 
             try {
                 var appURL:String = _applicationOptions.uri;
-                var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
-                var result:Array = pattern.exec(appURL);
-
-                BandwidthMonitor.getInstance().serverURL = result.server;
-            
-                var protocol:String = "rtmp";
-                var uri:String = appURL + "/" + intMeetingId;
-            
-                if (BBB.initConnectionManager().isTunnelling) {
-                    bbbAppsUrl = "rtmpt://" + result.server + "/" + result.app + "/" + intMeetingId;
-                } else {
-                    bbbAppsUrl = "rtmp://" + result.server + ":1935/" + result.app + "/" + intMeetingId;
+								var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
+								var result:Array = pattern.exec(appURL);
+
+								var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS;
+								
+								if (BBB.initConnectionManager().isTunnelling) {
+									var tunnelProtocol: String = ConnUtil.RTMPT;
+								
+									if (useRTMPS) {
+										_netConnection.proxyType = ConnUtil.PROXY_NONE;
+										tunnelProtocol = ConnUtil.RTMPS;
+									}
+								
+									bbbAppsUrl = tunnelProtocol + "://" + result.server + "/" + result.app + "/" + intMeetingId;
+									LOGGER.debug("BBB APPS CONNECT tunnel = TRUE " + "url=" +  bbbAppsUrl);
+								} else {
+									var nativeProtocol: String = ConnUtil.RTMP;
+									if (useRTMPS) {
+										_netConnection.proxyType = ConnUtil.PROXY_BEST;
+										nativeProtocol = ConnUtil.RTMPS;
+									}
+								
+									bbbAppsUrl = nativeProtocol + "://" + result.server + "/" + result.app + "/" + intMeetingId;
+									LOGGER.debug("BBB APPS CONNECT tunnel = FALSE " + "url=" +  bbbAppsUrl);
+								
                 }
 
                 var logData:Object = UsersUtil.initLogData();
@@ -448,10 +460,10 @@ package org.bigbluebutton.main.model.users
                 // Invalid parameters.
                 switch (e.errorID) {
                     case 2004 :
-                        LOGGER.debug("Error! Invalid server location: {0}", [uri]);
+                        LOGGER.debug("Error! Invalid server location: {0}", [bbbAppsUrl]);
                         break;
                     default :
-                        LOGGER.debug("UNKNOWN Error! Invalid server location: {0}", [uri]);
+                        LOGGER.debug("UNKNOWN Error! Invalid server location: {0}", [bbbAppsUrl]);
                        break;
                 }
             }
@@ -546,7 +558,7 @@ package org.bigbluebutton.main.model.users
                 
                 case "NetConnection.Connect.NetworkChange":
                     numNetworkChangeCount++;
-                    if (numNetworkChangeCount % 20 == 0) {
+                    if (numNetworkChangeCount % 2 == 0) {
                         logData.message = "Detected network change on bbb-apps";
                         logData.numNetworkChangeCount = numNetworkChangeCount;
                         LOGGER.info(JSON.stringify(logData));
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/BrowserPermissionHelper.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/BrowserPermissionHelper.mxml
index b81c105d01809ba84a242e5735a9a9a14b852c18..d9c57814b33d40ec74a00eb9ab1c8b9721b4efea 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/BrowserPermissionHelper.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/BrowserPermissionHelper.mxml
@@ -42,7 +42,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	<mx:states>
 		<mx:State name="default"/>
 		<mx:State name="chromeMic"/>
+		<mx:State name="chromeMicMacOSX" basedOn="chromeMic"/>
 		<mx:State name="chromeCam"/>
+		<mx:State name="chromeCamMacOSX" basedOn="chromeCam"/>
 		<mx:State name="firefoxMic"/>
 		<mx:State name="firefoxMicMacOSX" basedOn="firefoxMic"/>
 	</mx:states>
@@ -80,8 +82,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 					 text.firefoxMic="{ResourceUtil.getInstance().getString('bbb.micPermissions.firefox.message')}"
 					 selectable="false"
 					 styleName="permissionSettingsTextStyle" />
-			<mx:Image source.chromeMic="@Embed('assets/chrome-permissions.png')" 
-					  source.chromeCam="@Embed('assets/chrome-permissions.png')" 
+			<mx:Image source.chromeMic="@Embed('assets/chrome-permissions-windows.png')" 
+					  source.chromeMicMacOSX="@Embed('assets/chrome-permissions-macosx.png')" 
+					  source.chromeCam="@Embed('assets/chrome-permissions-windows.png')" 
+					  source.chromeCamMacOSX="@Embed('assets/chrome-permissions-macosx.png')" 
 					  source.firefoxMic="@Embed('assets/firefox-permissions-windows.png')"
 					  source.firefoxMicMacOSX="@Embed('assets/firefox-permissions-macosx.png')"/>
 		</mx:HBox>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
index f9b5a59e83620cf995be22a7342430310b553fec..7ccbf190c7fc1be6ea1cd8c7e9d88f3c568bf338 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/FlashMicSettings.mxml
@@ -95,6 +95,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
       private function reInitialize():void {
         my_nc = new NetConnection();
+				my_nc.objectEncoding = ObjectEncoding.AMF3;
 	      my_nc.proxyType = "best";
         my_nc.connect(null);
         nsStream = new NetStream(my_nc);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/LoadingBar.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/LoadingBar.mxml
index 9792d00af9ae952c7af234dee0a15e847ab97a0e..292d9e0f9881be6470599775df6b8335db56c93a 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/LoadingBar.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/LoadingBar.mxml
@@ -20,12 +20,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 -->
 
-<mx:ProgressBar xmlns:mate="http://mate.asfusion.com/"
-				xmlns:fx="http://ns.adobe.com/mxml/2009"
-				xmlns:mx="library://ns.adobe.com/flex/mx"
-				minimum="0"
-				maximum="100"
-				mode="manual">
+<mx:VBox xmlns:mate="http://mate.asfusion.com/"
+		 xmlns:fx="http://ns.adobe.com/mxml/2009"
+		 xmlns:mx="library://ns.adobe.com/flex/mx">
 
 	<fx:Declarations>
 		<mate:Listener type="{ModuleLoadEvent.MODULE_LOADING_STARTED}"
@@ -61,7 +58,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 			private function moduleLoadingStarted(e:ModuleLoadEvent):void {
 				numModules = BBB.getConfigManager().config.numberOfModules();
-				this.label = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.loading');
+				loadingbarLabel.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.loading');
 				this.visible = true;
 			}
 
@@ -79,7 +76,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 				ExternalInterface.call("setProgressBar", int(totalProgress / numModules));
 				//LogUtil.debug("Progress: " + totalProgress);
-				this.setProgress(totalProgress / numModules, 100);
+				progressBar.setProgress(totalProgress / numModules, 100);
 			}
 
 			private function allModulesLoaded(e:ModuleLoadEvent):void {
@@ -90,18 +87,28 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 			private function testRTMP(e:PortTestEvent):void {
 				//- Cannot get locale string this early in loading process
-				this.label = portUpdateStr; //ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.connecting');
+				loadingbarLabel.text = portUpdateStr; //ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.connecting');
 			}
 
 			private function testRTMPupdate(e:PortTestEvent):void {
 				//- Cannot get locale string this early in loading process
 				portUpdateStr += "...";
-				this.label = portUpdateStr; //ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.connecting');
+				loadingbarLabel.text = portUpdateStr; //ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.connecting');
 			}
 
 			private function tunnelingFailed(e:PortTestEvent):void {
-				this.label = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.cannotConnectServer');
+				loadingbarLabel.text = ResourceUtil.getInstance().getString('bbb.mainshell.statusProgress.cannotConnectServer');
 			}
 		]]>
 	</fx:Script>
-</mx:ProgressBar>
+
+	<mx:ProgressBar width="280"
+					height="15"
+					id="progressBar"
+					labelWidth="0"
+					minimum="0"
+					maximum="100"
+					mode="manual" />
+	<mx:Label id="loadingbarLabel" styleName="loadingBarLabel"/>
+
+</mx:VBox>
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/LoggedOutWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/LoggedOutWindow.mxml
index 411da10098ac0e7990dde4e8781a9e6b00dc3271..cb07337ec9483706b072f34fbd92a1e6231cc19e 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/LoggedOutWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/LoggedOutWindow.mxml
@@ -119,7 +119,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				LOGGER.info(JSON.stringify(logData));
 
 				var layoutOptions:LayoutOptions = Options.getOptions(LayoutOptions) as LayoutOptions;
-				if (layoutOptions.askForFeedbackOnLogout) {
+				if (layoutOptions.askForFeedbackOnLogout && !UsersUtil.isBreakout()) {
 					currentState = "feedback";
 				}
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml
index dea8c2c61dd0a3324b3a19614235800608714f76..e299657e76b0a1dad21d35cb1d05fabca0efa092 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/MainApplicationShell.mxml
@@ -127,9 +127,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.bigbluebutton.core.events.RoundTripLatencyReceivedEvent;
 			import org.bigbluebutton.core.events.SwitchedLayoutEvent;
 			import org.bigbluebutton.core.model.LiveMeeting;
-			import org.bigbluebutton.core.model.Meeting;
-			import org.bigbluebutton.core.model.MeetingBuilder;
-			import org.bigbluebutton.core.model.MeetingBuilder2x;
 			import org.bigbluebutton.core.vo.LockSettingsVO;
 			import org.bigbluebutton.main.events.AppVersionEvent;
 			import org.bigbluebutton.main.events.BBBEvent;
@@ -566,7 +563,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 logData.message = "Loaded locale.";
                 LOGGER.info(JSON.stringify(logData));
                     
-				if ((version == "old-locales") || (version == "") || (version == null)) {
+				if ((version == "old-locales") || StringUtils.isEmpty(version)) {
 					wrongLocaleVersion();
 				} else {
 					if (version != localeVersion) wrongLocaleVersion();
@@ -629,7 +626,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                     }
                 } else if (BrowserCheck.isChrome()) {
                     if (browserPermissionHelper) {
-						browserPermissionHelper.currentState = "chromeMic";
+						if (Capabilities.os.indexOf("Mac") >= 0){
+							browserPermissionHelper.currentState = "chromeMicMacOSX";
+						} else {
+							browserPermissionHelper.currentState = "chromeMic";
+						}
 						browserPermissionHelper.x = 50;
 						browserPermissionHelper.y = 130;
                     }
@@ -650,7 +651,11 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private function showbrowserPermissionHelper() : void {
 				var browserPermissionHelper : BrowserPermissionHelper = PopUpUtil.createNonModalPopUp(FlexGlobals.topLevelApplication as DisplayObject, BrowserPermissionHelper, false) as BrowserPermissionHelper;
 				if (browserPermissionHelper) {
-					browserPermissionHelper.currentState = "chromeCam";
+					if (Capabilities.os.indexOf("Mac") >= 0){
+						browserPermissionHelper.currentState = "chromeCamMacOSX";
+					} else {
+						browserPermissionHelper.currentState = "chromeCam";
+					}
 					browserPermissionHelper.x = 20;
 					browserPermissionHelper.y = 150;
 				}
@@ -898,7 +903,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 		<mx:Canvas id="backgroundPlaceHolder" width="100%" height="100%" />
 		<mx:VBox horizontalCenter="0" verticalCenter="0" horizontalAlign="center" verticalGap="20">
 			<views:QuotesView id="quoteView"/>
-			<views:LoadingBar id="progressBar" width="280" height="15" labelWidth="280" textAlign="center"/>
+			<views:LoadingBar id="progressBar"/>
 		</mx:VBox>
 	</views:MainCanvas>	
 	
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/QuotesView.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/QuotesView.mxml
index 5d4eb923213ef8bd6c15da2ccf84ff67383336c2..e3f21b7fbf8a977daf248eb7a94f8f151cdcfd39 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/QuotesView.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/QuotesView.mxml
@@ -23,6 +23,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 		 xmlns:s="library://ns.adobe.com/flex/spark"
 		 xmlns:mx="library://ns.adobe.com/flex/mx"
 		 xmlns:mate="http://mate.asfusion.com/"
+		 xmlns:common="org.bigbluebutton.common.*"
 		 width="620"
 		 alpha="0"
 		 verticalScrollPolicy="off"
@@ -83,12 +84,14 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 	<mx:Image source="{getStyle('iconQuote')}" />
 
-	<s:Label id="quoteLabel"
+	<common:AdvancedLabel id="quoteLabel"
 			 styleName="quoteSentenceStyle"
+			 selectable="false"
 			 width="620" />
 
-	<s:Label id="quoteAttribution"
+	<common:AdvancedLabel id="quoteAttribution"
 			 styleName="quoteAttributionStyle"
+			 selectable="false"
 			 width="620" />
 
 	<mx:HRule width="120" />
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordButton.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordButton.mxml
index 7267bde7a5ffa1dde887a9c4cedfe8bf126e392f..e8703e67bec6996e41733c845b20ec23cc427b39 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordButton.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/RecordButton.mxml
@@ -48,7 +48,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			import mx.controls.Alert;
 			import mx.events.CloseEvent;
-			import mx.managers.PopUpManager;
 			
 			import org.as3commons.logging.api.ILogger;
 			import org.as3commons.logging.api.getClassLogger;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/VideoWithWarnings.as b/bigbluebutton-client/src/org/bigbluebutton/main/views/VideoWithWarnings.as
index d8bfb4b94f2657556f150dbbd334f05f1c3a9de9..0129920432361b0364223f82c263361b3ce9ccd2 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/VideoWithWarnings.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/VideoWithWarnings.as
@@ -39,11 +39,11 @@ package org.bigbluebutton.main.views
 
         public function VideoWithWarnings() {
             super();
-
-            this.addEventListener(FlexEvent.CREATION_COMPLETE , creationCompleteHandler);
         }
 
-        private function creationCompleteHandler(e:FlexEvent):void {
+        override protected function creationCompleteHandler(e:FlexEvent):void {
+			super.creationCompleteHandler(e);
+
             _video.smoothing = true;
             _videoHolder.addChild(_video);
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/VideoWithWarningsBase.mxml b/bigbluebutton-client/src/org/bigbluebutton/main/views/VideoWithWarningsBase.mxml
index 0e73cd9802cf96912e84f7eb10274664161c7162..f6fa5b9d0391d959113b341ef2007ee99499cd40 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/main/views/VideoWithWarningsBase.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/main/views/VideoWithWarningsBase.mxml
@@ -21,13 +21,34 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 <mx:VBox xmlns:mx="library://ns.adobe.com/flex/mx" 
 		 xmlns:fx="http://ns.adobe.com/mxml/2009"
 		 xmlns:mate="http://mate.asfusion.com/" width="100%" height="100%"
+		 creationComplete="creationCompleteHandler(event)"
          horizontalAlign="center" >
+	<fx:Script>
+		<![CDATA[
+			import mx.events.FlexEvent;
+			
+			protected function creationCompleteHandler(event:FlexEvent):void
+			{
+				if (Capabilities.os.indexOf("Mac") >= 0){
+					this.currentState = "chromeMacOSX";
+				} else {
+					this.currentState = "chrome";
+				}
+			}
+			
+		]]>
+	</fx:Script>
 
 	<fx:Declarations>
 	    <mx:Fade id="dissolveOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/>
 	    <mx:Fade id="dissolveIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>
 	</fx:Declarations>
 
+	<mx:states>
+		<mx:State name="chrome"/>
+		<mx:State name="chromeMacOSX" basedOn="chrome"/>
+	</mx:states>
+
     <mx:Canvas
             id="videoCanvas"
             width="100%"
@@ -42,7 +63,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
                 y="60"
                 x="{this.width/2 - imgChromeHelp.width/2}"
                 visible="false"
-                source="@Embed('assets/chrome-permissions.png')" />
+                source.chrome="@Embed('assets/chrome-permissions-windows.png')"
+				source.chromeMacOSX="@Embed('assets/chrome-permissions-macosx.png')"/>
         <mx:VBox
                 width="100%"
                 height="100%"
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/assets/chrome-permissions.png b/bigbluebutton-client/src/org/bigbluebutton/main/views/assets/chrome-permissions-macosx.png
similarity index 100%
rename from bigbluebutton-client/src/org/bigbluebutton/main/views/assets/chrome-permissions.png
rename to bigbluebutton-client/src/org/bigbluebutton/main/views/assets/chrome-permissions-macosx.png
diff --git a/bigbluebutton-client/src/org/bigbluebutton/main/views/assets/chrome-permissions-windows.png b/bigbluebutton-client/src/org/bigbluebutton/main/views/assets/chrome-permissions-windows.png
new file mode 100644
index 0000000000000000000000000000000000000000..df4f60413620fa2af52985133c4c59d787198033
Binary files /dev/null and b/bigbluebutton-client/src/org/bigbluebutton/main/views/assets/chrome-permissions-windows.png differ
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/broadcast/models/Stream.as b/bigbluebutton-client/src/org/bigbluebutton/modules/broadcast/models/Stream.as
old mode 100644
new mode 100755
index 16ccef20b23ab2db460d2243c4f5e7604ab0883d..6764a035f9da4709b51c18faf88346f870b6abff
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/broadcast/models/Stream.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/broadcast/models/Stream.as
@@ -24,6 +24,7 @@ package org.bigbluebutton.modules.broadcast.models
 	import flash.media.Video;
 	import flash.net.NetConnection;
 	import flash.net.NetStream;
+	import flash.net.ObjectEncoding;
 	
 	import mx.core.UIComponent;
 	
@@ -119,6 +120,7 @@ package org.bigbluebutton.modules.broadcast.models
 		private function connect():void {
 			LOGGER.debug("Connecting {0}", [uri]);
 			nc = new NetConnection();
+			nc.objectEncoding = ObjectEncoding.AMF3;
 			nc.proxyType = "best";
 			nc.connect(uri);
 			nc.client = this;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/caption/views/CaptionWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/caption/views/CaptionWindow.mxml
index e4e9df66dbacc40178e6fe784403c09173e81b66..f05397d6795106a96bf5e3ab214d2012cb068eaa 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/caption/views/CaptionWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/caption/views/CaptionWindow.mxml
@@ -44,6 +44,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			import flexlib.controls.tabBarClasses.SuperTab;
 			
+			import org.as3commons.lang.StringUtils;
 			import org.bigbluebutton.common.events.LocaleChangeEvent;
 			import org.bigbluebutton.core.Options;
 			import org.bigbluebutton.core.UsersUtil;
@@ -185,7 +186,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private function setTextTabLabel(ownerId:String):void {
 				var ownerText:String = null;
 				
-				if (ownerId == "") {
+				if (StringUtils.isEmpty(ownerId)) {
 					//unclaimed text
 					//ownerNameOutputLabel.text = "Owner - " + "None";
 					ownerText = ResourceUtil.getInstance().getString('bbb.caption.transcript.noowner');
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/model/ChatConversation.as b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/model/ChatConversation.as
index f5c06267b94311170c063e1fce2ac2ff4bed9b56..a7a2901bcf8539884f7c06f8e3be6b8628a97558 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/model/ChatConversation.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/model/ChatConversation.as
@@ -50,6 +50,7 @@ package org.bigbluebutton.modules.chat.model
 		  newCM.lastTime = previousCM.time;
 	  }
 	  messages.addItem(newCM);
+	  messages.refresh();
     }
     
     public function processChatHistory(messageVOs:Array):void {
@@ -71,6 +72,7 @@ package org.bigbluebutton.modules.chat.model
           newCM.lastSenderId = previousCM.senderId;
           newCM.lastTime = previousCM.time;
         }
+		messages.refresh();
       }
     }
     
@@ -126,6 +128,8 @@ package org.bigbluebutton.modules.chat.model
       messages.removeAll();
       messages.addItem(cm);
 
+	  messages.refresh();
+
       var welcomeEvent:ChatHistoryEvent = new ChatHistoryEvent(ChatHistoryEvent.RECEIVED_HISTORY);
       _dispatcher.dispatchEvent(welcomeEvent);
     }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/model/ChatMessage.as b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/model/ChatMessage.as
index 9f00c500305d3a50cc998d2b38503ea29bc1301b..d3b5121465bd1d589c4e814ed0289533d3a727a7 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/model/ChatMessage.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/model/ChatMessage.as
@@ -17,6 +17,9 @@
 *
 */
 package org.bigbluebutton.modules.chat.model {
+	import org.as3commons.lang.StringUtils;
+	import org.bigbluebutton.common.Role;
+	import org.bigbluebutton.core.UsersUtil;
 	import org.bigbluebutton.util.i18n.ResourceUtil;
 	
 	public class ChatMessage {
@@ -30,20 +33,31 @@ package org.bigbluebutton.modules.chat.model {
 		[Bindable] public var lastTime:String;
 		[Bindable] public var text:String;
 
-	
-    // Stores the time (millis) when the sender sent the message.
-    public var fromTime:Number;
-    // Stores the timezone offset (minutes) of the sender.
-    public var fromTimezoneOffset:Number;
-	
-	/*
-    // Stores what we display to the user. The converted fromTime and fromTimezoneOffset to local time.
-    [Bindable] public var senderTime:String;
-    */
+	    // Stores the time (millis) when the sender sent the message.
+	    public var fromTime:Number;
+	    // Stores the timezone offset (minutes) of the sender.
+	    public var fromTimezoneOffset:Number;
+
+		/*
+	    // Stores what we display to the user. The converted fromTime and fromTimezoneOffset to local time.
+	    [Bindable] public var senderTime:String;
+	    */
+		
+		public function get differentLastSenderAndTime():Boolean {
+			return !(lastTime == time) || !sameLastSender;
+		}
+		
+		public function get sameLastSender() : Boolean {
+			return StringUtils.trimToEmpty(senderId) == StringUtils.trimToEmpty(lastSenderId);
+		}
+		
+		public function get isModerator():Boolean {
+			return UsersUtil.getUser(senderId) && UsersUtil.getUser(senderId).role == Role.MODERATOR
+		}
 		
 		public function toString() : String {
 			var result:String;
-			var accName:String = (!name || name == "" || name == " "? ResourceUtil.getInstance().getString("bbb.chat.chatMessage.systemMessage") : name);
+			var accName:String = (StringUtils.isBlank(name) ? ResourceUtil.getInstance().getString("bbb.chat.chatMessage.systemMessage") : name);
 			result = ResourceUtil.getInstance().getString("bbb.chat.chatMessage.stringRespresentation", [accName, stripTags(text), time]);
 			return result;
 		}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/AdvancedList.as b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/AdvancedList.as
index 401d27f091d97373763a5515f09bfb96f2ee603e..ddf653a7feaaf1afb4dd743c942e1ad816e0c11f 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/AdvancedList.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/AdvancedList.as
@@ -30,11 +30,6 @@ package org.bigbluebutton.modules.chat.views
   {
 	private static const LOGGER:ILogger = getClassLogger(AdvancedList);      
 	  
-    public function AdvancedList()
-    {
-      super();
-    }
-	
 	override protected function drawHighlightIndicator(indicator:Sprite, x:Number, y:Number, width:Number, height:Number, color:uint, itemRenderer:IListItemRenderer):void {
 		//intentionally empty to not show on hover
 	}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatBox.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatBox.mxml
index a642ffbd6ac27076e16e6a8062447596f9c39953..858839a848394776c88a9acdacaf16c29c6b8574 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatBox.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatBox.mxml
@@ -94,7 +94,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       
       private var globalDispatcher:Dispatcher = new Dispatcher();
       [Bindable] public var colorPickerColours:Array = ['0x000000', '0x7A7A7A' ,'0xFF0000', '0xFF8800',
-        '0x88FF00', '0x00FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF'];
+        '0x88FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF'];
       
       [Bindable]
       private var backgroundColor:uint = 0x000000;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatMessageRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatMessageRenderer.mxml
index b8ca99fb89258dcd98fed20957fc43ba1b40be4b..9bda142c251f7072a2bf6227ae2d04944a8e1316 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatMessageRenderer.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatMessageRenderer.mxml
@@ -22,19 +22,19 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 <mx:VBox xmlns:mx="library://ns.adobe.com/flex/mx"
 		 xmlns:fx="http://ns.adobe.com/mxml/2009"
-		 verticalAlign="top" verticalGap="0" paddingTop="0" paddingBottom="0"
+		 xmlns:common="org.bigbluebutton.common.*"
 		 verticalScrollPolicy="off" horizontalScrollPolicy="off"
-		 xmlns:common="org.bigbluebutton.common.*">
+		 dataChange="dataChangeHandler(event)"
+		 >
 	
 	<fx:Script>
 		<![CDATA[
 			import mx.core.UITextField;
 			import mx.core.mx_internal;
+			import mx.events.FlexEvent;
 			
 			import org.as3commons.logging.api.ILogger;
 			import org.as3commons.logging.api.getClassLogger;
-			import org.bigbluebutton.common.Role;
-			import org.bigbluebutton.core.UsersUtil;
 			
 			private static const LOGGER:ILogger = getClassLogger(ChatMessageRenderer);      
 
@@ -45,52 +45,28 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				}
 			}
 
-			//private function dataChangeHandler(e:Event = null):void{
-			override public function set data(value:Object):void {
-				//if (data == null) {
-				//	return;
-				//}		
-				super.data = value;
-				
-				//chatMsg = data as ChatMessage;
-				//data = null;
-				
-				if (data == null) return;
-				
-				// The visibility check has to go here becasue ORs don't work with databinding
-				lblTime.visible = (!(data.lastTime == data.time) || !(data.senderId == data.lastSenderId));
-				// check the visibility of the name as well because events might fire in different order
-				lblName.visible = !(data.senderId == data.lastSenderId);
-				
-				//remove the header if not needed to save space
-				hbHeader.includeInLayout = hbHeader.visible = lblName.visible || lblTime.visible;
-				
-				if (data.hasOwnProperty("senderId") && UsersUtil.getUser(data.senderId) && UsersUtil.getUser(data.senderId).role == Role.MODERATOR) {
-					hbHeader.styleName = "chatMessageHeaderModerator";
-					if (lblName.visible) {
-						moderatorIcon.visible = true;
-					}
-				}
-				
-				// If you remove this some of the chat messages will fail to render
-				validateNow();
-			}
-			
 			private function onKeyDown(event:KeyboardEvent):void{
 				if(event.ctrlKey == true && event.keyCode == Keyboard.C){
 					System.setClipboard(UITextField(txtMessage.mx_internal::getTextField()).selectedText);
 				}
 			}
-						
+
+			protected function dataChangeHandler(event:FlexEvent):void {
+				// If you remove this some of the chat messages will fail to render
+				validateNow();
+			}
 		]]>
 	</fx:Script>
 	
-  <mx:Canvas width="100%" id="hbHeader" styleName="chatMessageHeader" verticalScrollPolicy="off" horizontalScrollPolicy="off">
-    <mx:Label id="lblName" text="{data.name}" visible="true" verticalCenter="0" textAlign="left" left="0" maxWidth="{this.width - lblTime.width - moderatorIcon.width - 22}"/>
-	<mx:Image id="moderatorIcon" visible="false" source="{getStyle('moderatorIcon')}" x="{lblName.width + 4}" verticalCenter="0"/>
-    <mx:Text id="lblTime" htmlText="{data.time}" textAlign="right"
+  <mx:Canvas width="100%" id="hbHeader" styleName="chatMessageHeader" verticalScrollPolicy="off" horizontalScrollPolicy="off"
+			 visible="{lblName.visible || lblTime.visible}" includeInLayout="{lblName.visible || lblTime.visible}">
+    <mx:Label id="lblName" text="{data.name}" visible="{!data.sameLastSender}"
+			  verticalCenter="0" textAlign="left" left="0" maxWidth="{this.width - lblTime.width - moderatorIcon.width - 22}"
+			  styleName="{data.isModerator ? 'chatMessageHeaderModerator' : ''}"/>
+	<mx:Image id="moderatorIcon" visible="{lblName.visible &amp;&amp; data.isModerator}"
+			  source="{getStyle('moderatorIcon')}" x="{lblName.width + 4}" verticalCenter="0"/>
+    <mx:Text id="lblTime" visible="{data.differentLastSenderAndTime}" htmlText="{data.time}" textAlign="right"
 			 verticalCenter="0"
-             visible="true"
              right="4" />
   </mx:Canvas>
   <mx:Text id="txtMessage" htmlText="{data.text}" link="onLinkClick(event)" color="{data.senderColor}"
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatView.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatView.mxml
index 75de9da2b2962f8311b5f0e971ff9dc72610ff4a..bf092061b11da04d3051b0c3c0e4b7089c5f03f1 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatView.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/chat/views/ChatView.mxml
@@ -53,6 +53,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import flexlib.controls.tabBarClasses.SuperTab;
 			import flexlib.events.SuperTabEvent;
 			
+			import org.as3commons.lang.StringUtils;
 			import org.bigbluebutton.core.EventConstants;
 			import org.bigbluebutton.core.Options;
 			import org.bigbluebutton.core.UsersUtil;
@@ -128,7 +129,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 				var chatBox:ChatBox = getPublicChatBox();
 				var saveEvent:ChatSaveEvent = new ChatSaveEvent(ChatSaveEvent.SAVE_CHAT_EVENT);
 
-				if (chatBox.chatWithUsername == null || chatBox.chatWithUsername == "") {
+				if (StringUtils.isEmpty(chatBox.chatWithUsername)) {
 					saveEvent.filename = ResourceUtil.getInstance().getString('bbb.chat.save.filename');
 				} else {
 					saveEvent.filename = chatBox.chatWithUsername;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/layout/services/MessageReceiver.as b/bigbluebutton-client/src/org/bigbluebutton/modules/layout/services/MessageReceiver.as
index 3e6f666182d0780a27c6089178d7e157e52226ea..b951a7179625b3f668315a9c41c9c9f8ad7a8530 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/layout/services/MessageReceiver.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/layout/services/MessageReceiver.as
@@ -4,6 +4,7 @@ package org.bigbluebutton.modules.layout.services {
 	import flash.events.TimerEvent;
 	import flash.utils.Timer;
 	
+	import org.as3commons.lang.StringUtils;
 	import org.as3commons.logging.api.ILogger;
 	import org.as3commons.logging.api.getClassLogger;
 	import org.bigbluebutton.core.BBB;
@@ -90,7 +91,7 @@ package org.bigbluebutton.modules.layout.services {
 		private function onReceivedFirstLayout(message:Object):void {
 			LOGGER.debug("LayoutService: handling the first layout. locked = [{0}] layout = [{1}]", [message.locked, message.layout]);
 			trace("LayoutService: handling the first layout. locked = [" + message.locked + "] layout = [" + message.layout + "], moderator = [" + UsersUtil.amIModerator() + "]");
-			if (message.layout == "" || UsersUtil.amIModerator())
+			if (StringUtils.isEmpty(message.layout) || UsersUtil.amIModerator())
 				_dispatcher.dispatchEvent(new LayoutEvent(LayoutEvent.APPLY_DEFAULT_LAYOUT_EVENT));
 			else {
 				handleSyncLayout(message);
@@ -102,8 +103,8 @@ package org.bigbluebutton.modules.layout.services {
 		private function handleSyncLayout(message:Object):void {
 			// is this event needed? Doesn't seem to do anything becasue it only applies to the original layout and then it's changed right afterwards once the new one is loaded
 			_dispatcher.dispatchEvent(new RemoteSyncLayoutEvent(message.layout));
-			
-			if (message.layout == "")
+
+			if (StringUtils.isEmpty(message.layout))
 				return;
 
 			var layoutDefinition:LayoutDefinition = new LayoutDefinition();
@@ -122,5 +123,5 @@ package org.bigbluebutton.modules.layout.services {
 			_dispatcher.dispatchEvent(redefineLayout);
 		}
 	}
-}
+}
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/notes/views/NotesView.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/notes/views/NotesView.mxml
index e37ee82b4e75b4347b594abce72347be8621d6e4..52d7e639e961e60377b2231426aa858945b66826 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/notes/views/NotesView.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/notes/views/NotesView.mxml
@@ -34,7 +34,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       import org.bigbluebutton.util.i18n.ResourceUtil;
       
       [Bindable] public var colorPickerColours:Array = ['0x000000', '0x7A7A7A' ,'0xFF0000', '0xFF8800',
-        '0x88FF00', '0x00FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF'];
+        '0x88FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF'];
       
       [Bindable]
       public var notesArray:NotesModel;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/ConnectionManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/ConnectionManager.as
index 123c3d369171d24de349b3c8f2e900d7bcc7718a..08ccd6620ad3130137989af155a47ec9ed5e8847 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/ConnectionManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/phone/managers/ConnectionManager.as
@@ -25,16 +25,19 @@ package org.bigbluebutton.modules.phone.managers {
 	import flash.events.SecurityErrorEvent;
 	import flash.net.NetConnection;
 	import flash.net.NetStream;
+	import flash.net.ObjectEncoding;
 	
 	import org.as3commons.logging.api.ILogger;
 	import org.as3commons.logging.api.getClassLogger;
 	import org.bigbluebutton.core.BBB;
 	import org.bigbluebutton.core.UsersUtil;
 	import org.bigbluebutton.core.managers.ReconnectionManager;
+	import org.bigbluebutton.core.model.LiveMeeting;
 	import org.bigbluebutton.main.events.BBBEvent;
 	import org.bigbluebutton.modules.phone.events.FlashCallConnectedEvent;
 	import org.bigbluebutton.modules.phone.events.FlashCallDisconnectedEvent;
 	import org.bigbluebutton.modules.phone.events.FlashVoiceConnectionStatusEvent;
+	import org.bigbluebutton.util.ConnUtil;
 	
 	public class ConnectionManager {
 		private static const LOGGER:ILogger = getClassLogger(ConnectionManager);
@@ -85,18 +88,44 @@ package org.bigbluebutton.modules.phone.managers {
 		public function connect():void {				
 			if (!reconnecting || amIListenOnly) {
 				closedByUser = false;
-				var isTunnelling:Boolean = BBB.initConnectionManager().isTunnelling;
-				if (isTunnelling) {
-					uri = uri.replace(/rtmp:/gi, "rtmpt:");
-				}
-				LOGGER.debug("Connecting to uri=[{0}]", [uri]);
-				NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
+				
+				var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
+				var result:Array = pattern.exec(uri);
+				var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS
+					
 				netConnection = new NetConnection();
-				netConnection.proxyType = "best";
+				
+				if (BBB.initConnectionManager().isTunnelling) {
+					var tunnelProtocol: String = ConnUtil.RTMPT;
+					
+					if (useRTMPS) {
+						netConnection.proxyType = ConnUtil.PROXY_NONE;
+						tunnelProtocol = ConnUtil.RTMPS;
+					}
+						
+					uri = tunnelProtocol + "://" + result.server + "/" + result.app;
+					LOGGER.debug("BBB SIP CONNECT tunnel = TRUE " + "url=" +  uri);
+				} else {
+					var nativeProtocol: String = ConnUtil.RTMP;
+					if (useRTMPS) {
+						netConnection.proxyType = ConnUtil.PROXY_BEST;
+						nativeProtocol = ConnUtil.RTMPS;
+					}
+					
+					uri = nativeProtocol + "://" + result.server + "/" + result.app;
+					LOGGER.debug("BBB SIP CONNECT tunnel = FALSE " + "url=" +  uri);
+				}
+				
+				LOGGER.debug("VOICE CONF == Connecting to uri=[{0}]", [uri]);
+				
+				netConnection.objectEncoding = ObjectEncoding.AMF3;
+
 				netConnection.client = this;
 				netConnection.addEventListener( NetStatusEvent.NET_STATUS , netStatus );
 				netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
-				netConnection.connect(uri, meetingId, externUserId, username);
+				
+				var authToken: String = LiveMeeting.inst().me.authToken;
+				netConnection.connect(uri, meetingId, externUserId, username, authToken);
 			}
 			if (reconnecting && !amIListenOnly) {
 				handleConnectionSuccess();
@@ -165,7 +194,7 @@ package org.bigbluebutton.modules.phone.managers {
           break;
         case "NetConnection.Connect.NetworkChange":
           numNetworkChangeCount++;
-          if (numNetworkChangeCount % 20 == 0) {
+          if (numNetworkChangeCount % 2 == 0) {
               logData.tags = ["voice", "flash"];
              logData.message = "Detected network change on bbb-voice";
              logData.numNetworkChangeCount = numNetworkChangeCount;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/polling/service/PollDataProcessor.as b/bigbluebutton-client/src/org/bigbluebutton/modules/polling/service/PollDataProcessor.as
index 406ad42aa63fc9ef3fddf3599d2da3664117c001..03a39e1fbe023334eb39c9150b99541e13faa117 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/polling/service/PollDataProcessor.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/polling/service/PollDataProcessor.as
@@ -4,6 +4,7 @@ package org.bigbluebutton.modules.polling.service
   
   import flash.accessibility.Accessibility;
   
+  import org.as3commons.lang.StringUtils;
   import org.as3commons.logging.api.ILogger;
   import org.as3commons.logging.api.getClassLogger;
   import org.bigbluebutton.modules.chat.ChatConstants;
@@ -77,7 +78,7 @@ package org.bigbluebutton.modules.polling.service
         for (var k:int = 0; k < answers.length; k++) {
           var localizedKey: String = ResourceUtil.getInstance().getString('bbb.polling.answer.'+answers[k].key);
 
-          if (localizedKey == null || localizedKey == "" || localizedKey == "undefined") {
+          if (StringUtils.isEmpty(localizedKey) || localizedKey == "undefined") {
             localizedKey = answers[k].key;
           }
           accessibleAnswers += ResourceUtil.getInstance().getString("bbb.polling.results.accessible.answer", [localizedKey, answers[k].numVotes]) + "<br />";
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollResultsModal.as b/bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollResultsModal.as
index e66866b4b79d8049fdcfe335e17db03579964a3a..d613eae8fe20eec82bf4f230cb2d6e42178c3869 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollResultsModal.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/polling/views/PollResultsModal.as
@@ -14,6 +14,7 @@ package org.bigbluebutton.modules.polling.views
 	import mx.controls.HRule;
 	import mx.controls.Label;
 	
+	import org.as3commons.lang.StringUtils;
 	import org.bigbluebutton.common.AdvancedLabel;
 	import org.bigbluebutton.core.PopUpUtil;
 	import org.bigbluebutton.modules.polling.events.PollStoppedEvent;
@@ -130,7 +131,7 @@ package org.bigbluebutton.modules.polling.views
 				var a:SimpleAnswer = answers[j] as SimpleAnswer;
 				var localizedKey: String = ResourceUtil.getInstance().getString('bbb.polling.answer.' + a.key);
 				
-				if (localizedKey == null || localizedKey == "" || localizedKey == "undefined") {
+				if (StringUtils.isEmpty(localizedKey) || localizedKey == "undefined") {
 					localizedKey = a.key
 				} 
 				resultData.push({a:localizedKey, v:0});
@@ -155,7 +156,7 @@ package org.bigbluebutton.modules.polling.views
 				var a:SimpleAnswerResult = answers[j] as SimpleAnswerResult;
 				var localizedKey: String = ResourceUtil.getInstance().getString('bbb.polling.answer.' + a.key);
 				
-				if (localizedKey == null || localizedKey == "" || localizedKey == "undefined") {
+				if (StringUtils.isEmpty(localizedKey) || localizedKey == "undefined") {
 					localizedKey = a.key;
 				} 
 				
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml
index 9b3f05cafa5d66adde5fd4d62230eacb14fda7da..603e6b6d3be87151ff93cab66ecff96cadc9276e 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/FileUploadWindow.mxml
@@ -376,9 +376,9 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
   </fx:Script>
 	
 	<mx:states>
-		<s:State name="normal" />
-		<s:State name="uploading" />
-		<s:State name="error" />
+		<mx:State name="normal" />
+		<mx:State name="uploading" />
+		<mx:State name="error" />
 	</mx:states>
 	
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml
index 67617d8224335eeaad4b4b0e13a107b323eea41a..33746543080db22271f5cf4a204083839c4fc6b0 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/present/ui/views/PresentationWindow.mxml
@@ -77,6 +77,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			
 			import flexlib.mdi.events.MDIWindowEvent;
 			
+			import org.as3commons.lang.StringUtils;
 			import org.as3commons.logging.api.ILogger;
 			import org.as3commons.logging.api.getClassLogger;
 			import org.bigbluebutton.common.events.AddUIComponentToMainCanvas;
@@ -721,7 +722,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 							
 							var localizedKey: String = ResourceUtil.getInstance().getString('bbb.polling.answer.'+e.poll.answers[i].key);
 
-							if (localizedKey == null || localizedKey == "" || localizedKey == "undefined") {
+							if (StringUtils.isEmpty(localizedKey) || localizedKey == "undefined") {
 								localizedKey = e.poll.answers[i].key;
 							} 
 							
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/PublishWindowManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/PublishWindowManager.as
index 603f6e4fd5f6067c089b46bd6bf13163e50f77fc..9c1141d49bcd9f67a2e4a55f7f76f5b67fb11444 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/PublishWindowManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/PublishWindowManager.as
@@ -46,11 +46,11 @@ package org.bigbluebutton.modules.screenshare.managers {
             if (shareWindow != null) shareWindow.stopSharing();
         }
         
-        public function startSharing(uri:String, room:String, tunnel:Boolean):void {
+        public function startSharing():void {
             LOGGER.debug("DS:PublishWindowManager::opening desk share window");
             if (shareWindow == null) {
               shareWindow = new ScreensharePublishWindow();
-              shareWindow.initWindow(service.getConnection(), uri, room, tunnel);
+              shareWindow.initWindow(service.getConnection());
               shareWindow.visible = true;
               openWindow(shareWindow);
             }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ScreenshareManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ScreenshareManager.as
index 031bbe8f8ff1fc4230aa0c887a3794ab7491ccc5..1734b5675c567a9993bb4bc251d4cb28c697b43d 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ScreenshareManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/ScreenshareManager.as
@@ -152,7 +152,7 @@ package org.bigbluebutton.modules.screenshare.managers {
 
             if (force || (options.tryWebRTCFirst && !BrowserCheck.isWebRTCSupported()) || !options.tryWebRTCFirst) {
               usingJava = true;
-              publishWindowManager.startSharing(module.getCaptureServerUri(), module.getRoom(), BBB.initConnectionManager().isTunnelling);
+              publishWindowManager.startSharing();
               sharing = true;
               service.requestShareToken();
             } else {
@@ -200,7 +200,7 @@ package org.bigbluebutton.modules.screenshare.managers {
         public function handleStartSharingEvent():void {
             //toolbarButtonManager.disableToolbarButton();
             toolbarButtonManager.startedSharing();
-            publishWindowManager.startSharing(module.getCaptureServerUri(), module.getRoom(), module.tunnel());
+            publishWindowManager.startSharing();
             sharing = true;
         }
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCViewerWindowManager.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCViewerWindowManager.as
old mode 100644
new mode 100755
index 2a04b8b8d50a6e49beff8b35bf3a9d8b9fa90eb2..75b0c47c0d906731e08c34cef4ba8047798f6cbf
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCViewerWindowManager.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/managers/WebRTCViewerWindowManager.as
@@ -34,12 +34,10 @@ package org.bigbluebutton.modules.screenshare.managers
 
 		private var viewWindow:WebRTCDesktopViewWindow;
 		private var shareWindow:WebRTCDesktopPublishWindow;
-		private var service:WebRTCDeskshareService;
 		private var isViewing:Boolean = false;
 		private var globalDispatcher:Dispatcher;
 
 		public function WebRTCViewerWindowManager(service:WebRTCDeskshareService) {
-			this.service = service;
 			globalDispatcher = new Dispatcher();
 		}
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/model/ScreenshareOptions.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/model/ScreenshareOptions.as
index 902dbffbf638feec2411e7c6dcf54e89fe2cfa05..1907609dc4210f2a2d240b46eb009f434d58bf7c 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/model/ScreenshareOptions.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/model/ScreenshareOptions.as
@@ -21,6 +21,9 @@ package org.bigbluebutton.modules.screenshare.model {
 
 	public class ScreenshareOptions extends Options {
 
+		[Bindable]
+		public var uri: String = "";
+			
 		[Bindable]
 		public var showButton:Boolean = true;
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/ScreenshareService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/ScreenshareService.as
index 185bd9240ca4bc89a9e7c9dfb5af3aef66415763..4087f09bf089814f2433f110c66fab7d17511ca4 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/ScreenshareService.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/ScreenshareService.as
@@ -18,8 +18,6 @@
  */
 package org.bigbluebutton.modules.screenshare.services {
     import com.asfusion.mate.events.Dispatcher;
-    
-    import flash.net.NetConnection;
     import org.as3commons.logging.api.ILogger;
     import org.as3commons.logging.api.getClassLogger;
     import org.bigbluebutton.core.UsersUtil;
@@ -52,19 +50,14 @@ package org.bigbluebutton.modules.screenshare.services {
         public function handleStartModuleEvent(module:ScreenshareModule):void {
             LOGGER.debug("Screenshare Module starting");
             this.module = module;
-            connect(module.uri, module.getRoom());
+            connect();
         }
         
-        public function connect(uri:String, room:String):void {
-            this.uri = uri;
-            this.room = room;
-            LOGGER.debug("Screenshare Service connecting to " + uri);
-            conn = new Connection(room);
-            
+        public function connect():void {
+            conn = new Connection();
             sender = new MessageSender(conn);
             receiver = new MessageReceiver(conn);
-            
-            conn.setURI(uri);
+
             conn.connect();
         }
         
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/WebRTCDeskshareService.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/WebRTCDeskshareService.as
index 7bdefe4f660a35a498c292492209f353e4324e0c..73aa12c9a731f47e49e10b8926968e52ad0498b2 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/WebRTCDeskshareService.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/WebRTCDeskshareService.as
@@ -37,13 +37,10 @@ package org.bigbluebutton.modules.screenshare.services
 
 		private var sender:MessageSender;
 
-		private var uri:String;
-		private var room:String;
-
 		public function WebRTCDeskshareService() {
 			this.dispatcher = new Dispatcher();
 
-			red5conn = new Connection(room);
+			red5conn = new Connection();
 			sender = new MessageSender(red5conn);
 			sender.queryForScreenshare();
 		}
@@ -51,13 +48,6 @@ package org.bigbluebutton.modules.screenshare.services
 		public function handleStartModuleEvent(module:ScreenshareModule):void {
 			LOGGER.debug("Deskshare Module starting");
 			this.module = module;
-			connect(module.uri, module.getRoom());
-		}
-
-		public function connect(uri:String, room:String):void {
-			this.uri = uri;
-			this.room = room;
-			LOGGER.debug("Deskshare Service connecting to {0}", [uri]);
 		}
 
 		public function getConnection():NetConnection{
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/red5/Connection.as b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/red5/Connection.as
index 28419963b217eadef24da530622866bf16e2223b..4612e26a07ea42dcc56150f0122c83fb189d8f80 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/red5/Connection.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/services/red5/Connection.as
@@ -19,64 +19,77 @@
 
 package org.bigbluebutton.modules.screenshare.services.red5 {
     import com.asfusion.mate.events.Dispatcher;
-    
     import flash.events.NetStatusEvent;
     import flash.events.SecurityErrorEvent;
     import flash.net.NetConnection;
     import flash.net.ObjectEncoding;
     import flash.net.Responder;
-    
     import org.as3commons.logging.api.ILogger;
     import org.as3commons.logging.api.getClassLogger;
     import org.bigbluebutton.core.BBB;
+		import org.bigbluebutton.core.Options;
     import org.bigbluebutton.core.UsersUtil;
     import org.bigbluebutton.core.managers.ReconnectionManager;
     import org.bigbluebutton.main.events.BBBEvent;
     import org.bigbluebutton.modules.screenshare.events.ViewStreamEvent;
     import org.bigbluebutton.modules.screenshare.model.ScreenshareModel;
-    
+		import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
+		import org.bigbluebutton.util.ConnUtil;
+		
     public class Connection {
         private static const LOGGER:ILogger = getClassLogger(Connection);
         
         private var netConnection:NetConnection;
-        private var uri:String;
         private var responder:Responder;
         private var width:Number;
         private var height:Number;
-        private var meetingId:String;
         
         private var dispatcher:Dispatcher = new Dispatcher();
         private var _messageListeners:Array = new Array();
         private var logoutOnUserCommand:Boolean = false;
         private var reconnecting:Boolean = false;
-        
-        public function Connection(meetingId:String) {
-            this.meetingId = meetingId;
-        }
-        
-        public function connect():void {
-            var isTunnelling:Boolean = BBB.initConnectionManager().isTunnelling;
-            if (isTunnelling) {
-              uri = uri.replace(/rtmp:/gi, "rtmpt:");
-            }
-
-            NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
-            netConnection = new NetConnection();
-            netConnection.proxyType = "best";
-            netConnection.client = this;
-            netConnection.addEventListener( NetStatusEvent.NET_STATUS , netStatusHandler);
-            netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
-
-            // uri may include internal meetingId if we are reconnecting
-            var internalMeetingID:String = UsersUtil.getInternalMeetingID();
-            if (uri.indexOf(internalMeetingID) == -1) {
-                uri = uri + "/" + internalMeetingID;
-            }
-
-            LOGGER.debug("Connecting to uri=[{0}]", [uri]);
-            netConnection.connect(uri);
-            
-        }
+				private var numNetworkChangeCount:int = 0;
+				private var ssAppUrl: String = null;
+				
+			public function connect():void {
+				netConnection = new NetConnection();
+				netConnection.objectEncoding = ObjectEncoding.AMF3;
+				
+				var options: ScreenshareOptions = Options.getOptions(ScreenshareOptions) as ScreenshareOptions;
+				var appURL: String = options.uri;
+				
+				var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
+				var result:Array = pattern.exec(appURL);
+			
+				var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS;
+				
+				if (BBB.initConnectionManager().isTunnelling) {
+					var tunnelProtocol: String = ConnUtil.RTMPT;
+				
+					if (useRTMPS) {
+						netConnection.proxyType = ConnUtil.PROXY_NONE;
+						tunnelProtocol = ConnUtil.RTMPS;
+					}
+					
+					ssAppUrl = tunnelProtocol + "://" + result.server + "/" + result.app + "/" + UsersUtil.getInternalMeetingID();
+					LOGGER.debug("SCREENSHARE CONNECT tunnel = TRUE " + "url=" +  ssAppUrl);
+				} else {
+					var nativeProtocol: String = ConnUtil.RTMP;
+					if (useRTMPS) {
+						netConnection.proxyType = ConnUtil.PROXY_BEST;
+						nativeProtocol = ConnUtil.RTMPS;
+					}
+				
+					ssAppUrl = nativeProtocol + "://" + result.server + "/" + result.app + "/" + UsersUtil.getInternalMeetingID();
+					LOGGER.debug("SCREENSHARE CONNECT tunnel = FALSE " + "url=" +  ssAppUrl);
+				}
+				
+				netConnection.client = this;
+				netConnection.addEventListener( NetStatusEvent.NET_STATUS , netStatusHandler);
+				netConnection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
+				LOGGER.debug("Connecting to uri=[{0}]", [ssAppUrl]);
+				netConnection.connect(ssAppUrl);
+			}
         
         public function addMessageListener(listener:IMessageListener):void {
             _messageListeners.push(listener);
@@ -216,10 +229,6 @@ package org.bigbluebutton.modules.screenshare.services.red5 {
             }, message);
         }
         
-        public function setURI(p_URI:String):void {
-            uri = p_URI;
-        }
-        
         public function onBWCheck(... rest):Number {
             return 0;
         }
@@ -234,7 +243,7 @@ package org.bigbluebutton.modules.screenshare.services.red5 {
         
         private function sendUserIdToServer():void {
             var message:Object = new Object();
-            message["meetingId"] = meetingId;
+            message["meetingId"] = UsersUtil.getInternalMeetingID();
             message["userId"] = UsersUtil.getMyUserID();
             
             sendMessage("screenshare.setUserId", function(result:String):void { // On successful result
@@ -250,11 +259,15 @@ package org.bigbluebutton.modules.screenshare.services.red5 {
         }
         
         private function netStatusHandler(event:NetStatusEvent):void {
-            LOGGER.debug("Connected to [" + uri + "]. [" + event.info.code + "]");
+						var logData:Object = UsersUtil.initLogData();
+						logData.tags = ["screenshare"];
+						logData.user.eventCode = event.info.code + "[reconnecting=" + reconnecting + "]";
             
             var ce:ConnectionEvent;
             switch (event.info.code) {
             case "NetConnection.Connect.Failed":
+								logData.message = "NetStream.Play.Failed from bbb-screenshare";
+								LOGGER.info(JSON.stringify(logData));
                 if (reconnecting) {
                     var attemptFailedEvent:BBBEvent = new BBBEvent(BBBEvent.RECONNECT_CONNECTION_ATTEMPT_FAILED_EVENT);
                     attemptFailedEvent.payload.type = ReconnectionManager.DESKSHARE_CONNECTION;
@@ -265,6 +278,7 @@ package org.bigbluebutton.modules.screenshare.services.red5 {
                 break;
             
             case "NetConnection.Connect.Success":
+								numNetworkChangeCount = 0;
                 if (reconnecting) {
                     reconnecting = false;
                     if (ScreenshareModel.getInstance().isSharing) {
@@ -288,7 +302,8 @@ package org.bigbluebutton.modules.screenshare.services.red5 {
                 break;
             
             case "NetConnection.Connect.Closed":
-                LOGGER.debug("Screenshare connection closed.");
+								logData.message = "NetConnection.Connect.Closed from bbb-screenshare";
+								LOGGER.info(JSON.stringify(logData));
                 if (!logoutOnUserCommand) {
                     reconnecting = true;
                     
@@ -312,8 +327,14 @@ package org.bigbluebutton.modules.screenshare.services.red5 {
                 break;
             
             case "NetConnection.Connect.NetworkChange":
-                LOGGER.debug("Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
-                break;
+								numNetworkChangeCount++;
+								if (numNetworkChangeCount % 2 == 0) {
+									logData.tags = ["screenshare", "flash"];
+									logData.message = "Detected network change on bbb-screenshare";
+									logData.numNetworkChangeCount = numNetworkChangeCount;
+									LOGGER.info(JSON.stringify(logData));
+								}
+								break;
             }
         }
         
@@ -332,11 +353,11 @@ package org.bigbluebutton.modules.screenshare.services.red5 {
         }
         
         public function connectionFailedHandler(e:ConnectionEvent):void {
-            LOGGER.error("connection failed to " + uri + " with message " + e.toString());
+            LOGGER.error("connection failed to " + ssAppUrl + " with message " + e.toString());
         }
         
         public function connectionRejectedHandler(e:ConnectionEvent):void {
-            LOGGER.error("connection rejected " + uri + " with message " + e.toString());
+            LOGGER.error("connection rejected " + ssAppUrl + " with message " + e.toString());
         }
         
     }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
index d4cdf78e29adfff2a21625c2dcb36b84e4e5904b..579474746b4667b5671db1f120ba516ba7be12d6 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/ScreensharePublishWindow.mxml
@@ -49,32 +49,33 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
   <fx:Script>
     <![CDATA[
-		import com.asfusion.mate.events.Dispatcher;
-		
-		import org.as3commons.logging.api.ILogger;
-		import org.as3commons.logging.api.getClassLogger;
-		import org.bigbluebutton.common.events.LocaleChangeEvent;
-		import org.bigbluebutton.core.Options;
-		import org.bigbluebutton.core.UsersUtil;
-		import org.bigbluebutton.core.managers.ReconnectionManager;
-		import org.bigbluebutton.main.events.BBBEvent;
-		import org.bigbluebutton.main.events.MadePresenterEvent;
-		import org.bigbluebutton.main.events.ShortcutEvent;
-		import org.bigbluebutton.main.views.MainCanvas;
-		import org.bigbluebutton.modules.screenshare.events.RequestToPauseSharing;
-		import org.bigbluebutton.modules.screenshare.events.RequestToRestartSharing;
-		import org.bigbluebutton.modules.screenshare.events.RequestToStopSharing;
-		import org.bigbluebutton.modules.screenshare.events.ScreenSharePausedEvent;
-		import org.bigbluebutton.modules.screenshare.events.ShareStartEvent;
-		import org.bigbluebutton.modules.screenshare.events.ShareStoppedEvent;
-		import org.bigbluebutton.modules.screenshare.events.ShareWindowEvent;
-		import org.bigbluebutton.modules.screenshare.events.StartShareRequestSuccessEvent;
-		import org.bigbluebutton.modules.screenshare.events.StopSharingButtonEvent;
-		import org.bigbluebutton.modules.screenshare.events.ViewStreamEvent;
-		import org.bigbluebutton.modules.screenshare.model.ScreenshareModel;
-		import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
-		import org.bigbluebutton.modules.screenshare.services.red5.Connection;
-		import org.bigbluebutton.util.i18n.ResourceUtil;
+			import com.asfusion.mate.events.Dispatcher;
+			
+			import org.as3commons.logging.api.ILogger;
+			import org.as3commons.logging.api.getClassLogger;
+			import org.bigbluebutton.common.events.LocaleChangeEvent;
+			import org.bigbluebutton.core.BBB;
+			import org.bigbluebutton.core.Options;
+			import org.bigbluebutton.core.UsersUtil;
+			import org.bigbluebutton.core.managers.ReconnectionManager;
+			import org.bigbluebutton.main.events.BBBEvent;
+			import org.bigbluebutton.main.events.MadePresenterEvent;
+			import org.bigbluebutton.main.events.ShortcutEvent;
+			import org.bigbluebutton.main.views.MainCanvas;
+			import org.bigbluebutton.modules.screenshare.events.RequestToPauseSharing;
+			import org.bigbluebutton.modules.screenshare.events.RequestToRestartSharing;
+			import org.bigbluebutton.modules.screenshare.events.RequestToStopSharing;
+			import org.bigbluebutton.modules.screenshare.events.ScreenSharePausedEvent;
+			import org.bigbluebutton.modules.screenshare.events.ShareStartEvent;
+			import org.bigbluebutton.modules.screenshare.events.ShareStoppedEvent;
+			import org.bigbluebutton.modules.screenshare.events.ShareWindowEvent;
+			import org.bigbluebutton.modules.screenshare.events.StartShareRequestSuccessEvent;
+			import org.bigbluebutton.modules.screenshare.events.StopSharingButtonEvent;
+			import org.bigbluebutton.modules.screenshare.events.ViewStreamEvent;
+			import org.bigbluebutton.modules.screenshare.model.ScreenshareModel;
+			import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
+			import org.bigbluebutton.modules.screenshare.services.red5.Connection;
+			import org.bigbluebutton.util.i18n.ResourceUtil;
 		
       
       private static const LOGGER:ILogger = getClassLogger(ScreensharePublishWindow);
@@ -84,9 +85,6 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       private static const VID_WIDTH_PAD:Number = 6;
       
       private var connection:Connection;
-      private var uri:String;
-      private var room:String;
-      private var tunnel:Boolean = false;
       private var sharingFullScreen:Boolean = false;
       private var streaming:Boolean = false;
 
@@ -137,7 +135,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 		focusManager.setFocus(titleBarOverlay);
 
-		if (tunnel) {
+		if (BBB.initConnectionManager().isTunnelling) {
 			helpInfoBox.visible = helpInfoBox.includeInLayout = false;
 			previewBox.visible = previewBox.includeInLayout = false;
 			tunnelBox.visible = tunnelBox.includeInLayout = true;
@@ -184,11 +182,8 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
       */
       public function resetWidthAndHeight():void{/* do nothing */}
 
-      public function initWindow(connection:Connection, uri:String, room:String, tunnel:Boolean):void {
+      public function initWindow(connection:Connection):void {
         this.connection = connection;
-        this.uri = uri;
-        this.room = room;
-		this.tunnel = tunnel;
       }
 
       private function handleStartShareRequestSuccessEvent(event:StartShareRequestSuccessEvent):void {
@@ -254,10 +249,10 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
         startBtn.enabled = false;
         var shareStartEvent:ShareStartEvent = new ShareStartEvent();
         dispatchEvent(shareStartEvent);
-        startSharing(connection.getConnection(), uri, room, fullScreen);
+        startSharing(connection.getConnection(), fullScreen);
       }
 
-      private function startSharing(connection:NetConnection, uri:String, room:String, fullScreen:Boolean):void {
+      private function startSharing(connection:NetConnection, fullScreen:Boolean):void {
         var captureX:Number = 0;
         var captureY:Number = 0;
         sharingFullScreen = fullScreen;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopPublishWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopPublishWindow.mxml
index 945196a1eed7ae046168c307e5b5f2e3a4bf0049..a7392dc64338eea092524b40c1f8258b48906175 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopPublishWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopPublishWindow.mxml
@@ -58,6 +58,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.as3commons.logging.api.getClassLogger;
 			import org.bigbluebutton.common.IBbbModuleWindow;
 			import org.bigbluebutton.common.events.LocaleChangeEvent;
+			import org.bigbluebutton.core.BBB;
 			import org.bigbluebutton.core.Options;
 			import org.bigbluebutton.main.api.JSLog;
 			import org.bigbluebutton.main.events.BBBEvent;
@@ -74,6 +75,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			import org.bigbluebutton.modules.screenshare.events.WebRTCViewStreamEvent;
 			import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
 			import org.bigbluebutton.modules.screenshare.services.red5.WebRTCConnectionEvent;
+			import org.bigbluebutton.util.ConnUtil;
 			import org.bigbluebutton.util.i18n.ResourceUtil;
 
 			private static const LOGGER:ILogger = getClassLogger(WebRTCDesktopPublishWindow);
@@ -240,13 +242,41 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 
 				connection = new NetConnection();
-				connection.proxyType = "best";
-				connection.objectEncoding = ObjectEncoding.AMF0;
+				
+				var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<serverAndApp>.+)/;
+				var result:Array = pattern.exec(meetingUrl);
+				
+				var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS;
+				var ssAppUrl: String = null;
+				
+				if (BBB.initConnectionManager().isTunnelling) {
+					var tunnelProtocol: String = ConnUtil.RTMPT;
+					
+					if (useRTMPS) {
+						connection.proxyType = ConnUtil.PROXY_NONE;
+						tunnelProtocol = ConnUtil.RTMPS;
+					}
+					
+					
+					ssAppUrl = tunnelProtocol + "://" + result.serverAndApp;
+					LOGGER.debug("WEBRTC SSHARE CONNECT tunnel = TRUE " + "url=" +  ssAppUrl);
+				} else {
+					var nativeProtocol: String = ConnUtil.RTMP;
+					if (useRTMPS) {
+						connection.proxyType = ConnUtil.PROXY_BEST;
+						nativeProtocol = ConnUtil.RTMPS;
+					}
+					
+					ssAppUrl = nativeProtocol + "://" + result.serverAndApp;
+					LOGGER.debug("WEBRTC SSHARE CONNECT tunnel = FALSE " + "url=" +  ssAppUrl);
+				}
+				
+				connection.objectEncoding = ObjectEncoding.AMF3;
 				connection.client = this;
 
 				connection.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
 				connection.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
-				connection.connect(meetingUrl);
+				connection.connect(ssAppUrl);
 			}
 
 			private function netStatusHandler(event:NetStatusEvent):void {
@@ -268,7 +298,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 						break;
 
 					case "NetConnection.Connect.Closed":
-						trace("Deskshare connection closed.");
+						LOGGER.debug("Deskshare connection closed.");
 						ce.status = WebRTCConnectionEvent.CLOSED;
 						break;
 
@@ -281,7 +311,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 						break;
 
 					case "NetConnection.Connect.NetworkChange":
-						trace("Detected network change. User might be on a wireless and " +
+						LOGGER.debug("Detected network change. User might be on a wireless and " +
 							"temporarily dropped connection. Doing nothing. Just making a note.");
 						break;
 				}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopViewWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopViewWindow.mxml
old mode 100644
new mode 100755
index cb4b352d43fc34e73a53f34c7c6b1c50e6014c4b..015177fefa4864bba1200a630146cf62e981396c
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopViewWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/screenshare/view/components/WebRTCDesktopViewWindow.mxml
@@ -40,19 +40,19 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	<fx:Script>
 		<![CDATA[
 			import mx.core.UIComponent;
-			
 			import flexlib.mdi.events.MDIWindowEvent;
-			
 			import org.as3commons.logging.api.ILogger;
 			import org.as3commons.logging.api.getClassLogger;
 			import org.bigbluebutton.common.IBbbModuleWindow;
-			import org.bigbluebutton.common.events.LocaleChangeEvent;
-			import org.bigbluebutton.core.Options;
+			import org.bigbluebutton.common.events.LocaleChangeEvent;
+			import org.bigbluebutton.core.BBB;
+			import org.bigbluebutton.core.Options;
 			import org.bigbluebutton.main.views.MainCanvas;
 			import org.bigbluebutton.modules.screenshare.events.ViewStreamEvent;
 			import org.bigbluebutton.modules.screenshare.events.ViewWindowEvent;
 			import org.bigbluebutton.modules.screenshare.model.ScreenshareOptions;
-			import org.bigbluebutton.modules.screenshare.services.red5.WebRTCConnectionEvent;
+			import org.bigbluebutton.modules.screenshare.services.red5.WebRTCConnectionEvent;
+			import org.bigbluebutton.util.ConnUtil;
 			import org.bigbluebutton.util.i18n.ResourceUtil;
 
 			public static const LOG:String = "Deskshare::DesktopViewWindow - ";
@@ -130,13 +130,41 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 
 			public function connect(rtmpUrl: String):void {
 				nc = new NetConnection();
-				nc.proxyType = "best";
-				nc.objectEncoding = ObjectEncoding.AMF0;
+				
+				var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<serverAndApp>.+)/;
+				var result:Array = pattern.exec(rtmpUrl);
+				
+				var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS;
+				var ssAppUrl: String = null;
+				
+				if (BBB.initConnectionManager().isTunnelling) {
+					var tunnelProtocol: String = ConnUtil.RTMPT;
+				
+					if (useRTMPS) {
+						nc.proxyType = ConnUtil.PROXY_NONE;
+						tunnelProtocol = ConnUtil.RTMPS;
+					}
+					
+					
+					ssAppUrl = tunnelProtocol + "://" + result.serverAndApp;
+					LOGGER.debug("WEBRTC SSHARE CONNECT tunnel = TRUE " + "url=" +  ssAppUrl);
+				} else {
+					var nativeProtocol: String = ConnUtil.RTMP;
+					if (useRTMPS) {
+						nc.proxyType = ConnUtil.PROXY_BEST;
+						nativeProtocol = ConnUtil.RTMPS;
+					}
+				
+					ssAppUrl = nativeProtocol + "://" + result.serverAndApp;
+					LOGGER.debug("WEBRTC SSHARE CONNECT tunnel = FALSE " + "url=" +  ssAppUrl);
+				}
+				
+				nc.objectEncoding = ObjectEncoding.AMF3;
 				nc.client = this;
 
 				nc.addEventListener(NetStatusEvent.NET_STATUS, netStatusHandler);
 				nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
-				nc.connect(rtmpUrl);
+				nc.connect(ssAppUrl);
 			}
 
 			public function connectionSuccessHandler():void{
@@ -193,7 +221,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 						break;
 
 					case "NetConnection.Connect.NetworkChange":
-						trace(LOG + "Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
+						LOGGER.debug(LOG + "Detected network change. User might be on a wireless and temporarily dropped connection. Doing nothing. Just making a note.");
 						break;
 				}
 			}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/components/SharedNotesRichTextEditor.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/components/SharedNotesRichTextEditor.mxml
index b10042db3cfd47c35ce5e7a1743b0f8a83f33761..c2fe647dac2f6b6afaa67467ab5c44e783c81309 100644
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/components/SharedNotesRichTextEditor.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/sharednotes/views/components/SharedNotesRichTextEditor.mxml
@@ -283,23 +283,23 @@
 
     <fx:Script>
     <![CDATA[
-
-    import flash.events.Event;
-    import flash.events.FocusEvent;
-    import flash.events.KeyboardEvent;
-    import flash.events.MouseEvent;
-    import flash.events.TextEvent;
-    import flash.text.TextFormat;
-    
-    import mx.collections.ArrayCollection;
-    import mx.controls.textClasses.TextRange;
-    import mx.core.IUITextField;
-    import mx.core.UITextFormat;
-    import mx.core.mx_internal;
-    
-    import org.as3commons.logging.api.ILogger;
-    import org.as3commons.logging.api.getClassLogger;
-    import org.bigbluebutton.modules.sharednotes.util.DiffPatch;
+		import flash.events.Event;
+		import flash.events.FocusEvent;
+		import flash.events.KeyboardEvent;
+		import flash.events.MouseEvent;
+		import flash.events.TextEvent;
+		import flash.text.TextFormat;
+		
+		import mx.collections.ArrayCollection;
+		import mx.controls.textClasses.TextRange;
+		import mx.core.IUITextField;
+		import mx.core.UITextFormat;
+		import mx.core.mx_internal;
+		
+		import org.as3commons.lang.StringUtils;
+		import org.as3commons.logging.api.ILogger;
+		import org.as3commons.logging.api.getClassLogger;
+		import org.bigbluebutton.modules.sharednotes.util.DiffPatch;
     use namespace mx_internal;
 
     private static const LOGGER:ILogger = getClassLogger(SharedNotesRichTextEditor);
@@ -902,7 +902,7 @@
                 if (carIndex < textArea.getTextField().length)
                 {
                     var tfNext:TextFormat=textArea.getTextField().getTextFormat(carIndex, carIndex + 1);
-                    if (!tfNext.url || tfNext.url == "")
+                    if (StringUtils.isEmpty(tfNext.url))
                         tf.url = tf.target = "";
                 }
                 else
@@ -938,7 +938,7 @@
         if (!previousTextFormat || previousTextFormat.bullet != tf.bullet)
             bulletButton.selected = tf.bullet;
         if (!previousTextFormat || previousTextFormat.url != tf.url)
-            linkTextInput.text = (tf.url == "" || tf.url == null) ? defaultLinkProtocol : tf.url;
+            linkTextInput.text = (StringUtils.isEmpty(tf.url)) ? defaultLinkProtocol : tf.url;
 
         if (textArea.getTextField().defaultTextFormat != tf)
             textArea.getTextField().defaultTextFormat = tf;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
index 9d0ade9e057022f663c3acddcf89cb2696187e64..3e1aed204ea0d146adfc52c2335ef8e61cccadd2 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/JoinBreakoutRoomWindow.mxml
@@ -75,17 +75,15 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 		<mx:Label htmlText="{ResourceUtil.getInstance().getString('bbb.users.breakout.invited')}" paddingTop="4" />
 		<mx:Canvas>
 			<mx:Image source="{getStyle('iconRooms')}" />
-			<mx:Canvas x="16"
-					   y="47"
-					   height="38"
-					   width="70">
-				<s:Label id="sequenceLabel"
+			<mx:Canvas x="16" y="47" height="38" width="70"
+					   verticalScrollPolicy="off" horizontalScrollPolicy="off">
+				<mx:Label id="sequenceLabel"
 						 styleName="roomNumberStyle"
 						 verticalCenter="0"
 						 horizontalCenter="0" />
 			</mx:Canvas>
 		</mx:Canvas>
-		<s:Label width="100%" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.users.breakout.accept')}" />
+		<mx:Label width="100%" textAlign="center" text="{ResourceUtil.getInstance().getString('bbb.users.breakout.accept')}" />
 		<mx:Button id="joinButton"
 				   label="{ResourceUtil.getInstance().getString('bbb.users.breakout.joinSession')}"
 				   accessibilityName="{ResourceUtil.getInstance().getString('bbb.users.breakout.joinSession.accessibilityName')}"
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/MediaItemRenderer.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/MediaItemRenderer.mxml
index c7a36152c7d02f73c5aa504e22f2a482330baab5..ccc19433b75818796f65b77002a6289bca470599 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/MediaItemRenderer.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/MediaItemRenderer.mxml
@@ -209,6 +209,12 @@
 							muteImg.includeInLayout = true;
 							muteBtn.visible = false;
 							muteBtn.includeInLayout = false;
+
+							if (data.talking && !rolledOver) {
+								muteImg.filters = [new GlowFilter(getStyle("glowFilterColor"), 1, 6, 6, 2, BitmapFilterQuality.HIGH, false, false)];
+							} else {
+								muteImg.filters = [];
+							}
 						} else {
 							muteImg.visible = !rolledOver;
 							muteImg.includeInLayout = !rolledOver;
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
index 8c5e847bc69bb14ac5b38d4e038d9c0e5b5f327f..dd16652b104fcb448a41f767cd1776742b3198c5 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/users/views/UsersWindow.mxml
@@ -38,7 +38,8 @@ $Id: $
     <mate:Listener type="{ShortcutEvent.MUTE_ALL_BUT_PRES}" method="remoteMuteAllButPres" />
     <mate:Listener type="{ShortcutEvent.OPEN_BREAKOUT_ROOMS}" method="handleOpenBreakoutRooms" />
     <mate:Listener type="{MeetingMutedEvent.MEETING_MUTED}" method="handleMeetingMuted" />
-    <mate:Listener type="{LockControlEvent.CHANGED_LOCK_SETTINGS}" method="handleChangedLockSettingsEvent" />
+    <mate:Listener type="{LockControlEvent.CHANGED_LOCK_SETTINGS}" method="setRoomLocked" />
+	<mate:Listener type="{BBBEvent.CHANGE_WEBCAMS_ONLY_FOR_MODERATOR}" method="setRoomLocked"/>
     <mate:Listener type="{BreakoutRoomEvent.UPDATE_REMAINING_TIME_PARENT}" method="handleRemainingTimeUpdate" />
     <mate:Listener type="{BreakoutRoomEvent.BREAKOUT_JOIN_URL}" method="handleBreakoutJoinUrl" />
     <mate:Listener type="{ChangeMyRole.CHANGE_MY_ROLE_EVENT}" method="onChangeMyRole" />
@@ -266,8 +267,7 @@ $Id: $
         resourcesChanged();
         
         roomMuted = LiveMeeting.inst().meetingStatus.isMeetingMuted;
-        var lockSettings:LockSettingsVO = UsersUtil.getLockSettings();
-        roomLocked = lockSettings.isAnythingLocked() && ( lockSettings.getLockOnJoin() || UsersUtil.isAnyoneLocked());
+        setRoomLocked();
         
         titleBarOverlay.tabIndex = partOptions.baseTabIndex;
         minimizeBtn.tabIndex = partOptions.baseTabIndex+1;
@@ -421,10 +421,10 @@ $Id: $
         }
       }
       
-      private function handleChangedLockSettingsEvent(e:LockControlEvent):void {
-        var lockSettings:LockSettingsVO = UsersUtil.getLockSettings();
-        roomLocked = lockSettings.isAnythingLocked() && (lockSettings.getLockOnJoin() || UsersUtil.isAnyoneLocked());
-      }
+	  private function setRoomLocked(e:Event = null) {
+		  var lockSettings:LockSettingsVO = UsersUtil.getLockSettings();
+		  roomLocked = (lockSettings.isAnythingLocked() || LiveMeeting.inst().meeting.webcamsOnlyForModerator) && (lockSettings.getLockOnJoin() || UsersUtil.isAnyoneLocked());
+	  }
       
       private function lockSettings():void {
         var event:LockControlEvent = new LockControlEvent(LockControlEvent.OPEN_LOCK_SETTINGS);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/business/VideoProxy.as b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/business/VideoProxy.as
index ec1341728c34e5e6bacc8905f4958650cd80a057..26a92a28ecbcfdef370c356d0dd8cd0c04377cdb 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/business/VideoProxy.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/business/VideoProxy.as
@@ -36,13 +36,13 @@ package org.bigbluebutton.modules.videoconf.business
 	import org.bigbluebutton.core.Options;
 	import org.bigbluebutton.core.UsersUtil;
 	import org.bigbluebutton.core.managers.ReconnectionManager;
-	import org.bigbluebutton.main.api.JSLog;
+	import org.bigbluebutton.core.model.LiveMeeting;
 	import org.bigbluebutton.main.events.BBBEvent;
 	import org.bigbluebutton.modules.videoconf.events.ConnectedEvent;
 	import org.bigbluebutton.modules.videoconf.events.StartBroadcastEvent;
 	import org.bigbluebutton.modules.videoconf.events.StopBroadcastEvent;
 	import org.bigbluebutton.modules.videoconf.model.VideoConfOptions;
-
+	import org.bigbluebutton.util.ConnUtil;
 	
 	public class VideoProxy
 	{	
@@ -51,12 +51,12 @@ package org.bigbluebutton.modules.videoconf.business
 		public var videoOptions:VideoConfOptions;
 		
 		private var nc:NetConnection;
-		private var _url:String;
 		private var camerasPublishing:Object = new Object();
 		private var reconnect:Boolean = false;
 		private var reconnecting:Boolean = false;
 		private var dispatcher:Dispatcher = new Dispatcher();
 
+		private var videoConnUrl: String;
 		private var numNetworkChangeCount:int = 0;
 		
 		private function parseOptions():void {
@@ -64,12 +64,11 @@ package org.bigbluebutton.modules.videoconf.business
 			videoOptions.parseOptions();	
 		}
 		
-		public function VideoProxy(url:String)
+		public function VideoProxy()
 		{
-      		_url = url;
 			parseOptions();			
 			nc = new NetConnection();
-			nc.proxyType = "best";
+
 			nc.client = this;
 			nc.addEventListener(AsyncErrorEvent.ASYNC_ERROR, onAsyncError);
 			nc.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
@@ -81,9 +80,41 @@ package org.bigbluebutton.modules.videoconf.business
 			reconnect = connect;
 		}
 		
-	    public function connect():void {
-	      nc.connect(_url, UsersUtil.getInternalMeetingID(), UsersUtil.getMyUserID());
-	    }
+		public function connect():void {
+				var options: VideoConfOptions = Options.getOptions(VideoConfOptions) as VideoConfOptions;
+				var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
+				var result:Array = pattern.exec(options.uri);
+				
+				
+				var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS;
+				if (BBB.initConnectionManager().isTunnelling) {
+					var tunnelProtocol: String = ConnUtil.RTMPT;
+				
+					if (useRTMPS) {
+						nc.proxyType = ConnUtil.PROXY_NONE;
+						tunnelProtocol = ConnUtil.RTMPS;
+					}
+				
+					videoConnUrl = tunnelProtocol + "://" + result.server + "/" + result.app;
+					LOGGER.debug("VIDEO CONNECT tunnel = TRUE " + "url=" +  videoConnUrl);
+				} else {
+					var nativeProtocol: String = ConnUtil.RTMP;
+					if (useRTMPS) {
+						nc.proxyType = ConnUtil.PROXY_BEST;
+						nativeProtocol = ConnUtil.RTMPS;
+					}
+				
+					videoConnUrl = nativeProtocol + "://" + result.server + "/" + result.app;
+					LOGGER.debug("VIDEO CONNECT tunnel = FALSE " + "url=" +  videoConnUrl);
+				}
+				
+				videoConnUrl = videoConnUrl + "/" + UsersUtil.getInternalMeetingID();
+				var authToken: String = LiveMeeting.inst().me.authToken;
+
+				nc.objectEncoding = flash.net.ObjectEncoding.AMF3;
+				nc.connect(videoConnUrl, UsersUtil.getInternalMeetingID(), 
+						UsersUtil.getMyUserID(), authToken);
+		}
 	    
 		private function onAsyncError(event:AsyncErrorEvent):void{
 			var logData:Object = UsersUtil.initLogData();
@@ -112,7 +143,7 @@ package org.bigbluebutton.modules.videoconf.business
     
 		private function onNetStatus(event:NetStatusEvent):void{
 
-			LOGGER.debug("[{0}] for [{1}]", [event.info.code, _url]);
+			LOGGER.debug("[{0}] for [{1}]", [event.info.code, videoConnUrl]);
 			var logData:Object = UsersUtil.initLogData();
 			logData.tags = ["webcam"];
 			logData.user.eventCode = event.info.code + "[reconnecting=" + reconnecting + ",reconnect=" + reconnect + "]";
@@ -169,14 +200,14 @@ package org.bigbluebutton.modules.videoconf.business
 					break;		
 				case "NetConnection.Connect.NetworkChange":
 					numNetworkChangeCount++;
-					if (numNetworkChangeCount % 20 == 0) {
+					if (numNetworkChangeCount % 2 == 0) {
 						logData.message = "Detected network change on bbb-video";
 						logData.numNetworkChangeCount = numNetworkChangeCount;
 						LOGGER.info(JSON.stringify(logData));
 					}
 					break;
         		default:
-					LOGGER.debug("[{0}] for [{1}]", [event.info.code, _url]);
+					LOGGER.debug("[{0}] for [{1}]", [event.info.code, videoConnUrl]);
 					break;
 			}
 		}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/events/VideoModuleStartEvent.as b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/events/VideoModuleStartEvent.as
index 6f394e3c084de1502447a54ef3f7bd8c01e09693..f82f2a746cae9aaba4f2b3afee3ac8efd4462e55 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/events/VideoModuleStartEvent.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/events/VideoModuleStartEvent.as
@@ -24,8 +24,6 @@ package org.bigbluebutton.modules.videoconf.events
   {
     public static const START:String = "video module start event";
     
-    public var uri:String;
-    
     public function VideoModuleStartEvent(type:String, bubbles:Boolean=true, cancelable:Boolean=false)
     {
       super(type, bubbles, cancelable);
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/maps/VideoEventMap.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/maps/VideoEventMap.mxml
index 64205624f0667ad277d02cf89f3db4c3f58adca9..9d274c2dcf886a9592ed7dfd538ec7d81f1c14a6 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/maps/VideoEventMap.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/maps/VideoEventMap.mxml
@@ -46,7 +46,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 	<fx:Declarations>
 		<EventHandlers type="{VideoModuleStartEvent.START}">
 			<ObjectBuilder generator="{VideoEventMapDelegate}" cache="global" constructorArguments="{scope.dispatcher}"/>
-			<MethodInvoker generator="{VideoEventMapDelegate}" method="start" arguments="{event.uri}"/>
+			<MethodInvoker generator="{VideoEventMapDelegate}" method="start"/>
 			<EventAnnouncer generator="{ConnectAppEvent}" type="{ConnectAppEvent.CONNECT_VIDEO_APP}" />
 		</EventHandlers>
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/maps/VideoEventMapDelegate.as b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/maps/VideoEventMapDelegate.as
index e74ba40e7103ddcb97c4104449d6b6b5582ba5ae..5dbe48e36a7fd975c1641a8820d8eccff30f74b5 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/maps/VideoEventMapDelegate.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/videoconf/maps/VideoEventMapDelegate.as
@@ -68,7 +68,6 @@ package org.bigbluebutton.modules.videoconf.maps
     private static var PERMISSION_DENIED_ERROR:String = "PermissionDeniedError";
 
     private var options:VideoConfOptions;
-    private var uri:String;
 
     private var button:ToolbarPopupButton = new ToolbarPopupButton();
     private var proxy:VideoProxy;
@@ -100,9 +99,8 @@ package org.bigbluebutton.modules.videoconf.maps
       return UsersUtil.getMyUsername();
     }
 
-    public function start(uri:String):void {
+    public function start():void {
       LOGGER.debug("VideoEventMapDelegate:: [{0}] Video Module Started.", [me]);
-      this.uri = uri;
 
       _videoDock = new VideoDock();
       var windowEvent:OpenWindowEvent = new OpenWindowEvent(OpenWindowEvent.OPEN_WINDOW_EVENT);
@@ -328,7 +326,7 @@ package org.bigbluebutton.modules.videoconf.maps
     }
 
     public function connectToVideoApp():void {
-      proxy = new VideoProxy(uri);
+      proxy = new VideoProxy();
       proxy.reconnectWhenDisconnected(true);
       proxy.connect();
     }
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/PollResultObject.as b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/PollResultObject.as
index 594856ddb8416d1896930be986d15ec1c2a59cdc..e59bdcb77435968fcb48c333943035ad651884a0 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/PollResultObject.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/business/shapes/PollResultObject.as
@@ -26,6 +26,7 @@ package org.bigbluebutton.modules.whiteboard.business.shapes
   import flash.text.TextFormat;
   import flash.text.TextFormatAlign;
   
+  import org.as3commons.lang.StringUtils;
   import org.as3commons.logging.api.ILogger;
   import org.as3commons.logging.api.getClassLogger;
   import org.as3commons.logging.util.jsonXify;
@@ -313,7 +314,7 @@ package org.bigbluebutton.modules.whiteboard.business.shapes
         var ar:Object = answers[j];
         var localizedKey: String = ResourceUtil.getInstance().getString('bbb.polling.answer.' + ar.key);
         
-        if (localizedKey == null || localizedKey == "" || localizedKey == "undefined") {
+        if (StringUtils.isEmpty(localizedKey) || localizedKey == "undefined") {
           localizedKey = ar.key;
         } 
         var rs:Object = {a: localizedKey, v: ar.numVotes};
diff --git a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardToolbar.mxml b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardToolbar.mxml
index 9720858c9fd1004e59000c25766482571a9fe430..f5ee3ac032c7fefc03e28535af3f8d7961a5241d 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardToolbar.mxml
+++ b/bigbluebutton-client/src/org/bigbluebutton/modules/whiteboard/views/WhiteboardToolbar.mxml
@@ -81,7 +81,7 @@ with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
 			private var multiUser:Boolean = false;
 		
 			[Bindable] private var colorPickerColours:Array = ['0x000000', '0xFFFFFF' , '0xFF0000', '0xFF8800',
-                '0xCCFF00', '0x00FF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF', '0xC0C0C0'];
+                '0xCCFF00', '0x00FF88', '0x00FFFF', '0x0088FF', '0x0000FF', '0x8800FF', '0xFF00FF', '0xC0C0C0'];
 
 			private var _hideToolbarTimer:Timer = new Timer(500, 1);
 
diff --git a/bigbluebutton-client/src/org/bigbluebutton/util/ConnUtil.as b/bigbluebutton-client/src/org/bigbluebutton/util/ConnUtil.as
new file mode 100755
index 0000000000000000000000000000000000000000..c79aea4c978e20b7f80d1512e6a1a61375861f82
--- /dev/null
+++ b/bigbluebutton-client/src/org/bigbluebutton/util/ConnUtil.as
@@ -0,0 +1,18 @@
+package org.bigbluebutton.util
+{
+	public class ConnUtil
+	{
+			public static const RTMPS: String = "rtmps";
+			public static const RTMPT: String = "rtmpt";
+			public static const RTMP: String = "rtmp";
+			public static const PROXY_NONE: String = "none";
+			public static const PROXY_BEST: String = "best";
+			
+			
+			public static function parseRTMPConn(appURL: String):Array {
+				var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)\/(?P<app>.+)/;
+				var result:Array = pattern.exec(appURL);
+				return result;
+			}
+	}
+}
\ No newline at end of file
diff --git a/bigbluebutton-client/src/org/bigbluebutton/util/QueryStringParameters.as b/bigbluebutton-client/src/org/bigbluebutton/util/QueryStringParameters.as
index a73e2863a9a7d5d8afa94c3c7f952175e75ef518..02d66634d78b074ba5d2797f1cb0b0ecd5fbdfe5 100755
--- a/bigbluebutton-client/src/org/bigbluebutton/util/QueryStringParameters.as
+++ b/bigbluebutton-client/src/org/bigbluebutton/util/QueryStringParameters.as
@@ -1,52 +1,54 @@
 /**
-* BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
-* 
-* Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
-*
-* This program is free software; you can redistribute it and/or modify it under the
-* terms of the GNU Lesser General Public License as published by the Free Software
-* Foundation; either version 3.0 of the License, or (at your option) any later
-* version.
-* 
-* BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
-* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
-*
-* You should have received a copy of the GNU Lesser General Public License along
-* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
-*
-*/
-package org.bigbluebutton.util
-{
+ * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
+ *
+ * Copyright (c) 2012 BigBlueButton Inc. and by respective authors (see below).
+ *
+ * This program is free software; you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation; either version 3.0 of the License, or (at your option) any later
+ * version.
+ *
+ * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
+ * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License along
+ * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+package org.bigbluebutton.util {
 	import flash.external.ExternalInterface;
-	
+
+	import org.as3commons.lang.StringUtils;
 	import org.as3commons.logging.api.ILogger;
 	import org.as3commons.logging.api.getClassLogger;
-	
+
 	public class QueryStringParameters {
 		private static const LOGGER:ILogger = getClassLogger(QueryStringParameters);
 
-		private var params:Array;
-		
+		private var params:Array = [];
+
+		private var _sessionToken:String = null;
+
 		public function collectParameters():void {
 			try {
 				var url:String = ExternalInterface.call("window.location.search.substring", 1);
 				//var url:String = "host.pl?logouturl=http://www.google.com&host=rtmp://192.168.0.120/deskShare&room=6e87dfef-9f08-4f80-993f-c0ef5f7b999b&width=1024&height=768";
 				// Remove everything before the question mark, including the question mark
-				var paramPattern:RegExp = /.*\?/;					
+				var paramPattern:RegExp = /.*\?/;
 				url = url.replace(paramPattern, "");
-					
+
 				// Create an array of name=value Strings.
 				params = url.split("&");
-									
-			} catch(e:Error) {
+
+			} catch (e:Error) {
 				LOGGER.error(e.toString());
 			}
 		}
-		
+
 		public function getParameter(key:String):String {
 			var value:String = "";
-						
+
 			for (var i:int = 0; i < params.length; i++) {
 				var tempA:Array = params[i].split("=");
 				//LOGGER.debug("{0} {1}", [String(tempA[0]).toUpperCase(), String(tempA[1]).toUpperCase()]);
@@ -57,5 +59,13 @@ package org.bigbluebutton.util
 			}
 			return value;
 		}
+
+		public function getSessionToken():String {
+			if (StringUtils.isEmpty(_sessionToken)) {
+				collectParameters();
+				_sessionToken = getParameter("sessionToken");
+			}
+			return _sessionToken;
+		}
 	}
-}
\ No newline at end of file
+}
diff --git a/bigbluebutton-client/src/org/bigbluebutton/util/SessionTokenUtil.as b/bigbluebutton-client/src/org/bigbluebutton/util/SessionTokenUtil.as
deleted file mode 100755
index 276fab399e473682425d3cfaadc6fddaa44da783..0000000000000000000000000000000000000000
--- a/bigbluebutton-client/src/org/bigbluebutton/util/SessionTokenUtil.as
+++ /dev/null
@@ -1,33 +0,0 @@
-/**
- * BigBlueButton open source conferencing system - http://www.bigbluebutton.org/
- *
- * Copyright (c) 2017 BigBlueButton Inc. and by respective authors (see below).
- *
- * This program is free software; you can redistribute it and/or modify it under the
- * terms of the GNU Lesser General Public License as published by the Free Software
- * Foundation; either version 3.0 of the License, or (at your option) any later
- * version.
- *
- * BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along
- * with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
- *
- */
-package org.bigbluebutton.util {
-
-	public class SessionTokenUtil {
-		private var _sessionToken:String = null;
-
-		public function getSessionToken():String {
-			if (_sessionToken == null || _sessionToken == "") {
-				var p:QueryStringParameters = new QueryStringParameters();
-				p.collectParameters();
-				_sessionToken = p.getParameter("sessionToken");
-			}
-			return _sessionToken;
-		}
-	}
-}
diff --git a/bigbluebutton-client/src/org/red5/flash/bwcheck/app/BandwidthDetectionApp.as b/bigbluebutton-client/src/org/red5/flash/bwcheck/app/BandwidthDetectionApp.as
index 4ce74b00b8b52a8a169f9ab62a89379c1c4bca0e..d18d270927ac3ead2552d87204544df6d5050d41 100755
--- a/bigbluebutton-client/src/org/red5/flash/bwcheck/app/BandwidthDetectionApp.as
+++ b/bigbluebutton-client/src/org/red5/flash/bwcheck/app/BandwidthDetectionApp.as
@@ -7,6 +7,10 @@ package org.red5.flash.bwcheck.app
 	import mx.core.Application;
 	
 	import org.bigbluebutton.common.LogUtil;
+	import org.bigbluebutton.core.BBB;
+	import org.bigbluebutton.core.Options;
+	import org.bigbluebutton.core.model.BandwidthMonOptions;
+	import org.bigbluebutton.util.ConnUtil;
 	import org.red5.flash.bwcheck.ClientServerBandwidth;
 	import org.red5.flash.bwcheck.ServerClientBandwidth;
 	import org.red5.flash.bwcheck.events.BandwidthDetectEvent;
@@ -17,7 +21,7 @@ package org.red5.flash.bwcheck.app
 		private var _serverApplication:String = "";
 		private var _clientServerService:String = "";
 		private var _serverClientService:String = "";
-		
+		private var bwMonOption: BandwidthMonOptions; 
 		private var nc:NetConnection;
 		
 		public function BandwidthDetectionApp()
@@ -47,12 +51,41 @@ package org.red5.flash.bwcheck.app
 		
 		public function connect():void
 		{
+			bwMonOption = Options.getOptions(BandwidthMonOptions) as BandwidthMonOptions;
+			
+			var pattern:RegExp = /(?P<protocol>.+):\/\/(?P<server>.+)/;
+			var result:Array = pattern.exec(bwMonOption.server);
+			
+			var bwMonUrl: String;
+			
 			nc = new NetConnection();
-			nc.proxyType = "best";
-			nc.objectEncoding = flash.net.ObjectEncoding.AMF0;
+			
+			var useRTMPS: Boolean = result.protocol == ConnUtil.RTMPS;
+			if (BBB.initConnectionManager().isTunnelling) {
+				var tunnelProtocol: String = ConnUtil.RTMPT;
+				
+				if (useRTMPS) {
+					nc.proxyType = ConnUtil.PROXY_NONE;
+					tunnelProtocol = ConnUtil.RTMPS;
+				}
+				
+				bwMonUrl = tunnelProtocol + "://" + result.server + "/" + bwMonOption.application;
+				trace("******* BW MON CONNECT tunnel = TRUE " + "url=" +  bwMonUrl);
+			} else {
+				var nativeProtocol: String = ConnUtil.RTMP;
+				if (useRTMPS) {
+					nc.proxyType = ConnUtil.PROXY_BEST;
+					nativeProtocol = ConnUtil.RTMPS;
+				}
+				
+				bwMonUrl = nativeProtocol + "://" + result.server + "/" + bwMonOption.application;
+				trace("******* BBB MON CONNECT tunnel = FALSE " + "url=" +  bwMonUrl);
+			}
+
+			nc.objectEncoding = flash.net.ObjectEncoding.AMF3;
 			nc.client = this;
 			nc.addEventListener(NetStatusEvent.NET_STATUS, onStatus);	
-			nc.connect("rtmp://" + _serverURL + "/" + _serverApplication);
+			nc.connect(bwMonUrl);
 		}
 		
 		
diff --git a/bigbluebutton-config/bin/bbb-conf b/bigbluebutton-config/bin/bbb-conf
index 386a241d530f93c9b04d605e60c6cb24789c1376..b258cd53f2a52b90fd4a50c485b5738e1d37b13a 100755
--- a/bigbluebutton-config/bin/bbb-conf
+++ b/bigbluebutton-config/bin/bbb-conf
@@ -422,7 +422,7 @@ start_bigbluebutton () {
 	#
 	echo -n "Waiting for BigBlueButton to finish starting up (this may take a minute): "
 
-	NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}' | cut -d' ' -f1)
+	NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*server_name[ ]*//;s/;//;p}' | cut -d' ' -f1)
 	check_no_value server_name /etc/nginx/sites-available/bigbluebutton $NGINX_IP
 
         #if ! wget http://$BBB_WEB/bigbluebutton/api -O - --quiet | grep -q SUCCESS; then
@@ -478,7 +478,7 @@ start_bigbluebutton () {
 
 display_bigbluebutton_status () {
     if command -v systemctl >/dev/null; then
-	units="start red5 $TOMCAT_SERVICE nginx freeswitch $REDIS_SERVICE libreoffice bbb-apps-akka bbb-transcode-akka bbb-fsesl-akka"
+	units="start red5 $TOMCAT_SERVICE nginx freeswitch $REDIS_SERVICE bbb-apps-akka bbb-transcode-akka bbb-fsesl-akka"
 	for unit in $units; do
 		echo "$unit: $(systemctl is-active $unit)"
 	done 
@@ -835,7 +835,7 @@ check_configuration() {
 	#
 	# Check if the IP resolves to a different host
 	#
- 	NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}' | cut -d' ' -f1)
+ 	NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*server_name[ ]*//;s/;//;p}' | cut -d' ' -f1)
  	check_no_value server_name /etc/nginx/sites-available/bigbluebutton $NGINX_IP
  
 	if which host > /dev/null 2>&1; then	
@@ -879,7 +879,7 @@ check_configuration() {
 	fi
 
 	BBB_SECRET=$(cat ${SERVLET_DIR}/bigbluebutton/WEB-INF/classes/bigbluebutton.properties | grep -v '#' | tr -d '\r' | sed -n '/securitySalt/{s/.*=//;p}')
-	NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}' | cut -d' ' -f1)
+	NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*server_name[ ]*//;s/;//;p}' | cut -d' ' -f1)
 
 	if [ -f /usr/local/bigbluebutton/bbb-webhooks/config_local.coffee ]; then
 		WEBHOOKS_SECRET=$(cat /usr/local/bigbluebutton/bbb-webhooks/config_local.coffee | grep '^[ \t]*config.bbb.sharedSecret[ =]*' | cut -d '"' -f2)
@@ -1524,7 +1524,7 @@ if [ $CHECK ]; then
 
 	echo
 	echo "/etc/nginx/sites-available/bigbluebutton (nginx)"
-	NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*name[ ]*//;s/;//;p}' | cut -d' ' -f1)
+	NGINX_IP=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/server_name/{s/.*server_name[ ]*//;s/;//;p}' | cut -d' ' -f1)
 	echo "                       server name: $NGINX_IP"
 
         PORT=$(cat /etc/nginx/sites-available/bigbluebutton | grep -v '#' | sed -n '/listen/{s/.*listen[ ]*//;s/;//;p}' | grep -v ssl | tr --delete '\n' | sed 's/\[/, \[/g' | sed 's/0$/0\n/g')
@@ -1727,7 +1727,7 @@ if [ -n "$HOST" ]; then
 	# Just use the IP for port test in /var/www/bigbluebutton/client/conf/config.xml
 	#
 	echo "Assigning $HOST for testing for firewall in /var/www/bigbluebutton/client/conf/config.xml"
-	sudo sed -i "s/porttest host=\(\"[^\"]*\"\)/porttest host=\"$HOST\"/g" /var/www/bigbluebutton/client/conf/config.xml
+	sudo sed -i "s/porttest host=\(\"[^\"]*\"\)/porttest host=\"$PROTOCOL_RTMP:\/\/$HOST\"/g" /var/www/bigbluebutton/client/conf/config.xml
 
 	echo "Assigning $HOST for rtmp:// in /var/www/bigbluebutton/client/conf/config.xml"
 	sudo sed -i "s/rtmp[s]*:\/\/\([^\"\/]*\)\([\"\/]\)/$PROTOCOL_RTMP:\/\/$HOST\2/g" /var/www/bigbluebutton/client/conf/config.xml
@@ -1735,11 +1735,16 @@ if [ -n "$HOST" ]; then
 	echo "Assigning $HOST for servername in /etc/nginx/sites-available/bigbluebutton"
 	sudo sed -i "s/server_name  .*/server_name  $HOST;/g" /etc/nginx/sites-available/bigbluebutton
 
-	#
-	# Update configuration for BigBlueButton client
-	#
-	echo "Assigning $HOST for http[s]:// in /var/www/bigbluebutton/client/conf/config.xml"
-	sudo sed -i "s/http[s]*:\/\/\([^\"\/]*\)\([\"\/]\)/$PROTOCOL_HTTP:\/\/$HOST\2/g"  /var/www/bigbluebutton/client/conf/config.xml
+        #
+        # Update configuration for BigBlueButton client (and perserve hostname for chromeExtensionLink if exists)
+        #
+
+        echo "Assigning $HOST for http[s]:// in /var/www/bigbluebutton/client/conf/config.xml"
+        chromeExtensionLinkURL=$(cat /var/www/bigbluebutton/client/conf/config.xml | sed -n '/chromeExtensionLink/{s/.*https*:\/\///;s/\/.*//;p}')
+        sudo sed -i "s/http[s]*:\/\/\([^\"\/]*\)\([\"\/]\)/$PROTOCOL_HTTP:\/\/$HOST\2/g"  \
+		/var/www/bigbluebutton/client/conf/config.xml
+        sudo sed -i "s/chromeExtensionLink=\"https:\/\/[^\/]*/chromeExtensionLink=\"https:\/\/$chromeExtensionLinkURL/g" \ 
+		/var/www/bigbluebutton/client/conf/config.xml
 
         echo "Assigning $HOST for publishURI in /var/www/bigbluebutton/client/conf/config.xml"
         sudo sed -i "s/publishURI=\"[^\"]*\"/publishURI=\"$HOST\"/" /var/www/bigbluebutton/client/conf/config.xml
diff --git a/bigbluebutton-config/bin/bbb-record b/bigbluebutton-config/bin/bbb-record
index 1e0dca08c5868847b68379e87198c13aff55d885..146cda052f21ff41ad69ae9ab3b52d86fd19e6be 100755
--- a/bigbluebutton-config/bin/bbb-record
+++ b/bigbluebutton-config/bin/bbb-record
@@ -716,10 +716,11 @@ if [ $CHECK ]; then
 	#set -x
         for type in $TYPES; do
 		for recording in $(find $BASE/publish/$type -name metadata.xml); do
-			url_playback=$(cat $recording | grep "<link>" | sed 's/[ ]*<link>http:\/\/\([^\"\/]*\)[^>]*>/\1/g')
-			if [ "$BBB_WEB" != "$url_playback" ]; then
+			url_playback_http=$(cat $recording | grep "<link>" | sed 's/[ ]*<link>http:\/\/\([^\"\/]*\)[^>]*>/\1/g')
+			url_playback_https=$(cat $recording | grep "<link>" | sed 's/[ ]*<link>https:\/\/\([^\"\/]*\)[^>]*>/\1/g')
+			if [ "$BBB_WEB" != "$url_playback_http" ] && [ "$BBB_WEB" != "$url_playback_https" ]; then
                                 echo
-                                echo "# The hostname in <link> .. </link> ($url_playback)"
+                                echo "# The hostname in <link> .. </link> ($url_playback_http)"
                                 echo "#     $recording"
                                 echo "# do not match the hostname for bigbluebutton.web.serverURL ($BBB_WEB)"
                                 echo "#     /usr/share/red5/webapps/bigbluebutton/WEB-INF/bigbluebutton.properties"
@@ -727,10 +728,11 @@ if [ $CHECK ]; then
 			fi
 		done
 		for recording in $(find /var/bigbluebutton/published/$type -name metadata.xml); do
-			url_playback=$(cat $recording | grep "<link>" | sed 's/[ ]*<link>http:\/\/\([^\"\/]*\)[^>]*>/\1/g')
-			if [ "$BBB_WEB" != "$url_playback" ]; then
+			url_playback_http=$(cat $recording | grep "<link>" | sed 's/[ ]*<link>http:\/\/\([^\"\/]*\)[^>]*>/\1/g')
+			url_playback_https=$(cat $recording | grep "<link>" | sed 's/[ ]*<link>https:\/\/\([^\"\/]*\)[^>]*>/\1/g')
+			if [ "$BBB_WEB" != "$url_playback_http" ] && [ "$BBB_WEB" != "$url_playback_https" ]; then
                                 echo
-                                echo "# The hostname in <link> .. </link> ($url_playback)"
+                                echo "# The hostname in <link> .. </link> ($url_playback_http)"
                                 echo "#     $recording"
                                 echo "# do not match the hostname for bigbluebutton.web.serverURL ($BBB_WEB)"
                                 echo "#     /usr/share/red5/webapps/bigbluebutton/WEB-INF/bigbluebutton.properties"
diff --git a/bigbluebutton-config/web/index.html b/bigbluebutton-config/web/index.html
index 86fee4b3489730360022647fbd8a2ad4747f3ba7..ef3854d2f5334192d91fc9ea3aa0eadac0bcfc8d 100644
--- a/bigbluebutton-config/web/index.html
+++ b/bigbluebutton-config/web/index.html
@@ -261,8 +261,8 @@
 
 	      <div class="row">
 	      	<div class="span twelve center">
-		        <p>Copyright &copy; 2017 BigBlueButton Inc.<br>
-		        <small>Version <a href="http://docs.bigbluebutton.org/">2.0-dev</a></small>		        
+		        <p>Copyright &copy; 2018 BigBlueButton Inc.<br>
+		        <small>Version <a href="http://docs.bigbluebutton.org/">2.0-beta</a></small>		        
 		        </p>
 	      	</div>
 	      </div>
diff --git a/bigbluebutton-config/web/index_html5_vs_flash.html b/bigbluebutton-config/web/index_html5_vs_flash.html
index fb92c0d8a9d21807db2734abf0e6ca83ce1f1cfd..35e199e8dffd44c65d76159c43428f6a9e453291 100644
--- a/bigbluebutton-config/web/index_html5_vs_flash.html
+++ b/bigbluebutton-config/web/index_html5_vs_flash.html
@@ -287,7 +287,7 @@
 
 	      <div class="row">
 	      	<div class="span twelve center">
-		        <p>Copyright &copy; 2017 BigBlueButton Inc.<br>
+		        <p>Copyright &copy; 2018 BigBlueButton Inc.<br>
 		        <small>Version <a href="http://docs.bigbluebutton.org/">2.0-beta</a></small>
 		        </p>
 	      	</div>
diff --git a/bigbluebutton-html5/imports/api/annotations/server/modifiers/addAnnotation.js b/bigbluebutton-html5/imports/api/annotations/server/modifiers/addAnnotation.js
index c5e0dda1e8f20c69fc336cb5055d65cc8ecb107f..f1b9f39ebe26d7a3fbfdeb79e804572409d0b6fe 100644
--- a/bigbluebutton-html5/imports/api/annotations/server/modifiers/addAnnotation.js
+++ b/bigbluebutton-html5/imports/api/annotations/server/modifiers/addAnnotation.js
@@ -82,6 +82,7 @@ function handlePencilUpdate(meetingId, whiteboardId, userId, annotation) {
     meetingId,
     id,
     userId,
+    whiteboardId,
   };
   let baseModifier;
   let chunkSelector;
@@ -169,6 +170,7 @@ function handlePencilUpdate(meetingId, whiteboardId, userId, annotation) {
         id,
         userId,
         meetingId,
+        whiteboardId,
         position,
         annotationType: 'pencil_base',
         numberOfChunks: chunks.length,
@@ -279,6 +281,7 @@ function handlePencilUpdate(meetingId, whiteboardId, userId, annotation) {
         id,
         userId,
         meetingId,
+        whiteboardId,
         position,
         annotationType: 'pencil_base',
         numberOfChunks: _chunks.length,
diff --git a/bigbluebutton-html5/imports/startup/client/auth.js b/bigbluebutton-html5/imports/startup/client/auth.js
index b87b1c735cc03aebf52220c8d6e4d266b883f483..d360052de51292327048c5ce53f32ea5ad46f4f6 100644
--- a/bigbluebutton-html5/imports/startup/client/auth.js
+++ b/bigbluebutton-html5/imports/startup/client/auth.js
@@ -18,7 +18,9 @@ export function joinRouteHandler(nextState, replace, callback) {
   fetch(url)
     .then(response => response.json())
     .then((data) => {
-      const { meetingID, internalUserID, authToken, logoutUrl } = data.response;
+      const {
+        meetingID, internalUserID, authToken, logoutUrl,
+      } = data.response;
 
       Auth.set(meetingID, internalUserID, authToken, logoutUrl, sessionToken);
       replace({ pathname: '/' });
diff --git a/bigbluebutton-html5/imports/startup/client/base.jsx b/bigbluebutton-html5/imports/startup/client/base.jsx
index e81a75c6421494d370155c5ca0a8c4401b577515..25471a3e3f92ce07baaa3a321360093d039d7c10 100644
--- a/bigbluebutton-html5/imports/startup/client/base.jsx
+++ b/bigbluebutton-html5/imports/startup/client/base.jsx
@@ -8,6 +8,7 @@ import ErrorScreen from '/imports/ui/components/error-screen/component';
 import MeetingEnded from '/imports/ui/components/meeting-ended/component';
 import LoadingScreen from '/imports/ui/components/loading-screen/component';
 import Settings from '/imports/ui/services/settings';
+import AudioManager from '/imports/ui/services/audio-manager';
 import IntlStartup from './intl';
 
 const propTypes = {
@@ -59,7 +60,10 @@ class Base extends Component {
     const { subscriptionsReady, errorCode } = this.props;
     const { endedCode } = this.props.params;
 
-    if (endedCode) return (<MeetingEnded code={endedCode} />);
+    if (endedCode) {
+      AudioManager.exitAudio();
+      return (<MeetingEnded code={endedCode} />);
+    }
 
     if (error || errorCode) {
       return (<ErrorScreen code={errorCode}>{error}</ErrorScreen>);
diff --git a/bigbluebutton-html5/imports/startup/client/routes.js b/bigbluebutton-html5/imports/startup/client/routes.js
index f396812ae71284a456c183fe58a3dc5347165621..fea09093674686c35ce7dd502b40e0839816c6f6 100644
--- a/bigbluebutton-html5/imports/startup/client/routes.js
+++ b/bigbluebutton-html5/imports/startup/client/routes.js
@@ -5,17 +5,15 @@ import { createHistory } from 'history';
 import LoadingScreen from '/imports/ui/components/loading-screen/component';
 import ChatContainer from '/imports/ui/components/chat/container';
 import UserListContainer from '/imports/ui/components/user-list/container';
-import MeetingEnded from '/imports/ui/components/meeting-ended/component';
 import { joinRouteHandler, logoutRouteHandler, authenticatedRouteHandler } from './auth';
 import Base from './base';
 
-
 const browserHistory = useRouterHistory(createHistory)({
   basename: Meteor.settings.public.app.basename,
 });
 
 const renderRoutes = () => (
-  <Router history={browserHistory}>
+  <Router history={browserHistory} >
     <Route path="/logout" onEnter={logoutRouteHandler} />
     <Route
       path="/join"
@@ -35,9 +33,10 @@ const renderRoutes = () => (
       />
       <Redirect from="users/chat" to="/users/chat/public" />
     </Route>
-    <Route name="meeting-ended" path="/ended/:endedCode" component={Base} />
+    <Route name="meeting-ended" path="/ended/:endedCode" component={Base} onLeave={logoutRouteHandler} />
     <Route name="error" path="/error/:errorCode" component={Base} />
     <Redirect from="*" to="/error/404" />
   </Router>
 );
+
 export default renderRoutes;
diff --git a/bigbluebutton-html5/imports/startup/server/logger.js b/bigbluebutton-html5/imports/startup/server/logger.js
index 25226349319cec1a258e07082b21c0de04f743c9..99b89030f788c81a5805fcf99d03ca8cae24dcd9 100644
--- a/bigbluebutton-html5/imports/startup/server/logger.js
+++ b/bigbluebutton-html5/imports/startup/server/logger.js
@@ -16,32 +16,47 @@ Logger.configure({
   },
 });
 
-// Write logs to console
-Logger.add(Winston.transports.Console, {
-  prettyPrint: false,
-  humanReadableUnhandledException: true,
-  colorize: true,
-  handleExceptions: true,
-});
-
 Meteor.startup(() => {
   const LOG_CONFIG = Meteor.settings.private.log || {};
   let { filename } = LOG_CONFIG;
+  const { level } = LOG_CONFIG;
 
-  // Set Logger message level priority for the console
-  Logger.transports.console.level = LOG_CONFIG.level;
+  // console logging
+  if (Meteor.isDevelopment) {
+    Logger.add(Winston.transports.Console, {
+      prettyPrint: false,
+      humanReadableUnhandledException: true,
+      colorize: true,
+      handleExceptions: true,
+      level,
+    });
+  }
 
-  // Determine file to write logs to
+  // file logging
   if (filename) {
+    // no file rotation
     if (Meteor.isDevelopment) {
       const path = Npm.require('path');
       filename = path.join(process.env.PWD, filename);
+
+      Logger.add(Winston.transports.File, {
+        filename,
+        prettyPrint: true,
+        level,
+        prepend: true,
+      });
     }
 
-    Logger.add(Winston.transports.File, {
-      filename,
-      prettyPrint: true,
-    });
+    // daily file rotation
+    if (Meteor.isProduction) {
+      Winston.transports.DailyRotateFile = Npm.require('winston-daily-rotate-file');
+      Logger.add(Winston.transports.DailyRotateFile, {
+        filename,
+        datePattern: '.yyyy-MM-dd',
+        prepend: false,
+        level,
+      });
+    }
   }
 });
 
diff --git a/bigbluebutton-html5/imports/startup/server/redis.js b/bigbluebutton-html5/imports/startup/server/redis.js
index 1a2cec69747591bf404b47ea051616c433abd44e..0314b3ce6c8541174339a53275aabccf35288972 100644
--- a/bigbluebutton-html5/imports/startup/server/redis.js
+++ b/bigbluebutton-html5/imports/startup/server/redis.js
@@ -65,7 +65,7 @@ class MettingMessageQueue {
     };
 
     const onError = (reason) => {
-      this.debug(`${eventName}: ${reason}`);
+      this.debug(`${eventName}: ${reason.stack ? reason.stack : reason}`);
       callNext();
     };
 
diff --git a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
index 09235a2cd5068409a143007a8c13ab1d66083130..06f028c8aca7cf443f63f6decef031879b3e73c5 100644
--- a/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/meeting-ended/component.jsx
@@ -1,5 +1,6 @@
 import React from 'react';
 import { withRouter } from 'react-router';
+import PropTypes from 'prop-types';
 import { defineMessages, injectIntl } from 'react-intl';
 import Button from '/imports/ui/components/button/component';
 import { styles } from './styles';
@@ -23,24 +24,42 @@ const intlMessage = defineMessages({
   },
 });
 
-const MeetingEnded = ({ intl, router, code }) => (
-  <div className={styles.parent}>
-    <div className={styles.modal}>
-      <div className={styles.content}>
-        <h1 className={styles.title}>{intl.formatMessage(intlMessage[code])}</h1>
-        <div className={styles.text}>
-          {intl.formatMessage(intlMessage.messageEnded)}
+const propTypes = {
+  intl: PropTypes.shape({
+    formatMessage: PropTypes.func.isRequired,
+  }).isRequired,
+  code: PropTypes.string.isRequired,
+  router: PropTypes.shape({
+    push: PropTypes.func.isRequired,
+  }).isRequired,
+};
+
+class MeetingEnded extends React.PureComponent {
+  render() {
+    const { intl, router, code } = this.props;
+
+    return (
+      <div className={styles.parent}>
+        <div className={styles.modal}>
+          <div className={styles.content}>
+            <h1 className={styles.title}>{intl.formatMessage(intlMessage[code])}</h1>
+            <div className={styles.text}>
+              {intl.formatMessage(intlMessage.messageEnded)}
+            </div>
+            <Button
+              color="primary"
+              className={styles.button}
+              label={intl.formatMessage(intlMessage.buttonOkay)}
+              size="sm"
+              onClick={() => router.push('/logout')}
+            />
+          </div>
         </div>
-        <Button
-          color="primary"
-          className={styles.button}
-          label={intl.formatMessage(intlMessage.buttonOkay)}
-          size="sm"
-          onClick={() => router.push('/logout')}
-        />
       </div>
-    </div>
-  </div>
-);
+    );
+  }
+}
+
+MeetingEnded.propTypes = propTypes;
 
 export default injectIntl(withRouter(MeetingEnded));
diff --git a/bigbluebutton-html5/imports/ui/components/video-dock/component.jsx b/bigbluebutton-html5/imports/ui/components/video-dock/component.jsx
index 231bd01b5a4b4ac1fdc7ea2487473ccc7459987a..95dfcaa6036be70d5465b6bd8ed03a12a9095ea0 100644
--- a/bigbluebutton-html5/imports/ui/components/video-dock/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/video-dock/component.jsx
@@ -30,6 +30,10 @@ const intlMessages = defineMessages({
   },
 });
 
+const RECONNECT_WAIT_TIME = 5000;
+const INITIAL_SHARE_WAIT_TIME = 2000;
+const CAMERA_SHARE_FAILED_WAIT_TIME = 10000;
+
 class VideoElement extends Component {
   constructor(props) {
     super(props);
@@ -62,8 +66,7 @@ class VideoDock extends Component {
     this.webRtcPeers = {};
     this.reconnectWebcam = false;
     this.reconnectList = [];
-    this.sharedCameraTimeout = null;
-    this.subscribedCamerasTimeouts = [];
+    this.cameraTimeouts = {};
 
     this.state = {
       videos: {},
@@ -94,7 +97,7 @@ class VideoDock extends Component {
         setTimeout(() => {
           log('debug', ` [camera] Trying to reconnect camera ${id}`);
           this.start(id, false);
-        }, 5000);
+        }, RECONNECT_WAIT_TIME);
       }
     }
 
@@ -113,7 +116,11 @@ class VideoDock extends Component {
 
     users.forEach((user) => {
       if (user.has_stream && user.userId !== userId) {
-        this.start(user.userId, false);
+        // FIX: Really ugly hack, but sometimes the ICE candidates aren't
+        // generated properly when we send videos right after componentDidMount
+        setTimeout(() => {
+          this.start(user.userId, false);
+        }, INITIAL_SHARE_WAIT_TIME);
       }
     });
 
@@ -131,13 +138,12 @@ class VideoDock extends Component {
     this.ws.addEventListener('close', this.onWsClose);
 
     window.addEventListener('online', this.ws.open.bind(this.ws));
-    window.addEventListener('offline', this.ws.close.bind(this.ws));
+    window.addEventListener('offline', this.onWsClose);
   }
 
   componentWillUpdate(nextProps) {
     const { isLocked } = nextProps;
     if (isLocked && VideoService.isConnected()) {
-      console.error(this.unshareWebcam);
       this.unshareWebcam();
     }
   }
@@ -153,8 +159,8 @@ class VideoDock extends Component {
     this.ws.removeEventListener('close', this.onWsClose);
     // Close websocket connection to prevent multiple reconnects from happening
 
-    window.removeEventListener('online', this.ws.open);
-    window.removeEventListener('offline', this.ws.close);
+    window.removeEventListener('online', this.ws.open.bind(this.ws));
+    window.removeEventListener('offline', this.onWsClose);
 
     this.ws.close();
   }
@@ -194,10 +200,6 @@ class VideoDock extends Component {
         this.startResponse(parsedMessage);
         break;
 
-      case 'error':
-        this.handleError(parsedMessage);
-        break;
-
       case 'playStart':
         this.handlePlayStart(parsedMessage);
         break;
@@ -210,7 +212,7 @@ class VideoDock extends Component {
       case 'iceCandidate':
         const webRtcPeer = this.webRtcPeers[parsedMessage.cameraId];
 
-        if (webRtcPeer !== null) {
+        if (!!webRtcPeer) {
           if (webRtcPeer.didSDPAnswered) {
             webRtcPeer.addIceCandidate(parsedMessage.candidate, (err) => {
               if (err) {
@@ -222,17 +224,34 @@ class VideoDock extends Component {
             webRtcPeer.iceQueue.push(parsedMessage.candidate);
           }
         } else {
-          log('error', ' [ICE] Message arrived before webRtcPeer?');
+          log('error', ' [ICE] Message arrived after the peer was already thrown out, discarding it...');
         }
         break;
+
+      case 'error':
+      default:
+        this.handleError(parsedMessage);
+        break;
     }
   }
 
   start(id, shareWebcam) {
     const that = this;
+    const { intl } = this.props;
 
     console.log(`Starting video call for video: ${id} with ${shareWebcam}`);
 
+    this.cameraTimeouts[id] = setTimeout(() => {
+      log('error', `Camera share has not suceeded in ${CAMERA_SHARE_FAILED_WAIT_TIME}`);
+      if (that.myId == id) {
+        that.notifyError(intl.formatMessage(intlMessages.sharingError));
+        that.unshareWebcam();
+      } else {
+        that.stop(id);
+        that.start(id, shareWebcam);
+      }
+    }, CAMERA_SHARE_FAILED_WAIT_TIME);
+
     if (shareWebcam) {
       VideoService.joiningVideo();
       this.setState({ sharedWebcam: true });
@@ -383,6 +402,10 @@ class VideoDock extends Component {
       cameraId: id,
     });
 
+    if (id === userId) {
+      VideoService.exitedVideo();
+    }
+
     this.destroyWebRTCPeer(id);
     this.destroyVideoTag(id);
   }
@@ -408,6 +431,10 @@ class VideoDock extends Component {
   destroyWebRTCPeer(id) {
     const webRtcPeer = this.webRtcPeers[id];
 
+    // Clear the shared camera fail timeout when destroying
+    clearTimeout(this.cameraTimeouts[id]);
+    this.cameraTimeouts[id] = null;
+
     if (webRtcPeer) {
       log('info', 'Stopping WebRTC peer');
 
@@ -439,7 +466,6 @@ class VideoDock extends Component {
     console.warn(this.props);
     const { userId } = this.props;
     VideoService.sendUserUnshareWebcam(userId);
-    VideoService.exitedVideo();
   }
 
   startResponse(message) {
@@ -460,12 +486,12 @@ class VideoDock extends Component {
       if (error) {
         return log('error', error);
       }
-    });
 
-    if (message.cameraId == this.props.userId) {
-      log('info', 'camera id sendusershare ', id);
-      VideoService.sendUserShareWebcam(id);
-    }
+      if (message.cameraId == this.props.userId) {
+        log('info', 'camera id sendusershare ', id);
+        VideoService.sendUserShareWebcam(id);
+      }
+    });
   }
 
   sendMessage(message) {
@@ -499,9 +525,7 @@ class VideoDock extends Component {
     log('info', 'Handle play stop <--------------------');
     log('error', message);
 
-    const { users } = this.props;
-
-    if (message.cameraId == this.props) {
+    if (message.cameraId == this.props.userId) {
       this.unshareWebcam();
     } else {
       this.stop(message.cameraId);
@@ -511,14 +535,24 @@ class VideoDock extends Component {
   handlePlayStart(message) {
     log('info', 'Handle play start <===================');
 
+    // Clear camera shared timeout when camera succesfully starts
+    clearTimeout(this.cameraTimeouts[message.cameraId]);
+    this.cameraTimeouts[message.cameraId] = null;
+
     if (message.cameraId == this.props.userId) {
       VideoService.joinedVideo();
     }
   }
 
   handleError(message) {
-    const { intl } = this.props;
-    this.notifyError(intl.formatMessage(intlMessages.sharingError));
+    const { intl, userId } = this.props;
+
+    if (message.cameraId == userId) {
+      this.unshareWebcam();
+      this.notifyError(intl.formatMessage(intlMessages.sharingError));
+    } else {
+      this.stop(message.cameraId);
+    }
 
     console.error(' Handle error --------------------->');
     log('debug', message.message);
@@ -572,38 +606,63 @@ class VideoDock extends Component {
   }
 
   shouldComponentUpdate(nextProps, nextState) {
-    const { users, userId } = this.props;
+    const { userId } = this.props;
+    const currentUsers = this.props.users || {};
     const nextUsers = nextProps.users;
 
-    if (users) {
-      let suc = false;
+    let users = {};
+    let present = {};
 
-      for (let i = 0; i < users.length; i++) {
-        if (users && users[i] && nextUsers && nextUsers[i]) {
-          if (users[i].has_stream !== nextUsers[i].has_stream) {
-            console.log(`User ${nextUsers[i].has_stream ? '' : 'un'}shared webcam ${users[i].userId}`);
+    if (!currentUsers)
+      return false;
 
-            if (nextUsers[i].has_stream) {
-              if (userId !== users[i].userId) {
-                this.start(users[i].userId, false);
-              }
-            } else {
-              this.stop(users[i].userId);
-            }
 
-            if (!nextUsers[i].has_stream) {
-              this.destroyVideoTag(users[i].userId);
-            }
+    // Map user objectos to an object in the form {userId: has_stream}
+    currentUsers.forEach((user) => {
+      users[user.userId] = user.has_stream;
+    });
+
 
-            suc = suc || true;
-          }
-        }
+    // Keep instances where the flag has changed or next user adds it
+    nextUsers.forEach((user) => {
+      let id = user.userId;
+      // The case when a user exists and stream status has not changed
+      if (users[id] === user.has_stream) {
+        delete users[id];
+      } else {
+        // Case when a user has been added to the list
+        users[id] = user.has_stream;
       }
 
-      return true;
-    }
+      // Mark the ids which are present in nextUsers
+      present[id] = true;
+    });
+
+    const userIds = Object.keys(users);
+
+    for (let i = 0; i < userIds.length; i++) {
+      let id = userIds[i];
+
+      // If a userId is not present in nextUsers let's stop it
+      if (!present[id]) {
+        this.stop(id);
+        continue;
+      }
 
-    return false;
+      console.log(`User ${users[id] ? '' : 'un'}shared webcam ${id}`);
+
+      // If a user stream is true, changed and was shared by other
+      // user we'll start it. If it is false and changed we stop it
+      if (users[id]) {
+        if (userId !== id) {
+          this.start(id, false);
+        }
+      }
+      else {
+        this.stop(id);
+      }
+    }
+    return true;
   }
 }
 
diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/annotations/pencil/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/annotations/pencil/component.jsx
index b95003b2a99fe358b8a330048da663227cd3b9b8..6cbd68722123735c50dc9da554e2a40b28fbdc0e 100644
--- a/bigbluebutton-html5/imports/ui/components/whiteboard/annotations/pencil/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/whiteboard/annotations/pencil/component.jsx
@@ -3,17 +3,16 @@ import PropTypes from 'prop-types';
 import AnnotationHelpers from '../helpers';
 
 export default class PencilDrawComponent extends Component {
-
   static getInitialCoordinates(annotation, slideWidth, slideHeight) {
     const { points } = annotation;
     let i = 2;
     let path = '';
     if (points && points.length >= 2) {
       path = `M${(points[0] / 100) * slideWidth
-        }, ${(points[1] / 100) * slideHeight}`;
+      }, ${(points[1] / 100) * slideHeight}`;
       while (i < points.length) {
         path = `${path} L${(points[i] / 100) * slideWidth
-          }, ${(points[i + 1] / 100) * slideHeight}`;
+        }, ${(points[i + 1] / 100) * slideHeight}`;
         i += 2;
       }
     }
@@ -29,7 +28,7 @@ export default class PencilDrawComponent extends Component {
     let j;
     for (i = 0, j = 0; i < commands.length; i += 1) {
       switch (commands[i]) {
-          // MOVE_TO - consumes 1 pair of values
+        // MOVE_TO - consumes 1 pair of values
         case 1:
           path = `${path} M${(points[j] / 100) * slideWidth} ${(points[j + 1] / 100) * slideHeight}`;
           j += 2;
@@ -45,8 +44,8 @@ export default class PencilDrawComponent extends Component {
           // 1st pair is a control point, second is a coordinate
         case 3:
           path = `${path} Q${(points[j] / 100) * slideWidth}, ${
-              (points[j + 1] / 100) * slideHeight}, ${(points[j + 2] / 100) * slideWidth}, ${
-              (points[j + 3] / 100) * slideHeight}`;
+            (points[j + 1] / 100) * slideHeight}, ${(points[j + 2] / 100) * slideWidth}, ${
+            (points[j + 3] / 100) * slideHeight}`;
           j += 4;
           break;
 
@@ -54,9 +53,9 @@ export default class PencilDrawComponent extends Component {
           // 1st and 2nd are control points, 3rd is an end coordinate
         case 4:
           path = `${path} C${(points[j] / 100) * slideWidth}, ${
-              (points[j + 1] / 100) * slideHeight}, ${(points[j + 2] / 100) * slideWidth}, ${
-              (points[j + 3] / 100) * slideHeight}, ${(points[j + 4] / 100) * slideWidth}, ${
-              (points[j + 5] / 100) * slideHeight}`;
+            (points[j + 1] / 100) * slideHeight}, ${(points[j + 2] / 100) * slideWidth}, ${
+            (points[j + 3] / 100) * slideHeight}, ${(points[j + 4] / 100) * slideWidth}, ${
+            (points[j + 5] / 100) * slideHeight}`;
           j += 6;
           break;
 
@@ -97,6 +96,10 @@ export default class PencilDrawComponent extends Component {
   }
 
   getCoordinates(annotation, slideWidth, slideHeight) {
+    if (annotation.points.length === 0) {
+      return undefined;
+    }
+
     let data;
     // Final message, display smoothes coordinates
     if (annotation.status === 'DRAW_END') {
@@ -124,7 +127,7 @@ export default class PencilDrawComponent extends Component {
 
     while (i < points.length) {
       path = `${path} L${(points[i] / 100) * slideWidth
-        }, ${(points[i + 1] / 100) * slideHeight}`;
+      }, ${(points[i + 1] / 100) * slideHeight}`;
       i += 2;
     }
     path = this.path + path;
diff --git a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/toolbar-menu-item/component.jsx b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/toolbar-menu-item/component.jsx
index 0fb421517f3701be8d7a96a8a92eedc969c05dc5..f85489e12ce1fcb5e62cea755375299bdbeb7f9f 100644
--- a/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/toolbar-menu-item/component.jsx
+++ b/bigbluebutton-html5/imports/ui/components/whiteboard/whiteboard-toolbar/toolbar-menu-item/component.jsx
@@ -8,8 +8,12 @@ export default class ToolbarMenuItem extends Component {
   constructor() {
     super();
 
+    // a flag to keep track of whether the menu item was actually clicked
+    this.clicked = false;
+
     this.handleTouchStart = this.handleTouchStart.bind(this);
     this.handleOnMouseUp = this.handleOnMouseUp.bind(this);
+    this.handleOnMouseDown = this.handleOnMouseDown.bind(this);
     this.setRef = this.setRef.bind(this);
   }
 
@@ -45,7 +49,18 @@ export default class ToolbarMenuItem extends Component {
     onItemClick(objectToReturn);
   }
 
+  handleOnMouseDown() {
+    this.clicked = true;
+  }
+
   handleOnMouseUp() {
+    // checks whether the button was actually clicked
+    // or if a person was drawing and just release their mouse above the menu item
+    if (!this.clicked) {
+      return;
+    }
+    this.clicked = false;
+
     const { objectToReturn, onItemClick } = this.props;
     // if there is a submenu name, then pass it to onClick
     // if not - it's probably "Undo", "Clear All", "Multi-user", etc.
@@ -64,6 +79,7 @@ export default class ToolbarMenuItem extends Component {
           label={this.props.label}
           icon={this.props.icon ? this.props.icon : null}
           customIcon={this.props.customIcon ? this.props.customIcon : null}
+          onMouseDown={this.handleOnMouseDown}
           onMouseUp={this.handleOnMouseUp}
           onBlur={this.props.onBlur}
           className={this.props.className}
diff --git a/bigbluebutton-html5/imports/ui/services/auth/index.js b/bigbluebutton-html5/imports/ui/services/auth/index.js
index 782a6df3856210f165d208c779a913080fd5ac44..b4e837727bfc6287225b87667b944bf97eecd168 100644
--- a/bigbluebutton-html5/imports/ui/services/auth/index.js
+++ b/bigbluebutton-html5/imports/ui/services/auth/index.js
@@ -4,7 +4,7 @@ import { Tracker } from 'meteor/tracker';
 import Storage from '/imports/ui/services/storage/session';
 
 import Users from '/imports/api/users';
-import { makeCall, log } from '/imports/ui/services/api';
+import { makeCall } from '/imports/ui/services/api';
 
 const CONNECTION_TIMEOUT = Meteor.settings.public.app.connectionTimeout;
 
@@ -152,6 +152,15 @@ class Auth {
         // Skip in case the user is not in the collection yet or is a dummy user
         if (!User || !('intId' in User)) return;
 
+        if (User.ejected) {
+          this.loggedIn = false;
+
+          return reject({
+            error: 401,
+            description: 'User has been ejected.',
+          });
+        }
+
         if (User.validated === true) {
           computation.stop();
           clearTimeout(validationTimeout);
diff --git a/bigbluebutton-html5/package-lock.json b/bigbluebutton-html5/package-lock.json
index 11bab643c9f78c12f785ba8acbd62d85712046de..65c1f781632634964306430b65245a0094a5854f 100644
--- a/bigbluebutton-html5/package-lock.json
+++ b/bigbluebutton-html5/package-lock.json
@@ -3,4004 +3,3140 @@
   "requires": true,
   "lockfileVersion": 1,
   "dependencies": {
-    "attr-accept": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.0.tgz",
-      "integrity": "sha1-tc01In8WOTWo8d4Q7T66FpQfa+Y="
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
     },
-    "autoprefixer": {
-      "version": "7.1.6",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.6.tgz",
-      "integrity": "sha512-C9yv/UF3X+eJTi/zvfxuyfxmLibYrntpF3qoJYrMeQwgUJOZrZvpJiMG2FMQ3qnhWtF/be4pYONBBw95ZGe3vA==",
+    "acorn": {
+      "version": "5.3.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz",
+      "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==",
+      "dev": true
+    },
+    "acorn-jsx": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
+      "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
       "dev": true,
       "requires": {
-        "browserslist": "2.11.0",
-        "caniuse-lite": "1.0.30000789",
-        "normalize-range": "0.1.2",
-        "num2fraction": "1.2.2",
-        "postcss": "6.0.16",
-        "postcss-value-parser": "3.3.0"
+        "acorn": "3.3.0"
       },
       "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.1"
-          }
-        },
-        "browserslist": {
-          "version": "2.11.0",
-          "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.0.tgz",
-          "integrity": "sha512-mNYp0RNeu1xueGuJFSXkU+K0nH+dBE/gcjtyhtNKfU8hwdrVIfoA7i5iFSjOmzkGdL2QaO7YX9ExiVPE7AY9JA==",
-          "dev": true,
-          "requires": {
-            "caniuse-lite": "1.0.30000789",
-            "electron-to-chromium": "1.3.30"
-          }
-        },
-        "caniuse-lite": {
-          "version": "1.0.30000789",
-          "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000789.tgz",
-          "integrity": "sha1-Lj2TeyZxM/Y2Ne9/RB+sZjYPyIk=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
-          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.5.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "4.5.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
-              "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
-              "dev": true,
-              "requires": {
-                "has-flag": "2.0.0"
-              }
-            }
-          }
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "electron-to-chromium": {
-          "version": "1.3.30",
-          "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz",
-          "integrity": "sha512-zx1Prv7kYLfc4OA60FhxGbSo4qrEjgSzpo1/37i7l9ltXPYOoQBtjQxY9KmsgfHnBxHlBGXwLlsbt/gub1w5lw==",
-          "dev": true,
-          "requires": {
-            "electron-releases": "2.1.0"
-          }
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "normalize-range": {
-          "version": "0.1.2",
-          "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
-          "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
-          "dev": true
-        },
-        "num2fraction": {
-          "version": "1.2.2",
-          "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
-          "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.16",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
-          "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.3.0",
-            "source-map": "0.6.1",
-            "supports-color": "5.1.0"
-          }
-        },
-        "postcss-value-parser": {
+        "acorn": {
           "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
-          "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
-          "dev": true
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+          "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
           "dev": true
-        },
-        "supports-color": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
-          "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
         }
       }
     },
-    "babel-runtime": {
-      "version": "6.26.0",
-      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
-      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
-      "requires": {
-        "core-js": "2.5.3",
-        "regenerator-runtime": "0.11.1"
-      },
-      "dependencies": {
-        "core-js": {
-          "version": "2.5.3",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
-          "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4="
-        },
-        "regenerator-runtime": {
-          "version": "0.11.1",
-          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
-          "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
-        }
-      }
+    "adm-zip": {
+      "version": "0.4.7",
+      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.7.tgz",
+      "integrity": "sha1-hgbCy/HEJs6MjsABdER/1Jtur8E=",
+      "dev": true
     },
-    "block-stream": {
-      "version": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
-      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+    "ajv": {
+      "version": "5.5.2",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+      "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
       "requires": {
-        "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz"
+        "co": "4.6.0",
+        "fast-deep-equal": "1.0.0",
+        "fast-json-stable-stringify": "2.0.0",
+        "json-schema-traverse": "0.3.1"
       }
     },
-    "chai": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
-      "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
+    "ajv-keywords": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+      "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
+      "dev": true
+    },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+    },
+    "ansi-escapes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
+      "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==",
+      "dev": true
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+    },
+    "any-promise": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+      "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
+    },
+    "app-root-path": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz",
+      "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=",
+      "dev": true
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
+    },
+    "archiver": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz",
+      "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=",
       "dev": true,
       "requires": {
-        "assertion-error": "1.1.0",
-        "check-error": "1.0.2",
-        "deep-eql": "3.0.1",
-        "get-func-name": "2.0.0",
-        "pathval": "1.1.0",
-        "type-detect": "4.0.5"
+        "archiver-utils": "1.3.0",
+        "async": "2.6.0",
+        "buffer-crc32": "0.2.13",
+        "glob": "7.1.2",
+        "lodash": "4.17.4",
+        "readable-stream": "2.3.3",
+        "tar-stream": "1.5.5",
+        "walkdir": "0.0.11",
+        "zip-stream": "1.2.0"
       },
       "dependencies": {
-        "assertion-error": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
-          "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
-          "dev": true
-        },
-        "check-error": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
-          "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
-          "dev": true
-        },
-        "deep-eql": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
-          "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+        "async": {
+          "version": "2.6.0",
+          "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
+          "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
           "dev": true,
           "requires": {
-            "type-detect": "4.0.5"
+            "lodash": "4.17.4"
           }
-        },
-        "get-func-name": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
-          "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
-          "dev": true
-        },
-        "pathval": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
-          "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
-          "dev": true
-        },
-        "type-detect": {
-          "version": "4.0.5",
-          "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.5.tgz",
-          "integrity": "sha512-N9IvkQslUGYGC24RkJk1ba99foK6TkwC2FHAEBlQFBP0RxQZS8ZpJuAZcwiY/w9ZJHFQb1aOXBI60OdxhTrwEQ==",
-          "dev": true
         }
       }
     },
-    "chardet": {
-      "version": "0.4.2",
-      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
-      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
-      "dev": true
-    },
-    "classnames": {
-      "version": "2.2.5",
-      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz",
-      "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0="
-    },
-    "clipboard": {
-      "version": "1.7.1",
-      "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.7.1.tgz",
-      "integrity": "sha1-Ng1taUbpmnof7zleQrqStem1oWs=",
+    "archiver-utils": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
+      "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
+      "dev": true,
       "requires": {
-        "good-listener": "1.2.2",
-        "select": "1.1.2",
-        "tiny-emitter": "2.0.2"
+        "glob": "7.1.2",
+        "graceful-fs": "4.1.11",
+        "lazystream": "1.0.0",
+        "lodash": "4.17.4",
+        "normalize-path": "2.1.1",
+        "readable-stream": "2.3.3"
       },
       "dependencies": {
-        "delegate": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
-          "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
-        },
-        "good-listener": {
-          "version": "1.2.2",
-          "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
-          "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
+        "normalize-path": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+          "dev": true,
           "requires": {
-            "delegate": "3.2.0"
+            "remove-trailing-separator": "1.1.0"
           }
-        },
-        "select": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
-          "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
-        },
-        "tiny-emitter": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz",
-          "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow=="
         }
       }
     },
-    "core-js": {
-      "version": "2.5.3",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
-      "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4="
+    "are-we-there-yet": {
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
+      "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
+      "requires": {
+        "delegates": "1.0.0",
+        "readable-stream": "2.3.3"
+      }
     },
-    "electron-releases": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz",
-      "integrity": "sha512-cyKFD1bTE/UgULXfaueIN1k5EPFzs+FRc/rvCY5tIynefAPqopQEgjr0EzY+U3Dqrk/G4m9tXSPuZ77v6dL/Rw==",
+    "argparse": {
+      "version": "1.0.9",
+      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
+      "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
+      "dev": true,
+      "requires": {
+        "sprintf-js": "1.0.3"
+      }
+    },
+    "aria-query": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.7.0.tgz",
+      "integrity": "sha512-/r2lHl09V3o74+2MLKEdewoj37YZqiQZnfen1O4iNlrOjUgeKuu1U2yF3iKh6HJxqF+OXkLMfQv65Z/cvxD6vA==",
+      "dev": true,
+      "requires": {
+        "ast-types-flow": "0.0.7"
+      }
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
+    },
+    "array-includes": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
+      "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "es-abstract": "1.10.0"
+      }
+    },
+    "array-parallel": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/array-parallel/-/array-parallel-0.1.3.tgz",
+      "integrity": "sha1-j3hTCJJu1apHjEfmTRszS2wMlH0=",
       "dev": true
     },
-    "eslint": {
-      "version": "4.9.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.9.0.tgz",
-      "integrity": "sha1-doedJ0BoJhsZH+Dy9Wx0wvQgjos=",
+    "array-series": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/array-series/-/array-series-0.1.5.tgz",
+      "integrity": "sha1-3103v8XC7wdV4qpPkv6ufUtaly8=",
+      "dev": true
+    },
+    "array-union": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+      "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
       "dev": true,
       "requires": {
-        "ajv": "5.5.2",
-        "babel-code-frame": "6.26.0",
-        "chalk": "2.3.0",
-        "concat-stream": "1.6.0",
-        "cross-spawn": "5.1.0",
-        "debug": "3.1.0",
-        "doctrine": "2.1.0",
-        "eslint-scope": "3.7.1",
-        "espree": "3.5.2",
-        "esquery": "1.0.0",
-        "estraverse": "4.2.0",
-        "esutils": "2.0.2",
-        "file-entry-cache": "2.0.0",
-        "functional-red-black-tree": "1.0.1",
-        "glob": "7.1.2",
-        "globals": "9.18.0",
-        "ignore": "3.3.7",
-        "imurmurhash": "0.1.4",
-        "inquirer": "3.3.0",
-        "is-resolvable": "1.0.1",
-        "js-yaml": "3.10.0",
-        "json-stable-stringify": "1.0.1",
-        "levn": "0.3.0",
-        "lodash": "4.17.4",
-        "minimatch": "3.0.4",
-        "mkdirp": "0.5.1",
-        "natural-compare": "1.4.0",
-        "optionator": "0.8.2",
-        "path-is-inside": "1.0.2",
-        "pluralize": "7.0.0",
-        "progress": "2.0.0",
-        "require-uncached": "1.0.3",
-        "semver": "5.4.1",
-        "strip-ansi": "4.0.0",
-        "strip-json-comments": "2.0.1",
-        "table": "4.0.2",
-        "text-table": "0.2.0"
-      },
-      "dependencies": {
-        "acorn": {
-          "version": "5.3.0",
-          "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz",
-          "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==",
-          "dev": true
-        },
-        "acorn-jsx": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
-          "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
-          "dev": true,
-          "requires": {
-            "acorn": "3.3.0"
-          },
-          "dependencies": {
-            "acorn": {
-              "version": "3.3.0",
-              "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
-              "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=",
-              "dev": true
-            }
-          }
-        },
-        "ajv": {
-          "version": "5.5.2",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
-          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
-          "dev": true,
-          "requires": {
-            "co": "4.6.0",
-            "fast-deep-equal": "1.0.0",
-            "fast-json-stable-stringify": "2.0.0",
-            "json-schema-traverse": "0.3.1"
-          }
-        },
-        "ajv-keywords": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
-          "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=",
-          "dev": true
-        },
-        "ansi-escapes": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz",
-          "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==",
-          "dev": true
-        },
-        "ansi-regex": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "argparse": {
-          "version": "1.0.9",
-          "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
-          "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
-          "dev": true,
-          "requires": {
-            "sprintf-js": "1.0.3"
-          }
-        },
-        "array-union": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
-          "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
-          "dev": true,
-          "requires": {
-            "array-uniq": "1.0.3"
-          }
-        },
-        "array-uniq": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
-          "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
-          "dev": true
-        },
-        "arrify": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
-          "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
-          "dev": true
-        },
-        "babel-code-frame": {
-          "version": "6.26.0",
-          "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
-          "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
-          "dev": true,
-          "requires": {
-            "chalk": "1.1.3",
-            "esutils": "2.0.2",
-            "js-tokens": "3.0.2"
-          },
-          "dependencies": {
-            "chalk": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-              "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "2.2.1",
-                "escape-string-regexp": "1.0.5",
-                "has-ansi": "2.0.0",
-                "strip-ansi": "3.0.1",
-                "supports-color": "2.0.0"
-              }
-            },
-            "strip-ansi": {
-              "version": "3.0.1",
-              "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-              "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-              "dev": true,
-              "requires": {
-                "ansi-regex": "2.1.1"
-              }
-            }
-          }
-        },
-        "balanced-match": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "dev": true
-        },
-        "brace-expansion": {
-          "version": "1.1.8",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
-          "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
-          "dev": true,
-          "requires": {
-            "balanced-match": "1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "caller-path": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
-          "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
-          "dev": true,
-          "requires": {
-            "callsites": "0.2.0"
-          }
-        },
-        "callsites": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
-          "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
-          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.5.0"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "3.2.0",
-              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-              "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-              "dev": true,
-              "requires": {
-                "color-convert": "1.9.1"
-              }
-            },
-            "supports-color": {
-              "version": "4.5.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
-              "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
-              "dev": true,
-              "requires": {
-                "has-flag": "2.0.0"
-              }
-            }
-          }
-        },
-        "circular-json": {
-          "version": "0.3.3",
-          "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
-          "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
-          "dev": true
-        },
-        "cli-cursor": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
-          "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
-          "dev": true,
-          "requires": {
-            "restore-cursor": "2.0.0"
-          }
-        },
-        "cli-width": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
-          "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
-          "dev": true
-        },
-        "co": {
-          "version": "4.6.0",
-          "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-          "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
-          "dev": true
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "dev": true
-        },
-        "concat-stream": {
-          "version": "1.6.0",
-          "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
-          "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
-          "dev": true,
-          "requires": {
-            "inherits": "2.0.3",
-            "readable-stream": "2.3.3",
-            "typedarray": "0.0.6"
-          }
-        },
-        "core-util-is": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-          "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
-          "dev": true
-        },
-        "cross-spawn": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
-          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
-          "dev": true,
-          "requires": {
-            "lru-cache": "4.1.1",
-            "shebang-command": "1.2.0",
-            "which": "1.3.0"
-          }
-        },
-        "debug": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
-          "dev": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "deep-is": {
-          "version": "0.1.3",
-          "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
-          "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
-          "dev": true
-        },
-        "del": {
-          "version": "2.2.2",
-          "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
-          "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
-          "dev": true,
-          "requires": {
-            "globby": "5.0.0",
-            "is-path-cwd": "1.0.0",
-            "is-path-in-cwd": "1.0.0",
-            "object-assign": "4.1.1",
-            "pify": "2.3.0",
-            "pinkie-promise": "2.0.1",
-            "rimraf": "2.6.2"
-          }
-        },
-        "doctrine": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
-          "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
-          "dev": true,
-          "requires": {
-            "esutils": "2.0.2"
-          }
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "eslint-scope": {
-          "version": "3.7.1",
-          "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
-          "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
-          "dev": true,
-          "requires": {
-            "esrecurse": "4.2.0",
-            "estraverse": "4.2.0"
-          }
-        },
-        "espree": {
-          "version": "3.5.2",
-          "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz",
-          "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==",
-          "dev": true,
-          "requires": {
-            "acorn": "5.3.0",
-            "acorn-jsx": "3.0.1"
-          }
-        },
-        "esprima": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
-          "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
-          "dev": true
-        },
-        "esquery": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
-          "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
-          "dev": true,
-          "requires": {
-            "estraverse": "4.2.0"
-          }
-        },
-        "esrecurse": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
-          "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
-          "dev": true,
-          "requires": {
-            "estraverse": "4.2.0",
-            "object-assign": "4.1.1"
-          }
-        },
-        "estraverse": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
-          "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
-          "dev": true
-        },
-        "esutils": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
-          "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
-          "dev": true
-        },
-        "external-editor": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz",
-          "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==",
-          "dev": true,
-          "requires": {
-            "chardet": "0.4.2",
-            "iconv-lite": "0.4.19",
-            "tmp": "0.0.33"
-          }
-        },
-        "fast-deep-equal": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
-          "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=",
-          "dev": true
-        },
-        "fast-json-stable-stringify": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
-          "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
-          "dev": true
-        },
-        "fast-levenshtein": {
-          "version": "2.0.6",
-          "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-          "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
-          "dev": true
-        },
-        "figures": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
-          "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
-          "dev": true,
-          "requires": {
-            "escape-string-regexp": "1.0.5"
-          }
-        },
-        "file-entry-cache": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
-          "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
-          "dev": true,
-          "requires": {
-            "flat-cache": "1.3.0",
-            "object-assign": "4.1.1"
-          }
-        },
-        "flat-cache": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
-          "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
-          "dev": true,
-          "requires": {
-            "circular-json": "0.3.3",
-            "del": "2.2.2",
-            "graceful-fs": "4.1.11",
-            "write": "0.2.1"
-          }
-        },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-          "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-          "dev": true
-        },
-        "functional-red-black-tree": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
-          "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
-          "dev": true
-        },
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
-          }
-        },
-        "globals": {
-          "version": "9.18.0",
-          "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
-          "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
-          "dev": true
-        },
-        "globby": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
-          "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
-          "dev": true,
-          "requires": {
-            "array-union": "1.0.2",
-            "arrify": "1.0.1",
-            "glob": "7.1.2",
-            "object-assign": "4.1.1",
-            "pify": "2.3.0",
-            "pinkie-promise": "2.0.1"
-          }
-        },
-        "graceful-fs": {
-          "version": "4.1.11",
-          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
-          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
-          "dev": true
-        },
-        "has-ansi": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
-          "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "2.1.1"
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "iconv-lite": {
-          "version": "0.4.19",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
-          "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
-          "dev": true
-        },
-        "ignore": {
-          "version": "3.3.7",
-          "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz",
-          "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==",
-          "dev": true
-        },
-        "imurmurhash": {
-          "version": "0.1.4",
-          "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
-          "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
-          "dev": true
-        },
-        "inflight": {
-          "version": "1.0.6",
-          "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-          "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-          "dev": true,
-          "requires": {
-            "once": "1.4.0",
-            "wrappy": "1.0.2"
-          }
-        },
-        "inherits": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-          "dev": true
-        },
-        "inquirer": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
-          "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "3.0.0",
-            "chalk": "2.3.0",
-            "cli-cursor": "2.1.0",
-            "cli-width": "2.2.0",
-            "external-editor": "2.1.0",
-            "figures": "2.0.0",
-            "lodash": "4.17.4",
-            "mute-stream": "0.0.7",
-            "run-async": "2.3.0",
-            "rx-lite": "4.0.8",
-            "rx-lite-aggregates": "4.0.8",
-            "string-width": "2.1.1",
-            "strip-ansi": "4.0.0",
-            "through": "2.3.8"
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
-          "dev": true
-        },
-        "is-path-cwd": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
-          "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
-          "dev": true
-        },
-        "is-path-in-cwd": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
-          "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
-          "dev": true,
-          "requires": {
-            "is-path-inside": "1.0.1"
-          }
-        },
-        "is-path-inside": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
-          "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
-          "dev": true,
-          "requires": {
-            "path-is-inside": "1.0.2"
-          }
-        },
-        "is-promise": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
-          "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
-          "dev": true
-        },
-        "is-resolvable": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz",
-          "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==",
-          "dev": true
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "isexe": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-          "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-          "dev": true
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
-          "dev": true
-        },
-        "js-yaml": {
-          "version": "3.10.0",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
-          "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
-          "dev": true,
-          "requires": {
-            "argparse": "1.0.9",
-            "esprima": "4.0.0"
-          }
-        },
-        "json-schema-traverse": {
-          "version": "0.3.1",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
-          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=",
-          "dev": true
-        },
-        "json-stable-stringify": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
-          "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
-          "dev": true,
-          "requires": {
-            "jsonify": "0.0.0"
-          }
-        },
-        "jsonify": {
-          "version": "0.0.0",
-          "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
-          "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
-          "dev": true
-        },
-        "levn": {
-          "version": "0.3.0",
-          "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
-          "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
-          "dev": true,
-          "requires": {
-            "prelude-ls": "1.1.2",
-            "type-check": "0.3.2"
-          }
-        },
-        "lru-cache": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
-          "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
-          "dev": true,
-          "requires": {
-            "pseudomap": "1.0.2",
-            "yallist": "2.1.2"
-          }
-        },
-        "mimic-fn": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
-          "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
-          "dev": true
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "1.1.8"
-          }
-        },
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
-        },
-        "mkdirp": {
-          "version": "0.5.1",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-          "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-          "dev": true,
-          "requires": {
-            "minimist": "0.0.8"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        },
-        "mute-stream": {
-          "version": "0.0.7",
-          "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-          "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
-          "dev": true
-        },
-        "natural-compare": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
-          "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
-          "dev": true
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-          "dev": true
-        },
-        "once": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-          "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-          "dev": true,
-          "requires": {
-            "wrappy": "1.0.2"
-          }
-        },
-        "onetime": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
-          "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
-          "dev": true,
-          "requires": {
-            "mimic-fn": "1.1.0"
-          }
-        },
-        "optionator": {
-          "version": "0.8.2",
-          "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
-          "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
-          "dev": true,
-          "requires": {
-            "deep-is": "0.1.3",
-            "fast-levenshtein": "2.0.6",
-            "levn": "0.3.0",
-            "prelude-ls": "1.1.2",
-            "type-check": "0.3.2",
-            "wordwrap": "1.0.0"
-          }
-        },
-        "os-tmpdir": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-          "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-          "dev": true
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-          "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-          "dev": true
-        },
-        "path-is-inside": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
-          "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
-          "dev": true
-        },
-        "pify": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-          "dev": true
-        },
-        "pinkie": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-          "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
-          "dev": true
-        },
-        "pinkie-promise": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
-          "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-          "dev": true,
-          "requires": {
-            "pinkie": "2.0.4"
-          }
-        },
-        "pluralize": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
-          "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
-          "dev": true
-        },
-        "prelude-ls": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
-          "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
-          "dev": true
-        },
-        "process-nextick-args": {
-          "version": "1.0.7",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
-          "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
-          "dev": true
-        },
-        "progress": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
-          "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
-          "dev": true
-        },
-        "pseudomap": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-          "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.3",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
-          "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "1.0.2",
-            "inherits": "2.0.3",
-            "isarray": "1.0.0",
-            "process-nextick-args": "1.0.7",
-            "safe-buffer": "5.1.1",
-            "string_decoder": "1.0.3",
-            "util-deprecate": "1.0.2"
-          }
-        },
-        "require-uncached": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
-          "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
-          "dev": true,
-          "requires": {
-            "caller-path": "0.1.0",
-            "resolve-from": "1.0.1"
-          }
-        },
-        "resolve-from": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
-          "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
-          "dev": true
-        },
-        "restore-cursor": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
-          "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
-          "dev": true,
-          "requires": {
-            "onetime": "2.0.1",
-            "signal-exit": "3.0.2"
-          }
-        },
-        "rimraf": {
-          "version": "2.6.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
-          "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
-          "dev": true,
-          "requires": {
-            "glob": "7.1.2"
-          }
-        },
-        "run-async": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
-          "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
-          "dev": true,
-          "requires": {
-            "is-promise": "2.1.0"
-          }
-        },
-        "rx-lite": {
-          "version": "4.0.8",
-          "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
-          "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
-          "dev": true
-        },
-        "rx-lite-aggregates": {
-          "version": "4.0.8",
-          "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
-          "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
-          "dev": true,
-          "requires": {
-            "rx-lite": "4.0.8"
-          }
-        },
-        "safe-buffer": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
-          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
-          "dev": true
-        },
-        "semver": {
-          "version": "5.4.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
-          "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
-          "dev": true
-        },
-        "shebang-command": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-          "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
-          "dev": true,
-          "requires": {
-            "shebang-regex": "1.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-          "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
-          "dev": true
-        },
-        "signal-exit": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-          "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
-          "dev": true
-        },
-        "slice-ansi": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
-          "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "2.0.0"
-          }
-        },
-        "sprintf-js": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-          "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-          "dev": true
-        },
-        "string-width": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
-          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
-          "dev": true,
-          "requires": {
-            "is-fullwidth-code-point": "2.0.0",
-            "strip-ansi": "4.0.0"
-          }
-        },
-        "string_decoder": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
-          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "5.1.1"
-          }
-        },
-        "strip-ansi": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
-          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "3.0.0"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-              "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
-              "dev": true
-            }
-          }
-        },
-        "strip-json-comments": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-          "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-          "dev": true
-        },
-        "table": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
-          "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
-          "dev": true,
-          "requires": {
-            "ajv": "5.5.2",
-            "ajv-keywords": "2.1.1",
-            "chalk": "2.3.0",
-            "lodash": "4.17.4",
-            "slice-ansi": "1.0.0",
-            "string-width": "2.1.1"
-          }
-        },
-        "text-table": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-          "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
-          "dev": true
-        },
-        "through": {
-          "version": "2.3.8",
-          "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-          "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
-          "dev": true
-        },
-        "tmp": {
-          "version": "0.0.33",
-          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-          "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-          "dev": true,
-          "requires": {
-            "os-tmpdir": "1.0.2"
-          }
-        },
-        "type-check": {
-          "version": "0.3.2",
-          "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
-          "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
-          "dev": true,
-          "requires": {
-            "prelude-ls": "1.1.2"
-          }
-        },
-        "typedarray": {
-          "version": "0.0.6",
-          "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
-          "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
-          "dev": true
-        },
-        "util-deprecate": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-          "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-          "dev": true
-        },
-        "which": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
-          "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
-          "dev": true,
-          "requires": {
-            "isexe": "2.0.0"
-          }
-        },
-        "wordwrap": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
-          "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
-          "dev": true
-        },
-        "wrappy": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-          "dev": true
-        },
-        "write": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
-          "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
-          "dev": true,
-          "requires": {
-            "mkdirp": "0.5.1"
-          }
-        },
-        "yallist": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
-          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
-          "dev": true
-        }
-      }
-    },
-    "eslint-config-airbnb": {
-      "version": "16.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-16.1.0.tgz",
-      "integrity": "sha512-zLyOhVWhzB/jwbz7IPSbkUuj7X2ox4PHXTcZkEmDqTvd0baJmJyuxlFPDlZOE/Y5bC+HQRaEkT3FoHo9wIdRiw==",
-      "dev": true,
-      "requires": {
-        "eslint-config-airbnb-base": "12.1.0"
-      }
-    },
-    "eslint-config-airbnb-base": {
-      "version": "12.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz",
-      "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==",
-      "dev": true,
-      "requires": {
-        "eslint-restricted-globals": "0.1.1"
-      },
-      "dependencies": {
-        "eslint-restricted-globals": {
-          "version": "0.1.1",
-          "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz",
-          "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=",
-          "dev": true
-        }
-      }
-    },
-    "eslint-plugin-import": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz",
-      "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==",
-      "dev": true,
-      "requires": {
-        "builtin-modules": "1.1.1",
-        "contains-path": "0.1.0",
-        "debug": "2.6.9",
-        "doctrine": "1.5.0",
-        "eslint-import-resolver-node": "0.3.2",
-        "eslint-module-utils": "2.1.1",
-        "has": "1.0.1",
-        "lodash.cond": "4.5.2",
-        "minimatch": "3.0.4",
-        "read-pkg-up": "2.0.0"
-      },
-      "dependencies": {
-        "balanced-match": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "dev": true
-        },
-        "brace-expansion": {
-          "version": "1.1.8",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
-          "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
-          "dev": true,
-          "requires": {
-            "balanced-match": "1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "builtin-modules": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
-          "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
-          "dev": true
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "dev": true
-        },
-        "contains-path": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
-          "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
-          "dev": true
-        },
-        "debug": {
-          "version": "2.6.9",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-          "dev": true,
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "doctrine": {
-          "version": "1.5.0",
-          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
-          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
-          "dev": true,
-          "requires": {
-            "esutils": "2.0.2",
-            "isarray": "1.0.0"
-          }
-        },
-        "error-ex": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
-          "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
-          "dev": true,
-          "requires": {
-            "is-arrayish": "0.2.1"
-          }
-        },
-        "eslint-import-resolver-node": {
-          "version": "0.3.2",
-          "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
-          "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
-          "dev": true,
-          "requires": {
-            "debug": "2.6.9",
-            "resolve": "1.5.0"
-          }
-        },
-        "eslint-module-utils": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz",
-          "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==",
-          "dev": true,
-          "requires": {
-            "debug": "2.6.9",
-            "pkg-dir": "1.0.0"
-          }
-        },
-        "esutils": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
-          "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
-          "dev": true
-        },
-        "find-up": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
-          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
-          "dev": true,
-          "requires": {
-            "path-exists": "2.1.0",
-            "pinkie-promise": "2.0.1"
-          }
-        },
-        "function-bind": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-          "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-          "dev": true
-        },
-        "graceful-fs": {
-          "version": "4.1.11",
-          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
-          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
-          "dev": true
-        },
-        "has": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
-          "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
-          "dev": true,
-          "requires": {
-            "function-bind": "1.1.1"
-          }
-        },
-        "hosted-git-info": {
-          "version": "2.5.0",
-          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
-          "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==",
-          "dev": true
-        },
-        "is-arrayish": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-          "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
-          "dev": true
-        },
-        "is-builtin-module": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
-          "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
-          "dev": true,
-          "requires": {
-            "builtin-modules": "1.1.1"
-          }
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "load-json-file": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
-          "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "4.1.11",
-            "parse-json": "2.2.0",
-            "pify": "2.3.0",
-            "strip-bom": "3.0.0"
-          }
-        },
-        "locate-path": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
-          "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
-          "dev": true,
-          "requires": {
-            "p-locate": "2.0.0",
-            "path-exists": "3.0.0"
-          },
-          "dependencies": {
-            "path-exists": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
-              "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
-              "dev": true
-            }
-          }
-        },
-        "lodash.cond": {
-          "version": "4.5.2",
-          "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
-          "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=",
-          "dev": true
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "1.1.8"
-          }
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
-          "dev": true
-        },
-        "normalize-package-data": {
-          "version": "2.4.0",
-          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
-          "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
-          "dev": true,
-          "requires": {
-            "hosted-git-info": "2.5.0",
-            "is-builtin-module": "1.0.0",
-            "semver": "5.4.1",
-            "validate-npm-package-license": "3.0.1"
-          }
-        },
-        "p-limit": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
-          "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
-          "dev": true,
-          "requires": {
-            "p-try": "1.0.0"
-          }
-        },
-        "p-locate": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
-          "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
-          "dev": true,
-          "requires": {
-            "p-limit": "1.2.0"
-          }
-        },
-        "parse-json": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
-          "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
-          "dev": true,
-          "requires": {
-            "error-ex": "1.3.1"
-          }
-        },
-        "path-exists": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
-          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
-          "dev": true,
-          "requires": {
-            "pinkie-promise": "2.0.1"
-          }
-        },
-        "path-parse": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
-          "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
-          "dev": true
-        },
-        "path-type": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
-          "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
-          "dev": true,
-          "requires": {
-            "pify": "2.3.0"
-          }
-        },
-        "pify": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
-          "dev": true
-        },
-        "pinkie": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-          "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
-          "dev": true
-        },
-        "pinkie-promise": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
-          "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-          "dev": true,
-          "requires": {
-            "pinkie": "2.0.4"
-          }
-        },
-        "pkg-dir": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
-          "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
-          "dev": true,
-          "requires": {
-            "find-up": "1.1.2"
-          }
-        },
-        "read-pkg": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
-          "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
-          "dev": true,
-          "requires": {
-            "load-json-file": "2.0.0",
-            "normalize-package-data": "2.4.0",
-            "path-type": "2.0.0"
-          }
-        },
-        "read-pkg-up": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
-          "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
-          "dev": true,
-          "requires": {
-            "find-up": "2.1.0",
-            "read-pkg": "2.0.0"
-          },
-          "dependencies": {
-            "find-up": {
-              "version": "2.1.0",
-              "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
-              "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
-              "dev": true,
-              "requires": {
-                "locate-path": "2.0.0"
-              }
-            }
-          }
-        },
-        "resolve": {
-          "version": "1.5.0",
-          "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
-          "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
-          "dev": true,
-          "requires": {
-            "path-parse": "1.0.5"
-          }
-        },
-        "semver": {
-          "version": "5.4.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
-          "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
-          "dev": true
-        },
-        "spdx-correct": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
-          "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
-          "dev": true,
-          "requires": {
-            "spdx-license-ids": "1.2.2"
-          }
-        },
-        "spdx-expression-parse": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
-          "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=",
-          "dev": true
-        },
-        "spdx-license-ids": {
-          "version": "1.2.2",
-          "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
-          "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=",
-          "dev": true
-        },
-        "strip-bom": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
-          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
-          "dev": true
-        },
-        "validate-npm-package-license": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
-          "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
-          "dev": true,
-          "requires": {
-            "spdx-correct": "1.0.2",
-            "spdx-expression-parse": "1.0.4"
-          }
-        }
-      }
-    },
-    "eslint-plugin-jsx-a11y": {
-      "version": "6.0.3",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.3.tgz",
-      "integrity": "sha1-VFg9GuRCSDFi4EDhPMMYZUZRAOU=",
-      "dev": true,
-      "requires": {
-        "aria-query": "0.7.0",
-        "array-includes": "3.0.3",
-        "ast-types-flow": "0.0.7",
-        "axobject-query": "0.1.0",
-        "damerau-levenshtein": "1.0.4",
-        "emoji-regex": "6.5.1",
-        "jsx-ast-utils": "2.0.1"
-      },
-      "dependencies": {
-        "aria-query": {
-          "version": "0.7.0",
-          "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-0.7.0.tgz",
-          "integrity": "sha512-/r2lHl09V3o74+2MLKEdewoj37YZqiQZnfen1O4iNlrOjUgeKuu1U2yF3iKh6HJxqF+OXkLMfQv65Z/cvxD6vA==",
-          "dev": true,
-          "requires": {
-            "ast-types-flow": "0.0.7"
-          }
-        },
-        "array-includes": {
-          "version": "3.0.3",
-          "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
-          "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
-          "dev": true,
-          "requires": {
-            "define-properties": "1.1.2",
-            "es-abstract": "1.10.0"
-          }
-        },
-        "ast-types-flow": {
-          "version": "0.0.7",
-          "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
-          "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
-          "dev": true
-        },
-        "axobject-query": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
-          "integrity": "sha1-YvWdvFnJ+SQnWco0mWDnov48NsA=",
-          "dev": true,
-          "requires": {
-            "ast-types-flow": "0.0.7"
-          }
-        },
-        "damerau-levenshtein": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz",
-          "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=",
-          "dev": true
-        },
-        "define-properties": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
-          "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
-          "dev": true,
-          "requires": {
-            "foreach": "2.0.5",
-            "object-keys": "1.0.11"
-          }
-        },
-        "emoji-regex": {
-          "version": "6.5.1",
-          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz",
-          "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==",
-          "dev": true
-        },
-        "es-abstract": {
-          "version": "1.10.0",
-          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz",
-          "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==",
-          "dev": true,
-          "requires": {
-            "es-to-primitive": "1.1.1",
-            "function-bind": "1.1.1",
-            "has": "1.0.1",
-            "is-callable": "1.1.3",
-            "is-regex": "1.0.4"
-          }
-        },
-        "es-to-primitive": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
-          "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
-          "dev": true,
-          "requires": {
-            "is-callable": "1.1.3",
-            "is-date-object": "1.0.1",
-            "is-symbol": "1.0.1"
-          }
-        },
-        "foreach": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
-          "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
-          "dev": true
-        },
-        "function-bind": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-          "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-          "dev": true
-        },
-        "has": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
-          "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
-          "dev": true,
-          "requires": {
-            "function-bind": "1.1.1"
-          }
-        },
-        "is-callable": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
-          "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
-          "dev": true
-        },
-        "is-date-object": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
-          "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
-          "dev": true
-        },
-        "is-regex": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
-          "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
-          "dev": true,
-          "requires": {
-            "has": "1.0.1"
-          }
-        },
-        "is-symbol": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
-          "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
-          "dev": true
-        },
-        "jsx-ast-utils": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz",
-          "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=",
-          "dev": true,
-          "requires": {
-            "array-includes": "3.0.3"
-          }
-        },
-        "object-keys": {
-          "version": "1.0.11",
-          "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
-          "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
-          "dev": true
-        }
-      }
-    },
-    "eslint-plugin-react": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz",
-      "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==",
-      "dev": true,
-      "requires": {
-        "doctrine": "2.1.0",
-        "has": "1.0.1",
-        "jsx-ast-utils": "2.0.1",
-        "prop-types": "15.6.0"
-      },
-      "dependencies": {
-        "array-includes": {
-          "version": "3.0.3",
-          "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
-          "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
-          "dev": true,
-          "requires": {
-            "define-properties": "1.1.2",
-            "es-abstract": "1.10.0"
-          }
-        },
-        "define-properties": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
-          "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
-          "dev": true,
-          "requires": {
-            "foreach": "2.0.5",
-            "object-keys": "1.0.11"
-          }
-        },
-        "doctrine": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
-          "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
-          "dev": true,
-          "requires": {
-            "esutils": "2.0.2"
-          }
-        },
-        "es-abstract": {
-          "version": "1.10.0",
-          "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz",
-          "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==",
-          "dev": true,
-          "requires": {
-            "es-to-primitive": "1.1.1",
-            "function-bind": "1.1.1",
-            "has": "1.0.1",
-            "is-callable": "1.1.3",
-            "is-regex": "1.0.4"
-          }
-        },
-        "es-to-primitive": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
-          "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
-          "dev": true,
-          "requires": {
-            "is-callable": "1.1.3",
-            "is-date-object": "1.0.1",
-            "is-symbol": "1.0.1"
-          }
-        },
-        "esutils": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
-          "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
-          "dev": true
-        },
-        "foreach": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
-          "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
-          "dev": true
-        },
-        "function-bind": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-          "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-          "dev": true
-        },
-        "has": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
-          "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
-          "dev": true,
-          "requires": {
-            "function-bind": "1.1.1"
-          }
-        },
-        "is-callable": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
-          "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
-          "dev": true
-        },
-        "is-date-object": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
-          "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
-          "dev": true
-        },
-        "is-regex": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
-          "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
-          "dev": true,
-          "requires": {
-            "has": "1.0.1"
-          }
-        },
-        "is-symbol": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
-          "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
-          "dev": true
-        },
-        "jsx-ast-utils": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz",
-          "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=",
-          "dev": true,
-          "requires": {
-            "array-includes": "3.0.3"
-          }
-        },
-        "object-keys": {
-          "version": "1.0.11",
-          "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
-          "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
-          "dev": true
-        }
-      }
-    },
-    "eventemitter2": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz",
-      "integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU="
-    },
-    "flat": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/flat/-/flat-4.0.0.tgz",
-      "integrity": "sha512-ji/WMv2jdsE+LaznpkIF9Haax0sdpTBozrz/Dtg4qSRMfbs8oVg4ypJunIRYPiMLvH/ed6OflXbnbTIKJhtgeg==",
-      "requires": {
-        "is-buffer": "1.1.6"
-      },
-      "dependencies": {
-        "is-buffer": {
-          "version": "1.1.6",
-          "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
-          "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
-        }
-      }
-    },
-    "has-symbols": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
-      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
-      "dev": true
-    },
-    "hiredis": {
-      "version": "0.5.0",
-      "resolved": "https://registry.npmjs.org/hiredis/-/hiredis-0.5.0.tgz",
-      "integrity": "sha1-2wOpi+zXAD0TwmAEOs7s+s31m4c=",
-      "requires": {
-        "bindings": "1.3.0",
-        "nan": "2.8.0"
-      },
-      "dependencies": {
-        "bindings": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
-          "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw=="
-        },
-        "nan": {
-          "version": "2.8.0",
-          "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
-          "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo="
-        }
-      }
-    },
-    "history": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz",
-      "integrity": "sha1-/O3M6PEpdTcVRdc1RhAzV5ptrpw=",
-      "requires": {
-        "invariant": "2.2.2",
-        "loose-envify": "1.3.1",
-        "query-string": "4.3.4",
-        "warning": "3.0.0"
-      },
-      "dependencies": {
-        "invariant": {
-          "version": "2.2.2",
-          "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
-          "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
-          "requires": {
-            "loose-envify": "1.3.1"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
-        },
-        "loose-envify": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-          "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-          "requires": {
-            "js-tokens": "3.0.2"
-          }
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-        },
-        "query-string": {
-          "version": "4.3.4",
-          "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
-          "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
-          "requires": {
-            "object-assign": "4.1.1",
-            "strict-uri-encode": "1.1.0"
-          }
-        },
-        "strict-uri-encode": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
-          "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
-        },
-        "warning": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
-          "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
-          "requires": {
-            "loose-envify": "1.3.1"
-          }
-        }
-      }
-    },
-    "husky": {
-      "version": "0.14.3",
-      "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz",
-      "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==",
-      "dev": true,
-      "requires": {
-        "is-ci": "1.1.0",
-        "normalize-path": "1.0.0",
-        "strip-indent": "2.0.0"
-      },
-      "dependencies": {
-        "ci-info": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz",
-          "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==",
-          "dev": true
-        },
-        "is-ci": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
-          "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
-          "dev": true,
-          "requires": {
-            "ci-info": "1.1.2"
-          }
-        },
-        "normalize-path": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz",
-          "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=",
-          "dev": true
-        },
-        "strip-indent": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
-          "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
-          "dev": true
-        }
-      }
-    },
-    "immutability-helper": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/immutability-helper/-/immutability-helper-2.4.0.tgz",
-      "integrity": "sha512-rW/L/56ZMo9NStMK85kFrUFFGy4NeJbCdhfrDHIZrFfxYtuwuxD+dT3mWMcdmrNO61hllc60AeGglCRhfZ1dZw==",
-      "requires": {
-        "invariant": "2.2.2"
-      },
-      "dependencies": {
-        "invariant": {
-          "version": "2.2.2",
-          "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
-          "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
-          "requires": {
-            "loose-envify": "1.3.1"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
-        },
-        "loose-envify": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-          "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-          "requires": {
-            "js-tokens": "3.0.2"
-          }
-        }
-      }
-    },
-    "inherits": {
-      "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
-    },
-    "lint-staged": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-4.3.0.tgz",
-      "integrity": "sha512-C/Zxslg0VRbsxwmCu977iIs+QyrmW2cyRCPUV5NDFYOH/jtRFHH8ch7ua2fH0voI/nVC3Tpg7DykfgMZySliKw==",
-      "dev": true,
-      "requires": {
-        "app-root-path": "2.0.1",
-        "chalk": "2.3.0",
-        "commander": "2.12.2",
-        "cosmiconfig": "1.1.0",
-        "execa": "0.8.0",
-        "is-glob": "4.0.0",
-        "jest-validate": "21.2.1",
-        "listr": "0.12.0",
-        "lodash": "4.17.4",
-        "log-symbols": "2.1.0",
-        "minimatch": "3.0.4",
-        "npm-which": "3.0.1",
-        "p-map": "1.2.0",
-        "staged-git-files": "0.0.4",
-        "stringify-object": "3.2.1"
-      },
-      "dependencies": {
-        "ansi-escapes": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
-          "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
-          "dev": true
-        },
-        "ansi-regex": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.1"
-          }
-        },
-        "app-root-path": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz",
-          "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=",
-          "dev": true
-        },
-        "argparse": {
-          "version": "1.0.9",
-          "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
-          "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
-          "dev": true,
-          "requires": {
-            "sprintf-js": "1.0.3"
-          }
-        },
-        "balanced-match": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "dev": true
-        },
-        "brace-expansion": {
-          "version": "1.1.8",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
-          "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
-          "dev": true,
-          "requires": {
-            "balanced-match": "1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
-          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.5.0"
-          }
-        },
-        "cli-cursor": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
-          "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
-          "dev": true,
-          "requires": {
-            "restore-cursor": "1.0.1"
-          }
-        },
-        "cli-spinners": {
-          "version": "0.1.2",
-          "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz",
-          "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=",
-          "dev": true
-        },
-        "cli-truncate": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
-          "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
-          "dev": true,
-          "requires": {
-            "slice-ansi": "0.0.4",
-            "string-width": "1.0.2"
-          }
-        },
-        "code-point-at": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
-          "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
-          "dev": true
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "commander": {
-          "version": "2.12.2",
-          "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
-          "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
-          "dev": true
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "dev": true
-        },
-        "cosmiconfig": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-1.1.0.tgz",
-          "integrity": "sha1-DeoPmATv37kp+7GxiOJVU+oFPTc=",
-          "dev": true,
-          "requires": {
-            "graceful-fs": "4.1.11",
-            "js-yaml": "3.10.0",
-            "minimist": "1.2.0",
-            "object-assign": "4.1.1",
-            "os-homedir": "1.0.2",
-            "parse-json": "2.2.0",
-            "pinkie-promise": "2.0.1",
-            "require-from-string": "1.2.1"
-          }
-        },
-        "cross-spawn": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
-          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
-          "dev": true,
-          "requires": {
-            "lru-cache": "4.1.1",
-            "shebang-command": "1.2.0",
-            "which": "1.3.0"
-          }
-        },
-        "date-fns": {
-          "version": "1.29.0",
-          "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
-          "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==",
-          "dev": true
-        },
-        "elegant-spinner": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
-          "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=",
-          "dev": true
-        },
-        "error-ex": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
-          "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
-          "dev": true,
-          "requires": {
-            "is-arrayish": "0.2.1"
-          }
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "esprima": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
-          "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
-          "dev": true
-        },
-        "execa": {
-          "version": "0.8.0",
-          "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz",
-          "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=",
-          "dev": true,
-          "requires": {
-            "cross-spawn": "5.1.0",
-            "get-stream": "3.0.0",
-            "is-stream": "1.1.0",
-            "npm-run-path": "2.0.2",
-            "p-finally": "1.0.0",
-            "signal-exit": "3.0.2",
-            "strip-eof": "1.0.0"
-          }
-        },
-        "exit-hook": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
-          "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
-          "dev": true
-        },
-        "figures": {
-          "version": "1.7.0",
-          "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
-          "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
-          "dev": true,
-          "requires": {
-            "escape-string-regexp": "1.0.5",
-            "object-assign": "4.1.1"
-          }
-        },
-        "get-own-enumerable-property-symbols": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz",
-          "integrity": "sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug==",
-          "dev": true
-        },
-        "get-stream": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
-          "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
-          "dev": true
-        },
-        "graceful-fs": {
-          "version": "4.1.11",
-          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
-          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
-          "dev": true
-        },
-        "has-ansi": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
-          "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "2.1.1"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "2.1.1",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-              "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-              "dev": true
-            }
-          }
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "indent-string": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
-          "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
-          "dev": true,
-          "requires": {
-            "repeating": "2.0.1"
-          }
-        },
-        "is-arrayish": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-          "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=",
-          "dev": true
-        },
-        "is-extglob": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
-          "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
-          "dev": true
-        },
-        "is-finite": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
-          "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
-          "dev": true,
-          "requires": {
-            "number-is-nan": "1.0.1"
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
-          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
-          "dev": true,
-          "requires": {
-            "number-is-nan": "1.0.1"
-          }
-        },
-        "is-glob": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
-          "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
-          "dev": true,
-          "requires": {
-            "is-extglob": "2.1.1"
-          }
-        },
-        "is-obj": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
-          "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
-          "dev": true
-        },
-        "is-promise": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
-          "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
-          "dev": true
-        },
-        "is-regexp": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
-          "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
-          "dev": true
-        },
-        "is-stream": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-          "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
-          "dev": true
-        },
-        "isexe": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-          "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
-          "dev": true
-        },
-        "jest-get-type": {
-          "version": "21.2.0",
-          "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz",
-          "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==",
-          "dev": true
-        },
-        "jest-validate": {
-          "version": "21.2.1",
-          "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz",
-          "integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.3.0",
-            "jest-get-type": "21.2.0",
-            "leven": "2.1.0",
-            "pretty-format": "21.2.1"
-          }
-        },
-        "js-yaml": {
-          "version": "3.10.0",
-          "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
-          "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
-          "dev": true,
-          "requires": {
-            "argparse": "1.0.9",
-            "esprima": "4.0.0"
-          }
-        },
-        "leven": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
-          "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=",
-          "dev": true
-        },
-        "listr": {
-          "version": "0.12.0",
-          "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz",
-          "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=",
-          "dev": true,
-          "requires": {
-            "chalk": "1.1.3",
-            "cli-truncate": "0.2.1",
-            "figures": "1.7.0",
-            "indent-string": "2.1.0",
-            "is-promise": "2.1.0",
-            "is-stream": "1.1.0",
-            "listr-silent-renderer": "1.1.1",
-            "listr-update-renderer": "0.2.0",
-            "listr-verbose-renderer": "0.4.1",
-            "log-symbols": "1.0.2",
-            "log-update": "1.0.2",
-            "ora": "0.2.3",
-            "p-map": "1.2.0",
-            "rxjs": "5.5.6",
-            "stream-to-observable": "0.1.0",
-            "strip-ansi": "3.0.1"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "2.2.1",
-              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-              "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-              "dev": true
-            },
-            "chalk": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-              "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "2.2.1",
-                "escape-string-regexp": "1.0.5",
-                "has-ansi": "2.0.0",
-                "strip-ansi": "3.0.1",
-                "supports-color": "2.0.0"
-              }
-            },
-            "log-symbols": {
-              "version": "1.0.2",
-              "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
-              "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
-              "dev": true,
-              "requires": {
-                "chalk": "1.1.3"
-              }
-            },
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "listr-silent-renderer": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
-          "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
-          "dev": true
-        },
-        "listr-update-renderer": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz",
-          "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=",
-          "dev": true,
-          "requires": {
-            "chalk": "1.1.3",
-            "cli-truncate": "0.2.1",
-            "elegant-spinner": "1.0.1",
-            "figures": "1.7.0",
-            "indent-string": "3.2.0",
-            "log-symbols": "1.0.2",
-            "log-update": "1.0.2",
-            "strip-ansi": "3.0.1"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "2.2.1",
-              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-              "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-              "dev": true
-            },
-            "chalk": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-              "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "2.2.1",
-                "escape-string-regexp": "1.0.5",
-                "has-ansi": "2.0.0",
-                "strip-ansi": "3.0.1",
-                "supports-color": "2.0.0"
-              }
-            },
-            "indent-string": {
-              "version": "3.2.0",
-              "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
-              "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
-              "dev": true
-            },
-            "log-symbols": {
-              "version": "1.0.2",
-              "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
-              "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
-              "dev": true,
-              "requires": {
-                "chalk": "1.1.3"
-              }
-            },
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "listr-verbose-renderer": {
-          "version": "0.4.1",
-          "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz",
-          "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=",
-          "dev": true,
-          "requires": {
-            "chalk": "1.1.3",
-            "cli-cursor": "1.0.2",
-            "date-fns": "1.29.0",
-            "figures": "1.7.0"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "2.2.1",
-              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-              "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-              "dev": true
-            },
-            "chalk": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-              "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "2.2.1",
-                "escape-string-regexp": "1.0.5",
-                "has-ansi": "2.0.0",
-                "strip-ansi": "3.0.1",
-                "supports-color": "2.0.0"
-              }
-            },
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "log-symbols": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.1.0.tgz",
-          "integrity": "sha512-zLeLrzMA1A2vRF1e/0Mo+LNINzi6jzBylHj5WqvQ/WK/5WCZt8si9SyN4p9llr/HRYvVR1AoXHRHl4WTHyQAzQ==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.3.0"
-          }
-        },
-        "log-update": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz",
-          "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=",
-          "dev": true,
-          "requires": {
-            "ansi-escapes": "1.4.0",
-            "cli-cursor": "1.0.2"
-          }
-        },
-        "lru-cache": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
-          "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
-          "dev": true,
-          "requires": {
-            "pseudomap": "1.0.2",
-            "yallist": "2.1.2"
-          }
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "1.1.8"
-          }
-        },
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
-          "dev": true
-        },
-        "npm-path": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz",
-          "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==",
-          "dev": true,
-          "requires": {
-            "which": "1.3.0"
-          }
-        },
-        "npm-run-path": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
-          "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
-          "dev": true,
-          "requires": {
-            "path-key": "2.0.1"
-          }
-        },
-        "npm-which": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz",
-          "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=",
-          "dev": true,
-          "requires": {
-            "commander": "2.12.2",
-            "npm-path": "2.0.4",
-            "which": "1.3.0"
-          }
-        },
-        "number-is-nan": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-          "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
-          "dev": true
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
-          "dev": true
-        },
-        "onetime": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
-          "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
-          "dev": true
-        },
-        "ora": {
-          "version": "0.2.3",
-          "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz",
-          "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=",
-          "dev": true,
-          "requires": {
-            "chalk": "1.1.3",
-            "cli-cursor": "1.0.2",
-            "cli-spinners": "0.1.2",
-            "object-assign": "4.1.1"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "2.2.1",
-              "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-              "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-              "dev": true
-            },
-            "chalk": {
-              "version": "1.1.3",
-              "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-              "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-              "dev": true,
-              "requires": {
-                "ansi-styles": "2.2.1",
-                "escape-string-regexp": "1.0.5",
-                "has-ansi": "2.0.0",
-                "strip-ansi": "3.0.1",
-                "supports-color": "2.0.0"
-              }
-            },
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "os-homedir": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-          "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
-          "dev": true
-        },
-        "p-finally": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
-          "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
-          "dev": true
-        },
-        "p-map": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
-          "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
-          "dev": true
-        },
-        "parse-json": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
-          "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
-          "dev": true,
-          "requires": {
-            "error-ex": "1.3.1"
-          }
-        },
-        "path-key": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
-          "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
-          "dev": true
-        },
-        "pinkie": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-          "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
-          "dev": true
-        },
-        "pinkie-promise": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
-          "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-          "dev": true,
-          "requires": {
-            "pinkie": "2.0.4"
-          }
-        },
-        "pretty-format": {
-          "version": "21.2.1",
-          "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz",
-          "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "3.0.0",
-            "ansi-styles": "3.2.0"
-          }
-        },
-        "pseudomap": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-          "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
-          "dev": true
-        },
-        "repeating": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
-          "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
-          "dev": true,
-          "requires": {
-            "is-finite": "1.0.2"
-          }
-        },
-        "require-from-string": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
-          "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
-          "dev": true
-        },
-        "restore-cursor": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
-          "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
-          "dev": true,
-          "requires": {
-            "exit-hook": "1.1.1",
-            "onetime": "1.1.0"
-          }
-        },
-        "rxjs": {
-          "version": "5.5.6",
-          "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz",
-          "integrity": "sha512-v4Q5HDC0FHAQ7zcBX7T2IL6O5ltl1a2GX4ENjPXg6SjDY69Cmx9v4113C99a4wGF16ClPv5Z8mghuYorVkg/kg==",
-          "dev": true,
-          "requires": {
-            "symbol-observable": "1.0.1"
-          }
-        },
-        "shebang-command": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
-          "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
-          "dev": true,
-          "requires": {
-            "shebang-regex": "1.0.0"
-          }
-        },
-        "shebang-regex": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
-          "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
-          "dev": true
-        },
-        "signal-exit": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-          "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
-          "dev": true
-        },
+        "array-uniq": "1.0.3"
+      }
+    },
+    "array-uniq": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+      "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+      "dev": true
+    },
+    "arrify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+      "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+      "dev": true
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+    },
+    "asn1": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
+      "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+    },
+    "assertion-error": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+      "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+      "dev": true
+    },
+    "ast-types-flow": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
+      "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=",
+      "dev": true
+    },
+    "async": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
+      "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k="
+    },
+    "async-foreach": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI="
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+    },
+    "atob": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz",
+      "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=",
+      "dev": true
+    },
+    "attr-accept": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/attr-accept/-/attr-accept-1.1.0.tgz",
+      "integrity": "sha1-tc01In8WOTWo8d4Q7T66FpQfa+Y="
+    },
+    "autoprefixer": {
+      "version": "7.1.6",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.1.6.tgz",
+      "integrity": "sha512-C9yv/UF3X+eJTi/zvfxuyfxmLibYrntpF3qoJYrMeQwgUJOZrZvpJiMG2FMQ3qnhWtF/be4pYONBBw95ZGe3vA==",
+      "dev": true,
+      "requires": {
+        "browserslist": "2.11.3",
+        "caniuse-lite": "1.0.30000792",
+        "normalize-range": "0.1.2",
+        "num2fraction": "1.2.2",
+        "postcss": "6.0.16",
+        "postcss-value-parser": "3.3.0"
+      }
+    },
+    "autosize": {
+      "version": "3.0.21",
+      "resolved": "https://registry.npmjs.org/autosize/-/autosize-3.0.21.tgz",
+      "integrity": "sha1-8YL0DRd1fZeKE5pMnKQMTA5EhgM="
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+    },
+    "aws4": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
+      "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
+    },
+    "axobject-query": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-0.1.0.tgz",
+      "integrity": "sha1-YvWdvFnJ+SQnWco0mWDnov48NsA=",
+      "dev": true,
+      "requires": {
+        "ast-types-flow": "0.0.7"
+      }
+    },
+    "babel-code-frame": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+      "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "esutils": "2.0.2",
+        "js-tokens": "3.0.2"
+      }
+    },
+    "babel-plugin-react-remove-properties": {
+      "version": "0.2.5",
+      "resolved": "https://registry.npmjs.org/babel-plugin-react-remove-properties/-/babel-plugin-react-remove-properties-0.2.5.tgz",
+      "integrity": "sha1-wHbhKRlAxzD0+337ZwaR/EF4fPg=",
+      "dev": true
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "2.5.3",
+        "regenerator-runtime": "0.11.1"
+      }
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
+      "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
+      "optional": true,
+      "requires": {
+        "tweetnacl": "0.14.5"
+      }
+    },
+    "bignumber.js": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-2.4.0.tgz",
+      "integrity": "sha1-g4qZLan51zfg9LLbC+YrsJ3Qxeg=",
+      "dev": true
+    },
+    "bindings": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
+      "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw=="
+    },
+    "bl": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz",
+      "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.3"
+      }
+    },
+    "block-stream": {
+      "version": "0.0.9",
+      "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+      "requires": {
+        "inherits": "2.0.3"
+      }
+    },
+    "bmp-js": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/bmp-js/-/bmp-js-0.0.3.tgz",
+      "integrity": "sha1-ZBE+nHzxICs3btYHvzBibr5XsYo=",
+      "dev": true
+    },
+    "boom": {
+      "version": "4.3.1",
+      "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+      "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+      "requires": {
+        "hoek": "4.2.0"
+      }
+    },
+    "brace-expansion": {
+      "version": "1.1.8",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+      "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+      "requires": {
+        "balanced-match": "1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "browserslist": {
+      "version": "2.11.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.11.3.tgz",
+      "integrity": "sha512-yWu5cXT7Av6mVwzWc8lMsJMHWn4xyjSuGYi4IozbVTLUOEYPSagUB8kiMDUHA1fS3zjr8nkxkn9jdvug4BBRmA==",
+      "dev": true,
+      "requires": {
+        "caniuse-lite": "1.0.30000792",
+        "electron-to-chromium": "1.3.31"
+      }
+    },
+    "buffer-crc32": {
+      "version": "0.2.13",
+      "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+      "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+      "dev": true
+    },
+    "buffer-equal": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-0.0.1.tgz",
+      "integrity": "sha1-kbx0sR6kBbyRa8aqkI+q+ltKrEs=",
+      "dev": true
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
+    },
+    "caller-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
+      "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
+      "dev": true,
+      "requires": {
+        "callsites": "0.2.0"
+      }
+    },
+    "callsites": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
+      "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=",
+      "dev": true
+    },
+    "camelcase": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+      "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
+    },
+    "camelcase-keys": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "requires": {
+        "camelcase": "2.1.1",
+        "map-obj": "1.0.1"
+      }
+    },
+    "caniuse-lite": {
+      "version": "1.0.30000792",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000792.tgz",
+      "integrity": "sha1-0M6pgfgRjzlhRxr7tDyaHlu/AzI=",
+      "dev": true
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+    },
+    "chai": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/chai/-/chai-4.1.2.tgz",
+      "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=",
+      "dev": true,
+      "requires": {
+        "assertion-error": "1.1.0",
+        "check-error": "1.0.2",
+        "deep-eql": "3.0.1",
+        "get-func-name": "2.0.0",
+        "pathval": "1.1.0",
+        "type-detect": "4.0.7"
+      }
+    },
+    "chain-function": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.0.tgz",
+      "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w="
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "requires": {
+        "ansi-styles": "2.2.1",
+        "escape-string-regexp": "1.0.5",
+        "has-ansi": "2.0.0",
+        "strip-ansi": "3.0.1",
+        "supports-color": "2.0.0"
+      }
+    },
+    "chardet": {
+      "version": "0.4.2",
+      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+      "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+      "dev": true
+    },
+    "check-error": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+      "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+      "dev": true
+    },
+    "ci-info": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.2.tgz",
+      "integrity": "sha512-uTGIPNx/nSpBdsF6xnseRXLLtfr9VLqkz8ZqHXr3Y7b6SftyRxBGjwMtJj1OhNbmlc1wZzLNAlAcvyIiE8a6ZA==",
+      "dev": true
+    },
+    "circular-json": {
+      "version": "0.3.3",
+      "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
+      "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==",
+      "dev": true
+    },
+    "classnames": {
+      "version": "2.2.5",
+      "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz",
+      "integrity": "sha1-+zgB1FNGdknvNgPH1hoCvRKb3m0="
+    },
+    "cli-cursor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+      "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+      "dev": true,
+      "requires": {
+        "restore-cursor": "2.0.0"
+      }
+    },
+    "cli-spinners": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz",
+      "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=",
+      "dev": true
+    },
+    "cli-truncate": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz",
+      "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=",
+      "dev": true,
+      "requires": {
+        "slice-ansi": "0.0.4",
+        "string-width": "1.0.2"
+      },
+      "dependencies": {
         "slice-ansi": {
           "version": "0.0.4",
           "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
           "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
           "dev": true
-        },
-        "sprintf-js": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-          "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
-          "dev": true
-        },
-        "staged-git-files": {
-          "version": "0.0.4",
-          "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-0.0.4.tgz",
-          "integrity": "sha1-15fhtVHKemOd7AI33G60u5vhfTU=",
-          "dev": true
-        },
-        "stream-to-observable": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz",
-          "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=",
-          "dev": true
-        },
-        "string-width": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
-          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
-          "dev": true,
-          "requires": {
-            "code-point-at": "1.1.0",
-            "is-fullwidth-code-point": "1.0.0",
-            "strip-ansi": "3.0.1"
-          }
-        },
-        "stringify-object": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.1.tgz",
-          "integrity": "sha512-jPcQYw/52HUPP8uOE4kkjxl5bB9LfHkKCTptIk3qw7ozP5XMIMlHMLjt00GGSwW6DJAf/njY5EU6Vpwl4LlBKQ==",
-          "dev": true,
-          "requires": {
-            "get-own-enumerable-property-symbols": "2.0.1",
-            "is-obj": "1.0.1",
-            "is-regexp": "1.0.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "2.1.1"
-          },
-          "dependencies": {
-            "ansi-regex": {
-              "version": "2.1.1",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-              "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-              "dev": true
-            }
-          }
-        },
-        "strip-eof": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
-          "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "4.5.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
-          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        },
-        "symbol-observable": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
-          "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=",
-          "dev": true
-        },
-        "which": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
-          "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+        }
+      }
+    },
+    "cli-width": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+      "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+      "dev": true
+    },
+    "clipboard": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-1.7.1.tgz",
+      "integrity": "sha1-Ng1taUbpmnof7zleQrqStem1oWs=",
+      "requires": {
+        "good-listener": "1.2.2",
+        "select": "1.1.2",
+        "tiny-emitter": "2.0.2"
+      }
+    },
+    "cliui": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+      "requires": {
+        "string-width": "1.0.2",
+        "strip-ansi": "3.0.1",
+        "wrap-ansi": "2.1.0"
+      }
+    },
+    "co": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
+      "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+    },
+    "color-convert": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+      "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "colors": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+      "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs="
+    },
+    "combined-stream": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
+      "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+      "requires": {
+        "delayed-stream": "1.0.0"
+      }
+    },
+    "commander": {
+      "version": "2.13.0",
+      "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
+      "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
+      "dev": true
+    },
+    "compress-commons": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz",
+      "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=",
+      "dev": true,
+      "requires": {
+        "buffer-crc32": "0.2.13",
+        "crc32-stream": "2.0.0",
+        "normalize-path": "2.1.1",
+        "readable-stream": "2.3.3"
+      },
+      "dependencies": {
+        "normalize-path": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
           "dev": true,
           "requires": {
-            "isexe": "2.0.0"
+            "remove-trailing-separator": "1.1.0"
           }
-        },
-        "yallist": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
-          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+        }
+      }
+    },
+    "computed-style": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/computed-style/-/computed-style-0.1.4.tgz",
+      "integrity": "sha1-fzRP2FhLLkJb7cpKGvwOMAuwXXQ="
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    },
+    "concat-stream": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+      "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "readable-stream": "2.3.3",
+        "typedarray": "0.0.6"
+      }
+    },
+    "console-control-strings": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+    },
+    "contains-path": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz",
+      "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=",
+      "dev": true
+    },
+    "core-js": {
+      "version": "2.5.3",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
+      "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4="
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+    },
+    "cosmiconfig": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-1.1.0.tgz",
+      "integrity": "sha1-DeoPmATv37kp+7GxiOJVU+oFPTc=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "js-yaml": "3.10.0",
+        "minimist": "1.2.0",
+        "object-assign": "4.1.1",
+        "os-homedir": "1.0.2",
+        "parse-json": "2.2.0",
+        "pinkie-promise": "2.0.1",
+        "require-from-string": "1.2.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
           "dev": true
         }
       }
     },
-    "lodash": {
-      "version": "4.17.4",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
-      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+    "crc": {
+      "version": "3.5.0",
+      "resolved": "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz",
+      "integrity": "sha1-mLi6fUiWZbo5efWbITgTdBAaGWQ=",
+      "dev": true
     },
-    "meteor-node-stubs": {
-      "version": "0.3.2",
-      "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-0.3.2.tgz",
-      "integrity": "sha512-l93SS/HutbqBRJODO2m7hup8cYI2acF5bB39+ZvP2BX8HMmCSCXeFH7v0sr4hD7zrVvHQA5UqS0pcDYKn0VM6g==",
+    "crc32-stream": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
+      "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
+      "dev": true,
       "requires": {
-        "assert": "1.4.1",
-        "browserify-zlib": "0.1.4",
-        "buffer": "4.9.1",
-        "console-browserify": "1.1.0",
-        "constants-browserify": "1.0.0",
-        "crypto-browserify": "3.11.1",
-        "domain-browser": "1.1.7",
-        "events": "1.1.1",
-        "http-browserify": "1.7.0",
-        "https-browserify": "0.0.1",
-        "os-browserify": "0.2.1",
-        "path-browserify": "0.0.0",
-        "process": "0.11.10",
-        "punycode": "1.4.1",
-        "querystring-es3": "0.2.1",
-        "readable-stream": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502",
-        "stream-browserify": "2.0.1",
-        "string_decoder": "1.0.3",
-        "timers-browserify": "1.4.2",
-        "tty-browserify": "0.0.0",
-        "url": "0.11.0",
-        "util": "0.10.3",
-        "vm-browserify": "0.0.4"
+        "crc": "3.5.0",
+        "readable-stream": "2.3.3"
+      }
+    },
+    "create-react-class": {
+      "version": "15.6.2",
+      "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz",
+      "integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=",
+      "requires": {
+        "fbjs": "0.8.16",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1"
+      }
+    },
+    "cross-spawn": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+      "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+      "requires": {
+        "lru-cache": "4.1.1",
+        "which": "1.3.0"
+      }
+    },
+    "cryptiles": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+      "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+      "requires": {
+        "boom": "5.2.0"
       },
       "dependencies": {
-        "Base64": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/Base64/-/Base64-0.2.1.tgz",
-          "integrity": "sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg="
-        },
-        "asn1.js": {
-          "version": "4.9.1",
-          "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz",
-          "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=",
-          "requires": {
-            "bn.js": "4.11.8",
-            "inherits": "2.0.1",
-            "minimalistic-assert": "1.0.0"
-          }
-        },
-        "assert": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
-          "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
-          "requires": {
-            "util": "0.10.3"
-          }
-        },
-        "balanced-match": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
-        },
-        "base64-js": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
-          "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw=="
-        },
-        "bn.js": {
-          "version": "4.11.8",
-          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
-          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
-        },
-        "brace-expansion": {
-          "version": "1.1.8",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
-          "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
-          "requires": {
-            "balanced-match": "1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "brorand": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
-          "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
-        },
-        "browserify-aes": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.0.tgz",
-          "integrity": "sha512-W2bIMLYoZ9oow7TyePpMJk9l9LY7O3R61a/68bVCDOtnJynnwe3ZeW2IzzSkrQnPKNdJrxVDn3ALZNisSBwb7g==",
-          "requires": {
-            "buffer-xor": "1.0.3",
-            "cipher-base": "1.0.4",
-            "create-hash": "1.1.3",
-            "evp_bytestokey": "1.0.3",
-            "inherits": "2.0.1",
-            "safe-buffer": "5.1.1"
-          }
-        },
-        "browserify-cipher": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
-          "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
-          "requires": {
-            "browserify-aes": "1.1.0",
-            "browserify-des": "1.0.0",
-            "evp_bytestokey": "1.0.3"
-          }
-        },
-        "browserify-des": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
-          "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
-          "requires": {
-            "cipher-base": "1.0.4",
-            "des.js": "1.0.0",
-            "inherits": "2.0.1"
-          }
-        },
-        "browserify-rsa": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
-          "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
+        "boom": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
+          "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
           "requires": {
-            "bn.js": "4.11.8",
-            "randombytes": "2.0.5"
+            "hoek": "4.2.0"
           }
-        },
-        "browserify-sign": {
-          "version": "4.0.4",
-          "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
-          "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
+        }
+      }
+    },
+    "css": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz",
+      "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=",
+      "dev": true,
+      "requires": {
+        "inherits": "2.0.3",
+        "source-map": "0.1.43",
+        "source-map-resolve": "0.3.1",
+        "urix": "0.1.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.1.43",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
+          "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
+          "dev": true,
           "requires": {
-            "bn.js": "4.11.8",
-            "browserify-rsa": "4.0.1",
-            "create-hash": "1.1.3",
-            "create-hmac": "1.1.6",
-            "elliptic": "6.4.0",
-            "inherits": "2.0.1",
-            "parse-asn1": "5.1.0"
+            "amdefine": "1.0.1"
           }
+        }
+      }
+    },
+    "css-parse": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz",
+      "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=",
+      "dev": true,
+      "requires": {
+        "css": "2.2.1"
+      }
+    },
+    "css-selector-tokenizer": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
+      "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
+      "dev": true,
+      "requires": {
+        "cssesc": "0.1.0",
+        "fastparse": "1.1.1",
+        "regexpu-core": "1.0.0"
+      }
+    },
+    "css-value": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz",
+      "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=",
+      "dev": true
+    },
+    "cssesc": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
+      "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
+      "dev": true
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "requires": {
+        "array-find-index": "1.0.2"
+      }
+    },
+    "cycle": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
+      "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI="
+    },
+    "damerau-levenshtein": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.4.tgz",
+      "integrity": "sha1-AxkcQyy27qFou3fzpV/9zLiXhRQ=",
+      "dev": true
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "requires": {
+        "assert-plus": "1.0.0"
+      }
+    },
+    "date-fns": {
+      "version": "1.29.0",
+      "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
+      "integrity": "sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw==",
+      "dev": true
+    },
+    "date-format": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/date-format/-/date-format-0.0.2.tgz",
+      "integrity": "sha1-+v1Ej3IRXvHitzkVWukvK+bCjdE=",
+      "dev": true
+    },
+    "debug": {
+      "version": "2.6.9",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+      "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+      "requires": {
+        "ms": "2.0.0"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+    },
+    "decompress-response": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+      "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+      "requires": {
+        "mimic-response": "1.0.0"
+      }
+    },
+    "deep-eql": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+      "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+      "dev": true,
+      "requires": {
+        "type-detect": "4.0.7"
+      }
+    },
+    "deep-is": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+      "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+      "dev": true
+    },
+    "deepmerge": {
+      "version": "1.5.2",
+      "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
+      "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ=="
+    },
+    "define-properties": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
+      "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
+      "dev": true,
+      "requires": {
+        "foreach": "2.0.5",
+        "object-keys": "1.0.11"
+      }
+    },
+    "del": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
+      "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
+      "dev": true,
+      "requires": {
+        "globby": "5.0.0",
+        "is-path-cwd": "1.0.0",
+        "is-path-in-cwd": "1.0.0",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "rimraf": "2.6.2"
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+    },
+    "delegate": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz",
+      "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw=="
+    },
+    "delegates": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+    },
+    "doctrine": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+      "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
+      "dev": true,
+      "requires": {
+        "esutils": "2.0.2"
+      }
+    },
+    "dom-helpers": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz",
+      "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg=="
+    },
+    "dom-walk": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
+      "integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=",
+      "dev": true
+    },
+    "double-ended-queue": {
+      "version": "2.1.0-0",
+      "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
+      "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw="
+    },
+    "duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
+    },
+    "ecc-jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
+      "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
+      "optional": true,
+      "requires": {
+        "jsbn": "0.1.1"
+      }
+    },
+    "ejs": {
+      "version": "2.5.7",
+      "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz",
+      "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=",
+      "dev": true
+    },
+    "electron-to-chromium": {
+      "version": "1.3.31",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.31.tgz",
+      "integrity": "sha512-XE4CLbswkZgZFn34cKFy1xaX+F5LHxeDLjY1+rsK9asDzknhbrd9g/n/01/acbU25KTsUSiLKwvlLyA+6XLUOA==",
+      "dev": true
+    },
+    "elegant-spinner": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz",
+      "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=",
+      "dev": true
+    },
+    "emoji-regex": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz",
+      "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==",
+      "dev": true
+    },
+    "encoding": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
+      "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
+      "requires": {
+        "iconv-lite": "0.4.19"
+      }
+    },
+    "end-of-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "dev": true,
+      "requires": {
+        "once": "1.4.0"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
+      "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+      "requires": {
+        "is-arrayish": "0.2.1"
+      }
+    },
+    "es-abstract": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz",
+      "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==",
+      "dev": true,
+      "requires": {
+        "es-to-primitive": "1.1.1",
+        "function-bind": "1.1.1",
+        "has": "1.0.1",
+        "is-callable": "1.1.3",
+        "is-regex": "1.0.4"
+      }
+    },
+    "es-to-primitive": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz",
+      "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
+      "dev": true,
+      "requires": {
+        "is-callable": "1.1.3",
+        "is-date-object": "1.0.1",
+        "is-symbol": "1.0.1"
+      }
+    },
+    "es6-promise": {
+      "version": "3.3.1",
+      "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.3.1.tgz",
+      "integrity": "sha1-oIzd6EzNvzTQJ6FFG8kdS80ophM=",
+      "dev": true
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+    },
+    "eslint": {
+      "version": "4.9.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.9.0.tgz",
+      "integrity": "sha1-doedJ0BoJhsZH+Dy9Wx0wvQgjos=",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "babel-code-frame": "6.26.0",
+        "chalk": "2.3.0",
+        "concat-stream": "1.6.0",
+        "cross-spawn": "5.1.0",
+        "debug": "3.1.0",
+        "doctrine": "2.1.0",
+        "eslint-scope": "3.7.1",
+        "espree": "3.5.2",
+        "esquery": "1.0.0",
+        "estraverse": "4.2.0",
+        "esutils": "2.0.2",
+        "file-entry-cache": "2.0.0",
+        "functional-red-black-tree": "1.0.1",
+        "glob": "7.1.2",
+        "globals": "9.18.0",
+        "ignore": "3.3.7",
+        "imurmurhash": "0.1.4",
+        "inquirer": "3.3.0",
+        "is-resolvable": "1.1.0",
+        "js-yaml": "3.10.0",
+        "json-stable-stringify": "1.0.1",
+        "levn": "0.3.0",
+        "lodash": "4.17.4",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "natural-compare": "1.4.0",
+        "optionator": "0.8.2",
+        "path-is-inside": "1.0.2",
+        "pluralize": "7.0.0",
+        "progress": "2.0.0",
+        "require-uncached": "1.0.3",
+        "semver": "5.5.0",
+        "strip-ansi": "4.0.0",
+        "strip-json-comments": "2.0.1",
+        "table": "4.0.2",
+        "text-table": "0.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
         },
-        "browserify-zlib": {
-          "version": "0.1.4",
-          "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
-          "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
           "requires": {
-            "pako": "0.2.9"
+            "color-convert": "1.9.1"
           }
         },
-        "buffer": {
-          "version": "4.9.1",
-          "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
-          "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
           "requires": {
-            "base64-js": "1.2.1",
-            "ieee754": "1.1.8",
-            "isarray": "1.0.0"
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
           }
         },
-        "buffer-xor": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
-          "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
-        },
-        "cipher-base": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
-          "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
+        "cross-spawn": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+          "dev": true,
           "requires": {
-            "inherits": "2.0.1",
-            "safe-buffer": "5.1.1"
+            "lru-cache": "4.1.1",
+            "shebang-command": "1.2.0",
+            "which": "1.3.0"
           }
         },
-        "concat-map": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
-        },
-        "console-browserify": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
-          "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
           "requires": {
-            "date-now": "0.1.4"
+            "ms": "2.0.0"
           }
         },
-        "constants-browserify": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
-          "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U="
-        },
-        "create-ecdh": {
+        "strip-ansi": {
           "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
-          "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
           "requires": {
-            "bn.js": "4.11.8",
-            "elliptic": "6.4.0"
+            "ansi-regex": "3.0.0"
           }
         },
-        "create-hash": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
-          "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
           "requires": {
-            "cipher-base": "1.0.4",
-            "inherits": "2.0.1",
-            "ripemd160": "2.0.1",
-            "sha.js": "2.4.9"
+            "has-flag": "2.0.0"
           }
-        },
-        "create-hmac": {
-          "version": "1.1.6",
-          "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
-          "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
+        }
+      }
+    },
+    "eslint-config-airbnb": {
+      "version": "16.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-16.1.0.tgz",
+      "integrity": "sha512-zLyOhVWhzB/jwbz7IPSbkUuj7X2ox4PHXTcZkEmDqTvd0baJmJyuxlFPDlZOE/Y5bC+HQRaEkT3FoHo9wIdRiw==",
+      "dev": true,
+      "requires": {
+        "eslint-config-airbnb-base": "12.1.0"
+      }
+    },
+    "eslint-config-airbnb-base": {
+      "version": "12.1.0",
+      "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-12.1.0.tgz",
+      "integrity": "sha512-/vjm0Px5ZCpmJqnjIzcFb9TKZrKWz0gnuG/7Gfkt0Db1ELJR51xkZth+t14rYdqWgX836XbuxtArbIHlVhbLBA==",
+      "dev": true,
+      "requires": {
+        "eslint-restricted-globals": "0.1.1"
+      }
+    },
+    "eslint-import-resolver-node": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
+      "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "resolve": "1.5.0"
+      }
+    },
+    "eslint-module-utils": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz",
+      "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==",
+      "dev": true,
+      "requires": {
+        "debug": "2.6.9",
+        "pkg-dir": "1.0.0"
+      }
+    },
+    "eslint-plugin-import": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.8.0.tgz",
+      "integrity": "sha512-Rf7dfKJxZ16QuTgVv1OYNxkZcsu/hULFnC+e+w0Gzi6jMC3guQoWQgxYxc54IDRinlb6/0v5z/PxxIKmVctN+g==",
+      "dev": true,
+      "requires": {
+        "builtin-modules": "1.1.1",
+        "contains-path": "0.1.0",
+        "debug": "2.6.9",
+        "doctrine": "1.5.0",
+        "eslint-import-resolver-node": "0.3.2",
+        "eslint-module-utils": "2.1.1",
+        "has": "1.0.1",
+        "lodash.cond": "4.5.2",
+        "minimatch": "3.0.4",
+        "read-pkg-up": "2.0.0"
+      },
+      "dependencies": {
+        "doctrine": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+          "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+          "dev": true,
           "requires": {
-            "cipher-base": "1.0.4",
-            "create-hash": "1.1.3",
-            "inherits": "2.0.1",
-            "ripemd160": "2.0.1",
-            "safe-buffer": "5.1.1",
-            "sha.js": "2.4.9"
+            "esutils": "2.0.2",
+            "isarray": "1.0.0"
           }
         },
-        "crypto-browserify": {
-          "version": "3.11.1",
-          "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz",
-          "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==",
+        "find-up": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+          "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+          "dev": true,
           "requires": {
-            "browserify-cipher": "1.0.0",
-            "browserify-sign": "4.0.4",
-            "create-ecdh": "4.0.0",
-            "create-hash": "1.1.3",
-            "create-hmac": "1.1.6",
-            "diffie-hellman": "5.0.2",
-            "inherits": "2.0.1",
-            "pbkdf2": "3.0.14",
-            "public-encrypt": "4.0.0",
-            "randombytes": "2.0.5"
+            "locate-path": "2.0.0"
           }
         },
-        "date-now": {
-          "version": "0.1.4",
-          "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
-          "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
-        },
-        "des.js": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
-          "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
+        "load-json-file": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+          "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+          "dev": true,
           "requires": {
-            "inherits": "2.0.1",
-            "minimalistic-assert": "1.0.0"
+            "graceful-fs": "4.1.11",
+            "parse-json": "2.2.0",
+            "pify": "2.3.0",
+            "strip-bom": "3.0.0"
           }
         },
-        "diffie-hellman": {
-          "version": "5.0.2",
-          "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
-          "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
+        "path-type": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz",
+          "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
+          "dev": true,
           "requires": {
-            "bn.js": "4.11.8",
-            "miller-rabin": "4.0.1",
-            "randombytes": "2.0.5"
+            "pify": "2.3.0"
           }
         },
-        "domain-browser": {
-          "version": "1.1.7",
-          "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
-          "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw="
-        },
-        "elliptic": {
-          "version": "6.4.0",
-          "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
-          "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
+        "read-pkg": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz",
+          "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
+          "dev": true,
           "requires": {
-            "bn.js": "4.11.8",
-            "brorand": "1.1.0",
-            "hash.js": "1.1.3",
-            "hmac-drbg": "1.0.1",
-            "inherits": "2.0.1",
-            "minimalistic-assert": "1.0.0",
-            "minimalistic-crypto-utils": "1.0.1"
+            "load-json-file": "2.0.0",
+            "normalize-package-data": "2.4.0",
+            "path-type": "2.0.0"
           }
         },
-        "events": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
-          "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
-        },
-        "evp_bytestokey": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
-          "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
+        "read-pkg-up": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+          "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+          "dev": true,
           "requires": {
-            "md5.js": "1.3.4",
-            "safe-buffer": "5.1.1"
+            "find-up": "2.1.0",
+            "read-pkg": "2.0.0"
           }
         },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-          "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
-        },
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+        "strip-bom": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+          "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+          "dev": true
+        }
+      }
+    },
+    "eslint-plugin-jsx-a11y": {
+      "version": "6.0.3",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.0.3.tgz",
+      "integrity": "sha1-VFg9GuRCSDFi4EDhPMMYZUZRAOU=",
+      "dev": true,
+      "requires": {
+        "aria-query": "0.7.0",
+        "array-includes": "3.0.3",
+        "ast-types-flow": "0.0.7",
+        "axobject-query": "0.1.0",
+        "damerau-levenshtein": "1.0.4",
+        "emoji-regex": "6.5.1",
+        "jsx-ast-utils": "2.0.1"
+      }
+    },
+    "eslint-plugin-react": {
+      "version": "7.4.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.4.0.tgz",
+      "integrity": "sha512-tvjU9u3VqmW2vVuYnE8Qptq+6ji4JltjOjJ9u7VAOxVYkUkyBZWRvNYKbDv5fN+L6wiA+4we9+qQahZ0m63XEA==",
+      "dev": true,
+      "requires": {
+        "doctrine": "2.1.0",
+        "has": "1.0.1",
+        "jsx-ast-utils": "2.0.1",
+        "prop-types": "15.6.0"
+      }
+    },
+    "eslint-restricted-globals": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz",
+      "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=",
+      "dev": true
+    },
+    "eslint-scope": {
+      "version": "3.7.1",
+      "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
+      "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
+      "dev": true,
+      "requires": {
+        "esrecurse": "4.2.0",
+        "estraverse": "4.2.0"
+      }
+    },
+    "espree": {
+      "version": "3.5.2",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz",
+      "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==",
+      "dev": true,
+      "requires": {
+        "acorn": "5.3.0",
+        "acorn-jsx": "3.0.1"
+      }
+    },
+    "esprima": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
+      "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
+      "dev": true
+    },
+    "esquery": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
+      "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0"
+      }
+    },
+    "esrecurse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
+      "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+      "dev": true,
+      "requires": {
+        "estraverse": "4.2.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "estraverse": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+      "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+      "dev": true
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+      "dev": true
+    },
+    "eventemitter2": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-4.1.2.tgz",
+      "integrity": "sha1-DhqEd6+CGm7zmVsxG/dMI6UkfxU="
+    },
+    "execa": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz",
+      "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "5.1.0",
+        "get-stream": "3.0.0",
+        "is-stream": "1.1.0",
+        "npm-run-path": "2.0.2",
+        "p-finally": "1.0.0",
+        "signal-exit": "3.0.2",
+        "strip-eof": "1.0.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+          "dev": true,
           "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.1",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
+            "lru-cache": "4.1.1",
+            "shebang-command": "1.2.0",
+            "which": "1.3.0"
           }
-        },
-        "hash-base": {
-          "version": "2.0.2",
-          "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
-          "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+        }
+      }
+    },
+    "exenv": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
+      "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
+    },
+    "exif-parser": {
+      "version": "0.1.12",
+      "resolved": "https://registry.npmjs.org/exif-parser/-/exif-parser-0.1.12.tgz",
+      "integrity": "sha1-WKnS1ywCwfbwKg70qRZicrd2CSI=",
+      "dev": true
+    },
+    "exit": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+      "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+      "dev": true
+    },
+    "exit-hook": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
+      "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=",
+      "dev": true
+    },
+    "extend": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+      "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
+    },
+    "external-editor": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz",
+      "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==",
+      "dev": true,
+      "requires": {
+        "chardet": "0.4.2",
+        "iconv-lite": "0.4.19",
+        "tmp": "0.0.33"
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+    },
+    "eyes": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
+      "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A="
+    },
+    "fast-deep-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
+      "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+    },
+    "fast-levenshtein": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+      "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+      "dev": true
+    },
+    "fastparse": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
+      "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
+      "dev": true
+    },
+    "fbjs": {
+      "version": "0.8.16",
+      "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
+      "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
+      "requires": {
+        "core-js": "1.2.7",
+        "isomorphic-fetch": "2.2.1",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1",
+        "promise": "7.3.1",
+        "setimmediate": "1.0.5",
+        "ua-parser-js": "0.7.17"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "1.2.7",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
+          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
+        }
+      }
+    },
+    "fibers": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fibers/-/fibers-2.0.0.tgz",
+      "integrity": "sha512-sLxo4rZVk7xLgAjb/6zEzHJfSALx6u6coN1z61XCOF7i6CyTdJawF4+RdpjCSeS8AP66eR2InScbYAz9RAVOgA==",
+      "dev": true
+    },
+    "figures": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+      "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+      "dev": true,
+      "requires": {
+        "escape-string-regexp": "1.0.5"
+      }
+    },
+    "file-entry-cache": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
+      "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
+      "dev": true,
+      "requires": {
+        "flat-cache": "1.3.0",
+        "object-assign": "4.1.1"
+      }
+    },
+    "file-type": {
+      "version": "3.9.0",
+      "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
+      "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=",
+      "dev": true
+    },
+    "find-up": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+      "requires": {
+        "path-exists": "2.1.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "flat": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/flat/-/flat-4.0.0.tgz",
+      "integrity": "sha512-ji/WMv2jdsE+LaznpkIF9Haax0sdpTBozrz/Dtg4qSRMfbs8oVg4ypJunIRYPiMLvH/ed6OflXbnbTIKJhtgeg==",
+      "requires": {
+        "is-buffer": "1.1.6"
+      }
+    },
+    "flat-cache": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
+      "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
+      "dev": true,
+      "requires": {
+        "circular-json": "0.3.3",
+        "del": "2.2.2",
+        "graceful-fs": "4.1.11",
+        "write": "0.2.1"
+      }
+    },
+    "flatten": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
+      "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
+      "dev": true
+    },
+    "for-each": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz",
+      "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=",
+      "dev": true,
+      "requires": {
+        "is-function": "1.0.1"
+      }
+    },
+    "foreach": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+      "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+      "dev": true
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+    },
+    "form-data": {
+      "version": "2.3.1",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
+      "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+      "requires": {
+        "asynckit": "0.4.0",
+        "combined-stream": "1.0.5",
+        "mime-types": "2.1.17"
+      }
+    },
+    "fs-extra": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz",
+      "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "jsonfile": "3.0.1",
+        "universalify": "0.1.1"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+    },
+    "fstream": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+      "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "inherits": "2.0.3",
+        "mkdirp": "0.5.1",
+        "rimraf": "2.6.2"
+      }
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
+      "dev": true
+    },
+    "functional-red-black-tree": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+      "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+      "dev": true
+    },
+    "gauge": {
+      "version": "2.7.4",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+      "requires": {
+        "aproba": "1.2.0",
+        "console-control-strings": "1.1.0",
+        "has-unicode": "2.0.1",
+        "object-assign": "4.1.1",
+        "signal-exit": "3.0.2",
+        "string-width": "1.0.2",
+        "strip-ansi": "3.0.1",
+        "wide-align": "1.1.2"
+      }
+    },
+    "gaze": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
+      "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
+      "requires": {
+        "globule": "1.2.0"
+      }
+    },
+    "get-caller-file": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
+      "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U="
+    },
+    "get-func-name": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+      "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+      "dev": true
+    },
+    "get-own-enumerable-property-symbols": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz",
+      "integrity": "sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug==",
+      "dev": true
+    },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
+    },
+    "get-stream": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "requires": {
+        "assert-plus": "1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.2",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+      "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+      "requires": {
+        "fs.realpath": "1.0.0",
+        "inflight": "1.0.6",
+        "inherits": "2.0.3",
+        "minimatch": "3.0.4",
+        "once": "1.4.0",
+        "path-is-absolute": "1.0.1"
+      }
+    },
+    "global": {
+      "version": "4.3.2",
+      "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
+      "integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
+      "dev": true,
+      "requires": {
+        "min-document": "2.19.0",
+        "process": "0.5.2"
+      }
+    },
+    "globals": {
+      "version": "9.18.0",
+      "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+      "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+      "dev": true
+    },
+    "globby": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
+      "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
+      "dev": true,
+      "requires": {
+        "array-union": "1.0.2",
+        "arrify": "1.0.1",
+        "glob": "7.1.2",
+        "object-assign": "4.1.1",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "globule": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz",
+      "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
+      "requires": {
+        "glob": "7.1.2",
+        "lodash": "4.17.4",
+        "minimatch": "3.0.4"
+      }
+    },
+    "gm": {
+      "version": "1.23.1",
+      "resolved": "https://registry.npmjs.org/gm/-/gm-1.23.1.tgz",
+      "integrity": "sha1-Lt7rlYCE0PjqeYjl2ZWxx9/BR3c=",
+      "dev": true,
+      "requires": {
+        "array-parallel": "0.1.3",
+        "array-series": "0.1.5",
+        "cross-spawn": "4.0.2",
+        "debug": "3.1.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
+          "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
+          "dev": true,
           "requires": {
-            "inherits": "2.0.1"
+            "lru-cache": "4.1.1",
+            "which": "1.3.0"
           }
         },
-        "hash.js": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
-          "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "dev": true,
           "requires": {
-            "inherits": "2.0.3",
-            "minimalistic-assert": "1.0.0"
-          },
-          "dependencies": {
-            "inherits": {
-              "version": "2.0.3",
-              "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-              "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
-            }
+            "ms": "2.0.0"
           }
+        }
+      }
+    },
+    "good-listener": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz",
+      "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=",
+      "requires": {
+        "delegate": "3.2.0"
+      }
+    },
+    "got": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
+      "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
+      "requires": {
+        "decompress-response": "3.3.0",
+        "duplexer3": "0.1.4",
+        "get-stream": "3.0.0",
+        "is-plain-obj": "1.1.0",
+        "is-retry-allowed": "1.1.0",
+        "is-stream": "1.1.0",
+        "isurl": "1.0.0",
+        "lowercase-keys": "1.0.0",
+        "p-cancelable": "0.3.0",
+        "p-timeout": "1.2.1",
+        "safe-buffer": "5.1.1",
+        "timed-out": "4.0.1",
+        "url-parse-lax": "1.0.0",
+        "url-to-options": "1.0.1"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.1.11",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
+      "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+    },
+    "har-validator": {
+      "version": "5.0.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+      "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+      "requires": {
+        "ajv": "5.5.2",
+        "har-schema": "2.0.0"
+      }
+    },
+    "has": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz",
+      "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
+      "dev": true,
+      "requires": {
+        "function-bind": "1.1.1"
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "has-flag": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+      "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+      "dev": true
+    },
+    "has-symbol-support-x": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz",
+      "integrity": "sha512-JkaetveU7hFbqnAC1EV1sF4rlojU2D4Usc5CmS69l6NfmPDnpnFUegzFg33eDkkpNCxZ0mQp65HwUDrNFS/8MA=="
+    },
+    "has-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+      "dev": true
+    },
+    "has-to-string-tag-x": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
+      "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
+      "requires": {
+        "has-symbol-support-x": "1.4.1"
+      }
+    },
+    "has-unicode": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+    },
+    "hawk": {
+      "version": "6.0.2",
+      "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+      "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+      "requires": {
+        "boom": "4.3.1",
+        "cryptiles": "3.1.2",
+        "hoek": "4.2.0",
+        "sntp": "2.1.0"
+      }
+    },
+    "hiredis": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/hiredis/-/hiredis-0.5.0.tgz",
+      "integrity": "sha1-2wOpi+zXAD0TwmAEOs7s+s31m4c=",
+      "requires": {
+        "bindings": "1.3.0",
+        "nan": "2.8.0"
+      }
+    },
+    "history": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/history/-/history-3.3.0.tgz",
+      "integrity": "sha1-/O3M6PEpdTcVRdc1RhAzV5ptrpw=",
+      "requires": {
+        "invariant": "2.2.2",
+        "loose-envify": "1.3.1",
+        "query-string": "4.3.4",
+        "warning": "3.0.0"
+      }
+    },
+    "hoek": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
+      "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
+    },
+    "hoist-non-react-statics": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz",
+      "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs="
+    },
+    "hosted-git-info": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
+      "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg=="
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "requires": {
+        "assert-plus": "1.0.0",
+        "jsprim": "1.4.1",
+        "sshpk": "1.13.1"
+      }
+    },
+    "humanize-duration": {
+      "version": "3.12.1",
+      "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.12.1.tgz",
+      "integrity": "sha512-Eu68Xnq5C38391em1zfVy8tiapQrOvTNTlWpax9smHMlEEUcudXrdMfXMoMRyZx4uODowYgi1AYiMzUXEbG+sA==",
+      "dev": true
+    },
+    "husky": {
+      "version": "0.14.3",
+      "resolved": "https://registry.npmjs.org/husky/-/husky-0.14.3.tgz",
+      "integrity": "sha512-e21wivqHpstpoiWA/Yi8eFti8E+sQDSS53cpJsPptPs295QTOQR0ZwnHo2TXy1XOpZFD9rPOd3NpmqTK6uMLJA==",
+      "dev": true,
+      "requires": {
+        "is-ci": "1.1.0",
+        "normalize-path": "1.0.0",
+        "strip-indent": "2.0.0"
+      },
+      "dependencies": {
+        "strip-indent": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+          "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+          "dev": true
+        }
+      }
+    },
+    "iconv-lite": {
+      "version": "0.4.19",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+      "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
+    },
+    "icss-replace-symbols": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
+      "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
+      "dev": true
+    },
+    "ignore": {
+      "version": "3.3.7",
+      "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz",
+      "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==",
+      "dev": true
+    },
+    "image-size": {
+      "version": "0.5.5",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz",
+      "integrity": "sha1-Cd/Uq50g4p6xw+gLiZA3jfnjy5w=",
+      "dev": true
+    },
+    "immutability-helper": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/immutability-helper/-/immutability-helper-2.4.0.tgz",
+      "integrity": "sha512-rW/L/56ZMo9NStMK85kFrUFFGy4NeJbCdhfrDHIZrFfxYtuwuxD+dT3mWMcdmrNO61hllc60AeGglCRhfZ1dZw==",
+      "requires": {
+        "invariant": "2.2.2"
+      }
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "in-publish": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
+      "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E="
+    },
+    "indent-string": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+      "requires": {
+        "repeating": "2.0.1"
+      }
+    },
+    "indexes-of": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+      "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+      "dev": true
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "requires": {
+        "once": "1.4.0",
+        "wrappy": "1.0.2"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+    },
+    "ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true
+    },
+    "inquirer": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+      "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "3.0.0",
+        "chalk": "2.3.0",
+        "cli-cursor": "2.1.0",
+        "cli-width": "2.2.0",
+        "external-editor": "2.1.0",
+        "figures": "2.0.0",
+        "lodash": "4.17.4",
+        "mute-stream": "0.0.7",
+        "run-async": "2.3.0",
+        "rx-lite": "4.0.8",
+        "rx-lite-aggregates": "4.0.8",
+        "string-width": "2.1.1",
+        "strip-ansi": "4.0.0",
+        "through": "2.3.8"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
         },
-        "hmac-drbg": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
-          "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
           "requires": {
-            "hash.js": "1.1.3",
-            "minimalistic-assert": "1.0.0",
-            "minimalistic-crypto-utils": "1.0.1"
+            "color-convert": "1.9.1"
           }
         },
-        "http-browserify": {
-          "version": "1.7.0",
-          "resolved": "https://registry.npmjs.org/http-browserify/-/http-browserify-1.7.0.tgz",
-          "integrity": "sha1-M3la3nLfiKz7/TZ3PO/tp2RzWyA=",
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
           "requires": {
-            "Base64": "0.2.1",
-            "inherits": "2.0.1"
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
           }
         },
-        "https-browserify": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz",
-          "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI="
-        },
-        "ieee754": {
-          "version": "1.1.8",
-          "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
-          "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q="
-        },
-        "indexof": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
-          "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
         },
-        "inflight": {
-          "version": "1.0.6",
-          "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-          "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
           "requires": {
-            "once": "1.4.0",
-            "wrappy": "1.0.2"
+            "is-fullwidth-code-point": "2.0.0",
+            "strip-ansi": "4.0.0"
           }
         },
-        "inherits": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
-          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
-        },
-        "md5.js": {
-          "version": "1.3.4",
-          "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
-          "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
           "requires": {
-            "hash-base": "3.0.4",
-            "inherits": "2.0.1"
-          },
-          "dependencies": {
-            "hash-base": {
-              "version": "3.0.4",
-              "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
-              "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
-              "requires": {
-                "inherits": "2.0.1",
-                "safe-buffer": "5.1.1"
-              }
-            }
+            "ansi-regex": "3.0.0"
           }
         },
-        "miller-rabin": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
-          "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
           "requires": {
-            "bn.js": "4.11.8",
-            "brorand": "1.1.0"
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "intl-format-cache": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/intl-format-cache/-/intl-format-cache-2.1.0.tgz",
+      "integrity": "sha1-BKNp/sv61tpgBbrh8UMzMy3PkxY="
+    },
+    "intl-messageformat": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-2.2.0.tgz",
+      "integrity": "sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw=",
+      "requires": {
+        "intl-messageformat-parser": "1.4.0"
+      }
+    },
+    "intl-messageformat-parser": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz",
+      "integrity": "sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU="
+    },
+    "intl-relativeformat": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz",
+      "integrity": "sha1-AQ8RBYAiUfQKxH0OPhogE0iiVd8=",
+      "requires": {
+        "intl-messageformat": "2.2.0"
+      }
+    },
+    "invariant": {
+      "version": "2.2.2",
+      "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
+      "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+      "requires": {
+        "loose-envify": "1.3.1"
+      }
+    },
+    "invert-kv": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+      "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+    },
+    "ip-regex": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-1.0.3.tgz",
+      "integrity": "sha1-3FiQdvZZ9BnCIgOaMzFvHHOH7/0=",
+      "dev": true
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+    },
+    "is-builtin-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "requires": {
+        "builtin-modules": "1.1.1"
+      }
+    },
+    "is-callable": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz",
+      "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
+      "dev": true
+    },
+    "is-ci": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
+      "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
+      "dev": true,
+      "requires": {
+        "ci-info": "1.1.2"
+      }
+    },
+    "is-date-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
+      "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "is-fullwidth-code-point": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+      "requires": {
+        "number-is-nan": "1.0.1"
+      }
+    },
+    "is-function": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
+      "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=",
+      "dev": true
+    },
+    "is-glob": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+      "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "2.1.1"
+      }
+    },
+    "is-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+      "dev": true
+    },
+    "is-object": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
+      "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA="
+    },
+    "is-path-cwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
+      "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=",
+      "dev": true
+    },
+    "is-path-in-cwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz",
+      "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=",
+      "dev": true,
+      "requires": {
+        "is-path-inside": "1.0.1"
+      }
+    },
+    "is-path-inside": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+      "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "1.0.2"
+      }
+    },
+    "is-plain-obj": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+      "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+      "dev": true
+    },
+    "is-regex": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+      "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+      "dev": true,
+      "requires": {
+        "has": "1.0.1"
+      }
+    },
+    "is-regexp": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz",
+      "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=",
+      "dev": true
+    },
+    "is-resolvable": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+      "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+      "dev": true
+    },
+    "is-retry-allowed": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+      "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ="
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
+    },
+    "is-symbol": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
+      "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=",
+      "dev": true
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+    },
+    "isomorphic-fetch": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
+      "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
+      "requires": {
+        "node-fetch": "1.7.3",
+        "whatwg-fetch": "2.0.3"
+      }
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+    },
+    "isurl": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
+      "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
+      "requires": {
+        "has-to-string-tag-x": "1.4.1",
+        "is-object": "1.0.1"
+      }
+    },
+    "jasmine": {
+      "version": "2.9.0",
+      "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.9.0.tgz",
+      "integrity": "sha1-dlcfklyHg0CefGFTVy5aY0HPk+s=",
+      "dev": true,
+      "requires": {
+        "exit": "0.1.2",
+        "glob": "7.1.2",
+        "jasmine-core": "2.9.1"
+      }
+    },
+    "jasmine-core": {
+      "version": "2.9.1",
+      "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.9.1.tgz",
+      "integrity": "sha1-trvB2OZSUNVvWIhGFwXr7uuI8i8=",
+      "dev": true
+    },
+    "jest-get-type": {
+      "version": "21.2.0",
+      "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-21.2.0.tgz",
+      "integrity": "sha512-y2fFw3C+D0yjNSDp7ab1kcd6NUYfy3waPTlD8yWkAtiocJdBRQqNoRqVfMNxgj+IjT0V5cBIHJO0z9vuSSZ43Q==",
+      "dev": true
+    },
+    "jest-validate": {
+      "version": "21.2.1",
+      "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-21.2.1.tgz",
+      "integrity": "sha512-k4HLI1rZQjlU+EC682RlQ6oZvLrE5SCh3brseQc24vbZTxzT/k/3urar5QMCVgjadmSO7lECeGdc6YxnM3yEGg==",
+      "dev": true,
+      "requires": {
+        "chalk": "2.3.0",
+        "jest-get-type": "21.2.0",
+        "leven": "2.1.0",
+        "pretty-format": "21.2.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
+          "requires": {
+            "color-convert": "1.9.1"
           }
         },
-        "minimalistic-assert": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
-          "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M="
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
+          }
         },
-        "minimalistic-crypto-utils": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
-          "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
+          "requires": {
+            "has-flag": "2.0.0"
+          }
+        }
+      }
+    },
+    "jimp": {
+      "version": "0.2.28",
+      "resolved": "https://registry.npmjs.org/jimp/-/jimp-0.2.28.tgz",
+      "integrity": "sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI=",
+      "dev": true,
+      "requires": {
+        "bignumber.js": "2.4.0",
+        "bmp-js": "0.0.3",
+        "es6-promise": "3.3.1",
+        "exif-parser": "0.1.12",
+        "file-type": "3.9.0",
+        "jpeg-js": "0.2.0",
+        "load-bmfont": "1.3.0",
+        "mime": "1.6.0",
+        "mkdirp": "0.5.1",
+        "pixelmatch": "4.0.2",
+        "pngjs": "3.3.1",
+        "read-chunk": "1.0.1",
+        "request": "2.83.0",
+        "stream-to-buffer": "0.1.0",
+        "tinycolor2": "1.4.1",
+        "url-regex": "3.2.0"
+      },
+      "dependencies": {
+        "pngjs": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.1.tgz",
+          "integrity": "sha512-ggXCTsqHRIsGMkHlCEhbHhUmNTA2r1lpkE0NL4Q9S8spkXbm4vE9TVmPso2AGYn90Gltdz8W5CyzhcIGg2Gejg==",
+          "dev": true
+        }
+      }
+    },
+    "jpeg-js": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.2.0.tgz",
+      "integrity": "sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII=",
+      "dev": true
+    },
+    "js-base64": {
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz",
+      "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw=="
+    },
+    "js-tokens": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+      "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
+    },
+    "js-yaml": {
+      "version": "3.10.0",
+      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
+      "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+      "dev": true,
+      "requires": {
+        "argparse": "1.0.9",
+        "esprima": "4.0.0"
+      }
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+      "optional": true
+    },
+    "jsesc": {
+      "version": "0.5.0",
+      "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
+      "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
+      "dev": true
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+    },
+    "json-schema-traverse": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
+      "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
+    },
+    "json-stable-stringify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+      "dev": true,
+      "requires": {
+        "jsonify": "0.0.0"
+      }
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+    },
+    "jsonfile": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz",
+      "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "4.1.11"
+      }
+    },
+    "jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "jsx-ast-utils": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz",
+      "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=",
+      "dev": true,
+      "requires": {
+        "array-includes": "3.0.3"
+      }
+    },
+    "junit-report-builder": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/junit-report-builder/-/junit-report-builder-1.2.0.tgz",
+      "integrity": "sha1-aJfM1e49gFGRpL5vEse+hQ5QwNY=",
+      "dev": true,
+      "requires": {
+        "date-format": "0.0.2",
+        "lodash": "3.10.1",
+        "mkdirp": "0.5.1",
+        "xmlbuilder": "2.6.5"
+      },
+      "dependencies": {
+        "lodash": {
+          "version": "3.10.1",
+          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
+          "dev": true
         },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+        "xmlbuilder": {
+          "version": "2.6.5",
+          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.6.5.tgz",
+          "integrity": "sha1-b/etYPty0idk8AehZLd/K/FABSY=",
+          "dev": true,
           "requires": {
-            "brace-expansion": "1.1.8"
+            "lodash": "3.10.1"
           }
-        },
-        "once": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-          "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+        }
+      }
+    },
+    "langmap": {
+      "version": "0.0.16",
+      "resolved": "https://registry.npmjs.org/langmap/-/langmap-0.0.16.tgz",
+      "integrity": "sha512-AtYvBK7BsDvWwnSfmO7CfgeUy7GUT1wK3QX8eKH/Ey/eXodqoHuAtvdQ82hmWD9QVFVKnuiNjym9fGY4qSJeLA=="
+    },
+    "lazystream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+      "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "2.3.3"
+      }
+    },
+    "lcid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+      "requires": {
+        "invert-kv": "1.0.0"
+      }
+    },
+    "leven": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz",
+      "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=",
+      "dev": true
+    },
+    "levn": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+      "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+      "dev": true,
+      "requires": {
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2"
+      }
+    },
+    "line-height": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/line-height/-/line-height-0.3.1.tgz",
+      "integrity": "sha1-SxIF7d4YKHKl76PI9iCzGHqcVMk=",
+      "requires": {
+        "computed-style": "0.1.4"
+      }
+    },
+    "lint-staged": {
+      "version": "4.3.0",
+      "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-4.3.0.tgz",
+      "integrity": "sha512-C/Zxslg0VRbsxwmCu977iIs+QyrmW2cyRCPUV5NDFYOH/jtRFHH8ch7ua2fH0voI/nVC3Tpg7DykfgMZySliKw==",
+      "dev": true,
+      "requires": {
+        "app-root-path": "2.0.1",
+        "chalk": "2.3.0",
+        "commander": "2.13.0",
+        "cosmiconfig": "1.1.0",
+        "execa": "0.8.0",
+        "is-glob": "4.0.0",
+        "jest-validate": "21.2.1",
+        "listr": "0.12.0",
+        "lodash": "4.17.4",
+        "log-symbols": "2.2.0",
+        "minimatch": "3.0.4",
+        "npm-which": "3.0.1",
+        "p-map": "1.2.0",
+        "staged-git-files": "0.0.4",
+        "stringify-object": "3.2.1"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
           "requires": {
-            "wrappy": "1.0.2"
+            "color-convert": "1.9.1"
           }
         },
-        "os-browserify": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz",
-          "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8="
-        },
-        "pako": {
-          "version": "0.2.9",
-          "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
-          "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU="
-        },
-        "parse-asn1": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
-          "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
           "requires": {
-            "asn1.js": "4.9.1",
-            "browserify-aes": "1.1.0",
-            "create-hash": "1.1.3",
-            "evp_bytestokey": "1.0.3",
-            "pbkdf2": "3.0.14"
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
           }
         },
-        "path-browserify": {
-          "version": "0.0.0",
-          "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
-          "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo="
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-          "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
-        },
-        "pbkdf2": {
-          "version": "3.0.14",
-          "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
-          "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
           "requires": {
-            "create-hash": "1.1.3",
-            "create-hmac": "1.1.6",
-            "ripemd160": "2.0.1",
-            "safe-buffer": "5.1.1",
-            "sha.js": "2.4.9"
+            "has-flag": "2.0.0"
           }
-        },
-        "process": {
-          "version": "0.11.10",
-          "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
-          "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
-        },
-        "process-nextick-args": {
-          "version": "1.0.7",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
-          "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
-        },
-        "public-encrypt": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
-          "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+        }
+      }
+    },
+    "listr": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz",
+      "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "cli-truncate": "0.2.1",
+        "figures": "1.7.0",
+        "indent-string": "2.1.0",
+        "is-promise": "2.1.0",
+        "is-stream": "1.1.0",
+        "listr-silent-renderer": "1.1.1",
+        "listr-update-renderer": "0.2.0",
+        "listr-verbose-renderer": "0.4.1",
+        "log-symbols": "1.0.2",
+        "log-update": "1.0.2",
+        "ora": "0.2.3",
+        "p-map": "1.2.0",
+        "rxjs": "5.5.6",
+        "stream-to-observable": "0.1.0",
+        "strip-ansi": "3.0.1"
+      },
+      "dependencies": {
+        "figures": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+          "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+          "dev": true,
           "requires": {
-            "bn.js": "4.11.8",
-            "browserify-rsa": "4.0.1",
-            "create-hash": "1.1.3",
-            "parse-asn1": "5.1.0",
-            "randombytes": "2.0.5"
+            "escape-string-regexp": "1.0.5",
+            "object-assign": "4.1.1"
           }
         },
-        "punycode": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
-          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
-        },
-        "querystring": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
-          "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
-        },
-        "querystring-es3": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
-          "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
-        },
-        "randombytes": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
-          "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
+        "log-symbols": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+          "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
+          "dev": true,
           "requires": {
-            "safe-buffer": "5.1.1"
+            "chalk": "1.1.3"
           }
-        },
-        "readable-stream": {
-          "version": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502",
-          "requires": {
-            "inherits": "2.0.3",
-            "isarray": "1.0.0",
-            "process-nextick-args": "1.0.7",
-            "safe-buffer": "5.1.1",
-            "string_decoder": "1.0.3",
-            "util-deprecate": "1.0.2"
-          },
-          "dependencies": {
-            "inherits": {
-              "version": "2.0.3",
-              "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-              "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
-            }
+        }
+      }
+    },
+    "listr-silent-renderer": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz",
+      "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=",
+      "dev": true
+    },
+    "listr-update-renderer": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz",
+      "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "cli-truncate": "0.2.1",
+        "elegant-spinner": "1.0.1",
+        "figures": "1.7.0",
+        "indent-string": "3.2.0",
+        "log-symbols": "1.0.2",
+        "log-update": "1.0.2",
+        "strip-ansi": "3.0.1"
+      },
+      "dependencies": {
+        "figures": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+          "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+          "dev": true,
+          "requires": {
+            "escape-string-regexp": "1.0.5",
+            "object-assign": "4.1.1"
           }
         },
-        "rimraf": {
-          "version": "2.6.2",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
-          "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+        "indent-string": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+          "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+          "dev": true
+        },
+        "log-symbols": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz",
+          "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=",
+          "dev": true,
           "requires": {
-            "glob": "7.1.2"
+            "chalk": "1.1.3"
           }
-        },
-        "ripemd160": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
-          "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+        }
+      }
+    },
+    "listr-verbose-renderer": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz",
+      "integrity": "sha1-ggb0z21S3cWCfl/RSYng6WWTOjU=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "cli-cursor": "1.0.2",
+        "date-fns": "1.29.0",
+        "figures": "1.7.0"
+      },
+      "dependencies": {
+        "cli-cursor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+          "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+          "dev": true,
           "requires": {
-            "hash-base": "2.0.2",
-            "inherits": "2.0.1"
+            "restore-cursor": "1.0.1"
           }
         },
-        "safe-buffer": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
-          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
-        },
-        "sha.js": {
-          "version": "2.4.9",
-          "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz",
-          "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==",
+        "figures": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+          "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+          "dev": true,
           "requires": {
-            "inherits": "2.0.1",
-            "safe-buffer": "5.1.1"
+            "escape-string-regexp": "1.0.5",
+            "object-assign": "4.1.1"
           }
         },
-        "stream-browserify": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
-          "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
+        "onetime": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+          "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+          "dev": true
+        },
+        "restore-cursor": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+          "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+          "dev": true,
           "requires": {
-            "inherits": "2.0.1",
-            "readable-stream": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502"
+            "exit-hook": "1.1.1",
+            "onetime": "1.1.0"
           }
-        },
-        "string_decoder": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
-          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+        }
+      }
+    },
+    "load-bmfont": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/load-bmfont/-/load-bmfont-1.3.0.tgz",
+      "integrity": "sha1-u358cQ3mvK/LE8s7jIHgwBMey8k=",
+      "dev": true,
+      "requires": {
+        "buffer-equal": "0.0.1",
+        "mime": "1.6.0",
+        "parse-bmfont-ascii": "1.0.6",
+        "parse-bmfont-binary": "1.0.6",
+        "parse-bmfont-xml": "1.1.3",
+        "xhr": "2.4.1",
+        "xtend": "4.0.1"
+      }
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "parse-json": "2.2.0",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1",
+        "strip-bom": "2.0.0"
+      }
+    },
+    "locate-path": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+      "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+      "dev": true,
+      "requires": {
+        "p-locate": "2.0.0",
+        "path-exists": "3.0.0"
+      },
+      "dependencies": {
+        "path-exists": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+          "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+          "dev": true
+        }
+      }
+    },
+    "lodash": {
+      "version": "4.17.4",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
+      "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+    },
+    "lodash.assign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc="
+    },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
+    },
+    "lodash.cond": {
+      "version": "4.5.2",
+      "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
+      "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=",
+      "dev": true
+    },
+    "lodash.mergewith": {
+      "version": "4.6.0",
+      "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz",
+      "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU="
+    },
+    "log-symbols": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+      "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+      "dev": true,
+      "requires": {
+        "chalk": "2.3.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
           "requires": {
-            "safe-buffer": "5.1.1"
+            "color-convert": "1.9.1"
           }
         },
-        "timers-browserify": {
-          "version": "1.4.2",
-          "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
-          "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=",
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
           "requires": {
-            "process": "0.11.10"
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
           }
         },
-        "tty-browserify": {
-          "version": "0.0.0",
-          "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
-          "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
-        },
-        "url": {
-          "version": "0.11.0",
-          "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
-          "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
           "requires": {
-            "punycode": "1.3.2",
-            "querystring": "0.2.0"
-          },
-          "dependencies": {
-            "punycode": {
-              "version": "1.3.2",
-              "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
-              "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
-            }
+            "has-flag": "2.0.0"
           }
+        }
+      }
+    },
+    "log-update": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz",
+      "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=",
+      "dev": true,
+      "requires": {
+        "ansi-escapes": "1.4.0",
+        "cli-cursor": "1.0.2"
+      },
+      "dependencies": {
+        "ansi-escapes": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+          "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+          "dev": true
         },
-        "util": {
-          "version": "0.10.3",
-          "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
-          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+        "cli-cursor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+          "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+          "dev": true,
           "requires": {
-            "inherits": "2.0.1"
+            "restore-cursor": "1.0.1"
           }
         },
-        "util-deprecate": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-          "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+        "onetime": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+          "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+          "dev": true
         },
-        "vm-browserify": {
-          "version": "0.0.4",
-          "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
-          "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
+        "restore-cursor": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+          "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+          "dev": true,
           "requires": {
-            "indexof": "0.0.1"
+            "exit-hook": "1.1.1",
+            "onetime": "1.1.0"
           }
-        },
-        "wrappy": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
         }
       }
     },
-    "node-sass": {
-      "version": "4.5.3",
-      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.3.tgz",
-      "integrity": "sha1-0JydEXlkEjnRuX/8YjH9zsU+FWg=",
+    "loose-envify": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
+      "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
       "requires": {
-        "async-foreach": "0.1.3",
-        "chalk": "1.1.3",
-        "cross-spawn": "3.0.1",
-        "gaze": "1.1.2",
-        "get-stdin": "4.0.1",
-        "glob": "7.1.2",
-        "in-publish": "2.0.0",
-        "lodash.assign": "4.2.0",
-        "lodash.clonedeep": "4.5.0",
-        "lodash.mergewith": "4.6.0",
-        "meow": "3.7.0",
-        "mkdirp": "0.5.1",
-        "nan": "2.8.0",
-        "node-gyp": "3.6.2",
-        "npmlog": "4.1.2",
-        "request": "2.83.0",
-        "sass-graph": "2.2.4",
-        "stdout-stream": "1.4.0"
+        "js-tokens": "3.0.2"
+      }
+    },
+    "loud-rejection": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+      "requires": {
+        "currently-unhandled": "0.4.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "lowercase-keys": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
+      "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY="
+    },
+    "lru-cache": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
+      "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+      "requires": {
+        "pseudomap": "1.0.2",
+        "yallist": "2.1.2"
+      }
+    },
+    "map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
+    },
+    "material-colors": {
+      "version": "1.2.5",
+      "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.5.tgz",
+      "integrity": "sha1-UpJZPmdUyxvMK5gDDk4Najr8nqE="
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "requires": {
+        "camelcase-keys": "2.1.0",
+        "decamelize": "1.2.0",
+        "loud-rejection": "1.6.0",
+        "map-obj": "1.0.1",
+        "minimist": "1.2.0",
+        "normalize-package-data": "2.4.0",
+        "object-assign": "4.1.1",
+        "read-pkg-up": "1.0.1",
+        "redent": "1.0.0",
+        "trim-newlines": "1.0.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+        }
+      }
+    },
+    "meteor-node-stubs": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/meteor-node-stubs/-/meteor-node-stubs-0.3.2.tgz",
+      "integrity": "sha512-l93SS/HutbqBRJODO2m7hup8cYI2acF5bB39+ZvP2BX8HMmCSCXeFH7v0sr4hD7zrVvHQA5UqS0pcDYKn0VM6g==",
+      "requires": {
+        "assert": "1.4.1",
+        "browserify-zlib": "0.1.4",
+        "buffer": "4.9.1",
+        "console-browserify": "1.1.0",
+        "constants-browserify": "1.0.0",
+        "crypto-browserify": "3.11.1",
+        "domain-browser": "1.1.7",
+        "events": "1.1.1",
+        "http-browserify": "1.7.0",
+        "https-browserify": "0.0.1",
+        "os-browserify": "0.2.1",
+        "path-browserify": "0.0.0",
+        "process": "0.11.10",
+        "punycode": "1.4.1",
+        "querystring-es3": "0.2.1",
+        "readable-stream": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502",
+        "stream-browserify": "2.0.1",
+        "string_decoder": "1.0.3",
+        "timers-browserify": "1.4.2",
+        "tty-browserify": "0.0.0",
+        "url": "0.11.0",
+        "util": "0.10.3",
+        "vm-browserify": "0.0.4"
       },
       "dependencies": {
-        "abbrev": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
-          "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+        "Base64": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/Base64/-/Base64-0.2.1.tgz",
+          "integrity": "sha1-ujpCMHCOGGcFBl5mur3Uw1z2ACg="
         },
-        "ajv": {
-          "version": "5.5.2",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
-          "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
+        "asn1.js": {
+          "version": "4.9.1",
+          "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz",
+          "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=",
           "requires": {
-            "co": "4.6.0",
-            "fast-deep-equal": "1.0.0",
-            "fast-json-stable-stringify": "2.0.0",
-            "json-schema-traverse": "0.3.1"
+            "bn.js": "4.11.8",
+            "inherits": "2.0.1",
+            "minimalistic-assert": "1.0.0"
           }
         },
-        "amdefine": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
-          "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
-        },
-        "ansi-regex": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
-        },
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
-        },
-        "aproba": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
-          "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
-        },
-        "are-we-there-yet": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
-          "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
+        "assert": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+          "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
           "requires": {
-            "delegates": "1.0.0",
-            "readable-stream": "2.3.3"
+            "util": "0.10.3"
           }
         },
-        "array-find-index": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
-          "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
-        },
-        "asn1": {
-          "version": "0.2.3",
-          "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
-          "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
-        },
-        "assert-plus": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
-        },
-        "async-foreach": {
-          "version": "0.1.3",
-          "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
-          "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI="
-        },
-        "asynckit": {
-          "version": "0.4.0",
-          "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-          "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
-        },
-        "aws-sign2": {
-          "version": "0.7.0",
-          "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
-          "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
-        },
-        "aws4": {
-          "version": "1.6.0",
-          "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
-          "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
-        },
         "balanced-match": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
           "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
         },
-        "bcrypt-pbkdf": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
-          "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
-          "optional": true,
-          "requires": {
-            "tweetnacl": "0.14.5"
-          }
+        "base64-js": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
+          "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw=="
         },
-        "boom": {
-          "version": "4.3.1",
-          "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
-          "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
-          "requires": {
-            "hoek": "4.2.0"
-          }
+        "bn.js": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz",
+          "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA=="
         },
         "brace-expansion": {
           "version": "1.1.8",
@@ -4011,266 +3147,229 @@
             "concat-map": "0.0.1"
           }
         },
-        "builtin-modules": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
-          "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
-        },
-        "camelcase": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
-          "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
+        "brorand": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
+          "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
         },
-        "camelcase-keys": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
-          "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+        "browserify-aes": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.1.0.tgz",
+          "integrity": "sha512-W2bIMLYoZ9oow7TyePpMJk9l9LY7O3R61a/68bVCDOtnJynnwe3ZeW2IzzSkrQnPKNdJrxVDn3ALZNisSBwb7g==",
           "requires": {
-            "camelcase": "2.1.1",
-            "map-obj": "1.0.1"
+            "buffer-xor": "1.0.3",
+            "cipher-base": "1.0.4",
+            "create-hash": "1.1.3",
+            "evp_bytestokey": "1.0.3",
+            "inherits": "2.0.1",
+            "safe-buffer": "5.1.1"
           }
         },
-        "caseless": {
-          "version": "0.12.0",
-          "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-          "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+        "browserify-cipher": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
+          "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
           "requires": {
-            "ansi-styles": "2.2.1",
-            "escape-string-regexp": "1.0.5",
-            "has-ansi": "2.0.0",
-            "strip-ansi": "3.0.1",
-            "supports-color": "2.0.0"
+            "browserify-aes": "1.1.0",
+            "browserify-des": "1.0.0",
+            "evp_bytestokey": "1.0.3"
           }
         },
-        "cliui": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
-          "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+        "browserify-des": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
+          "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
           "requires": {
-            "string-width": "1.0.2",
-            "strip-ansi": "3.0.1",
-            "wrap-ansi": "2.1.0"
+            "cipher-base": "1.0.4",
+            "des.js": "1.0.0",
+            "inherits": "2.0.1"
           }
         },
-        "co": {
-          "version": "4.6.0",
-          "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-          "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
-        },
-        "code-point-at": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
-          "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
-        },
-        "combined-stream": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
-          "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+        "browserify-rsa": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz",
+          "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
           "requires": {
-            "delayed-stream": "1.0.0"
+            "bn.js": "4.11.8",
+            "randombytes": "2.0.5"
           }
         },
-        "concat-map": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
-        },
-        "console-control-strings": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
-          "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
-        },
-        "core-util-is": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-          "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
-        },
-        "cross-spawn": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
-          "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+        "browserify-sign": {
+          "version": "4.0.4",
+          "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz",
+          "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
           "requires": {
-            "lru-cache": "4.1.1",
-            "which": "1.3.0"
+            "bn.js": "4.11.8",
+            "browserify-rsa": "4.0.1",
+            "create-hash": "1.1.3",
+            "create-hmac": "1.1.6",
+            "elliptic": "6.4.0",
+            "inherits": "2.0.1",
+            "parse-asn1": "5.1.0"
           }
         },
-        "cryptiles": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
-          "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+        "browserify-zlib": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz",
+          "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
           "requires": {
-            "boom": "5.2.0"
-          },
-          "dependencies": {
-            "boom": {
-              "version": "5.2.0",
-              "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
-              "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
-              "requires": {
-                "hoek": "4.2.0"
-              }
-            }
+            "pako": "0.2.9"
           }
         },
-        "currently-unhandled": {
-          "version": "0.4.1",
-          "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
-          "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+        "buffer": {
+          "version": "4.9.1",
+          "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz",
+          "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
           "requires": {
-            "array-find-index": "1.0.2"
+            "base64-js": "1.2.1",
+            "ieee754": "1.1.8",
+            "isarray": "1.0.0"
           }
         },
-        "dashdash": {
-          "version": "1.14.1",
-          "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-          "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+        "buffer-xor": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
+          "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+        },
+        "cipher-base": {
+          "version": "1.0.4",
+          "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
+          "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
           "requires": {
-            "assert-plus": "1.0.0"
+            "inherits": "2.0.1",
+            "safe-buffer": "5.1.1"
           }
         },
-        "decamelize": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
-          "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+        "concat-map": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
         },
-        "delayed-stream": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-          "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+        "console-browserify": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+          "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+          "requires": {
+            "date-now": "0.1.4"
+          }
         },
-        "delegates": {
+        "constants-browserify": {
           "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
-          "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
-        },
-        "ecc-jsbn": {
-          "version": "0.1.1",
-          "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
-          "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
-          "optional": true,
+          "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
+          "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U="
+        },
+        "create-ecdh": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
+          "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
           "requires": {
-            "jsbn": "0.1.1"
+            "bn.js": "4.11.8",
+            "elliptic": "6.4.0"
           }
         },
-        "error-ex": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
-          "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
+        "create-hash": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
+          "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
           "requires": {
-            "is-arrayish": "0.2.1"
+            "cipher-base": "1.0.4",
+            "inherits": "2.0.1",
+            "ripemd160": "2.0.1",
+            "sha.js": "2.4.9"
           }
         },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
-        },
-        "extend": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
-          "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
-        },
-        "extsprintf": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-          "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
-        },
-        "fast-deep-equal": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
-          "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
-        },
-        "fast-json-stable-stringify": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
-          "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
-        },
-        "find-up": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
-          "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+        "create-hmac": {
+          "version": "1.1.6",
+          "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
+          "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
           "requires": {
-            "path-exists": "2.1.0",
-            "pinkie-promise": "2.0.1"
+            "cipher-base": "1.0.4",
+            "create-hash": "1.1.3",
+            "inherits": "2.0.1",
+            "ripemd160": "2.0.1",
+            "safe-buffer": "5.1.1",
+            "sha.js": "2.4.9"
           }
         },
-        "forever-agent": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-          "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
-        },
-        "form-data": {
-          "version": "2.3.1",
-          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
-          "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+        "crypto-browserify": {
+          "version": "3.11.1",
+          "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz",
+          "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==",
           "requires": {
-            "asynckit": "0.4.0",
-            "combined-stream": "1.0.5",
-            "mime-types": "2.1.17"
+            "browserify-cipher": "1.0.0",
+            "browserify-sign": "4.0.4",
+            "create-ecdh": "4.0.0",
+            "create-hash": "1.1.3",
+            "create-hmac": "1.1.6",
+            "diffie-hellman": "5.0.2",
+            "inherits": "2.0.1",
+            "pbkdf2": "3.0.14",
+            "public-encrypt": "4.0.0",
+            "randombytes": "2.0.5"
           }
         },
-        "fs.realpath": {
+        "date-now": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+          "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
+        },
+        "des.js": {
           "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-          "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
-        },
-        "fstream": {
-          "version": "1.0.11",
-          "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
-          "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+          "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz",
+          "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
           "requires": {
-            "graceful-fs": "4.1.11",
-            "inherits": "2.0.3",
-            "mkdirp": "0.5.1",
-            "rimraf": "2.6.2"
+            "inherits": "2.0.1",
+            "minimalistic-assert": "1.0.0"
           }
         },
-        "gauge": {
-          "version": "2.7.4",
-          "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
-          "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+        "diffie-hellman": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
+          "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
           "requires": {
-            "aproba": "1.2.0",
-            "console-control-strings": "1.1.0",
-            "has-unicode": "2.0.1",
-            "object-assign": "4.1.1",
-            "signal-exit": "3.0.2",
-            "string-width": "1.0.2",
-            "strip-ansi": "3.0.1",
-            "wide-align": "1.1.2"
+            "bn.js": "4.11.8",
+            "miller-rabin": "4.0.1",
+            "randombytes": "2.0.5"
           }
         },
-        "gaze": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
-          "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
+        "domain-browser": {
+          "version": "1.1.7",
+          "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
+          "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw="
+        },
+        "elliptic": {
+          "version": "6.4.0",
+          "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
+          "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
           "requires": {
-            "globule": "1.2.0"
+            "bn.js": "4.11.8",
+            "brorand": "1.1.0",
+            "hash.js": "1.1.3",
+            "hmac-drbg": "1.0.1",
+            "inherits": "2.0.1",
+            "minimalistic-assert": "1.0.0",
+            "minimalistic-crypto-utils": "1.0.1"
           }
         },
-        "get-caller-file": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz",
-          "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U="
-        },
-        "get-stdin": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
-          "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
+        "events": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz",
+          "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ="
         },
-        "getpass": {
-          "version": "0.1.7",
-          "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-          "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+        "evp_bytestokey": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz",
+          "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==",
           "requires": {
-            "assert-plus": "1.0.0"
+            "md5.js": "1.3.4",
+            "safe-buffer": "5.1.1"
           }
         },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+          "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+        },
         "glob": {
           "version": "7.1.2",
           "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
@@ -4278,97 +3377,69 @@
           "requires": {
             "fs.realpath": "1.0.0",
             "inflight": "1.0.6",
-            "inherits": "2.0.3",
+            "inherits": "2.0.1",
             "minimatch": "3.0.4",
             "once": "1.4.0",
             "path-is-absolute": "1.0.1"
           }
         },
-        "globule": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz",
-          "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
+        "hash-base": {
+          "version": "2.0.2",
+          "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
+          "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
           "requires": {
-            "glob": "7.1.2",
-            "lodash": "4.17.4",
-            "minimatch": "3.0.4"
+            "inherits": "2.0.1"
           }
         },
-        "graceful-fs": {
-          "version": "4.1.11",
-          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
-          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
-        },
-        "har-schema": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
-          "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
-        },
-        "har-validator": {
-          "version": "5.0.3",
-          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
-          "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+        "hash.js": {
+          "version": "1.1.3",
+          "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz",
+          "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==",
           "requires": {
-            "ajv": "5.5.2",
-            "har-schema": "2.0.0"
+            "inherits": "2.0.3",
+            "minimalistic-assert": "1.0.0"
+          },
+          "dependencies": {
+            "inherits": {
+              "version": "2.0.3",
+              "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+              "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+            }
           }
         },
-        "has-ansi": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
-          "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+        "hmac-drbg": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
+          "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
           "requires": {
-            "ansi-regex": "2.1.1"
+            "hash.js": "1.1.3",
+            "minimalistic-assert": "1.0.0",
+            "minimalistic-crypto-utils": "1.0.1"
           }
         },
-        "has-unicode": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
-          "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
-        },
-        "hawk": {
-          "version": "6.0.2",
-          "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
-          "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+        "http-browserify": {
+          "version": "1.7.0",
+          "resolved": "https://registry.npmjs.org/http-browserify/-/http-browserify-1.7.0.tgz",
+          "integrity": "sha1-M3la3nLfiKz7/TZ3PO/tp2RzWyA=",
           "requires": {
-            "boom": "4.3.1",
-            "cryptiles": "3.1.2",
-            "hoek": "4.2.0",
-            "sntp": "2.1.0"
+            "Base64": "0.2.1",
+            "inherits": "2.0.1"
           }
         },
-        "hoek": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
-          "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
-        },
-        "hosted-git-info": {
-          "version": "2.5.0",
-          "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
-          "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg=="
-        },
-        "http-signature": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
-          "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
-          "requires": {
-            "assert-plus": "1.0.0",
-            "jsprim": "1.4.1",
-            "sshpk": "1.13.1"
-          }
+        "https-browserify": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz",
+          "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI="
         },
-        "in-publish": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
-          "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E="
+        "ieee754": {
+          "version": "1.1.8",
+          "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
+          "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q="
         },
-        "indent-string": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
-          "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
-          "requires": {
-            "repeating": "2.0.1"
-          }
+        "indexof": {
+          "version": "0.0.1",
+          "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+          "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
         },
         "inflight": {
           "version": "1.0.6",
@@ -4380,193 +3451,53 @@
           }
         },
         "inherits": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
-        },
-        "invert-kv": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
-          "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
-        },
-        "is-arrayish": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
-          "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
-        },
-        "is-builtin-module": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
-          "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
-          "requires": {
-            "builtin-modules": "1.1.1"
-          }
-        },
-        "is-finite": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
-          "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
-          "requires": {
-            "number-is-nan": "1.0.1"
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
-          "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
-          "requires": {
-            "number-is-nan": "1.0.1"
-          }
-        },
-        "is-typedarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-          "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
-        },
-        "is-utf8": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
-          "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
         },
         "isarray": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
           "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
         },
-        "isexe": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
-          "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
-        },
-        "isstream": {
-          "version": "0.1.2",
-          "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-          "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
-        },
-        "js-base64": {
-          "version": "2.4.0",
-          "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.0.tgz",
-          "integrity": "sha512-Wehd+7Pf9tFvGb+ydPm9TjYjV8X1YHOVyG8QyELZxEMqOhemVwGRmoG8iQ/soqI3n8v4xn59zaLxiCJiaaRzKA=="
-        },
-        "jsbn": {
-          "version": "0.1.1",
-          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-          "optional": true
-        },
-        "json-schema": {
-          "version": "0.2.3",
-          "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-          "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
-        },
-        "json-schema-traverse": {
-          "version": "0.3.1",
-          "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz",
-          "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A="
-        },
-        "json-stringify-safe": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-          "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
-        },
-        "jsprim": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-          "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-          "requires": {
-            "assert-plus": "1.0.0",
-            "extsprintf": "1.3.0",
-            "json-schema": "0.2.3",
-            "verror": "1.10.0"
-          }
-        },
-        "lcid": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
-          "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
-          "requires": {
-            "invert-kv": "1.0.0"
-          }
-        },
-        "load-json-file": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
-          "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+        "md5.js": {
+          "version": "1.3.4",
+          "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
+          "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
           "requires": {
-            "graceful-fs": "4.1.11",
-            "parse-json": "2.2.0",
-            "pify": "2.3.0",
-            "pinkie-promise": "2.0.1",
-            "strip-bom": "2.0.0"
+            "hash-base": "3.0.4",
+            "inherits": "2.0.1"
+          },
+          "dependencies": {
+            "hash-base": {
+              "version": "3.0.4",
+              "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+              "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
+              "requires": {
+                "inherits": "2.0.1",
+                "safe-buffer": "5.1.1"
+              }
+            }
           }
         },
-        "lodash.assign": {
-          "version": "4.2.0",
-          "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
-          "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc="
-        },
-        "lodash.clonedeep": {
-          "version": "4.5.0",
-          "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
-          "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
-        },
-        "lodash.mergewith": {
-          "version": "4.6.0",
-          "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.0.tgz",
-          "integrity": "sha1-FQzwoWeR9ZA7iJHqsVRgknS96lU="
-        },
-        "loud-rejection": {
-          "version": "1.6.0",
-          "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
-          "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+        "miller-rabin": {
+          "version": "4.0.1",
+          "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+          "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
           "requires": {
-            "currently-unhandled": "0.4.1",
-            "signal-exit": "3.0.2"
+            "bn.js": "4.11.8",
+            "brorand": "1.1.0"
           }
         },
-        "lru-cache": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
-          "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
-          "requires": {
-            "pseudomap": "1.0.2",
-            "yallist": "2.1.2"
-          }
+        "minimalistic-assert": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
+          "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M="
         },
-        "map-obj": {
+        "minimalistic-crypto-utils": {
           "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
-          "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
-        },
-        "meow": {
-          "version": "3.7.0",
-          "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
-          "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
-          "requires": {
-            "camelcase-keys": "2.1.0",
-            "decamelize": "1.2.0",
-            "loud-rejection": "1.6.0",
-            "map-obj": "1.0.1",
-            "minimist": "1.2.0",
-            "normalize-package-data": "2.4.0",
-            "object-assign": "4.1.1",
-            "read-pkg-up": "1.0.1",
-            "redent": "1.0.0",
-            "trim-newlines": "1.0.0"
-          }
-        },
-        "mime-db": {
-          "version": "1.30.0",
-          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
-          "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
-        },
-        "mime-types": {
-          "version": "2.1.17",
-          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
-          "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
-          "requires": {
-            "mime-db": "1.30.0"
-          }
+          "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
+          "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
         },
         "minimatch": {
           "version": "3.0.4",
@@ -4576,301 +3507,121 @@
             "brace-expansion": "1.1.8"
           }
         },
-        "minimist": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
-          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
-        },
-        "mkdirp": {
-          "version": "0.5.1",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-          "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-          "requires": {
-            "minimist": "0.0.8"
-          },
-          "dependencies": {
-            "minimist": {
-              "version": "0.0.8",
-              "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-              "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
-            }
-          }
-        },
-        "nan": {
-          "version": "2.8.0",
-          "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
-          "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo="
-        },
-        "node-gyp": {
-          "version": "3.6.2",
-          "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
-          "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=",
-          "requires": {
-            "fstream": "1.0.11",
-            "glob": "7.1.2",
-            "graceful-fs": "4.1.11",
-            "minimatch": "3.0.4",
-            "mkdirp": "0.5.1",
-            "nopt": "3.0.6",
-            "npmlog": "4.1.2",
-            "osenv": "0.1.4",
-            "request": "2.83.0",
-            "rimraf": "2.6.2",
-            "semver": "5.3.0",
-            "tar": "2.2.1",
-            "which": "1.3.0"
-          },
-          "dependencies": {
-            "semver": {
-              "version": "5.3.0",
-              "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
-              "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
-            }
-          }
-        },
-        "nopt": {
-          "version": "3.0.6",
-          "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
-          "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
-          "requires": {
-            "abbrev": "1.1.1"
-          }
-        },
-        "normalize-package-data": {
-          "version": "2.4.0",
-          "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
-          "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
-          "requires": {
-            "hosted-git-info": "2.5.0",
-            "is-builtin-module": "1.0.0",
-            "semver": "5.4.1",
-            "validate-npm-package-license": "3.0.1"
-          }
-        },
-        "npmlog": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
-          "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
-          "requires": {
-            "are-we-there-yet": "1.1.4",
-            "console-control-strings": "1.1.0",
-            "gauge": "2.7.4",
-            "set-blocking": "2.0.0"
-          }
-        },
-        "number-is-nan": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
-          "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
-        },
-        "oauth-sign": {
-          "version": "0.8.2",
-          "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
-          "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-        },
         "once": {
           "version": "1.4.0",
           "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
           "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
           "requires": {
-            "wrappy": "1.0.2"
-          }
-        },
-        "os-homedir": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
-          "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
-        },
-        "os-locale": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
-          "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
-          "requires": {
-            "lcid": "1.0.0"
-          }
-        },
-        "os-tmpdir": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-          "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
-        },
-        "osenv": {
-          "version": "0.1.4",
-          "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
-          "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
-          "requires": {
-            "os-homedir": "1.0.2",
-            "os-tmpdir": "1.0.2"
-          }
-        },
-        "parse-json": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
-          "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
-          "requires": {
-            "error-ex": "1.3.1"
+            "wrappy": "1.0.2"
           }
         },
-        "path-exists": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
-          "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+        "os-browserify": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz",
+          "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8="
+        },
+        "pako": {
+          "version": "0.2.9",
+          "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz",
+          "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU="
+        },
+        "parse-asn1": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
+          "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
           "requires": {
-            "pinkie-promise": "2.0.1"
+            "asn1.js": "4.9.1",
+            "browserify-aes": "1.1.0",
+            "create-hash": "1.1.3",
+            "evp_bytestokey": "1.0.3",
+            "pbkdf2": "3.0.14"
           }
         },
+        "path-browserify": {
+          "version": "0.0.0",
+          "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz",
+          "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo="
+        },
         "path-is-absolute": {
           "version": "1.0.1",
           "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
           "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
         },
-        "path-type": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
-          "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+        "pbkdf2": {
+          "version": "3.0.14",
+          "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
+          "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
           "requires": {
-            "graceful-fs": "4.1.11",
-            "pify": "2.3.0",
-            "pinkie-promise": "2.0.1"
+            "create-hash": "1.1.3",
+            "create-hmac": "1.1.6",
+            "ripemd160": "2.0.1",
+            "safe-buffer": "5.1.1",
+            "sha.js": "2.4.9"
           }
         },
-        "performance-now": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
-          "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
-        },
-        "pify": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
-          "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
-        },
-        "pinkie": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
-          "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
-        },
-        "pinkie-promise": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
-          "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
-          "requires": {
-            "pinkie": "2.0.4"
-          }
+        "process": {
+          "version": "0.11.10",
+          "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+          "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI="
         },
         "process-nextick-args": {
           "version": "1.0.7",
           "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
           "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
         },
-        "pseudomap": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
-          "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+        "public-encrypt": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
+          "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+          "requires": {
+            "bn.js": "4.11.8",
+            "browserify-rsa": "4.0.1",
+            "create-hash": "1.1.3",
+            "parse-asn1": "5.1.0",
+            "randombytes": "2.0.5"
+          }
         },
         "punycode": {
           "version": "1.4.1",
           "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
           "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
         },
-        "qs": {
-          "version": "6.5.1",
-          "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
-          "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
+        "querystring": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+          "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
         },
-        "read-pkg": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
-          "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
-          "requires": {
-            "load-json-file": "1.1.0",
-            "normalize-package-data": "2.4.0",
-            "path-type": "1.1.0"
-          }
+        "querystring-es3": {
+          "version": "0.2.1",
+          "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz",
+          "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM="
         },
-        "read-pkg-up": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
-          "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+        "randombytes": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
+          "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
           "requires": {
-            "find-up": "1.1.2",
-            "read-pkg": "1.1.0"
+            "safe-buffer": "5.1.1"
           }
         },
         "readable-stream": {
-          "version": "2.3.3",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
-          "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+          "version": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502",
           "requires": {
-            "core-util-is": "1.0.2",
             "inherits": "2.0.3",
             "isarray": "1.0.0",
             "process-nextick-args": "1.0.7",
             "safe-buffer": "5.1.1",
             "string_decoder": "1.0.3",
             "util-deprecate": "1.0.2"
+          },
+          "dependencies": {
+            "inherits": {
+              "version": "2.0.3",
+              "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+              "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+            }
           }
         },
-        "redent": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
-          "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
-          "requires": {
-            "indent-string": "2.1.0",
-            "strip-indent": "1.0.1"
-          }
-        },
-        "repeating": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
-          "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
-          "requires": {
-            "is-finite": "1.0.2"
-          }
-        },
-        "request": {
-          "version": "2.83.0",
-          "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
-          "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
-          "requires": {
-            "aws-sign2": "0.7.0",
-            "aws4": "1.6.0",
-            "caseless": "0.12.0",
-            "combined-stream": "1.0.5",
-            "extend": "3.0.1",
-            "forever-agent": "0.6.1",
-            "form-data": "2.3.1",
-            "har-validator": "5.0.3",
-            "hawk": "6.0.2",
-            "http-signature": "1.2.0",
-            "is-typedarray": "1.0.0",
-            "isstream": "0.1.2",
-            "json-stringify-safe": "5.0.1",
-            "mime-types": "2.1.17",
-            "oauth-sign": "0.8.2",
-            "performance-now": "2.1.0",
-            "qs": "6.5.1",
-            "safe-buffer": "5.1.1",
-            "stringstream": "0.0.5",
-            "tough-cookie": "2.3.3",
-            "tunnel-agent": "0.6.0",
-            "uuid": "3.1.0"
-          }
-        },
-        "require-directory": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-          "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
-        },
-        "require-main-filename": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
-          "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
-        },
         "rimraf": {
           "version": "2.6.2",
           "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
@@ -4879,1898 +3630,1950 @@
             "glob": "7.1.2"
           }
         },
+        "ripemd160": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
+          "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
+          "requires": {
+            "hash-base": "2.0.2",
+            "inherits": "2.0.1"
+          }
+        },
         "safe-buffer": {
           "version": "5.1.1",
           "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
           "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
         },
-        "sass-graph": {
-          "version": "2.2.4",
-          "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
-          "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
+        "sha.js": {
+          "version": "2.4.9",
+          "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz",
+          "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==",
           "requires": {
-            "glob": "7.1.2",
-            "lodash": "4.17.4",
-            "scss-tokenizer": "0.2.3",
-            "yargs": "7.1.0"
+            "inherits": "2.0.1",
+            "safe-buffer": "5.1.1"
           }
         },
-        "scss-tokenizer": {
-          "version": "0.2.3",
-          "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
-          "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+        "stream-browserify": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
+          "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
           "requires": {
-            "js-base64": "2.4.0",
-            "source-map": "0.4.4"
+            "inherits": "2.0.1",
+            "readable-stream": "git+https://github.com/meteor/readable-stream.git#d64a64aa6061b9b6855feff4d09e58fb3b2e4502"
           }
         },
-        "semver": {
-          "version": "5.4.1",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
-          "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
-        },
-        "set-blocking": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
-          "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
-        },
-        "signal-exit": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-          "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
-        },
-        "sntp": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
-          "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
+        "string_decoder": {
+          "version": "1.0.3",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
           "requires": {
-            "hoek": "4.2.0"
+            "safe-buffer": "5.1.1"
           }
         },
-        "source-map": {
-          "version": "0.4.4",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
-          "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+        "timers-browserify": {
+          "version": "1.4.2",
+          "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz",
+          "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=",
           "requires": {
-            "amdefine": "1.0.1"
+            "process": "0.11.10"
           }
         },
-        "spdx-correct": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
-          "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+        "tty-browserify": {
+          "version": "0.0.0",
+          "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
+          "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY="
+        },
+        "url": {
+          "version": "0.11.0",
+          "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+          "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
           "requires": {
-            "spdx-license-ids": "1.2.2"
+            "punycode": "1.3.2",
+            "querystring": "0.2.0"
+          },
+          "dependencies": {
+            "punycode": {
+              "version": "1.3.2",
+              "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+              "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+            }
           }
         },
-        "spdx-expression-parse": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
-          "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw="
-        },
-        "spdx-license-ids": {
-          "version": "1.2.2",
-          "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
-          "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc="
-        },
-        "sshpk": {
-          "version": "1.13.1",
-          "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
-          "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+        "util": {
+          "version": "0.10.3",
+          "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
+          "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
           "requires": {
-            "asn1": "0.2.3",
-            "assert-plus": "1.0.0",
-            "bcrypt-pbkdf": "1.0.1",
-            "dashdash": "1.14.1",
-            "ecc-jsbn": "0.1.1",
-            "getpass": "0.1.7",
-            "jsbn": "0.1.1",
-            "tweetnacl": "0.14.5"
+            "inherits": "2.0.1"
           }
         },
-        "stdout-stream": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
-          "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=",
+        "util-deprecate": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+          "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+        },
+        "vm-browserify": {
+          "version": "0.0.4",
+          "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz",
+          "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=",
           "requires": {
-            "readable-stream": "2.3.3"
+            "indexof": "0.0.1"
           }
         },
-        "string-width": {
+        "wrappy": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+        }
+      }
+    },
+    "mime": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+      "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
+      "dev": true
+    },
+    "mime-db": {
+      "version": "1.30.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
+      "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
+    },
+    "mime-types": {
+      "version": "2.1.17",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
+      "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+      "requires": {
+        "mime-db": "1.30.0"
+      }
+    },
+    "mimic-fn": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
+      "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
+      "dev": true
+    },
+    "mimic-response": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
+      "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4="
+    },
+    "min-document": {
+      "version": "2.19.0",
+      "resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
+      "integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
+      "dev": true,
+      "requires": {
+        "dom-walk": "0.1.1"
+      }
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "requires": {
+        "brace-expansion": "1.1.8"
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "ms": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+      "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+    },
+    "mute-stream": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+      "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
+      "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo="
+    },
+    "natural-compare": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+      "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+      "dev": true
+    },
+    "next-tick": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
+    },
+    "node-fetch": {
+      "version": "1.7.3",
+      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
+      "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+      "requires": {
+        "encoding": "0.1.12",
+        "is-stream": "1.1.0"
+      }
+    },
+    "node-gyp": {
+      "version": "3.6.2",
+      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz",
+      "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=",
+      "requires": {
+        "fstream": "1.0.11",
+        "glob": "7.1.2",
+        "graceful-fs": "4.1.11",
+        "minimatch": "3.0.4",
+        "mkdirp": "0.5.1",
+        "nopt": "3.0.6",
+        "npmlog": "4.1.2",
+        "osenv": "0.1.4",
+        "request": "2.83.0",
+        "rimraf": "2.6.2",
+        "semver": "5.3.0",
+        "tar": "2.2.1",
+        "which": "1.3.0"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.3.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
+        }
+      }
+    },
+    "node-resemble-js": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/node-resemble-js/-/node-resemble-js-0.0.5.tgz",
+      "integrity": "sha1-rLOxWOCxaiQahuyJO+Hfx9MzR2Q=",
+      "dev": true,
+      "requires": {
+        "pngjs": "2.2.0"
+      }
+    },
+    "node-sass": {
+      "version": "4.5.3",
+      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.5.3.tgz",
+      "integrity": "sha1-0JydEXlkEjnRuX/8YjH9zsU+FWg=",
+      "requires": {
+        "async-foreach": "0.1.3",
+        "chalk": "1.1.3",
+        "cross-spawn": "3.0.1",
+        "gaze": "1.1.2",
+        "get-stdin": "4.0.1",
+        "glob": "7.1.2",
+        "in-publish": "2.0.0",
+        "lodash.assign": "4.2.0",
+        "lodash.clonedeep": "4.5.0",
+        "lodash.mergewith": "4.6.0",
+        "meow": "3.7.0",
+        "mkdirp": "0.5.1",
+        "nan": "2.8.0",
+        "node-gyp": "3.6.2",
+        "npmlog": "4.1.2",
+        "request": "2.83.0",
+        "sass-graph": "2.2.4",
+        "stdout-stream": "1.4.0"
+      }
+    },
+    "nopt": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+      "requires": {
+        "abbrev": "1.1.1"
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+      "requires": {
+        "hosted-git-info": "2.5.0",
+        "is-builtin-module": "1.0.0",
+        "semver": "5.5.0",
+        "validate-npm-package-license": "3.0.1"
+      }
+    },
+    "normalize-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-1.0.0.tgz",
+      "integrity": "sha1-MtDkcvkf80VwHBWoMRAY07CpA3k=",
+      "dev": true
+    },
+    "normalize-range": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+      "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+      "dev": true
+    },
+    "npm-install-package": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz",
+      "integrity": "sha1-1+/jz816sAYUuJbqUxGdyaslkSU=",
+      "dev": true
+    },
+    "npm-path": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz",
+      "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==",
+      "dev": true,
+      "requires": {
+        "which": "1.3.0"
+      }
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "requires": {
+        "path-key": "2.0.1"
+      }
+    },
+    "npm-which": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz",
+      "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=",
+      "dev": true,
+      "requires": {
+        "commander": "2.13.0",
+        "npm-path": "2.0.4",
+        "which": "1.3.0"
+      }
+    },
+    "npmlog": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+      "requires": {
+        "are-we-there-yet": "1.1.4",
+        "console-control-strings": "1.1.0",
+        "gauge": "2.7.4",
+        "set-blocking": "2.0.0"
+      }
+    },
+    "num2fraction": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+      "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+      "dev": true
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+    },
+    "oauth-sign": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
+      "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM="
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+    },
+    "object-keys": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
+      "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
+      "dev": true
+    },
+    "object.assign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+      "dev": true,
+      "requires": {
+        "define-properties": "1.1.2",
+        "function-bind": "1.1.1",
+        "has-symbols": "1.0.0",
+        "object-keys": "1.0.11"
+      }
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "requires": {
+        "wrappy": "1.0.2"
+      }
+    },
+    "onetime": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+      "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+      "dev": true,
+      "requires": {
+        "mimic-fn": "1.1.0"
+      }
+    },
+    "optimist": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+      "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+      "dev": true,
+      "requires": {
+        "minimist": "0.0.8",
+        "wordwrap": "0.0.3"
+      },
+      "dependencies": {
+        "wordwrap": {
+          "version": "0.0.3",
+          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
+          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+          "dev": true
+        }
+      }
+    },
+    "optionator": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+      "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+      "dev": true,
+      "requires": {
+        "deep-is": "0.1.3",
+        "fast-levenshtein": "2.0.6",
+        "levn": "0.3.0",
+        "prelude-ls": "1.1.2",
+        "type-check": "0.3.2",
+        "wordwrap": "1.0.0"
+      }
+    },
+    "ora": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz",
+      "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=",
+      "dev": true,
+      "requires": {
+        "chalk": "1.1.3",
+        "cli-cursor": "1.0.2",
+        "cli-spinners": "0.1.2",
+        "object-assign": "4.1.1"
+      },
+      "dependencies": {
+        "cli-cursor": {
           "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
-          "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
-          "requires": {
-            "code-point-at": "1.1.0",
-            "is-fullwidth-code-point": "1.0.0",
-            "strip-ansi": "3.0.1"
-          }
-        },
-        "string_decoder": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
-          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
-          "requires": {
-            "safe-buffer": "5.1.1"
-          }
-        },
-        "stringstream": {
-          "version": "0.0.5",
-          "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
-          "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+          "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+          "dev": true,
           "requires": {
-            "ansi-regex": "2.1.1"
+            "restore-cursor": "1.0.1"
           }
         },
-        "strip-bom": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
-          "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
-          "requires": {
-            "is-utf8": "0.2.1"
-          }
+        "onetime": {
+          "version": "1.1.0",
+          "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+          "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
+          "dev": true
         },
-        "strip-indent": {
+        "restore-cursor": {
           "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
-          "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
-          "requires": {
-            "get-stdin": "4.0.1"
-          }
-        },
-        "supports-color": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-          "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
-        },
-        "tar": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
-          "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
-          "requires": {
-            "block-stream": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
-            "fstream": "1.0.11",
-            "inherits": "2.0.3"
-          }
-        },
-        "tough-cookie": {
-          "version": "2.3.3",
-          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
-          "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
-          "requires": {
-            "punycode": "1.4.1"
-          }
-        },
-        "trim-newlines": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
-          "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
-        },
-        "tunnel-agent": {
-          "version": "0.6.0",
-          "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-          "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-          "requires": {
-            "safe-buffer": "5.1.1"
-          }
-        },
-        "tweetnacl": {
-          "version": "0.14.5",
-          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-          "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-          "optional": true
-        },
-        "util-deprecate": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-          "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
-        },
-        "uuid": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
-          "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
-        },
-        "validate-npm-package-license": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
-          "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
-          "requires": {
-            "spdx-correct": "1.0.2",
-            "spdx-expression-parse": "1.0.4"
-          }
-        },
-        "verror": {
-          "version": "1.10.0",
-          "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-          "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-          "requires": {
-            "assert-plus": "1.0.0",
-            "core-util-is": "1.0.2",
-            "extsprintf": "1.3.0"
-          }
-        },
-        "which": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
-          "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
+          "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
+          "dev": true,
           "requires": {
-            "isexe": "2.0.0"
+            "exit-hook": "1.1.1",
+            "onetime": "1.1.0"
           }
-        },
-        "which-module": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
-          "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
-        },
-        "wide-align": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
-          "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
+        }
+      }
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
+    },
+    "os-locale": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+      "requires": {
+        "lcid": "1.0.0"
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+    },
+    "osenv": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
+      "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
+      "requires": {
+        "os-homedir": "1.0.2",
+        "os-tmpdir": "1.0.2"
+      }
+    },
+    "p-cancelable": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
+      "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw=="
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
+    },
+    "p-limit": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
+      "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
+      "dev": true,
+      "requires": {
+        "p-try": "1.0.0"
+      }
+    },
+    "p-locate": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+      "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+      "dev": true,
+      "requires": {
+        "p-limit": "1.2.0"
+      }
+    },
+    "p-map": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
+      "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
+      "dev": true
+    },
+    "p-timeout": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
+      "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
+      "requires": {
+        "p-finally": "1.0.0"
+      }
+    },
+    "p-try": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+      "dev": true
+    },
+    "parse-bmfont-ascii": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/parse-bmfont-ascii/-/parse-bmfont-ascii-1.0.6.tgz",
+      "integrity": "sha1-Eaw8P/WPfCAgqyJ2kHkQjU36AoU=",
+      "dev": true
+    },
+    "parse-bmfont-binary": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/parse-bmfont-binary/-/parse-bmfont-binary-1.0.6.tgz",
+      "integrity": "sha1-0Di0dtPp3Z2x4RoLDlOiJ5K2kAY=",
+      "dev": true
+    },
+    "parse-bmfont-xml": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.3.tgz",
+      "integrity": "sha1-1rZqNxr9OcUAfZ8O6yYqTyzOe3w=",
+      "dev": true,
+      "requires": {
+        "xml-parse-from-string": "1.0.1",
+        "xml2js": "0.4.19"
+      }
+    },
+    "parse-headers": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz",
+      "integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=",
+      "dev": true,
+      "requires": {
+        "for-each": "0.3.2",
+        "trim": "0.0.1"
+      }
+    },
+    "parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "requires": {
+        "error-ex": "1.3.1"
+      }
+    },
+    "path-exists": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+      "requires": {
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz",
+      "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
+      "dev": true
+    },
+    "path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "requires": {
+        "graceful-fs": "4.1.11",
+        "pify": "2.3.0",
+        "pinkie-promise": "2.0.1"
+      }
+    },
+    "pathval": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+      "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+      "dev": true
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+    },
+    "pify": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "requires": {
+        "pinkie": "2.0.4"
+      }
+    },
+    "pixelmatch": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz",
+      "integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=",
+      "dev": true,
+      "requires": {
+        "pngjs": "3.3.1"
+      },
+      "dependencies": {
+        "pngjs": {
+          "version": "3.3.1",
+          "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.1.tgz",
+          "integrity": "sha512-ggXCTsqHRIsGMkHlCEhbHhUmNTA2r1lpkE0NL4Q9S8spkXbm4vE9TVmPso2AGYn90Gltdz8W5CyzhcIGg2Gejg==",
+          "dev": true
+        }
+      }
+    },
+    "pkg-dir": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz",
+      "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
+      "dev": true,
+      "requires": {
+        "find-up": "1.1.2"
+      }
+    },
+    "platform": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz",
+      "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==",
+      "dev": true
+    },
+    "pluralize": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+      "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==",
+      "dev": true
+    },
+    "pngjs": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-2.2.0.tgz",
+      "integrity": "sha1-ZJZjYJoOurh8jwiz/nJASLUdnX8=",
+      "dev": true
+    },
+    "popper.js": {
+      "version": "1.12.9",
+      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.12.9.tgz",
+      "integrity": "sha1-DfvC3/lsRRuzMu3Pz6r1ZtMx1bM="
+    },
+    "postcss": {
+      "version": "6.0.16",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
+      "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
+      "dev": true,
+      "requires": {
+        "chalk": "2.3.0",
+        "source-map": "0.6.1",
+        "supports-color": "5.1.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
           "requires": {
-            "string-width": "1.0.2"
+            "color-convert": "1.9.1"
           }
         },
-        "wrap-ansi": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
-          "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
           "requires": {
-            "string-width": "1.0.2",
-            "strip-ansi": "3.0.1"
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
+          },
+          "dependencies": {
+            "supports-color": {
+              "version": "4.5.0",
+              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+              "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+              "dev": true,
+              "requires": {
+                "has-flag": "2.0.0"
+              }
+            }
           }
         },
-        "wrappy": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
-        },
-        "y18n": {
-          "version": "3.2.1",
-          "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
-          "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
-        },
-        "yallist": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
-          "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true
         },
-        "yargs": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
-          "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+        "supports-color": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
+          "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
+          "dev": true,
           "requires": {
-            "camelcase": "3.0.0",
-            "cliui": "3.2.0",
-            "decamelize": "1.2.0",
-            "get-caller-file": "1.0.2",
-            "os-locale": "1.4.0",
-            "read-pkg-up": "1.0.1",
-            "require-directory": "2.1.1",
-            "require-main-filename": "1.0.1",
-            "set-blocking": "2.0.0",
-            "string-width": "1.0.2",
-            "which-module": "1.0.0",
-            "y18n": "3.2.1",
-            "yargs-parser": "5.0.0"
-          },
-          "dependencies": {
-            "camelcase": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
-              "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
-            }
+            "has-flag": "2.0.0"
           }
+        }
+      }
+    },
+    "postcss-modules-extract-imports": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz",
+      "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=",
+      "dev": true,
+      "requires": {
+        "postcss": "6.0.16"
+      }
+    },
+    "postcss-modules-local-by-default": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
+      "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
+      "dev": true,
+      "requires": {
+        "css-selector-tokenizer": "0.7.0",
+        "postcss": "6.0.16"
+      }
+    },
+    "postcss-modules-scope": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
+      "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
+      "dev": true,
+      "requires": {
+        "css-selector-tokenizer": "0.7.0",
+        "postcss": "6.0.16"
+      }
+    },
+    "postcss-modules-values": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz",
+      "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
+      "dev": true,
+      "requires": {
+        "icss-replace-symbols": "1.1.0",
+        "postcss": "6.0.16"
+      }
+    },
+    "postcss-nested": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-2.1.2.tgz",
+      "integrity": "sha512-CU7KjbFOZSNrbFwrl8+KJHTj29GjCEhL86kCKyvf+k633fc+FQA6IuhGyPze5e+a4O5d2fP7hDlMOlVDXia1Xg==",
+      "dev": true,
+      "requires": {
+        "postcss": "6.0.16",
+        "postcss-selector-parser": "2.2.3"
+      }
+    },
+    "postcss-selector-parser": {
+      "version": "2.2.3",
+      "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
+      "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
+      "dev": true,
+      "requires": {
+        "flatten": "1.0.2",
+        "indexes-of": "1.0.1",
+        "uniq": "1.0.1"
+      }
+    },
+    "postcss-value-parser": {
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
+      "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
+      "dev": true
+    },
+    "prelude-ls": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+      "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+      "dev": true
+    },
+    "prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
+    },
+    "pretty-format": {
+      "version": "21.2.1",
+      "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-21.2.1.tgz",
+      "integrity": "sha512-ZdWPGYAnYfcVP8yKA3zFjCn8s4/17TeYH28MXuC8vTp0o21eXjbFGcOAXZEaDaOFJjc3h2qa7HQNHNshhvoh2A==",
+      "dev": true,
+      "requires": {
+        "ansi-regex": "3.0.0",
+        "ansi-styles": "3.2.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
         },
-        "yargs-parser": {
-          "version": "5.0.0",
-          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
-          "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
           "requires": {
-            "camelcase": "3.0.0"
-          },
-          "dependencies": {
-            "camelcase": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
-              "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
-            }
+            "color-convert": "1.9.1"
           }
         }
       }
     },
-    "p-try": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
-      "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
-      "dev": true
+    "probe-image-size": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-3.1.0.tgz",
+      "integrity": "sha1-50e+maDQqOUFiqcihUwkCSuS3WY=",
+      "requires": {
+        "any-promise": "1.3.0",
+        "deepmerge": "1.5.2",
+        "got": "7.1.0",
+        "inherits": "2.0.3",
+        "next-tick": "1.0.0",
+        "stream-parser": "0.3.1"
+      }
+    },
+    "process": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+      "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+      "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+    },
+    "progress": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+      "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
+      "dev": true
+    },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "requires": {
+        "asap": "2.0.6"
+      }
+    },
+    "prop-types": {
+      "version": "15.6.0",
+      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
+      "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
+      "requires": {
+        "fbjs": "0.8.16",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1"
+      }
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+    },
+    "punycode": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+      "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+    },
+    "q": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+      "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+      "dev": true
+    },
+    "qs": {
+      "version": "6.5.1",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+      "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
+    },
+    "query-string": {
+      "version": "4.3.4",
+      "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz",
+      "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
+      "requires": {
+        "object-assign": "4.1.1",
+        "strict-uri-encode": "1.1.0"
+      }
+    },
+    "querystring": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
+    },
+    "react": {
+      "version": "16.0.0",
+      "resolved": "https://registry.npmjs.org/react/-/react-16.0.0.tgz",
+      "integrity": "sha1-zn348ZQbA28Cssyp29DLHw6FXi0=",
+      "requires": {
+        "fbjs": "0.8.16",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1",
+        "prop-types": "15.6.0"
+      }
+    },
+    "react-autosize-textarea": {
+      "version": "0.4.9",
+      "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-0.4.9.tgz",
+      "integrity": "sha1-jVXIX0xmWm1jWehK8oYQnFBKsps=",
+      "requires": {
+        "autosize": "3.0.21",
+        "line-height": "0.3.1",
+        "prop-types": "15.6.0"
+      }
+    },
+    "react-color": {
+      "version": "2.13.8",
+      "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.13.8.tgz",
+      "integrity": "sha1-vMWPeaciub/DfEAuaM0Y8mlwruQ=",
+      "requires": {
+        "lodash": "4.17.4",
+        "material-colors": "1.2.5",
+        "prop-types": "15.6.0",
+        "reactcss": "1.2.3",
+        "tinycolor2": "1.4.1"
+      }
+    },
+    "react-dom": {
+      "version": "16.0.0",
+      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.0.0.tgz",
+      "integrity": "sha1-nMMHnD3NcNTG4BuEqrKn40wwP1g=",
+      "requires": {
+        "fbjs": "0.8.16",
+        "loose-envify": "1.3.1",
+        "object-assign": "4.1.1",
+        "prop-types": "15.6.0"
+      }
+    },
+    "react-dropzone": {
+      "version": "4.2.7",
+      "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-4.2.7.tgz",
+      "integrity": "sha512-BGEc/UtG0rHBEZjAkGsajPRO85d842LWeaP4CINHvXrSNyKp7Tq7s699NyZwWYHahvXaUNZzNJ17JMrfg5sxVg==",
+      "requires": {
+        "attr-accept": "1.1.0",
+        "prop-types": "15.6.0"
+      }
+    },
+    "react-intl": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-2.4.0.tgz",
+      "integrity": "sha1-ZsFNyd+ac7L7v71gIXJugKYT6xU=",
+      "requires": {
+        "intl-format-cache": "2.1.0",
+        "intl-messageformat": "2.2.0",
+        "intl-relativeformat": "2.1.0",
+        "invariant": "2.2.2"
+      }
+    },
+    "react-modal": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.0.4.tgz",
+      "integrity": "sha512-IvRZxJkXiDqEIl4cxCccCzP37z+YOSN+yNOkYH99Ime+n9nPSowgxkX0KfHzR2ezP72LSS3Uln54JDZXUJmLdA==",
+      "requires": {
+        "exenv": "1.2.2",
+        "prop-types": "15.6.0"
+      }
+    },
+    "react-router": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/react-router/-/react-router-3.0.5.tgz",
+      "integrity": "sha1-w7eHN1gEWou8lWKu9P9LyMznwTY=",
+      "requires": {
+        "create-react-class": "15.6.2",
+        "history": "3.3.0",
+        "hoist-non-react-statics": "1.2.0",
+        "invariant": "2.2.2",
+        "loose-envify": "1.3.1",
+        "prop-types": "15.6.0",
+        "warning": "3.0.0"
+      }
     },
-    "popper.js": {
-      "version": "1.12.9",
-      "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.12.9.tgz",
-      "integrity": "sha1-DfvC3/lsRRuzMu3Pz6r1ZtMx1bM="
+    "react-tabs": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-2.1.1.tgz",
+      "integrity": "sha512-55jl6lsYmPTQarnjgrBU68WZlNtVSngpRxOc4iXm+Te27F9ixUr/IBTbhlhDCMiFJreP+cqu1OaMdNGY2Hg10A==",
+      "requires": {
+        "classnames": "2.2.5",
+        "prop-types": "15.6.0"
+      }
     },
-    "postcss-modules-extract-imports": {
+    "react-toastify": {
+      "version": "2.1.7",
+      "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-2.1.7.tgz",
+      "integrity": "sha512-iMS5wXiTDKXcWTIF055BmsSwJINcxs9+CUGeEPMSllU0I00IKfV2inb3xhRxrB7d+4QvPqWZAtDPTk6nz6o1nA==",
+      "requires": {
+        "prop-types": "15.6.0",
+        "react-transition-group": "2.2.1"
+      }
+    },
+    "react-toggle": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/react-toggle/-/react-toggle-4.0.2.tgz",
+      "integrity": "sha512-EPTWnN7gQHgEAUEmjheanZXNzY5TPnQeyyHfEs3YshaiWZf5WNjfYDrglO5F1Hl/dNveX18i4l0grTEsYH2Ccw==",
+      "requires": {
+        "classnames": "2.2.5"
+      }
+    },
+    "react-transition-group": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.2.1.tgz",
+      "integrity": "sha512-q54UBM22bs/CekG8r3+vi9TugSqh0t7qcEVycaRc9M0p0aCEu+h6rp/RFiW7fHfgd1IKpd9oILFTl5QK+FpiPA==",
+      "requires": {
+        "chain-function": "1.0.0",
+        "classnames": "2.2.5",
+        "dom-helpers": "3.3.1",
+        "loose-envify": "1.3.1",
+        "prop-types": "15.6.0",
+        "warning": "3.0.0"
+      }
+    },
+    "reactcss": {
+      "version": "1.2.3",
+      "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
+      "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
+      "requires": {
+        "lodash": "4.17.4"
+      }
+    },
+    "read-chunk": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-chunk/-/read-chunk-1.0.1.tgz",
+      "integrity": "sha1-X2jKswfmY/GZk1J9m1icrORmEZQ=",
+      "dev": true
+    },
+    "read-pkg": {
       "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz",
-      "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=",
-      "dev": true,
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
       "requires": {
-        "postcss": "6.0.16"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.1"
-          }
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
-          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.5.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "4.5.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
-              "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
-              "dev": true,
-              "requires": {
-                "has-flag": "2.0.0"
-              }
-            }
-          }
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.16",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
-          "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.3.0",
-            "source-map": "0.6.1",
-            "supports-color": "5.1.0"
-          }
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
-          "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
+        "load-json-file": "1.1.0",
+        "normalize-package-data": "2.4.0",
+        "path-type": "1.1.0"
       }
     },
-    "postcss-modules-local-by-default": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
-      "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
-      "dev": true,
+    "read-pkg-up": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
       "requires": {
-        "css-selector-tokenizer": "0.7.0",
-        "postcss": "6.0.16"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.1"
-          }
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
-          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.5.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "4.5.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
-              "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
-              "dev": true,
-              "requires": {
-                "has-flag": "2.0.0"
-              }
-            }
-          }
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "css-selector-tokenizer": {
-          "version": "0.7.0",
-          "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
-          "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
-          "dev": true,
-          "requires": {
-            "cssesc": "0.1.0",
-            "fastparse": "1.1.1",
-            "regexpu-core": "1.0.0"
-          }
-        },
-        "cssesc": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
-          "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "fastparse": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
-          "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "jsesc": {
-          "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
-          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.16",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
-          "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.3.0",
-            "source-map": "0.6.1",
-            "supports-color": "5.1.0"
-          }
-        },
-        "regenerate": {
-          "version": "1.3.3",
-          "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
-          "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
-          "dev": true
-        },
-        "regexpu-core": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
-          "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
-          "dev": true,
-          "requires": {
-            "regenerate": "1.3.3",
-            "regjsgen": "0.2.0",
-            "regjsparser": "0.1.5"
-          }
-        },
-        "regjsgen": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
-          "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
-          "dev": true
-        },
-        "regjsparser": {
-          "version": "0.1.5",
-          "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
-          "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
-          "dev": true,
-          "requires": {
-            "jsesc": "0.5.0"
-          }
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
-          "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
+        "find-up": "1.1.2",
+        "read-pkg": "1.1.0"
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
+      "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+      "requires": {
+        "core-util-is": "1.0.2",
+        "inherits": "2.0.3",
+        "isarray": "1.0.0",
+        "process-nextick-args": "1.0.7",
+        "safe-buffer": "5.1.1",
+        "string_decoder": "1.0.3",
+        "util-deprecate": "1.0.2"
+      }
+    },
+    "redent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+      "requires": {
+        "indent-string": "2.1.0",
+        "strip-indent": "1.0.1"
+      }
+    },
+    "redis": {
+      "version": "2.8.0",
+      "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz",
+      "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==",
+      "requires": {
+        "double-ended-queue": "2.1.0-0",
+        "redis-commands": "1.3.1",
+        "redis-parser": "2.6.0"
       }
     },
-    "postcss-modules-scope": {
+    "redis-commands": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz",
+      "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs="
+    },
+    "redis-parser": {
+      "version": "2.6.0",
+      "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz",
+      "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs="
+    },
+    "regenerate": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
+      "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
+      "dev": true
+    },
+    "regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+    },
+    "regexpu-core": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
+      "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
+      "dev": true,
+      "requires": {
+        "regenerate": "1.3.3",
+        "regjsgen": "0.2.0",
+        "regjsparser": "0.1.5"
+      }
+    },
+    "regjsgen": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
+      "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
+      "dev": true
+    },
+    "regjsparser": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
+      "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
+      "dev": true,
+      "requires": {
+        "jsesc": "0.5.0"
+      }
+    },
+    "remove-trailing-separator": {
       "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
-      "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "requires": {
+        "is-finite": "1.0.2"
+      }
+    },
+    "request": {
+      "version": "2.83.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+      "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
+      "requires": {
+        "aws-sign2": "0.7.0",
+        "aws4": "1.6.0",
+        "caseless": "0.12.0",
+        "combined-stream": "1.0.5",
+        "extend": "3.0.1",
+        "forever-agent": "0.6.1",
+        "form-data": "2.3.1",
+        "har-validator": "5.0.3",
+        "hawk": "6.0.2",
+        "http-signature": "1.2.0",
+        "is-typedarray": "1.0.0",
+        "isstream": "0.1.2",
+        "json-stringify-safe": "5.0.1",
+        "mime-types": "2.1.17",
+        "oauth-sign": "0.8.2",
+        "performance-now": "2.1.0",
+        "qs": "6.5.1",
+        "safe-buffer": "5.1.1",
+        "stringstream": "0.0.5",
+        "tough-cookie": "2.3.3",
+        "tunnel-agent": "0.6.0",
+        "uuid": "3.2.1"
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+    },
+    "require-from-string": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz",
+      "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=",
+      "dev": true
+    },
+    "require-main-filename": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
+    },
+    "require-uncached": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
+      "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
       "dev": true,
       "requires": {
-        "css-selector-tokenizer": "0.7.0",
-        "postcss": "6.0.16"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.1"
-          }
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
-          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.5.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "4.5.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
-              "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
-              "dev": true,
-              "requires": {
-                "has-flag": "2.0.0"
-              }
-            }
-          }
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "css-selector-tokenizer": {
-          "version": "0.7.0",
-          "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
-          "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
-          "dev": true,
-          "requires": {
-            "cssesc": "0.1.0",
-            "fastparse": "1.1.1",
-            "regexpu-core": "1.0.0"
-          }
-        },
-        "cssesc": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz",
-          "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "fastparse": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz",
-          "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "jsesc": {
-          "version": "0.5.0",
-          "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz",
-          "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.16",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
-          "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.3.0",
-            "source-map": "0.6.1",
-            "supports-color": "5.1.0"
-          }
-        },
-        "regenerate": {
-          "version": "1.3.3",
-          "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
-          "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
-          "dev": true
-        },
-        "regexpu-core": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
-          "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
-          "dev": true,
-          "requires": {
-            "regenerate": "1.3.3",
-            "regjsgen": "0.2.0",
-            "regjsparser": "0.1.5"
-          }
-        },
-        "regjsgen": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz",
-          "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=",
-          "dev": true
-        },
-        "regjsparser": {
-          "version": "0.1.5",
-          "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz",
-          "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
-          "dev": true,
-          "requires": {
-            "jsesc": "0.5.0"
-          }
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
-          "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
+        "caller-path": "0.1.0",
+        "resolve-from": "1.0.1"
       }
     },
-    "postcss-modules-values": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz",
-      "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
+    "resolve": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz",
+      "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==",
       "dev": true,
       "requires": {
-        "icss-replace-symbols": "1.1.0",
-        "postcss": "6.0.16"
-      },
-      "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.1"
-          }
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
-          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.5.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "4.5.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
-              "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
-              "dev": true,
-              "requires": {
-                "has-flag": "2.0.0"
-              }
-            }
-          }
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "icss-replace-symbols": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
-          "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.16",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
-          "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.3.0",
-            "source-map": "0.6.1",
-            "supports-color": "5.1.0"
-          }
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
-          "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        }
+        "path-parse": "1.0.5"
+      }
+    },
+    "resolve-from": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
+      "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=",
+      "dev": true
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "restore-cursor": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+      "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+      "dev": true,
+      "requires": {
+        "onetime": "2.0.1",
+        "signal-exit": "3.0.2"
+      }
+    },
+    "rgb2hex": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.0.tgz",
+      "integrity": "sha1-zNVfhgrgxcTqN1BLlY5ELY0SMls=",
+      "dev": true
+    },
+    "rimraf": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+      "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+      "requires": {
+        "glob": "7.1.2"
+      }
+    },
+    "run-async": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+      "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+      "dev": true,
+      "requires": {
+        "is-promise": "2.1.0"
+      }
+    },
+    "rx": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
+      "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
+      "dev": true
+    },
+    "rx-lite": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+      "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+      "dev": true
+    },
+    "rx-lite-aggregates": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+      "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+      "dev": true,
+      "requires": {
+        "rx-lite": "4.0.8"
+      }
+    },
+    "rxjs": {
+      "version": "5.5.6",
+      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.6.tgz",
+      "integrity": "sha512-v4Q5HDC0FHAQ7zcBX7T2IL6O5ltl1a2GX4ENjPXg6SjDY69Cmx9v4113C99a4wGF16ClPv5Z8mghuYorVkg/kg==",
+      "dev": true,
+      "requires": {
+        "symbol-observable": "1.0.1"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+      "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+    },
+    "sass-graph": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
+      "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
+      "requires": {
+        "glob": "7.1.2",
+        "lodash": "4.17.4",
+        "scss-tokenizer": "0.2.3",
+        "yargs": "7.1.0"
       }
     },
-    "postcss-nested": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/postcss-nested/-/postcss-nested-2.1.2.tgz",
-      "integrity": "sha512-CU7KjbFOZSNrbFwrl8+KJHTj29GjCEhL86kCKyvf+k633fc+FQA6IuhGyPze5e+a4O5d2fP7hDlMOlVDXia1Xg==",
+    "sax": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+      "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+    },
+    "scss-tokenizer": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
+      "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+      "requires": {
+        "js-base64": "2.4.3",
+        "source-map": "0.4.4"
+      }
+    },
+    "select": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
+      "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0="
+    },
+    "semver": {
+      "version": "5.5.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+      "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+    },
+    "setimmediate": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
+      "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+    },
+    "slice-ansi": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+      "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
       "dev": true,
       "requires": {
-        "postcss": "6.0.16",
-        "postcss-selector-parser": "2.2.3"
+        "is-fullwidth-code-point": "2.0.0"
       },
       "dependencies": {
-        "ansi-styles": {
-          "version": "3.2.0",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
-          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
-          "dev": true,
-          "requires": {
-            "color-convert": "1.9.1"
-          }
-        },
-        "chalk": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
-          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "3.2.0",
-            "escape-string-regexp": "1.0.5",
-            "supports-color": "4.5.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "4.5.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
-              "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
-              "dev": true,
-              "requires": {
-                "has-flag": "2.0.0"
-              }
-            }
-          }
-        },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "flatten": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
-          "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
-          "dev": true
-        },
-        "has-flag": {
+        "is-fullwidth-code-point": {
           "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "indexes-of": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
-          "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
-          "dev": true
-        },
-        "postcss": {
-          "version": "6.0.16",
-          "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.16.tgz",
-          "integrity": "sha512-m758RWPmSjFH/2MyyG3UOW1fgYbR9rtdzz5UNJnlm7OLtu4B2h9C6gi+bE4qFKghsBRFfZT8NzoQBs6JhLotoA==",
-          "dev": true,
-          "requires": {
-            "chalk": "2.3.0",
-            "source-map": "0.6.1",
-            "supports-color": "5.1.0"
-          }
-        },
-        "postcss-selector-parser": {
-          "version": "2.2.3",
-          "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
-          "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
-          "dev": true,
-          "requires": {
-            "flatten": "1.0.2",
-            "indexes-of": "1.0.1",
-            "uniq": "1.0.1"
-          }
-        },
-        "source-map": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-          "dev": true
-        },
-        "supports-color": {
-          "version": "5.1.0",
-          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz",
-          "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==",
-          "dev": true,
-          "requires": {
-            "has-flag": "2.0.0"
-          }
-        },
-        "uniq": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
-          "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
           "dev": true
         }
       }
     },
-    "probe-image-size": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/probe-image-size/-/probe-image-size-3.1.0.tgz",
-      "integrity": "sha1-50e+maDQqOUFiqcihUwkCSuS3WY=",
+    "sntp": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+      "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
       "requires": {
-        "any-promise": "1.3.0",
-        "deepmerge": "1.5.2",
-        "got": "7.1.0",
-        "inherits": "2.0.3",
-        "next-tick": "1.0.0",
-        "stream-parser": "0.3.1"
-      },
-      "dependencies": {
-        "any-promise": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
-          "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
-        },
-        "debug": {
-          "version": "2.6.9",
-          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
-          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
-          "requires": {
-            "ms": "2.0.0"
-          }
-        },
-        "decompress-response": {
-          "version": "3.3.0",
-          "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
-          "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
-          "requires": {
-            "mimic-response": "1.0.0"
-          }
-        },
-        "deepmerge": {
-          "version": "1.5.2",
-          "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.5.2.tgz",
-          "integrity": "sha512-95k0GDqvBjZavkuvzx/YqVLv/6YYa17fz6ILMSf7neqQITCPbnfEnQvEgMPNjH4kgobe7+WIL0yJEHku+H3qtQ=="
-        },
-        "duplexer3": {
-          "version": "0.1.4",
-          "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
-          "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI="
-        },
-        "get-stream": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
-          "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ="
-        },
-        "got": {
-          "version": "7.1.0",
-          "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz",
-          "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==",
-          "requires": {
-            "decompress-response": "3.3.0",
-            "duplexer3": "0.1.4",
-            "get-stream": "3.0.0",
-            "is-plain-obj": "1.1.0",
-            "is-retry-allowed": "1.1.0",
-            "is-stream": "1.1.0",
-            "isurl": "1.0.0",
-            "lowercase-keys": "1.0.0",
-            "p-cancelable": "0.3.0",
-            "p-timeout": "1.2.1",
-            "safe-buffer": "5.1.1",
-            "timed-out": "4.0.1",
-            "url-parse-lax": "1.0.0",
-            "url-to-options": "1.0.1"
-          }
-        },
-        "has-symbol-support-x": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.1.tgz",
-          "integrity": "sha512-JkaetveU7hFbqnAC1EV1sF4rlojU2D4Usc5CmS69l6NfmPDnpnFUegzFg33eDkkpNCxZ0mQp65HwUDrNFS/8MA=="
-        },
-        "has-to-string-tag-x": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz",
-          "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==",
-          "requires": {
-            "has-symbol-support-x": "1.4.1"
-          }
-        },
-        "inherits": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
-        },
-        "is-object": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz",
-          "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA="
-        },
-        "is-plain-obj": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
-          "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4="
-        },
-        "is-retry-allowed": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
-          "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ="
-        },
-        "is-stream": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-          "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
-        },
-        "isurl": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz",
-          "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==",
-          "requires": {
-            "has-to-string-tag-x": "1.4.1",
-            "is-object": "1.0.1"
-          }
-        },
-        "lowercase-keys": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
-          "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY="
-        },
-        "mimic-response": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
-          "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4="
-        },
-        "ms": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
-        },
-        "next-tick": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
-          "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw="
-        },
-        "p-cancelable": {
-          "version": "0.3.0",
-          "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz",
-          "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw=="
-        },
-        "p-finally": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
-          "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4="
-        },
-        "p-timeout": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.1.tgz",
-          "integrity": "sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y=",
-          "requires": {
-            "p-finally": "1.0.0"
-          }
-        },
-        "prepend-http": {
-          "version": "1.0.4",
-          "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
-          "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw="
-        },
-        "safe-buffer": {
-          "version": "5.1.1",
-          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
-          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
-        },
-        "stream-parser": {
-          "version": "0.3.1",
-          "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz",
-          "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=",
-          "requires": {
-            "debug": "2.6.9"
-          }
-        },
-        "timed-out": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
-          "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
-        },
-        "url-parse-lax": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
-          "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
-          "requires": {
-            "prepend-http": "1.0.4"
-          }
-        },
-        "url-to-options": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
-          "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k="
-        }
+        "hoek": "4.2.0"
       }
     },
-    "prop-types": {
-      "version": "15.6.0",
-      "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
-      "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
+    "source-map": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+      "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
       "requires": {
-        "fbjs": "0.8.16",
-        "loose-envify": "1.3.1",
-        "object-assign": "4.1.1"
-      },
-      "dependencies": {
-        "asap": {
-          "version": "2.0.6",
-          "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
-          "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
-        },
-        "core-js": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
-        },
-        "encoding": {
-          "version": "0.1.12",
-          "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
-          "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
-          "requires": {
-            "iconv-lite": "0.4.19"
-          }
-        },
-        "fbjs": {
-          "version": "0.8.16",
-          "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
-          "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
-          "requires": {
-            "core-js": "1.2.7",
-            "isomorphic-fetch": "2.2.1",
-            "loose-envify": "1.3.1",
-            "object-assign": "4.1.1",
-            "promise": "7.3.1",
-            "setimmediate": "1.0.5",
-            "ua-parser-js": "0.7.17"
-          }
-        },
-        "iconv-lite": {
-          "version": "0.4.19",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
-          "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
-        },
-        "is-stream": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-          "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
-        },
-        "isomorphic-fetch": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
-          "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
-          "requires": {
-            "node-fetch": "1.7.3",
-            "whatwg-fetch": "2.0.3"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
-        },
-        "loose-envify": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-          "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-          "requires": {
-            "js-tokens": "3.0.2"
-          }
-        },
-        "node-fetch": {
-          "version": "1.7.3",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
-          "requires": {
-            "encoding": "0.1.12",
-            "is-stream": "1.1.0"
-          }
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-        },
-        "promise": {
-          "version": "7.3.1",
-          "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
-          "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
-          "requires": {
-            "asap": "2.0.6"
-          }
-        },
-        "setimmediate": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-          "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
-        },
-        "ua-parser-js": {
-          "version": "0.7.17",
-          "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
-          "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
-        },
-        "whatwg-fetch": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
-          "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
-        }
+        "amdefine": "1.0.1"
       }
     },
-    "react": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/react/-/react-16.0.0.tgz",
-      "integrity": "sha1-zn348ZQbA28Cssyp29DLHw6FXi0=",
+    "source-map-resolve": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz",
+      "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=",
+      "dev": true,
       "requires": {
-        "fbjs": "0.8.16",
-        "loose-envify": "1.3.1",
-        "object-assign": "4.1.1",
-        "prop-types": "15.6.0"
-      },
-      "dependencies": {
-        "asap": {
-          "version": "2.0.6",
-          "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
-          "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
-        },
-        "core-js": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
-        },
-        "encoding": {
-          "version": "0.1.12",
-          "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
-          "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
-          "requires": {
-            "iconv-lite": "0.4.19"
-          }
-        },
-        "fbjs": {
-          "version": "0.8.16",
-          "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
-          "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
-          "requires": {
-            "core-js": "1.2.7",
-            "isomorphic-fetch": "2.2.1",
-            "loose-envify": "1.3.1",
-            "object-assign": "4.1.1",
-            "promise": "7.3.1",
-            "setimmediate": "1.0.5",
-            "ua-parser-js": "0.7.17"
-          }
-        },
-        "iconv-lite": {
-          "version": "0.4.19",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
-          "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
-        },
-        "is-stream": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-          "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
-        },
-        "isomorphic-fetch": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
-          "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
-          "requires": {
-            "node-fetch": "1.7.3",
-            "whatwg-fetch": "2.0.3"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
-        },
-        "loose-envify": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-          "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-          "requires": {
-            "js-tokens": "3.0.2"
-          }
-        },
-        "node-fetch": {
-          "version": "1.7.3",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
-          "requires": {
-            "encoding": "0.1.12",
-            "is-stream": "1.1.0"
-          }
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-        },
-        "promise": {
-          "version": "7.3.1",
-          "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
-          "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
-          "requires": {
-            "asap": "2.0.6"
-          }
-        },
-        "setimmediate": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-          "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
-        },
-        "ua-parser-js": {
-          "version": "0.7.17",
-          "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
-          "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
-        },
-        "whatwg-fetch": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
-          "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
-        }
+        "atob": "1.1.3",
+        "resolve-url": "0.2.1",
+        "source-map-url": "0.3.0",
+        "urix": "0.1.0"
+      }
+    },
+    "source-map-url": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz",
+      "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
+      "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+      "requires": {
+        "spdx-license-ids": "1.2.2"
       }
     },
-    "react-autosize-textarea": {
-      "version": "0.4.9",
-      "resolved": "https://registry.npmjs.org/react-autosize-textarea/-/react-autosize-textarea-0.4.9.tgz",
-      "integrity": "sha1-jVXIX0xmWm1jWehK8oYQnFBKsps=",
+    "spdx-expression-parse": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
+      "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw="
+    },
+    "spdx-license-ids": {
+      "version": "1.2.2",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
+      "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc="
+    },
+    "sprintf-js": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+      "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+      "dev": true
+    },
+    "sshpk": {
+      "version": "1.13.1",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
+      "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
       "requires": {
-        "autosize": "3.0.21",
-        "line-height": "0.3.1",
-        "prop-types": "15.6.0"
-      },
-      "dependencies": {
-        "autosize": {
-          "version": "3.0.21",
-          "resolved": "https://registry.npmjs.org/autosize/-/autosize-3.0.21.tgz",
-          "integrity": "sha1-8YL0DRd1fZeKE5pMnKQMTA5EhgM="
-        },
-        "computed-style": {
-          "version": "0.1.4",
-          "resolved": "https://registry.npmjs.org/computed-style/-/computed-style-0.1.4.tgz",
-          "integrity": "sha1-fzRP2FhLLkJb7cpKGvwOMAuwXXQ="
-        },
-        "line-height": {
-          "version": "0.3.1",
-          "resolved": "https://registry.npmjs.org/line-height/-/line-height-0.3.1.tgz",
-          "integrity": "sha1-SxIF7d4YKHKl76PI9iCzGHqcVMk=",
-          "requires": {
-            "computed-style": "0.1.4"
-          }
-        }
+        "asn1": "0.2.3",
+        "assert-plus": "1.0.0",
+        "bcrypt-pbkdf": "1.0.1",
+        "dashdash": "1.14.1",
+        "ecc-jsbn": "0.1.1",
+        "getpass": "0.1.7",
+        "jsbn": "0.1.1",
+        "tweetnacl": "0.14.5"
       }
     },
-    "react-color": {
-      "version": "2.13.8",
-      "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.13.8.tgz",
-      "integrity": "sha1-vMWPeaciub/DfEAuaM0Y8mlwruQ=",
+    "stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
+    },
+    "staged-git-files": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-0.0.4.tgz",
+      "integrity": "sha1-15fhtVHKemOd7AI33G60u5vhfTU=",
+      "dev": true
+    },
+    "stdout-stream": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz",
+      "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=",
       "requires": {
-        "lodash": "4.17.4",
-        "material-colors": "1.2.5",
-        "prop-types": "15.6.0",
-        "reactcss": "1.2.3",
-        "tinycolor2": "1.4.1"
-      },
-      "dependencies": {
-        "material-colors": {
-          "version": "1.2.5",
-          "resolved": "https://registry.npmjs.org/material-colors/-/material-colors-1.2.5.tgz",
-          "integrity": "sha1-UpJZPmdUyxvMK5gDDk4Najr8nqE="
-        },
-        "reactcss": {
-          "version": "1.2.3",
-          "resolved": "https://registry.npmjs.org/reactcss/-/reactcss-1.2.3.tgz",
-          "integrity": "sha512-KiwVUcFu1RErkI97ywr8nvx8dNOpT03rbnma0SSalTYjkrPYaEajR4a/MRt6DZ46K6arDRbWMNHF+xH7G7n/8A==",
-          "requires": {
-            "lodash": "4.17.4"
-          }
-        },
-        "tinycolor2": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
-          "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
-        }
+        "readable-stream": "2.3.3"
       }
     },
-    "react-dom": {
-      "version": "16.0.0",
-      "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.0.0.tgz",
-      "integrity": "sha1-nMMHnD3NcNTG4BuEqrKn40wwP1g=",
+    "stream-parser": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/stream-parser/-/stream-parser-0.3.1.tgz",
+      "integrity": "sha1-FhhUhpRCACGhGC/wrxkRwSl2F3M=",
       "requires": {
-        "fbjs": "0.8.16",
-        "loose-envify": "1.3.1",
-        "object-assign": "4.1.1",
-        "prop-types": "15.6.0"
-      },
-      "dependencies": {
-        "asap": {
-          "version": "2.0.6",
-          "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
-          "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
-        },
-        "core-js": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
-        },
-        "encoding": {
-          "version": "0.1.12",
-          "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
-          "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
-          "requires": {
-            "iconv-lite": "0.4.19"
-          }
-        },
-        "fbjs": {
-          "version": "0.8.16",
-          "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
-          "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
-          "requires": {
-            "core-js": "1.2.7",
-            "isomorphic-fetch": "2.2.1",
-            "loose-envify": "1.3.1",
-            "object-assign": "4.1.1",
-            "promise": "7.3.1",
-            "setimmediate": "1.0.5",
-            "ua-parser-js": "0.7.17"
-          }
-        },
-        "iconv-lite": {
-          "version": "0.4.19",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
-          "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
-        },
-        "is-stream": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-          "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
-        },
-        "isomorphic-fetch": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
-          "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
-          "requires": {
-            "node-fetch": "1.7.3",
-            "whatwg-fetch": "2.0.3"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
-        },
-        "loose-envify": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-          "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-          "requires": {
-            "js-tokens": "3.0.2"
-          }
-        },
-        "node-fetch": {
-          "version": "1.7.3",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
-          "requires": {
-            "encoding": "0.1.12",
-            "is-stream": "1.1.0"
-          }
-        },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-        },
-        "promise": {
-          "version": "7.3.1",
-          "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
-          "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
-          "requires": {
-            "asap": "2.0.6"
-          }
-        },
-        "setimmediate": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-          "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
-        },
-        "ua-parser-js": {
-          "version": "0.7.17",
-          "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
-          "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
-        },
-        "whatwg-fetch": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
-          "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
-        }
+        "debug": "2.6.9"
       }
     },
-    "react-dropzone": {
-      "version": "4.2.3",
-      "resolved": "https://registry.npmjs.org/react-dropzone/-/react-dropzone-4.2.3.tgz",
-      "integrity": "sha512-QAXuGDqBUPC0p560pskC3yyS8I1jJUnzvZC0PHrd5NayYBQRD4poQfM1D/bxg4jhUaFU4avNhOB3ehMQd4JMvA==",
+    "stream-to": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/stream-to/-/stream-to-0.2.2.tgz",
+      "integrity": "sha1-hDBgmNhf25kLn6MAsbPM9V6O8B0=",
+      "dev": true
+    },
+    "stream-to-buffer": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz",
+      "integrity": "sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk=",
+      "dev": true,
       "requires": {
-        "attr-accept": "1.1.0",
-        "prop-types": "15.6.0"
+        "stream-to": "0.2.2"
       }
     },
-    "react-intl": {
-      "version": "2.4.0",
-      "resolved": "https://registry.npmjs.org/react-intl/-/react-intl-2.4.0.tgz",
-      "integrity": "sha1-ZsFNyd+ac7L7v71gIXJugKYT6xU=",
+    "stream-to-observable": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz",
+      "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=",
+      "dev": true
+    },
+    "strict-uri-encode": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz",
+      "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM="
+    },
+    "string-hash": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
+      "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs="
+    },
+    "string-width": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
       "requires": {
-        "intl-format-cache": "2.1.0",
-        "intl-messageformat": "2.2.0",
-        "intl-relativeformat": "2.1.0",
-        "invariant": "2.2.2"
-      },
-      "dependencies": {
-        "intl-format-cache": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/intl-format-cache/-/intl-format-cache-2.1.0.tgz",
-          "integrity": "sha1-BKNp/sv61tpgBbrh8UMzMy3PkxY="
-        },
-        "intl-messageformat": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-2.2.0.tgz",
-          "integrity": "sha1-NFvNRt5jC3aDMwwuUhd/9eq0hPw=",
-          "requires": {
-            "intl-messageformat-parser": "1.4.0"
-          }
-        },
-        "intl-messageformat-parser": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/intl-messageformat-parser/-/intl-messageformat-parser-1.4.0.tgz",
-          "integrity": "sha1-tD1FqXRoytvkQzHXS7Ho3qRPwHU="
-        },
-        "intl-relativeformat": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/intl-relativeformat/-/intl-relativeformat-2.1.0.tgz",
-          "integrity": "sha1-AQ8RBYAiUfQKxH0OPhogE0iiVd8=",
-          "requires": {
-            "intl-messageformat": "2.2.0"
-          }
-        },
-        "invariant": {
-          "version": "2.2.2",
-          "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
-          "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
-          "requires": {
-            "loose-envify": "1.3.1"
-          }
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
-        },
-        "loose-envify": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-          "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-          "requires": {
-            "js-tokens": "3.0.2"
-          }
-        }
+        "code-point-at": "1.1.0",
+        "is-fullwidth-code-point": "1.0.0",
+        "strip-ansi": "3.0.1"
       }
     },
-    "react-modal": {
-      "version": "3.0.4",
-      "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.0.4.tgz",
-      "integrity": "sha512-IvRZxJkXiDqEIl4cxCccCzP37z+YOSN+yNOkYH99Ime+n9nPSowgxkX0KfHzR2ezP72LSS3Uln54JDZXUJmLdA==",
+    "string_decoder": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
+      "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
       "requires": {
-        "exenv": "1.2.2",
-        "prop-types": "15.6.0"
-      },
-      "dependencies": {
-        "exenv": {
-          "version": "1.2.2",
-          "resolved": "https://registry.npmjs.org/exenv/-/exenv-1.2.2.tgz",
-          "integrity": "sha1-KueOhdmJQVhnCwPUe+wfA72Ru50="
-        }
+        "safe-buffer": "5.1.1"
       }
     },
-    "react-router": {
-      "version": "3.0.5",
-      "resolved": "https://registry.npmjs.org/react-router/-/react-router-3.0.5.tgz",
-      "integrity": "sha1-w7eHN1gEWou8lWKu9P9LyMznwTY=",
+    "stringify-object": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.1.tgz",
+      "integrity": "sha512-jPcQYw/52HUPP8uOE4kkjxl5bB9LfHkKCTptIk3qw7ozP5XMIMlHMLjt00GGSwW6DJAf/njY5EU6Vpwl4LlBKQ==",
+      "dev": true,
       "requires": {
-        "create-react-class": "15.6.2",
-        "history": "3.3.0",
-        "hoist-non-react-statics": "1.2.0",
-        "invariant": "2.2.2",
-        "loose-envify": "1.3.1",
-        "prop-types": "15.6.0",
-        "warning": "3.0.0"
+        "get-own-enumerable-property-symbols": "2.0.1",
+        "is-obj": "1.0.1",
+        "is-regexp": "1.0.0"
+      }
+    },
+    "stringstream": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
+      "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "requires": {
+        "ansi-regex": "2.1.1"
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "requires": {
+        "is-utf8": "0.2.1"
+      }
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true
+    },
+    "strip-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+      "requires": {
+        "get-stdin": "4.0.1"
+      }
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+    },
+    "symbol-observable": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.1.tgz",
+      "integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ=",
+      "dev": true
+    },
+    "table": {
+      "version": "4.0.2",
+      "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
+      "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
+      "dev": true,
+      "requires": {
+        "ajv": "5.5.2",
+        "ajv-keywords": "2.1.1",
+        "chalk": "2.3.0",
+        "lodash": "4.17.4",
+        "slice-ansi": "1.0.0",
+        "string-width": "2.1.1"
       },
       "dependencies": {
-        "asap": {
-          "version": "2.0.6",
-          "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
-          "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
-        },
-        "core-js": {
-          "version": "1.2.7",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
-          "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
-        },
-        "create-react-class": {
-          "version": "15.6.2",
-          "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz",
-          "integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=",
-          "requires": {
-            "fbjs": "0.8.16",
-            "loose-envify": "1.3.1",
-            "object-assign": "4.1.1"
-          }
-        },
-        "encoding": {
-          "version": "0.1.12",
-          "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
-          "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
-          "requires": {
-            "iconv-lite": "0.4.19"
-          }
-        },
-        "fbjs": {
-          "version": "0.8.16",
-          "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
-          "integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
-          "requires": {
-            "core-js": "1.2.7",
-            "isomorphic-fetch": "2.2.1",
-            "loose-envify": "1.3.1",
-            "object-assign": "4.1.1",
-            "promise": "7.3.1",
-            "setimmediate": "1.0.5",
-            "ua-parser-js": "0.7.17"
-          }
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
         },
-        "hoist-non-react-statics": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz",
-          "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs="
-        },
-        "iconv-lite": {
-          "version": "0.4.19",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
-          "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
-        },
-        "invariant": {
-          "version": "2.2.2",
-          "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
-          "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+        "ansi-styles": {
+          "version": "3.2.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
+          "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
+          "dev": true,
           "requires": {
-            "loose-envify": "1.3.1"
+            "color-convert": "1.9.1"
           }
         },
-        "is-stream": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
-          "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
-        },
-        "isomorphic-fetch": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
-          "integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
+        "chalk": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
+          "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
+          "dev": true,
           "requires": {
-            "node-fetch": "1.7.3",
-            "whatwg-fetch": "2.0.3"
+            "ansi-styles": "3.2.0",
+            "escape-string-regexp": "1.0.5",
+            "supports-color": "4.5.0"
           }
         },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
-        },
-        "loose-envify": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-          "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-          "requires": {
-            "js-tokens": "3.0.2"
-          }
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
         },
-        "node-fetch": {
-          "version": "1.7.3",
-          "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
-          "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
           "requires": {
-            "encoding": "0.1.12",
-            "is-stream": "1.1.0"
+            "is-fullwidth-code-point": "2.0.0",
+            "strip-ansi": "4.0.0"
           }
         },
-        "object-assign": {
-          "version": "4.1.1",
-          "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-          "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
-        },
-        "promise": {
-          "version": "7.3.1",
-          "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
-          "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
           "requires": {
-            "asap": "2.0.6"
+            "ansi-regex": "3.0.0"
           }
         },
-        "setimmediate": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-          "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
-        },
-        "ua-parser-js": {
-          "version": "0.7.17",
-          "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
-          "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
-        },
-        "warning": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
-          "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
+        "supports-color": {
+          "version": "4.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
+          "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+          "dev": true,
           "requires": {
-            "loose-envify": "1.3.1"
+            "has-flag": "2.0.0"
           }
-        },
-        "whatwg-fetch": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
-          "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
         }
       }
     },
-    "react-tabs": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/react-tabs/-/react-tabs-2.1.1.tgz",
-      "integrity": "sha512-55jl6lsYmPTQarnjgrBU68WZlNtVSngpRxOc4iXm+Te27F9ixUr/IBTbhlhDCMiFJreP+cqu1OaMdNGY2Hg10A==",
+    "tar": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+      "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+      "requires": {
+        "block-stream": "0.0.9",
+        "fstream": "1.0.11",
+        "inherits": "2.0.3"
+      }
+    },
+    "tar-stream": {
+      "version": "1.5.5",
+      "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz",
+      "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
+      "dev": true,
+      "requires": {
+        "bl": "1.2.1",
+        "end-of-stream": "1.4.1",
+        "readable-stream": "2.3.3",
+        "xtend": "4.0.1"
+      }
+    },
+    "text-table": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+      "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+      "dev": true
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "timed-out": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8="
+    },
+    "tiny-emitter": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz",
+      "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow=="
+    },
+    "tinycolor2": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
+      "integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
+    },
+    "tippy.js": {
+      "version": "2.0.9",
+      "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-2.0.9.tgz",
+      "integrity": "sha512-HgsZTP+unnDMEL7hkbAb9Iv11JLjd8SI38a9oR/1GpAHwhQ3ndNkdSHW5QziS5D4/GrapfbehPUZrCvBGGKY7Q==",
+      "requires": {
+        "popper.js": "1.12.9"
+      }
+    },
+    "tmp": {
+      "version": "0.0.33",
+      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+      "dev": true,
       "requires": {
-        "classnames": "2.2.5",
-        "prop-types": "15.6.0"
+        "os-tmpdir": "1.0.2"
       }
     },
-    "react-toastify": {
-      "version": "2.1.7",
-      "resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-2.1.7.tgz",
-      "integrity": "sha512-iMS5wXiTDKXcWTIF055BmsSwJINcxs9+CUGeEPMSllU0I00IKfV2inb3xhRxrB7d+4QvPqWZAtDPTk6nz6o1nA==",
+    "tough-cookie": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
+      "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
       "requires": {
-        "prop-types": "15.6.0",
-        "react-transition-group": "2.2.1"
+        "punycode": "1.4.1"
       }
     },
-    "react-toggle": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/react-toggle/-/react-toggle-4.0.2.tgz",
-      "integrity": "sha512-EPTWnN7gQHgEAUEmjheanZXNzY5TPnQeyyHfEs3YshaiWZf5WNjfYDrglO5F1Hl/dNveX18i4l0grTEsYH2Ccw==",
+    "trim": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
+      "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
+      "dev": true
+    },
+    "trim-newlines": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
       "requires": {
-        "classnames": "2.2.5"
+        "safe-buffer": "5.1.1"
       }
     },
-    "react-transition-group": {
-      "version": "2.2.1",
-      "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.2.1.tgz",
-      "integrity": "sha512-q54UBM22bs/CekG8r3+vi9TugSqh0t7qcEVycaRc9M0p0aCEu+h6rp/RFiW7fHfgd1IKpd9oILFTl5QK+FpiPA==",
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+      "optional": true
+    },
+    "type-check": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+      "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+      "dev": true,
       "requires": {
-        "chain-function": "1.0.0",
-        "classnames": "2.2.5",
-        "dom-helpers": "3.3.1",
-        "loose-envify": "1.3.1",
-        "prop-types": "15.6.0",
-        "warning": "3.0.0"
-      },
-      "dependencies": {
-        "chain-function": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.0.tgz",
-          "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w="
-        },
-        "dom-helpers": {
-          "version": "3.3.1",
-          "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz",
-          "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg=="
-        },
-        "js-tokens": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
-          "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
-        },
-        "loose-envify": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
-          "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
-          "requires": {
-            "js-tokens": "3.0.2"
-          }
-        },
-        "warning": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
-          "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
-          "requires": {
-            "loose-envify": "1.3.1"
-          }
-        }
+        "prelude-ls": "1.1.2"
       }
     },
-    "redis": {
-      "version": "2.8.0",
-      "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz",
-      "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==",
+    "type-detect": {
+      "version": "4.0.7",
+      "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.7.tgz",
+      "integrity": "sha512-4Rh17pAMVdMWzktddFhISRnUnFIStObtUMNGzDwlA6w/77bmGv3aBbRdCmQR6IjzfkTo9otnW+2K/cDRhKSxDA==",
+      "dev": true
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "ua-parser-js": {
+      "version": "0.7.17",
+      "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
+      "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
+    },
+    "uniq": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+      "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+      "dev": true
+    },
+    "universalify": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz",
+      "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=",
+      "dev": true
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+      "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
       "requires": {
-        "double-ended-queue": "2.1.0-0",
-        "redis-commands": "1.3.1",
-        "redis-parser": "2.6.0"
+        "punycode": "1.3.2",
+        "querystring": "0.2.0"
       },
       "dependencies": {
-        "double-ended-queue": {
-          "version": "2.1.0-0",
-          "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
-          "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw="
-        },
-        "redis-commands": {
-          "version": "1.3.1",
-          "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz",
-          "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs="
-        },
-        "redis-parser": {
-          "version": "2.6.0",
-          "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz",
-          "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs="
+        "punycode": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
         }
       }
     },
-    "string-hash": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
-      "integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs="
+    "url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "requires": {
+        "prepend-http": "1.0.4"
+      }
     },
-    "tippy.js": {
-      "version": "2.0.8",
-      "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-2.0.8.tgz",
-      "integrity": "sha512-GbEV0iQHE9NS/J3W2OBTM3evYjJV4P88axZeB9E6iyJz8+h/m75fL8wg2OW/U0c98K7qnrgLZ0plPucBpULpDw==",
+    "url-regex": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/url-regex/-/url-regex-3.2.0.tgz",
+      "integrity": "sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=",
+      "dev": true,
       "requires": {
-        "popper.js": "1.12.9"
+        "ip-regex": "1.0.3"
+      }
+    },
+    "url-to-options": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
+      "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k="
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+    },
+    "uuid": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz",
+      "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA=="
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
+      "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+      "requires": {
+        "spdx-correct": "1.0.2",
+        "spdx-expression-parse": "1.0.4"
       }
     },
+    "validator": {
+      "version": "7.0.0",
+      "resolved": "https://registry.npmjs.org/validator/-/validator-7.0.0.tgz",
+      "integrity": "sha1-x03rgGNRL6w1VHk45vCxUEooL9I=",
+      "dev": true
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "requires": {
+        "assert-plus": "1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "1.3.0"
+      }
+    },
+    "walkdir": {
+      "version": "0.0.11",
+      "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz",
+      "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
+      "dev": true
+    },
+    "warning": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
+      "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
+      "requires": {
+        "loose-envify": "1.3.1"
+      }
+    },
+    "wdio-dot-reporter": {
+      "version": "0.0.9",
+      "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.9.tgz",
+      "integrity": "sha1-kpsq2v1J1rBTT9oGjocxm0fjj+U=",
+      "dev": true
+    },
     "wdio-jasmine-framework": {
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/wdio-jasmine-framework/-/wdio-jasmine-framework-0.3.2.tgz",
@@ -6778,7 +5581,7 @@
       "dev": true,
       "requires": {
         "babel-runtime": "6.25.0",
-        "jasmine": "2.8.0",
+        "jasmine": "2.9.0",
         "wdio-sync": "0.7.0"
       },
       "dependencies": {
@@ -6792,185 +5595,11 @@
             "regenerator-runtime": "0.10.5"
           }
         },
-        "balanced-match": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "dev": true
-        },
-        "brace-expansion": {
-          "version": "1.1.8",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
-          "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
-          "dev": true,
-          "requires": {
-            "balanced-match": "1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "dev": true
-        },
-        "core-js": {
-          "version": "2.5.3",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
-          "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=",
-          "dev": true
-        },
-        "define-properties": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz",
-          "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
-          "dev": true,
-          "requires": {
-            "foreach": "2.0.5",
-            "object-keys": "1.0.11"
-          }
-        },
-        "exit": {
-          "version": "0.1.2",
-          "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
-          "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
-          "dev": true
-        },
-        "fibers": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/fibers/-/fibers-2.0.0.tgz",
-          "integrity": "sha512-sLxo4rZVk7xLgAjb/6zEzHJfSALx6u6coN1z61XCOF7i6CyTdJawF4+RdpjCSeS8AP66eR2InScbYAz9RAVOgA==",
-          "dev": true
-        },
-        "foreach": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
-          "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
-          "dev": true
-        },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-          "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-          "dev": true
-        },
-        "function-bind": {
-          "version": "1.1.1",
-          "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
-          "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
-          "dev": true
-        },
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
-          }
-        },
-        "inflight": {
-          "version": "1.0.6",
-          "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-          "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-          "dev": true,
-          "requires": {
-            "once": "1.4.0",
-            "wrappy": "1.0.2"
-          }
-        },
-        "inherits": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-          "dev": true
-        },
-        "jasmine": {
-          "version": "2.8.0",
-          "resolved": "https://registry.npmjs.org/jasmine/-/jasmine-2.8.0.tgz",
-          "integrity": "sha1-awicChFXax8W3xG4AUbZHU6Lij4=",
-          "dev": true,
-          "requires": {
-            "exit": "0.1.2",
-            "glob": "7.1.2",
-            "jasmine-core": "2.8.0"
-          }
-        },
-        "jasmine-core": {
-          "version": "2.8.0",
-          "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-2.8.0.tgz",
-          "integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=",
-          "dev": true
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "1.1.8"
-          }
-        },
-        "object-keys": {
-          "version": "1.0.11",
-          "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz",
-          "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=",
-          "dev": true
-        },
-        "object.assign": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
-          "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
-          "dev": true,
-          "requires": {
-            "define-properties": "1.1.2",
-            "function-bind": "1.1.1",
-            "has-symbols": "1.0.0",
-            "object-keys": "1.0.11"
-          }
-        },
-        "once": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-          "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-          "dev": true,
-          "requires": {
-            "wrappy": "1.0.2"
-          }
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-          "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
-          "dev": true
-        },
         "regenerator-runtime": {
           "version": "0.10.5",
           "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
           "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
           "dev": true
-        },
-        "wdio-sync": {
-          "version": "0.7.0",
-          "resolved": "https://registry.npmjs.org/wdio-sync/-/wdio-sync-0.7.0.tgz",
-          "integrity": "sha1-L7B9JQEh3IH1Y1MWVCw8SaEiAWg=",
-          "dev": true,
-          "requires": {
-            "babel-runtime": "6.25.0",
-            "fibers": "2.0.0",
-            "object.assign": "4.1.0"
-          }
-        },
-        "wrappy": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-          "dev": true
         }
       }
     },
@@ -6982,56 +5611,23 @@
       "requires": {
         "junit-report-builder": "1.2.0",
         "mkdirp": "0.5.1"
-      },
-      "dependencies": {
-        "date-format": {
-          "version": "0.0.2",
-          "resolved": "https://registry.npmjs.org/date-format/-/date-format-0.0.2.tgz",
-          "integrity": "sha1-+v1Ej3IRXvHitzkVWukvK+bCjdE=",
-          "dev": true
-        },
-        "junit-report-builder": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/junit-report-builder/-/junit-report-builder-1.2.0.tgz",
-          "integrity": "sha1-aJfM1e49gFGRpL5vEse+hQ5QwNY=",
-          "dev": true,
-          "requires": {
-            "date-format": "0.0.2",
-            "lodash": "3.10.1",
-            "mkdirp": "0.5.1",
-            "xmlbuilder": "2.6.5"
-          }
-        },
-        "lodash": {
-          "version": "3.10.1",
-          "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
-          "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
-          "dev": true
-        },
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
-        },
-        "mkdirp": {
-          "version": "0.5.1",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-          "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-          "dev": true,
-          "requires": {
-            "minimist": "0.0.8"
-          }
-        },
-        "xmlbuilder": {
-          "version": "2.6.5",
-          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-2.6.5.tgz",
-          "integrity": "sha1-b/etYPty0idk8AehZLd/K/FABSY=",
-          "dev": true,
-          "requires": {
-            "lodash": "3.10.1"
-          }
-        }
+      }
+    },
+    "wdio-screenshot": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/wdio-screenshot/-/wdio-screenshot-0.6.0.tgz",
+      "integrity": "sha1-+zJrGmuXUaE8LOpRH9cGLgW3Ok0=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "debug": "2.6.9",
+        "fs-extra": "3.0.1",
+        "gm": "1.23.1",
+        "image-size": "0.5.5",
+        "jimp": "0.2.28",
+        "lodash": "4.17.4",
+        "uuid": "3.2.1",
+        "which": "1.3.0"
       }
     },
     "wdio-spec-reporter": {
@@ -7065,39 +5661,6 @@
             "supports-color": "4.5.0"
           }
         },
-        "color-convert": {
-          "version": "1.9.1",
-          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
-          "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
-          "dev": true,
-          "requires": {
-            "color-name": "1.1.3"
-          }
-        },
-        "color-name": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
-          "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
-          "dev": true
-        },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "has-flag": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
-          "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
-          "dev": true
-        },
-        "humanize-duration": {
-          "version": "3.12.1",
-          "resolved": "https://registry.npmjs.org/humanize-duration/-/humanize-duration-3.12.1.tgz",
-          "integrity": "sha512-Eu68Xnq5C38391em1zfVy8tiapQrOvTNTlWpax9smHMlEEUcudXrdMfXMoMRyZx4uODowYgi1AYiMzUXEbG+sA==",
-          "dev": true
-        },
         "supports-color": {
           "version": "4.5.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
@@ -7109,6 +5672,77 @@
         }
       }
     },
+    "wdio-sync": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/wdio-sync/-/wdio-sync-0.7.0.tgz",
+      "integrity": "sha1-L7B9JQEh3IH1Y1MWVCw8SaEiAWg=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.25.0",
+        "fibers": "2.0.0",
+        "object.assign": "4.1.0"
+      },
+      "dependencies": {
+        "babel-runtime": {
+          "version": "6.25.0",
+          "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.25.0.tgz",
+          "integrity": "sha1-M7mOql1IK7AajRqmtDetKwGuxBw=",
+          "dev": true,
+          "requires": {
+            "core-js": "2.5.3",
+            "regenerator-runtime": "0.10.5"
+          }
+        },
+        "regenerator-runtime": {
+          "version": "0.10.5",
+          "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+          "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
+          "dev": true
+        }
+      }
+    },
+    "wdio-visual-regression-service": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/wdio-visual-regression-service/-/wdio-visual-regression-service-0.8.0.tgz",
+      "integrity": "sha1-3OhPm/B6B4O1DCAN94M0b89HVaM=",
+      "dev": true,
+      "requires": {
+        "babel-runtime": "6.26.0",
+        "debug": "2.6.9",
+        "fs-extra": "3.0.1",
+        "lodash": "4.17.4",
+        "node-resemble-js": "0.0.5",
+        "platform": "1.3.5",
+        "wdio-screenshot": "0.6.0"
+      }
+    },
+    "webdriver-manager": {
+      "version": "12.0.6",
+      "resolved": "https://registry.npmjs.org/webdriver-manager/-/webdriver-manager-12.0.6.tgz",
+      "integrity": "sha1-PfGkgZdwELTL+MnYXHpXeCjA5ws=",
+      "dev": true,
+      "requires": {
+        "adm-zip": "0.4.7",
+        "chalk": "1.1.3",
+        "del": "2.2.2",
+        "glob": "7.1.2",
+        "ini": "1.3.5",
+        "minimist": "1.2.0",
+        "q": "1.5.1",
+        "request": "2.83.0",
+        "rimraf": "2.6.2",
+        "semver": "5.5.0",
+        "xml2js": "0.4.19"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
     "webdriverio": {
       "version": "4.8.0",
       "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-4.8.0.tgz",
@@ -7128,422 +5762,83 @@
         "mkdirp": "0.5.1",
         "npm-install-package": "2.1.0",
         "optimist": "0.6.1",
-        "q": "1.5.1",
-        "request": "2.81.0",
-        "rgb2hex": "0.1.0",
-        "safe-buffer": "5.0.1",
-        "supports-color": "3.2.3",
-        "url": "0.11.0",
-        "validator": "7.0.0",
-        "wdio-dot-reporter": "0.0.9",
-        "wgxpath": "1.0.0"
-      },
-      "dependencies": {
-        "ajv": {
-          "version": "4.11.8",
-          "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
-          "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
-          "dev": true,
-          "requires": {
-            "co": "4.6.0",
-            "json-stable-stringify": "1.0.1"
-          }
-        },
-        "amdefine": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
-          "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
-          "dev": true
-        },
-        "ansi-escapes": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
-          "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
-          "dev": true
-        },
-        "ansi-regex": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
-          "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
-          "dev": true
-        },
-        "ansi-styles": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
-          "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
-          "dev": true
-        },
-        "archiver": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/archiver/-/archiver-1.3.0.tgz",
-          "integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=",
-          "dev": true,
-          "requires": {
-            "archiver-utils": "1.3.0",
-            "async": "2.6.0",
-            "buffer-crc32": "0.2.13",
-            "glob": "7.1.2",
-            "lodash": "4.17.4",
-            "readable-stream": "2.3.3",
-            "tar-stream": "1.5.5",
-            "walkdir": "0.0.11",
-            "zip-stream": "1.2.0"
-          }
-        },
-        "archiver-utils": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
-          "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
-          "dev": true,
-          "requires": {
-            "glob": "7.1.2",
-            "graceful-fs": "4.1.11",
-            "lazystream": "1.0.0",
-            "lodash": "4.17.4",
-            "normalize-path": "2.1.1",
-            "readable-stream": "2.3.3"
-          }
-        },
-        "asn1": {
-          "version": "0.2.3",
-          "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz",
-          "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=",
-          "dev": true
-        },
-        "assert-plus": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
-          "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
-          "dev": true
-        },
-        "async": {
-          "version": "2.6.0",
-          "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz",
-          "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==",
-          "dev": true,
-          "requires": {
-            "lodash": "4.17.4"
-          }
-        },
-        "asynckit": {
-          "version": "0.4.0",
-          "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-          "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
-          "dev": true
-        },
-        "atob": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz",
-          "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=",
-          "dev": true
-        },
-        "aws-sign2": {
-          "version": "0.6.0",
-          "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
-          "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
-          "dev": true
-        },
-        "aws4": {
-          "version": "1.6.0",
-          "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
-          "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=",
-          "dev": true
-        },
-        "babel-runtime": {
-          "version": "6.23.0",
-          "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz",
-          "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=",
-          "dev": true,
-          "requires": {
-            "core-js": "2.5.3",
-            "regenerator-runtime": "0.10.5"
-          }
-        },
-        "balanced-match": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-          "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-          "dev": true
-        },
-        "bcrypt-pbkdf": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz",
-          "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "tweetnacl": "0.14.5"
-          }
-        },
-        "bl": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz",
-          "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=",
-          "dev": true,
-          "requires": {
-            "readable-stream": "2.3.3"
-          }
-        },
-        "boom": {
-          "version": "2.10.1",
-          "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
-          "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
-          "dev": true,
-          "requires": {
-            "hoek": "2.16.3"
-          }
-        },
-        "brace-expansion": {
-          "version": "1.1.8",
-          "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
-          "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
-          "dev": true,
-          "requires": {
-            "balanced-match": "1.0.0",
-            "concat-map": "0.0.1"
-          }
-        },
-        "buffer-crc32": {
-          "version": "0.2.13",
-          "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
-          "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
-          "dev": true
-        },
-        "caseless": {
-          "version": "0.12.0",
-          "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
-          "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
-          "dev": true
-        },
-        "chalk": {
-          "version": "1.1.3",
-          "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
-          "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
-          "dev": true,
-          "requires": {
-            "ansi-styles": "2.2.1",
-            "escape-string-regexp": "1.0.5",
-            "has-ansi": "2.0.0",
-            "strip-ansi": "3.0.1",
-            "supports-color": "2.0.0"
-          },
-          "dependencies": {
-            "supports-color": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
-              "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
-              "dev": true
-            }
-          }
-        },
-        "cli-cursor": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
-          "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
-          "dev": true,
-          "requires": {
-            "restore-cursor": "2.0.0"
-          }
-        },
-        "cli-width": {
-          "version": "2.2.0",
-          "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
-          "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
-          "dev": true
-        },
-        "co": {
-          "version": "4.6.0",
-          "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
-          "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=",
-          "dev": true
-        },
-        "combined-stream": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
-          "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
-          "dev": true,
-          "requires": {
-            "delayed-stream": "1.0.0"
-          }
-        },
-        "compress-commons": {
-          "version": "1.2.2",
-          "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz",
-          "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=",
-          "dev": true,
-          "requires": {
-            "buffer-crc32": "0.2.13",
-            "crc32-stream": "2.0.0",
-            "normalize-path": "2.1.1",
-            "readable-stream": "2.3.3"
-          }
-        },
-        "concat-map": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-          "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-          "dev": true
-        },
-        "core-js": {
-          "version": "2.5.3",
-          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.3.tgz",
-          "integrity": "sha1-isw4NFgk8W2DZbfJtCWRaOjtYD4=",
-          "dev": true
-        },
-        "core-util-is": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
-          "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
-          "dev": true
-        },
-        "crc": {
-          "version": "3.5.0",
-          "resolved": "https://registry.npmjs.org/crc/-/crc-3.5.0.tgz",
-          "integrity": "sha1-mLi6fUiWZbo5efWbITgTdBAaGWQ=",
-          "dev": true
-        },
-        "crc32-stream": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
-          "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
-          "dev": true,
-          "requires": {
-            "crc": "3.5.0",
-            "readable-stream": "2.3.3"
-          }
-        },
-        "cryptiles": {
-          "version": "2.0.5",
-          "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
-          "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
-          "dev": true,
-          "requires": {
-            "boom": "2.10.1"
-          }
-        },
-        "css": {
-          "version": "2.2.1",
-          "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz",
-          "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=",
-          "dev": true,
-          "requires": {
-            "inherits": "2.0.3",
-            "source-map": "0.1.43",
-            "source-map-resolve": "0.3.1",
-            "urix": "0.1.0"
-          }
-        },
-        "css-parse": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz",
-          "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=",
+        "q": "1.5.1",
+        "request": "2.81.0",
+        "rgb2hex": "0.1.0",
+        "safe-buffer": "5.0.1",
+        "supports-color": "3.2.3",
+        "url": "0.11.0",
+        "validator": "7.0.0",
+        "wdio-dot-reporter": "0.0.9",
+        "wgxpath": "1.0.0"
+      },
+      "dependencies": {
+        "ajv": {
+          "version": "4.11.8",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+          "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
           "dev": true,
           "requires": {
-            "css": "2.2.1"
+            "co": "4.6.0",
+            "json-stable-stringify": "1.0.1"
           }
         },
-        "css-value": {
-          "version": "0.0.1",
-          "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz",
-          "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=",
+        "ansi-escapes": {
+          "version": "1.4.0",
+          "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+          "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
           "dev": true
         },
-        "dashdash": {
-          "version": "1.14.1",
-          "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-          "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
-          "dev": true,
-          "requires": {
-            "assert-plus": "1.0.0"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-              "dev": true
-            }
-          }
-        },
-        "deepmerge": {
-          "version": "1.3.2",
-          "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.3.2.tgz",
-          "integrity": "sha1-FmNpFinU2/42T6EqKk8KqGqjoFA=",
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
           "dev": true
         },
-        "delayed-stream": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-          "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+        "assert-plus": {
+          "version": "0.2.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+          "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
           "dev": true
         },
-        "ecc-jsbn": {
-          "version": "0.1.1",
-          "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz",
-          "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "jsbn": "0.1.1"
-          }
-        },
-        "ejs": {
-          "version": "2.5.7",
-          "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz",
-          "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=",
+        "aws-sign2": {
+          "version": "0.6.0",
+          "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+          "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
           "dev": true
         },
-        "end-of-stream": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
-          "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=",
+        "babel-runtime": {
+          "version": "6.23.0",
+          "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz",
+          "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=",
           "dev": true,
           "requires": {
-            "once": "1.4.0"
+            "core-js": "2.5.3",
+            "regenerator-runtime": "0.10.5"
           }
         },
-        "escape-string-regexp": {
-          "version": "1.0.5",
-          "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
-          "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
-          "dev": true
-        },
-        "extend": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
-          "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
-          "dev": true
-        },
-        "external-editor": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz",
-          "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==",
+        "boom": {
+          "version": "2.10.1",
+          "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+          "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
           "dev": true,
           "requires": {
-            "chardet": "0.4.2",
-            "iconv-lite": "0.4.19",
-            "tmp": "0.0.33"
+            "hoek": "2.16.3"
           }
         },
-        "extsprintf": {
-          "version": "1.3.0",
-          "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
-          "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
-          "dev": true
-        },
-        "figures": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
-          "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+        "cryptiles": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+          "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
           "dev": true,
           "requires": {
-            "escape-string-regexp": "1.0.5"
+            "boom": "2.10.1"
           }
         },
-        "forever-agent": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
-          "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+        "deepmerge": {
+          "version": "1.3.2",
+          "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-1.3.2.tgz",
+          "integrity": "sha1-FmNpFinU2/42T6EqKk8KqGqjoFA=",
           "dev": true
         },
         "form-data": {
@@ -7557,69 +5852,6 @@
             "mime-types": "2.1.17"
           }
         },
-        "fs.realpath": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-          "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
-          "dev": true
-        },
-        "gaze": {
-          "version": "1.1.2",
-          "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
-          "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
-          "dev": true,
-          "requires": {
-            "globule": "1.2.0"
-          }
-        },
-        "getpass": {
-          "version": "0.1.7",
-          "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-          "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
-          "dev": true,
-          "requires": {
-            "assert-plus": "1.0.0"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-              "dev": true
-            }
-          }
-        },
-        "glob": {
-          "version": "7.1.2",
-          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
-          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
-          "dev": true,
-          "requires": {
-            "fs.realpath": "1.0.0",
-            "inflight": "1.0.6",
-            "inherits": "2.0.3",
-            "minimatch": "3.0.4",
-            "once": "1.4.0",
-            "path-is-absolute": "1.0.1"
-          }
-        },
-        "globule": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz",
-          "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
-          "dev": true,
-          "requires": {
-            "glob": "7.1.2",
-            "lodash": "4.17.4",
-            "minimatch": "3.0.4"
-          }
-        },
-        "graceful-fs": {
-          "version": "4.1.11",
-          "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
-          "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
-          "dev": true
-        },
         "har-schema": {
           "version": "1.0.5",
           "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
@@ -7636,15 +5868,6 @@
             "har-schema": "1.0.5"
           }
         },
-        "has-ansi": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
-          "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "2.1.1"
-          }
-        },
         "has-flag": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
@@ -7680,28 +5903,6 @@
             "sshpk": "1.13.1"
           }
         },
-        "iconv-lite": {
-          "version": "0.4.19",
-          "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
-          "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==",
-          "dev": true
-        },
-        "inflight": {
-          "version": "1.0.6",
-          "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-          "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
-          "dev": true,
-          "requires": {
-            "once": "1.4.0",
-            "wrappy": "1.0.2"
-          }
-        },
-        "inherits": {
-          "version": "2.0.3",
-          "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
-          "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
-          "dev": true
-        },
         "inquirer": {
           "version": "3.0.6",
           "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz",
@@ -7721,211 +5922,12 @@
             "string-width": "2.1.1",
             "strip-ansi": "3.0.1",
             "through": "2.3.8"
-          }
-        },
-        "is-fullwidth-code-point": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
-          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
-          "dev": true
-        },
-        "is-promise": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
-          "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
-          "dev": true
-        },
-        "is-typedarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
-          "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
-          "dev": true
-        },
-        "isarray": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
-          "dev": true
-        },
-        "isstream": {
-          "version": "0.1.2",
-          "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-          "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
-          "dev": true
-        },
-        "jsbn": {
-          "version": "0.1.1",
-          "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-          "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
-          "dev": true,
-          "optional": true
-        },
-        "json-schema": {
-          "version": "0.2.3",
-          "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
-          "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
-          "dev": true
-        },
-        "json-stable-stringify": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
-          "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
-          "dev": true,
-          "requires": {
-            "jsonify": "0.0.0"
-          }
-        },
-        "json-stringify-safe": {
-          "version": "5.0.1",
-          "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
-          "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
-          "dev": true
-        },
-        "jsonify": {
-          "version": "0.0.0",
-          "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
-          "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
-          "dev": true
-        },
-        "jsprim": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
-          "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
-          "dev": true,
-          "requires": {
-            "assert-plus": "1.0.0",
-            "extsprintf": "1.3.0",
-            "json-schema": "0.2.3",
-            "verror": "1.10.0"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-              "dev": true
-            }
-          }
-        },
-        "lazystream": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
-          "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
-          "dev": true,
-          "requires": {
-            "readable-stream": "2.3.3"
-          }
-        },
-        "mime-db": {
-          "version": "1.30.0",
-          "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
-          "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=",
-          "dev": true
-        },
-        "mime-types": {
-          "version": "2.1.17",
-          "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
-          "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
-          "dev": true,
-          "requires": {
-            "mime-db": "1.30.0"
-          }
-        },
-        "mimic-fn": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
-          "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
-          "dev": true
-        },
-        "minimatch": {
-          "version": "3.0.4",
-          "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
-          "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-          "dev": true,
-          "requires": {
-            "brace-expansion": "1.1.8"
-          }
-        },
-        "minimist": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
-          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
-          "dev": true
-        },
-        "mkdirp": {
-          "version": "0.5.1",
-          "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
-          "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
-          "dev": true,
-          "requires": {
-            "minimist": "0.0.8"
-          }
-        },
-        "mute-stream": {
-          "version": "0.0.7",
-          "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
-          "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
-          "dev": true
-        },
-        "normalize-path": {
-          "version": "2.1.1",
-          "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
-          "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
-          "dev": true,
-          "requires": {
-            "remove-trailing-separator": "1.1.0"
-          }
-        },
-        "npm-install-package": {
-          "version": "2.1.0",
-          "resolved": "https://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz",
-          "integrity": "sha1-1+/jz816sAYUuJbqUxGdyaslkSU=",
-          "dev": true
-        },
-        "oauth-sign": {
-          "version": "0.8.2",
-          "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz",
-          "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=",
-          "dev": true
-        },
-        "once": {
-          "version": "1.4.0",
-          "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-          "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
-          "dev": true,
-          "requires": {
-            "wrappy": "1.0.2"
-          }
-        },
-        "onetime": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
-          "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
-          "dev": true,
-          "requires": {
-            "mimic-fn": "1.1.0"
-          }
-        },
-        "optimist": {
-          "version": "0.6.1",
-          "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
-          "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
-          "dev": true,
-          "requires": {
-            "minimist": "0.0.8",
-            "wordwrap": "0.0.3"
-          }
-        },
-        "os-tmpdir": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-          "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
-          "dev": true
-        },
-        "path-is-absolute": {
-          "version": "1.0.1",
-          "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-          "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
           "dev": true
         },
         "performance-now": {
@@ -7934,71 +5936,18 @@
           "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
           "dev": true
         },
-        "process-nextick-args": {
-          "version": "1.0.7",
-          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
-          "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
-          "dev": true
-        },
-        "punycode": {
-          "version": "1.4.1",
-          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
-          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
-          "dev": true
-        },
-        "q": {
-          "version": "1.5.1",
-          "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
-          "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
-          "dev": true
-        },
         "qs": {
           "version": "6.4.0",
           "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
           "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
           "dev": true
         },
-        "querystring": {
-          "version": "0.2.0",
-          "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
-          "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
-          "dev": true
-        },
-        "readable-stream": {
-          "version": "2.3.3",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
-          "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
-          "dev": true,
-          "requires": {
-            "core-util-is": "1.0.2",
-            "inherits": "2.0.3",
-            "isarray": "1.0.0",
-            "process-nextick-args": "1.0.7",
-            "safe-buffer": "5.1.1",
-            "string_decoder": "1.0.3",
-            "util-deprecate": "1.0.2"
-          },
-          "dependencies": {
-            "safe-buffer": {
-              "version": "5.1.1",
-              "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
-              "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
-              "dev": true
-            }
-          }
-        },
         "regenerator-runtime": {
           "version": "0.10.5",
           "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
           "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
           "dev": true
         },
-        "remove-trailing-separator": {
-          "version": "1.1.0",
-          "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
-          "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
-          "dev": true
-        },
         "request": {
           "version": "2.81.0",
           "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
@@ -8026,58 +5975,15 @@
             "stringstream": "0.0.5",
             "tough-cookie": "2.3.3",
             "tunnel-agent": "0.6.0",
-            "uuid": "3.1.0"
-          }
-        },
-        "resolve-url": {
-          "version": "0.2.1",
-          "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
-          "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
-          "dev": true
-        },
-        "restore-cursor": {
-          "version": "2.0.0",
-          "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
-          "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
-          "dev": true,
-          "requires": {
-            "onetime": "2.0.1",
-            "signal-exit": "3.0.2"
-          }
-        },
-        "rgb2hex": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.0.tgz",
-          "integrity": "sha1-zNVfhgrgxcTqN1BLlY5ELY0SMls=",
-          "dev": true
-        },
-        "run-async": {
-          "version": "2.3.0",
-          "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
-          "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
-          "dev": true,
-          "requires": {
-            "is-promise": "2.1.0"
+            "uuid": "3.2.1"
           }
         },
-        "rx": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
-          "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
-          "dev": true
-        },
         "safe-buffer": {
           "version": "5.0.1",
           "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
           "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=",
           "dev": true
         },
-        "signal-exit": {
-          "version": "3.0.2",
-          "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
-          "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
-          "dev": true
-        },
         "sntp": {
           "version": "1.0.9",
           "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
@@ -8087,57 +5993,6 @@
             "hoek": "2.16.3"
           }
         },
-        "source-map": {
-          "version": "0.1.43",
-          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz",
-          "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
-          "dev": true,
-          "requires": {
-            "amdefine": "1.0.1"
-          }
-        },
-        "source-map-resolve": {
-          "version": "0.3.1",
-          "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz",
-          "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=",
-          "dev": true,
-          "requires": {
-            "atob": "1.1.3",
-            "resolve-url": "0.2.1",
-            "source-map-url": "0.3.0",
-            "urix": "0.1.0"
-          }
-        },
-        "source-map-url": {
-          "version": "0.3.0",
-          "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz",
-          "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=",
-          "dev": true
-        },
-        "sshpk": {
-          "version": "1.13.1",
-          "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
-          "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
-          "dev": true,
-          "requires": {
-            "asn1": "0.2.3",
-            "assert-plus": "1.0.0",
-            "bcrypt-pbkdf": "1.0.1",
-            "dashdash": "1.14.1",
-            "ecc-jsbn": "0.1.1",
-            "getpass": "0.1.7",
-            "jsbn": "0.1.1",
-            "tweetnacl": "0.14.5"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-              "dev": true
-            }
-          }
-        },
         "string-width": {
           "version": "2.1.1",
           "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
@@ -8148,12 +6003,6 @@
             "strip-ansi": "4.0.0"
           },
           "dependencies": {
-            "ansi-regex": {
-              "version": "3.0.0",
-              "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
-              "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
-              "dev": true
-            },
             "strip-ansi": {
               "version": "4.0.0",
               "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
@@ -8165,38 +6014,6 @@
             }
           }
         },
-        "string_decoder": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
-          "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "5.1.1"
-          },
-          "dependencies": {
-            "safe-buffer": {
-              "version": "5.1.1",
-              "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
-              "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==",
-              "dev": true
-            }
-          }
-        },
-        "stringstream": {
-          "version": "0.0.5",
-          "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
-          "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=",
-          "dev": true
-        },
-        "strip-ansi": {
-          "version": "3.0.1",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
-          "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "2.1.1"
-          }
-        },
         "supports-color": {
           "version": "3.2.3",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
@@ -8205,170 +6022,41 @@
           "requires": {
             "has-flag": "1.0.0"
           }
-        },
-        "tar-stream": {
-          "version": "1.5.5",
-          "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz",
-          "integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
-          "dev": true,
-          "requires": {
-            "bl": "1.2.1",
-            "end-of-stream": "1.4.0",
-            "readable-stream": "2.3.3",
-            "xtend": "4.0.1"
-          }
-        },
-        "through": {
-          "version": "2.3.8",
-          "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-          "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
-          "dev": true
-        },
-        "tmp": {
-          "version": "0.0.33",
-          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-          "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-          "dev": true,
-          "requires": {
-            "os-tmpdir": "1.0.2"
-          }
-        },
-        "tough-cookie": {
-          "version": "2.3.3",
-          "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
-          "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
-          "dev": true,
-          "requires": {
-            "punycode": "1.4.1"
-          }
-        },
-        "tunnel-agent": {
-          "version": "0.6.0",
-          "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
-          "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
-          "dev": true,
-          "requires": {
-            "safe-buffer": "5.0.1"
-          }
-        },
-        "tweetnacl": {
-          "version": "0.14.5",
-          "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-          "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
-          "dev": true,
-          "optional": true
-        },
-        "urix": {
-          "version": "0.1.0",
-          "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
-          "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
-          "dev": true
-        },
-        "url": {
-          "version": "0.11.0",
-          "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
-          "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
-          "dev": true,
-          "requires": {
-            "punycode": "1.3.2",
-            "querystring": "0.2.0"
-          },
-          "dependencies": {
-            "punycode": {
-              "version": "1.3.2",
-              "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
-              "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
-              "dev": true
-            }
-          }
-        },
-        "util-deprecate": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-          "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
-          "dev": true
-        },
-        "uuid": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
-          "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
-          "dev": true
-        },
-        "validator": {
-          "version": "7.0.0",
-          "resolved": "https://registry.npmjs.org/validator/-/validator-7.0.0.tgz",
-          "integrity": "sha1-x03rgGNRL6w1VHk45vCxUEooL9I=",
-          "dev": true
-        },
-        "verror": {
-          "version": "1.10.0",
-          "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
-          "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
-          "dev": true,
-          "requires": {
-            "assert-plus": "1.0.0",
-            "core-util-is": "1.0.2",
-            "extsprintf": "1.3.0"
-          },
-          "dependencies": {
-            "assert-plus": {
-              "version": "1.0.0",
-              "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-              "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
-              "dev": true
-            }
-          }
-        },
-        "walkdir": {
-          "version": "0.0.11",
-          "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.0.11.tgz",
-          "integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
-          "dev": true
-        },
-        "wdio-dot-reporter": {
-          "version": "0.0.9",
-          "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.9.tgz",
-          "integrity": "sha1-kpsq2v1J1rBTT9oGjocxm0fjj+U=",
-          "dev": true
-        },
-        "wgxpath": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/wgxpath/-/wgxpath-1.0.0.tgz",
-          "integrity": "sha1-7vikudVYzEla06mit1FZfs2a9pA=",
-          "dev": true
-        },
-        "wordwrap": {
-          "version": "0.0.3",
-          "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
-          "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
-          "dev": true
-        },
-        "wrappy": {
-          "version": "1.0.2",
-          "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
-          "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
-          "dev": true
-        },
-        "xtend": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
-          "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
-          "dev": true
-        },
-        "zip-stream": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",
-          "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
-          "dev": true,
-          "requires": {
-            "archiver-utils": "1.3.0",
-            "compress-commons": "1.2.2",
-            "lodash": "4.17.4",
-            "readable-stream": "2.3.3"
-          }
         }
       }
     },
+    "wgxpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wgxpath/-/wgxpath-1.0.0.tgz",
+      "integrity": "sha1-7vikudVYzEla06mit1FZfs2a9pA=",
+      "dev": true
+    },
+    "whatwg-fetch": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
+      "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
+    },
+    "which": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
+      "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
+      "requires": {
+        "isexe": "2.0.0"
+      }
+    },
+    "which-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
+    },
+    "wide-align": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
+      "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
+      "requires": {
+        "string-width": "1.0.2"
+      }
+    },
     "winston": {
       "version": "2.4.0",
       "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.0.tgz",
@@ -8380,40 +6068,63 @@
         "eyes": "0.1.8",
         "isstream": "0.1.2",
         "stack-trace": "0.0.10"
-      },
-      "dependencies": {
-        "async": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
-          "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k="
-        },
-        "colors": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
-          "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs="
-        },
-        "cycle": {
-          "version": "1.0.3",
-          "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
-          "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI="
-        },
-        "eyes": {
-          "version": "0.1.8",
-          "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
-          "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A="
-        },
-        "isstream": {
-          "version": "0.1.2",
-          "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
-          "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
-        },
-        "stack-trace": {
-          "version": "0.0.10",
-          "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
-          "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
-        }
       }
     },
+    "winston-daily-rotate-file": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-1.7.2.tgz",
+      "integrity": "sha1-ZQK/opeCT9mC2l5WR8dThXjS+aA=",
+      "requires": {
+        "mkdirp": "0.5.1"
+      }
+    },
+    "wordwrap": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+      "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+      "dev": true
+    },
+    "wrap-ansi": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+      "requires": {
+        "string-width": "1.0.2",
+        "strip-ansi": "3.0.1"
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+    },
+    "write": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
+      "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+      "dev": true,
+      "requires": {
+        "mkdirp": "0.5.1"
+      }
+    },
+    "xhr": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.1.tgz",
+      "integrity": "sha512-pAIU5vBr9Hiy5cpFIbPnwf0C18ZF86DBsZKrlsf87N5De/JbA6RJ83UP/cv+aljl4S40iRVMqP4pr4sF9Dnj0A==",
+      "dev": true,
+      "requires": {
+        "global": "4.3.2",
+        "is-function": "1.0.1",
+        "parse-headers": "2.0.1",
+        "xtend": "4.0.1"
+      }
+    },
+    "xml-parse-from-string": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/xml-parse-from-string/-/xml-parse-from-string-1.0.1.tgz",
+      "integrity": "sha1-qQKekp09vN7RafPG4oI42VpdWig=",
+      "dev": true
+    },
     "xml2js": {
       "version": "0.4.19",
       "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
@@ -8421,19 +6132,82 @@
       "requires": {
         "sax": "1.2.4",
         "xmlbuilder": "9.0.4"
+      }
+    },
+    "xmlbuilder": {
+      "version": "9.0.4",
+      "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz",
+      "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8="
+    },
+    "xtend": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+      "dev": true
+    },
+    "y18n": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+    },
+    "yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+    },
+    "yargs": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+      "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+      "requires": {
+        "camelcase": "3.0.0",
+        "cliui": "3.2.0",
+        "decamelize": "1.2.0",
+        "get-caller-file": "1.0.2",
+        "os-locale": "1.4.0",
+        "read-pkg-up": "1.0.1",
+        "require-directory": "2.1.1",
+        "require-main-filename": "1.0.1",
+        "set-blocking": "2.0.0",
+        "string-width": "1.0.2",
+        "which-module": "1.0.0",
+        "y18n": "3.2.1",
+        "yargs-parser": "5.0.0"
       },
       "dependencies": {
-        "sax": {
-          "version": "1.2.4",
-          "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-          "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
-        },
-        "xmlbuilder": {
-          "version": "9.0.4",
-          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz",
-          "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8="
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
+        }
+      }
+    },
+    "yargs-parser": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+      "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+      "requires": {
+        "camelcase": "3.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
         }
       }
+    },
+    "zip-stream": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",
+      "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
+      "dev": true,
+      "requires": {
+        "archiver-utils": "1.3.0",
+        "compress-commons": "1.2.2",
+        "lodash": "4.17.4",
+        "readable-stream": "2.3.3"
+      }
     }
   }
 }
diff --git a/bigbluebutton-html5/package.json b/bigbluebutton-html5/package.json
index 2399c450e5d6ce879a737be36a8ecabcf73ec86c..63e5826b40c4de4b9ea4c11fec082a400ddd8ecc 100644
--- a/bigbluebutton-html5/package.json
+++ b/bigbluebutton-html5/package.json
@@ -59,6 +59,7 @@
     "string-hash": "~1.1.3",
     "tippy.js": "~2.0.2",
     "winston": "~2.4.0",
+    "winston-daily-rotate-file": "^1.7.2",
     "xml2js": "~0.4.19"
   },
   "devDependencies": {
diff --git a/bigbluebutton-html5/private/config/settings-development.json b/bigbluebutton-html5/private/config/settings-development.json
index aa28943454ccf1663252a415c7d985ca6b681f0c..756e857cfd831d51eb3ae3c581ad8db4d3683261 100644
--- a/bigbluebutton-html5/private/config/settings-development.json
+++ b/bigbluebutton-html5/private/config/settings-development.json
@@ -327,7 +327,7 @@
       "host": "127.0.0.1",
       "post": "6379",
       "timeout": 5000,
-      "debug": false,
+      "debug": true,
       "channels": {
         "toAkkaApps": "to-akka-apps-redis-channel"
       },
diff --git a/bigbluebutton-html5/private/config/settings-production.json b/bigbluebutton-html5/private/config/settings-production.json
index 3f826e6cc0a725f19237ee05f7b5a0524ff22c56..6c89744003ad91d55a971244495c7fe70275b69b 100644
--- a/bigbluebutton-html5/private/config/settings-production.json
+++ b/bigbluebutton-html5/private/config/settings-production.json
@@ -191,39 +191,51 @@
       "toolbar": {
         "colors": [
           {
+            "label": "black",
             "value": "#000000"
           },
           {
+            "label": "white",
             "value": "#ffffff"
           },
           {
+            "label": "red",
             "value": "#ff0000"
           },
           {
+            "label": "orange",
             "value": "#ff8800"
           },
           {
+            "label": "eletricLime",
             "value": "#ccff00"
           },
           {
+            "label": "Lime",
             "value": "#00ff00"
           },
           {
+            "label": "Cyan",
             "value": "#00ffff"
           },
           {
+            "label": "dodgerBlue",
             "value": "#0088ff"
           },
           {
+            "label": "blue",
             "value": "#0000ff"
           },
           {
+            "label": "violet",
             "value": "#8800ff"
           },
           {
+            "label": "magenta",
             "value": "#ff00ff"
           },
           {
+            "label": "silver",
             "value": "#c0c0c0"
           }
         ],
@@ -315,7 +327,7 @@
       "host": "127.0.0.1",
       "post": "6379",
       "timeout": 5000,
-      "debug": false,
+      "debug": true,
       "channels": {
         "toAkkaApps": "to-akka-apps-redis-channel"
       },
diff --git a/bigbluebutton-html5/private/locales/de.json b/bigbluebutton-html5/private/locales/de.json
index 0537ff16aceda093f32198ba34371750ff3bc9ee..6c9fa5a87e757e15a653d4d80dd05c310372c6de 100644
--- a/bigbluebutton-html5/private/locales/de.json
+++ b/bigbluebutton-html5/private/locales/de.json
@@ -1,6 +1,8 @@
 {
     "app.home.greeting": "Willkommen {0}! Ihre Präsentation wird in Kürze beginnen...",
     "app.chat.submitLabel": "Nachricht senden",
+    "app.chat.errorMinMessageLength": "Die Nachricht ist {0} Buchstabe(n) zu kurz",
+    "app.chat.errorMaxMessageLength": "Die Nachricht ist {0} Buchstabe(n) zu lang",
     "app.chat.inputLabel": "Chatnachricht eingeben für {0}",
     "app.chat.inputPlaceholder": "Nachricht {0}",
     "app.chat.titlePublic": "Öffentlicher Chat",
@@ -15,6 +17,7 @@
     "app.chat.dropdown.save": "Speichern",
     "app.chat.label": "Chat",
     "app.chat.emptyLogLabel": "Chat-Log ist leer",
+    "app.chat.clearPublicChatMessage": "Der öffentliche Chatverlauf wurde durch einen Moderator gelöscht",
     "app.userList.usersTitle": "Teilnehmer",
     "app.userList.participantsTitle": "Teilnehmer",
     "app.userList.messagesTitle": "Nachrichten",
@@ -30,13 +33,15 @@
     "app.userList.menu.chat.label": "Chat",
     "app.userList.menu.clearStatus.label": "Status löschen",
     "app.userList.menu.makePresenter.label": "Präsentationsrechte geben",
-    "app.userList.menu.kickUser.label": "Teilnehmer aus Konferenz entfernen",
+    "app.userList.menu.removeUser.label": "Nutzer entfernen",
     "app.userList.menu.muteUserAudio.label": "Teilnehmer stummschalten",
     "app.userList.menu.unmuteUserAudio.label": "Mikrofon freigeben",
     "app.userList.userAriaLabel": "Teilnehmer : {0}  Rolle: {1}  Person: {2}  Status: {3}",
     "app.userList.menu.promoteUser.label": "{0} zum Moderator machen",
     "app.userList.menu.demoteUser.label": "{0} zum Zuschauer zurückstufen",
     "app.media.label": "Media",
+    "app.meeting.ended":"Diese Konferenz wurde beendet",
+    "app.meeting.endedMessage":"Sie werden zum Startbildschirm weitergeleitet",
     "app.presentation.presentationToolbar.prevSlideLabel": "Vorherige Folie",
     "app.presentation.presentationToolbar.prevSlideDesc": "Präsentation zur vorherigen Folie wechseln",
     "app.presentation.presentationToolbar.nextSlideLabel": "Nächste Folie",
@@ -49,6 +54,27 @@
     "app.presentation.presentationToolbar.fitScreenDesc": "Gesamte Folie darstellen",
     "app.presentation.presentationToolbar.zoomLabel": "Vergrößerungsgrad",
     "app.presentation.presentationToolbar.zoomDesc": "Vergrößerungsstufe der Präsentation ändern",
+    "app.presentation.presentationToolbar.goToSlide":"Folie {0}",
+    "app.presentationUploder.title": "Präsentation",
+    "app.presentationUploder.message": "Als Präsentator haben Sie in BigBlueButton die Möglichkeit, jegliche Office-Dokumente oder PDF-Dateien hochzuladen. Die beste Qualität erzielen Sie mit PDF-Dateien.",
+    "app.presentationUploder.confirmLabel": "Start",
+    "app.presentationUploder.confirmDesc": "Änderungen speichern und Präsentation starten",
+    "app.presentationUploder.dismissLabel": "Abbrechen",
+    "app.presentationUploder.dismissDesc": "Fenster schließen und Änderungen verwerfen",
+    "app.presentationUploder.dropzoneLabel": "Hochzuladende Dateien hier hin ziehen",
+    "app.presentationUploder.browseFilesLabel": "oder nach Dateien suchen",
+    "app.presentationUploder.fileToUpload": "Hochzuladende Datei...",
+    "app.presentationUploder.currentBadge": "Aktuell",
+    "app.presentationUploder.genericError": "Ups, irgendwas ist schief gelaufen",
+    "app.presentationUploder.upload.progress": "Lade hoch ({progress}%)",
+    "app.presentationUploder.upload.413": "Die Datei ist zu groß",
+    "app.presentationUploder.conversion.conversionProcessingSlides": "Verarbeite Seite {current} von {total}",
+    "app.presentationUploder.conversion.genericConversionStatus": "Konvertiere Datei...",
+    "app.presentationUploder.conversion.generatingThumbnail": "Erzeuge Miniaturbild...",
+    "app.presentationUploder.conversion.generatedSlides": "Folien erzeugt...",
+    "app.presentationUploder.conversion.generatingSvg": "Erzeuge SVG Bilder...",
+    "app.presentationUploder.conversion.pageCountExceeded": "Ups, die Seitenanzahl überschreitet das Limit",
+    "app.presentationUploder.conversion.timeout": "Ups, die Konvertierung dauert zu lange",
     "app.polling.pollingTitle": "Umfrage Optionen",
     "app.failedMessage": "Es gibt Verbindungsprobleme mit dem Server.",
     "app.connectingMessage": "Verbinde...",
@@ -149,24 +175,26 @@
     "app.actionsBar.actionsDropdown.presentationLabel": "Eine Präsentation hochladen",
     "app.actionsBar.actionsDropdown.initPollLabel": "Eine Umfrage starten",
     "app.actionsBar.actionsDropdown.desktopShareLabel": "Bildschirm freigeben",
+    "app.actionsBar.actionsDropdown.stopDesktopShareLabel": "Bildschirmfreigabe beenden",
     "app.actionsBar.actionsDropdown.presentationDesc": "Präsentation hochladen",
     "app.actionsBar.actionsDropdown.initPollDesc": "Eine Umfrage starten",
     "app.actionsBar.actionsDropdown.desktopShareDesc": "Ihren Bildschirm mit anderen teilen",
+    "app.actionsBar.actionsDropdown.stopDesktopShareDesc": "Bildschirmfreigabe beenden mit",
     "app.actionsBar.emojiMenu.statusTriggerLabel": "Status",
     "app.actionsBar.emojiMenu.awayLabel": "Abwesend",
     "app.actionsBar.emojiMenu.awayDesc": "Ihren Status auf abwesend setzen",
-    "app.actionsBar.emojiMenu.raiseLabel": "Hand heben",
-    "app.actionsBar.emojiMenu.raiseDesc": "Heben Sie Ihre Hand, um eine Frage zu stellen",
-    "app.actionsBar.emojiMenu.undecidedLabel": "Unentschlossen",
-    "app.actionsBar.emojiMenu.undecidedDesc": "Ihren Status auf unentschlossen setzen",
+    "app.actionsBar.emojiMenu.raiseHandLabel": "Hand heben",
+    "app.actionsBar.emojiMenu.raiseHandDesc": "Heben Sie Ihre Hand, um eine Frage zu stellen",
+    "app.actionsBar.emojiMenu.neutralLabel": "Unentschlossen",
+    "app.actionsBar.emojiMenu.neutralDesc": "Ihren Status auf unentschieden setzen",
     "app.actionsBar.emojiMenu.confusedLabel": "Verwirrt",
     "app.actionsBar.emojiMenu.confusedDesc": "Ihren Status auf verwirrt setzen",
     "app.actionsBar.emojiMenu.sadLabel": "Traurig",
     "app.actionsBar.emojiMenu.sadDesc": "Ihren Status auf traurig setzen",
     "app.actionsBar.emojiMenu.happyLabel": "Glücklich",
     "app.actionsBar.emojiMenu.happyDesc": "Ihren Status auf glücklich setzen",
-    "app.actionsBar.emojiMenu.clearLabel": "Status löschen",
-    "app.actionsBar.emojiMenu.clearDesc": "Ihren aktuellen Status zurücksetzen",
+    "app.actionsBar.emojiMenu.noneLabel": "Status löschen",
+    "app.actionsBar.emojiMenu.noneDesc": "Status löschen",
     "app.actionsBar.emojiMenu.applauseLabel": "Applaus",
     "app.actionsBar.emojiMenu.applauseDesc": "Ihren Status auf Applaus setzen",
     "app.actionsBar.emojiMenu.thumbsUpLabel": "Daumen hoch",
@@ -202,6 +230,22 @@
     "app.audioModal.audioChoiceLabel": "Wie möchten Sie der Konferenz beitreten?",
     "app.audioModal.audioChoiceDesc": "Wie möchten Sie der Konferenz beitreten?",
     "app.audioModal.closeLabel": "Schließen",
+    "app.audioModal.yes": "Ja",
+    "app.audioModal.no": "Nein",
+    "app.audioModal.echoTestTitle": "Dies ist ein persönlicher Echotest. Sprechen Sie ein paar Worte. Hören Sie sich selbst?",
+    "app.audioModal.settingsTitle": "Audioeinstellungen ändern",
+    "app.audioModal.helpTitle": "Es gab ein Problem mit ihren Mediengeräten (Mikrofon/Webcam)",
+    "app.audioModal.helpText": "Haben Sie BigBlueButton die Berechtigung gegeben, auf Ihr Mikrofon zuzugreifen? Beachten Sie, dass sich ein Dialogfenster öffnen sollte, sobald sie versuchen der Audiokonferenz beizutreten. Dabei wird die Zugriffsberechtigung für Ihre Mediengerät (Mikrofon) abgefragt. Bitte erteilen Sie diese Zugriffsberechtigung, um der Konferenz beizutreten. Falls dies nicht funktioniert, versuchen Sie die Mikrofon-Berechtigung in ihren Browsereinstellungen zu ändern.",
+    "app.audioModal.connecting": "Verbinde",
+    "app.audioModal.connectingEchoTest": "Verbinde zum Echotest",
+    "app.audioManager.joinedAudio": "Sie sind der Konferenz beigetreten",
+    "app.audioManager.joinedEcho": "Der Echotest wurde gestartet",
+    "app.audioManager.leftAudio": "Sie haben die Konferenz verlassen",
+    "app.audioManager.genericError": "Fehler: Es ist ein Fehler aufgetreten, bitte versuchen Sie es erneut",
+    "app.audioManager.connectionError": "Fehler: Verbindungsfehler",
+    "app.audioManager.requestTimeout": "Fehler: Zeitüberschreitung beim Aufruf",
+    "app.audioManager.invalidTarget": "Fehler: Beim Aufruf wurde ein ungültiges Ziel angegeben",
+    "app.audioManager.mediaError": "Fehler: Es gab ein Problem bei der Abfrage Ihrer Mediengeräte",
     "app.audio.joinAudio": "Audio starten",
     "app.audio.leaveAudio": "Audio beenden",
     "app.audio.enterSessionLabel": "An Konferenz teilnehmen",
@@ -212,17 +256,60 @@
     "app.audio.audioSettings.microphoneSourceLabel": "Mikrofoneingang",
     "app.audio.audioSettings.speakerSourceLabel": "Lautsprecherausgang",
     "app.audio.audioSettings.microphoneStreamLabel": "Lautstärke Ihres Audiosignals",
+    "app.audio.audioSettings.retryLabel": "Erneut versuchen",
     "app.audio.listenOnly.backLabel": "Zurück",
     "app.audio.listenOnly.closeLabel": "Schließen",
-    "app.error.kicked": "Sie wurden aus dem Meeting entfernt",
+    "app.audio.permissionsOverlay.title": "Erlauben Sie BigBlueButton auf ihre Mediengeräte zuzugreifen",
+    "app.audio.permissionsOverlay.hint": "Es ist erforderlich, dass Sie BigBlueButton den Zugriff auf Ihre Mediengeräte erlauben, um an der Konferenz teilzunehmen :) ",
+    "app.error.removed": "Sie wurden aus der Konferenz entfernt",
     "app.error.meeting.ended": "Sie haben die Konferenz verlassen",
     "app.dropdown.close": "Schließen",
     "app.error.500": "Ups, irgendwas ist schiefgelaufen",
     "app.error.404": "Nicht gefunden",
     "app.error.401": "Nicht erlaubt",
-    "app.error.403": "Verboten",    
-    "app.error.leaveLabel": "Erneut einloggen",    
-    "app.guest.waiting": "Warte auf Erlaubnis zur Konferenzteilnahme"
+    "app.error.403": "Verboten",
+    "app.error.leaveLabel": "Erneut einloggen",
+    "app.guest.waiting": "Warte auf Erlaubnis zur Konferenzteilnahme",
+    "app.toast.breakoutRoomEnded": "Breakout Raum wurde beendet. Bitte klicken Sie aufs Mikrofon-Icon um wieder der Audiokonferenz im Hauptraum beizutreten",
+    "app.toast.chat.singular":"Sie haben {0} neue Nachricht in {1}",
+    "app.toast.chat.plural":"Sie haben {0} neue Nachrichten in {1}",
+    "app.notification.recordingStart": "Die Sitzung wird jetzt aufgezeichnet",
+    "app.notification.recordingStop": "Die Sitzung wird nicht mehr aufgezeichnet",
+    "app.video.joinVideo": "Webcam freigeben",
+    "app.video.leaveVideo": "Webcam stoppen",
+    "app.video.iceCandidateError": "Fehler beim Hinzufügen vom ice candidate",
+    "app.video.permissionError": "Fehler bei Freigabe der Webcam. Bitte Berechtigungen prüfen",
+    "app.video.sharingError": "Fehler bei Freigabe der Webcam",
+    "app.video.chromeExtensionError": "Sie müssen Folgendes installieren:",
+    "app.video.chromeExtensionErrorLink": "Diese Chrome Erweiterung",
+    "app.meeting.endNotification.ok.label": "OK",
+    "app.whiteboard.toolbar.tools": "Werkzeuge",
+    "app.whiteboard.toolbar.tools.hand": "Hand",
+    "app.whiteboard.toolbar.tools.pencil": "Stift",
+    "app.whiteboard.toolbar.tools.rectangle": "Rechteck",
+    "app.whiteboard.toolbar.tools.triangle": "Dreieck",
+    "app.whiteboard.toolbar.tools.ellipse": "Ellipse",
+    "app.whiteboard.toolbar.tools.line": "Linie",
+    "app.whiteboard.toolbar.tools.text": "Text",
+    "app.whiteboard.toolbar.thickness": "Strichstärkenliste",
+    "app.whiteboard.toolbar.color": "Farbliste",
+    "app.whiteboard.toolbar.color.black": "Schwarz",
+    "app.whiteboard.toolbar.color.white": "Weiß",
+    "app.whiteboard.toolbar.color.red": "Rot",
+    "app.whiteboard.toolbar.color.orange": "Orange",
+    "app.whiteboard.toolbar.color.eletricLime": "Gelbgrün",
+    "app.whiteboard.toolbar.color.lime": "Hellgrün",
+    "app.whiteboard.toolbar.color.cyan": "Cyan",
+    "app.whiteboard.toolbar.color.dodgerBlue": "Dodger blau",
+    "app.whiteboard.toolbar.color.blue": "Blau",
+    "app.whiteboard.toolbar.color.violet": "Violett",
+    "app.whiteboard.toolbar.color.magenta": "Magenta",
+    "app.whiteboard.toolbar.color.silver": "Silber",
+    "app.whiteboard.toolbar.undo": "Anmerkung zurücknehmen",
+    "app.whiteboard.toolbar.clear": "Alle Anmerkungen löschen",
+    "app.whiteboard.toolbar.multiUserOn": "Mehrbenutzermodus starten",
+    "app.whiteboard.toolbar.multiUserOff": "Mehrbenutzermodus beenden",
+    "app.whiteboard.toolbar.fontSize": "Schriftgrößenliste"
 
 }
 
diff --git a/bigbluebutton-html5/private/locales/es_ES.json b/bigbluebutton-html5/private/locales/es_ES.json
index 3a025e442fb35a7dd5dc2eab570618915db26910..f9f729d7d4605dd925330c74449b6f362c2d7ceb 100644
--- a/bigbluebutton-html5/private/locales/es_ES.json
+++ b/bigbluebutton-html5/private/locales/es_ES.json
@@ -30,7 +30,6 @@
     "app.userList.menu.chat.label": "Chat",
     "app.userList.menu.clearStatus.label": "Limpiar estátus",
     "app.userList.menu.makePresenter.label": "Hacer presentador",
-    "app.userList.menu.kickUser.label": "Expulsar usuario",
     "app.userList.menu.muteUserAudio.label": "Silenciar usuario",
     "app.userList.menu.unmuteUserAudio.label": "Activar sonido de usuario",
     "app.userList.userAriaLabel": "Usuario : {0} Rol: {1} Persona: {2} Estátus: {3}",
@@ -153,18 +152,12 @@
     "app.actionsBar.emojiMenu.statusTriggerLabel": "Estátus",
     "app.actionsBar.emojiMenu.awayLabel": "Ausente",
     "app.actionsBar.emojiMenu.awayDesc": "Cambiar tu estatus a ausente",
-    "app.actionsBar.emojiMenu.raiseLabel": "Alzar",
-    "app.actionsBar.emojiMenu.raiseDesc": "Alzar la mano para preguntar",
-    "app.actionsBar.emojiMenu.undecidedLabel": "Indeciso",
-    "app.actionsBar.emojiMenu.undecidedDesc": "Cambiar tu estatus a indeciso",
     "app.actionsBar.emojiMenu.confusedLabel": "Confundido",
     "app.actionsBar.emojiMenu.confusedDesc": "Cambiar tu estatus a confundido",
     "app.actionsBar.emojiMenu.sadLabel": "Triste",
     "app.actionsBar.emojiMenu.sadDesc": "Cambiar tu estatus a triste",
     "app.actionsBar.emojiMenu.happyLabel": "Feliz",
     "app.actionsBar.emojiMenu.happyDesc": "Cambiar tu estatus a feliz",
-    "app.actionsBar.emojiMenu.clearLabel": "Limpiar",
-    "app.actionsBar.emojiMenu.clearDesc": "Limpia tu estatus",
     "app.actionsBar.emojiMenu.applauseLabel": "Aplausos",
     "app.actionsBar.emojiMenu.applauseDesc": "Cambiar tu estatus a aplausos",
     "app.actionsBar.emojiMenu.thumbsUpLabel": "Señal de aprobación",
@@ -212,14 +205,13 @@
     "app.audio.audioSettings.microphoneStreamLabel": "Tu volúmen del flujo de audio",
     "app.audio.listenOnly.backLabel": "Atrás",
     "app.audio.listenOnly.closeLabel": "Cerrar",
-    "app.error.kicked": "Haz sido expulsado de la reunión",
     "app.error.meeting.ended": "Haz salido de la conferencia",
     "app.dropdown.close": "Cerrar",
     "app.error.500": "Ups, algo salio mal",
     "app.error.404": "No se encontró",
     "app.error.401": "No autorizado",
-    "app.error.403": "Prohibido",    
-    "app.error.leaveLabel": "Ingresa de nuevo",    
+    "app.error.403": "Prohibido",
+    "app.error.leaveLabel": "Ingresa de nuevo",
     "app.guest.waiting": "Esperando aprobación para unirse"
 
 }
diff --git a/bigbluebutton-html5/private/locales/fr.json b/bigbluebutton-html5/private/locales/fr.json
index 1956a250adb9fadeb62ef640b0b8689e47584868..ca0dbb6a3e8bf37d230d6e4762c96250a832704c 100644
--- a/bigbluebutton-html5/private/locales/fr.json
+++ b/bigbluebutton-html5/private/locales/fr.json
@@ -1,26 +1,51 @@
 {
     "app.chat.submitLabel": "Envoyer message",
+    "app.chat.errorMinMessageLength": "Le message est {0} caractère(s) trop court",
+    "app.chat.errorMaxMessageLength": "Le message est {0} caractère(s) trop long",
     "app.chat.inputPlaceholder": "Message {0}",
+    "app.chat.partnerDisconnected": "{0} a quitté la conférence",
     "app.chat.closeChatLabel": "Fermer {0}",
     "app.chat.hideChatLabel": "Cacher {0}",
+    "app.chat.dropdown.clear": "Effacer",
+    "app.chat.dropdown.copy": "Copier",
+    "app.chat.dropdown.save": "Sauvegarder",
+    "app.userList.usersTitle": "Utilisateurs",
+    "app.userList.participantsTitle": "Participants",
+    "app.userList.messagesTitle": "Messages",
+    "app.userList.presenter": "Présentateur",
+    "app.userList.you": "Vous",
+    "app.userList.locked": "Verrouillé",
+    "app.userList.label": "Liste d'utilisateurs",
+    "app.userList.guest": "Invité",
+    "app.userList.menuTitleContext": "Options disponibles",
+    "app.userList.chatListItem.unreadSingular": "{0} nouveau message",
+    "app.userList.chatListItem.unreadPlural": "{0} nouveaux messages",
+    "app.userList.userAriaLabel": "Présentation",
+    "app.media.label": "Média",
     "app.presentation.presentationToolbar.fitScreenLabel": "Ajuster à l'écran",
     "app.presentation.presentationToolbar.zoomLabel": "Zoom",
+    "app.presentationUploder.dismissLabel": "Annuler",
     "app.connectingMessage": "Connexion en cours...",
     "app.navBar.settingsDropdown.optionsLabel": "Options",
     "app.navBar.settingsDropdown.fullscreenLabel": "Plein écran",
+    "app.navBar.settingsDropdown.settingsLabel": "Ouvrir les paramètres",
     "app.navBar.settingsDropdown.aboutLabel": "À propos",
     "app.navBar.settingsDropdown.leaveSessionLabel": "Déconnexion",
+    "app.navBar.settingsDropdown.exitFullscreenLabel": "Quitter le plein écran",
+    "app.navBar.settingsDropdown.exitFullscreenDesc": "Quitter le mode plein écran",
     "app.leaveConfirmation.title": "Quitter la session",
     "app.leaveConfirmation.confirmLabel": "Quitter",
     "app.leaveConfirmation.dismissLabel": "Annuler",
     "app.about.title": "À propos",
-    "app.about.version": "Client Build:",
+    "app.about.version": "Version du client :",
     "app.about.copyright": "Copyright :",
     "app.about.confirmLabel": "OK",
     "app.about.confirmDesc": "OK",
     "app.about.dismissLabel": "Annuler",
     "app.actionsBar.changeStatusLabel": "Changer le statut",
+    "app.actionsBar.label": "Barre d'actions",
     "app.submenu.application.applicationSectionTitle": "Application",
+    "app.submenu.application.fontSizeControlLabel": "Taille des caractères",
     "app.submenu.application.languageLabel": "Langue de l'application",
     "app.submenu.application.ariaLanguageLabel": "Changer la langue de l'application",
     "app.submenu.application.languageOptionLabel": "Choisir la langue",
@@ -48,17 +73,30 @@
     "app.settings.main.save.label.description": "Sauvegarde les changements et ferme le menu des paramètres",
     "app.actionsBar.actionsDropdown.actionsLabel": "Actions",
     "app.actionsBar.emojiMenu.statusTriggerLabel": "Statut",
+    "app.actionsBar.emojiMenu.noneLabel": "Effacer",
+    "app.actionsBar.emojiMenu.noneDesc": "Effacer votre statut",
     "app.actionsBar.currentStatusDesc": "statut actuel {0}",
     "app.audioNotification.closeLabel": "Fermer",
     "app.breakoutJoinConfirmation.dismissLabel": "Annuler",
     "app.calculatingBreakoutTimeRemaining": "Calcul du temps restant...",
     "app.audioModal.microphoneLabel": "Microphone",
     "app.audioModal.closeLabel": "Fermer",
+    "app.audioModal.yes": "Oui",
+    "app.audioModal.no": "Non",
+    "app.audio.backLabel": "Retour",
+    "app.audio.audioSettings.speakerSourceLabel": "vous avez {0} nouveau message dans {1}",
     "app.audio.audioSettings.microphoneStreamLabel": "Le volume de votre flux audio",
+    "app.audio.audioSettings.retryLabel": "Réessayer",
+    "app.audio.listenOnly.backLabel": "Retour",
     "app.audio.listenOnly.closeLabel": "Fermer",
     "app.dropdown.close": "Fermer",
     "app.error.500": "Oups, quelque chose s'est mal passé",
     "app.error.404": "Non trouvé",
-    "app.error.403": "Interdit"
+    "app.error.403": "Interdit",
+    "app.toast.chat.singular":"vous avez {0} nouveau message dans {1}",
+    "app.toast.chat.plural":"vous avez {0} nouveaux messages dans {1}",
+    "app.notification.recordingStart": "Cette session est maintenant enregistrée",
+    "app.notification.recordingStop": "Cette session n'est maintenant plus enregistrée"
+
 }
 
diff --git a/bigbluebutton-html5/private/locales/id.json b/bigbluebutton-html5/private/locales/id.json
index 92e4ab06400c828cc0fb5078167ae87571a1dcfe..ed7e1f7189ad94c007490d75881464f4835d4ac0 100644
--- a/bigbluebutton-html5/private/locales/id.json
+++ b/bigbluebutton-html5/private/locales/id.json
@@ -116,18 +116,12 @@
     "app.actionsBar.emojiMenu.statusTriggerLabel": "Status",
     "app.actionsBar.emojiMenu.awayLabel": "Tidak Fokus",
     "app.actionsBar.emojiMenu.awayDesc": "Ubah status menjadi Tidak Fokus",
-    "app.actionsBar.emojiMenu.raiseLabel": "Naikan",
-    "app.actionsBar.emojiMenu.raiseDesc": "Angkat tangan untuk bertanya",
-    "app.actionsBar.emojiMenu.undecidedLabel": "Tidak memutuskan",
-    "app.actionsBar.emojiMenu.undecidedDesc": "Ubah status anda menjadi Tidak Memutuskan",
     "app.actionsBar.emojiMenu.confusedLabel": "Bingung",
     "app.actionsBar.emojiMenu.confusedDesc": "Ubah status anda menjadi Bingung",
     "app.actionsBar.emojiMenu.sadLabel": "Sedih",
     "app.actionsBar.emojiMenu.sadDesc": "Ubah status anda menjadi Sedih",
     "app.actionsBar.emojiMenu.happyLabel": "Bahagia",
     "app.actionsBar.emojiMenu.happyDesc": "Ubah status anda menjadi Bahagia",
-    "app.actionsBar.emojiMenu.clearLabel": "Normal",
-    "app.actionsBar.emojiMenu.clearDesc": "Normalkan status anda",
     "app.actionsBar.emojiMenu.applauseLabel": "Tepuk tangan",
     "app.actionsBar.emojiMenu.applauseDesc": "Ubah status anda menjadi Tepuk Tangan",
     "app.actionsBar.currentStatusDesc": "status saat ini {0}",
@@ -159,7 +153,6 @@
     "app.audio.audioSettings.microphoneStreamLabel": "Volume stream audio anda",
     "app.audio.listenOnly.backLabel": "Kembali",
     "app.audio.listenOnly.closeLabel": "Tutup",
-    "app.error.kicked": "Anda telah dikeluarkan dari meeting",
     "app.error.meeting.ended": "Anda telah keluar dari konferensi",
     "app.dropdown.close": "Tutup",
     "app.error.500": "Ops, sepertinya ada kesalahan",
@@ -167,5 +160,6 @@
     "app.error.401": "Tidak memiliki izin",
     "app.error.403": "Dilarang",
     "app.error.leaveLabel": "Log in Kembali"
+
 }
 
diff --git a/bigbluebutton-html5/private/locales/ja.json b/bigbluebutton-html5/private/locales/ja.json
deleted file mode 100644
index ef43adbca9a585010018842ee323dd3d7e7c0893..0000000000000000000000000000000000000000
--- a/bigbluebutton-html5/private/locales/ja.json
+++ /dev/null
@@ -1,171 +0,0 @@
-{
-    "app.home.greeting": "ようこそ {0} さん! プレゼンテーションは間もなく始まります…",
-    "app.chat.submitLabel": "メッセージを送信",
-    "app.chat.inputLabel": "チャット {0} へメッセージ入力",
-    "app.chat.inputPlaceholder": "メッセージ {0}",
-    "app.chat.titlePublic": "公開チャット",
-    "app.chat.titlePrivate": "{0} との非公開チャット",
-    "app.chat.partnerDisconnected": "{0} は会議から退出しました",
-    "app.chat.closeChatLabel": "{0} を閉じる",
-    "app.chat.hideChatLabel": "{0} を隠す",
-    "app.chat.moreMessages": "下にまだメッセージがあります",
-    "app.chat.emptyLogLabel": "チャットログは空です",
-    "app.presentation.presentationToolbar.prevSlideLabel": "前のスライド",
-    "app.presentation.presentationToolbar.nextSlideLabel": "次のスライド",
-    "app.presentation.presentationToolbar.skipSlideLabel": "スライドをスキップ",
-    "app.presentation.presentationToolbar.fitWidthLabel": "幅に合わせる",
-    "app.presentation.presentationToolbar.fitScreenLabel": "画面に合わせる",
-    "app.presentation.presentationToolbar.zoomLabel": "ズーム",
-    "app.polling.pollingTitle": "投票オプション",
-    "app.failedMessage": "サーバー接続障害",
-    "app.connectingMessage": "接続中…",
-    "app.waitingMessage": "切断されました。 {0} 秒後に再接続します…",
-    "app.navBar.settingsDropdown.optionsLabel": "オプション",
-    "app.navBar.settingsDropdown.fullscreenLabel": "全画面表示に切替",
-    "app.navBar.settingsDropdown.settingsLabel": "設定を開く",
-    "app.navBar.settingsDropdown.aboutLabel": "アバウト",
-    "app.navBar.settingsDropdown.leaveSessionLabel": "ログアウト",
-    "app.navBar.settingsDropdown.fullscreenDesc": "設定メニューを全画面表示",
-    "app.navBar.settingsDropdown.settingsDesc": "一般の設定を変更",
-    "app.navBar.settingsDropdown.aboutDesc": "クライアントに関する情報を表示",
-    "app.navBar.settingsDropdown.leaveSessionDesc": "会議から退室",
-    "app.navBar.userListToggleBtnLabel": "ユーザーリストのトグル",
-    "app.leaveConfirmation.title": "セッションから離れる",
-    "app.leaveConfirmation.message": "この会議から退室しますか?",
-    "app.leaveConfirmation.confirmLabel": "退室",
-    "app.leaveConfirmation.confirmDesc": "自分を会議からログアウトさせる",
-    "app.leaveConfirmation.dismissLabel": "キャンセル",
-    "app.leaveConfirmation.dismissDesc": "退出確認を破棄し閉じる",
-    "app.about.title": "アバウト",
-    "app.about.version": "Client Build:",
-    "app.about.copyright": "Copyright:",
-    "app.about.confirmLabel": "OK",
-    "app.about.confirmDesc": "OK",
-    "app.about.dismissLabel": "キャンセル",
-    "app.about.dismissDesc": "クライアント情報を閉じる",
-    "app.actionsBar.changeStatusLabel": "ステータス変更",
-    "app.actionsBar.muteLabel": "ミュート",
-    "app.actionsBar.unmuteLabel": "ミュート解除",
-    "app.actionsBar.camOffLabel": "カメラオフ",
-    "app.actionsBar.raiseLabel": "手をあげる",
-    "app.submenu.application.applicationSectionTitle": "アプリケーション",
-    "app.submenu.application.audioNotifyLabel": "チャットの音声通知",
-    "app.submenu.application.pushNotifyLabel": "チャットのプッシュ通知",
-    "app.submenu.application.fontSizeControlLabel": "フォントサイズ",
-    "app.submenu.application.increaseFontBtnLabel": "アプリケーションのフォントサイズを大きくする",
-    "app.submenu.application.decreaseFontBtnLabel": "アプリケーションのフォントサイズを小さくする",
-    "app.submenu.application.languageLabel": "アプリケーション言語",
-    "app.submenu.application.ariaLanguageLabel": "アプリケーション言語を変更",
-    "app.submenu.application.languageOptionLabel": "言語を選択",
-    "app.submenu.application.noLocaleOptionLabel": "アクティブなロケールがありません",
-    "app.submenu.audio.micSourceLabel": "マイクのソース",
-    "app.submenu.audio.speakerSourceLabel": "スピーカーのソース",
-    "app.submenu.audio.streamVolumeLabel": "音声ストリームの音量",
-    "app.submenu.video.title": "ビデオ",
-    "app.submenu.video.videoSourceLabel": "ソースを表示",
-    "app.submenu.video.videoOptionLabel": "ソース表示を選択",
-    "app.submenu.video.videoQualityLabel": "ビデオ品質",
-    "app.submenu.video.qualityOptionLabel": "ビデオ品質を選択",
-    "app.submenu.video.participantsCamLabel": "参加者のウェブカメラを見ています",
-    "app.submenu.closedCaptions.closedCaptionsLabel": "クローズドキャプション",
-    "app.submenu.closedCaptions.takeOwnershipLabel": "所有権をとる",
-    "app.submenu.closedCaptions.languageLabel": "言語",
-    "app.submenu.closedCaptions.localeOptionLabel": "言語を選択",
-    "app.submenu.closedCaptions.noLocaleOptionLabel": "アクティブなロケールがありません",
-    "app.submenu.closedCaptions.fontFamilyLabel": "フォントファミリー",
-    "app.submenu.closedCaptions.fontFamilyOptionLabel": "フォントファミリーを選択",
-    "app.submenu.closedCaptions.fontSizeLabel": "フォントサイズ",
-    "app.submenu.closedCaptions.fontSizeOptionLabel": "フォントサイズを選択",
-    "app.submenu.closedCaptions.backgroundColorLabel": "背景色",
-    "app.submenu.closedCaptions.fontColorLabel": "フォント色",
-    "app.submenu.participants.muteAllLabel": "プレゼンター以外の全員をミュート",
-    "app.submenu.participants.lockAllLabel": "すべての参加者をロック",
-    "app.submenu.participants.lockItemLabel": "参加者 {0}",
-    "app.submenu.participants.lockMicDesc": "ロック中のすべての参加者のマイクを無効化",
-    "app.submenu.participants.lockCamDesc": "ロック中のすべての参加者のウェブカメラを無効化",
-    "app.submenu.participants.lockPublicChatDesc": "ロック中のすべての参加者の公開チャットを無効化",
-    "app.submenu.participants.lockPrivateChatDesc": "ロック中のすべての参加者の非公開チャットを無効化",
-    "app.submenu.participants.lockLayoutDesc": "ロック中のすべての参加者のレイアウトを固定",
-    "app.submenu.participants.lockMicAriaLabel": "マイクのロック",
-    "app.submenu.participants.lockCamAriaLabel": "ウェブカメラのロック",
-    "app.submenu.participants.lockPublicChatAriaLabel": "公開チャットのロック",
-    "app.submenu.participants.lockPrivateChatAriaLabel": "非公開チャットのロック",
-    "app.submenu.participants.lockLayoutAriaLabel": "レイアウトのロック",
-    "app.submenu.participants.lockMicLabel": "マイク",
-    "app.submenu.participants.lockCamLabel": "ウェブカメラ",
-    "app.submenu.participants.lockPublicChatLabel": "公開チャット",
-    "app.submenu.participants.lockPrivateChatLabel": "非公開チャット",
-    "app.submenu.participants.lockLayoutLabel": "レイアウト",
-    "app.settings.applicationTab.label": "アプリケーション",
-    "app.settings.audioTab.label": "音声",
-    "app.settings.videoTab.label": "ビデオ",
-    "app.settings.closedcaptionTab.label": "クローズドキャプション",
-    "app.settings.usersTab.label": "参加者",
-    "app.settings.main.label": "設定",
-    "app.settings.main.cancel.label": "キャンセル",
-    "app.settings.main.cancel.label.description": "変更を破棄し設定メニューを閉じる",
-    "app.settings.main.save.label": "保存",
-    "app.settings.main.save.label.description": "変更を保存し設定メニューを閉じる",
-    "app.actionsBar.actionsDropdown.actionsLabel": "アクション",
-    "app.actionsBar.actionsDropdown.presentationLabel": "プレゼンテーションをアップロード",
-    "app.actionsBar.actionsDropdown.initPollLabel": "投票を初期化",
-    "app.actionsBar.actionsDropdown.desktopShareLabel": "画面を共有する",
-    "app.actionsBar.actionsDropdown.presentationDesc": "プレゼンテーションをアップロード",
-    "app.actionsBar.actionsDropdown.initPollDesc": "投票を初期化",
-    "app.actionsBar.actionsDropdown.desktopShareDesc": "他の人と画面を共有する",
-    "app.actionsBar.emojiMenu.statusTriggerLabel": "ステータス",
-    "app.actionsBar.emojiMenu.awayLabel": "不在",
-    "app.actionsBar.emojiMenu.awayDesc": "スタータスを「不在」にする",
-    "app.actionsBar.emojiMenu.raiseLabel": "手をあげる",
-    "app.actionsBar.emojiMenu.raiseDesc": "手をあげて質問する",
-    "app.actionsBar.emojiMenu.undecidedLabel": "未決定",
-    "app.actionsBar.emojiMenu.undecidedDesc": "ステータスを「未決定」にする",
-    "app.actionsBar.emojiMenu.confusedLabel": "わけがわからない",
-    "app.actionsBar.emojiMenu.confusedDesc": "ステータスを「わけがわからない」にする",
-    "app.actionsBar.emojiMenu.sadLabel": "悲しい",
-    "app.actionsBar.emojiMenu.sadDesc": "ステータスを「悲しい」にする",
-    "app.actionsBar.emojiMenu.happyLabel": "ハッピー",
-    "app.actionsBar.emojiMenu.happyDesc": "ステータスを「ハッピー」にする",
-    "app.actionsBar.emojiMenu.clearLabel": "クリア",
-    "app.actionsBar.emojiMenu.clearDesc": "ステータスをクリア",
-    "app.actionsBar.emojiMenu.applauseLabel": "拍手",
-    "app.actionsBar.emojiMenu.applauseDesc": "ステータスを「拍手」にする",
-    "app.actionsBar.currentStatusDesc": "現在のステータス {0}",
-    "app.audioNotification.audioFailedMessage": "音声接続に失敗しました",
-    "app.audioNotification.mediaFailedMessage": "getUserMicMedia に失敗。安全な接続だけが許可されます",
-    "app.audioNotification.closeLabel": "閉じる",
-    "app.breakoutJoinConfirmation.title": "小会議室に参加",
-    "app.breakoutJoinConfirmation.message": "参加しますか",
-    "app.breakoutJoinConfirmation.confirmLabel": "参加",
-    "app.breakoutJoinConfirmation.confirmDesc": "自分を小会議室に参加させる",
-    "app.breakoutJoinConfirmation.dismissLabel": "キャンセル",
-    "app.breakoutJoinConfirmation.dismissDesc": "小会議室の参加を拒否し閉じる",
-    "app.breakoutTimeRemainingMessage": "小会議室残り時間: {0}",
-    "app.breakoutWillCloseMessage": "終了時間。間もなく小会議室を閉じます",
-    "app.calculatingBreakoutTimeRemaining": "残り時間計算中…",
-    "app.audioModal.microphoneLabel": "マイク",
-    "app.audioModal.listenOnlyLabel": "聴講のみ",
-    "app.audioModal.audioChoiceLabel": "音声はどうしますか?",
-    "app.audioModal.closeLabel": "閉じる",
-    "app.audio.joinAudio": "音声で参加",
-    "app.audio.leaveAudio": "音声をやめる",
-    "app.audio.enterSessionLabel": "セッションに入る",
-    "app.audio.playSoundLabel": "音を出す",
-    "app.audio.backLabel": "戻る",
-    "app.audio.audioSettings.titleLabel": "音声設定を選択",
-    "app.audio.audioSettings.descriptionLabel": "マイク共有の許可を求めるダイアログがブラウザ内に現われますのでご了承ください。",
-    "app.audio.audioSettings.microphoneSourceLabel": "マイクのソース",
-    "app.audio.audioSettings.speakerSourceLabel": "スピーカーのソース",
-    "app.audio.audioSettings.microphoneStreamLabel": "音声ストリームの音量",
-    "app.audio.listenOnly.backLabel": "戻る",
-    "app.audio.listenOnly.closeLabel": "閉じる",
-    "app.error.kicked": "会議から退室させられました",
-    "app.error.meeting.ended": "会議からログアウトしました",
-    "app.dropdown.close": "閉じる",
-    "app.error.500": "あっ、何かがおかしくなりました",
-    "app.error.404": "見つかりません",
-    "app.error.401": "権限がありません",
-    "app.error.403": "禁止されています",
-    "app.error.leaveLabel": "再ログイン"
-}
-
diff --git a/bigbluebutton-html5/private/locales/ja_JP.json b/bigbluebutton-html5/private/locales/ja_JP.json
index ef43adbca9a585010018842ee323dd3d7e7c0893..b6c20e24e1350d6d899c2618ee1bd782b9746571 100644
--- a/bigbluebutton-html5/private/locales/ja_JP.json
+++ b/bigbluebutton-html5/private/locales/ja_JP.json
@@ -116,18 +116,12 @@
     "app.actionsBar.emojiMenu.statusTriggerLabel": "ステータス",
     "app.actionsBar.emojiMenu.awayLabel": "不在",
     "app.actionsBar.emojiMenu.awayDesc": "スタータスを「不在」にする",
-    "app.actionsBar.emojiMenu.raiseLabel": "手をあげる",
-    "app.actionsBar.emojiMenu.raiseDesc": "手をあげて質問する",
-    "app.actionsBar.emojiMenu.undecidedLabel": "未決定",
-    "app.actionsBar.emojiMenu.undecidedDesc": "ステータスを「未決定」にする",
     "app.actionsBar.emojiMenu.confusedLabel": "わけがわからない",
     "app.actionsBar.emojiMenu.confusedDesc": "ステータスを「わけがわからない」にする",
     "app.actionsBar.emojiMenu.sadLabel": "悲しい",
     "app.actionsBar.emojiMenu.sadDesc": "ステータスを「悲しい」にする",
     "app.actionsBar.emojiMenu.happyLabel": "ハッピー",
     "app.actionsBar.emojiMenu.happyDesc": "ステータスを「ハッピー」にする",
-    "app.actionsBar.emojiMenu.clearLabel": "クリア",
-    "app.actionsBar.emojiMenu.clearDesc": "ステータスをクリア",
     "app.actionsBar.emojiMenu.applauseLabel": "拍手",
     "app.actionsBar.emojiMenu.applauseDesc": "ステータスを「拍手」にする",
     "app.actionsBar.currentStatusDesc": "現在のステータス {0}",
@@ -159,7 +153,6 @@
     "app.audio.audioSettings.microphoneStreamLabel": "音声ストリームの音量",
     "app.audio.listenOnly.backLabel": "戻る",
     "app.audio.listenOnly.closeLabel": "閉じる",
-    "app.error.kicked": "会議から退室させられました",
     "app.error.meeting.ended": "会議からログアウトしました",
     "app.dropdown.close": "閉じる",
     "app.error.500": "あっ、何かがおかしくなりました",
@@ -167,5 +160,6 @@
     "app.error.401": "権限がありません",
     "app.error.403": "禁止されています",
     "app.error.leaveLabel": "再ログイン"
+
 }
 
diff --git a/bigbluebutton-html5/private/locales/km.json b/bigbluebutton-html5/private/locales/km.json
index 6c0485497928e4e7cc2bb5602510f3ac7dec281d..7d674fffc9a99c53e6e7228e3c5b3f989d519153 100644
--- a/bigbluebutton-html5/private/locales/km.json
+++ b/bigbluebutton-html5/private/locales/km.json
@@ -30,11 +30,10 @@
     "app.userList.menu.chat.label": "ជជែក",
     "app.userList.menu.clearStatus.label": "លុប​ស្ថានភាព",
     "app.userList.menu.makePresenter.label": "ធ្វើ​ជា​អ្នក​ធ្វើ​បទ​បង្ហាញ",
-    "app.userList.menu.kickUser.label": "ដកអ្នកប្រើប្រាស់ចេញ",
     "app.userList.menu.muteUserAudio.label": "បិទសម្លេងអ្នកប្រើប្រាស់",
     "app.userList.menu.unmuteUserAudio.label": "ឈប់បិទសម្លេងអ្នកប្រើប្រាស់",
     "app.userList.userAriaLabel": "អ្នកប្រើ ៖ {0} តួនាទី​ ៖ {1} មនុស្ស ៖ {2} ស្ថានភាព​ ៖ {3}",
-    "app.userList.menu.promoteUser.label": "ដំឡើងតួនាទី {0} ទៅជាអ្នកសម្រប់សម្រួល",
+    "app.userList.menu.promoteUser.label": "ដំឡើងតួនាទី {0} ទៅជាអ្នកសម្របសម្រួល",
     "app.userList.menu.demoteUser.label": "ដកតួនាទី {0} ទៅជាអ្នកមើល",
     "app.media.label": "មេឌៀ",
     "app.presentation.presentationToolbar.prevSlideLabel": "ស្លាយ​មុន",
@@ -155,24 +154,18 @@
     "app.actionsBar.emojiMenu.statusTriggerLabel": "ស្ថានភាព",
     "app.actionsBar.emojiMenu.awayLabel": "នៅ​ឆ្ងាយ",
     "app.actionsBar.emojiMenu.awayDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ \"នៅឆ្ងាយ\"",
-    "app.actionsBar.emojiMenu.raiseLabel": "លើកដៃ",
-    "app.actionsBar.emojiMenu.raiseDesc": "លើកដៃ​របស់​អ្នក​ដើម្បី​សួរ​សំនួរ",
-    "app.actionsBar.emojiMenu.undecidedLabel": "មិន​សម្រេច​ចិត្ត",
-    "app.actionsBar.emojiMenu.undecidedDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ \"មិន​សម្រេច​ចិត្ត\"",
     "app.actionsBar.emojiMenu.confusedLabel": "ច្រឡំ",
     "app.actionsBar.emojiMenu.confusedDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ \"ច្រឡំ\"",
     "app.actionsBar.emojiMenu.sadLabel": "មិន​សប្បាយ​ចិត្ត",
     "app.actionsBar.emojiMenu.sadDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ​ \"មិន​សប្បាយ​ចិត្ត\"",
     "app.actionsBar.emojiMenu.happyLabel": "សប្បាយចិត្ត",
     "app.actionsBar.emojiMenu.happyDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ​ \"សប្បាយចិត្ត\"",
-    "app.actionsBar.emojiMenu.clearLabel": "លុបចេញ",
-    "app.actionsBar.emojiMenu.clearDesc": "លុប​ស្ថានភាព​របស់​អ្នក",
     "app.actionsBar.emojiMenu.applauseLabel": "ទះដៃ",
     "app.actionsBar.emojiMenu.applauseDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ \"ទះដៃ\"",
     "app.actionsBar.emojiMenu.thumbsUpLabel": "មេដៃ​ឡើង",
-    "app.actionsBar.emojiMenu.thumbsUpDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ \\\"មេដៃ​ឡើង\\\"",
+    "app.actionsBar.emojiMenu.thumbsUpDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ \"មេដៃ​ឡើង\"",
     "app.actionsBar.emojiMenu.thumbsDownLabel": "មេ​ដៃ​ចុះ",
-    "app.actionsBar.emojiMenu.thumbsDownDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ \\\"មេ​ដៃ​ចុះ\\\"",
+    "app.actionsBar.emojiMenu.thumbsDownDesc": "ប្តូរ​ស្ថានភាព​របស់​អ្នក​ទៅ \"មេ​ដៃ​ចុះ\"",
     "app.actionsBar.currentStatusDesc": "ស្ថានភាព​បច្ចុប្បន្ន {0}",
     "app.audioNotification.audioFailedError1001": "កំហុស 1001: WebSocket មិនបានភ្ជាប់",
     "app.audioNotification.audioFailedError1002": "កំហុស 1002: មិនអាចធ្វើការតភ្ជាប់ WebSocket បាន",
@@ -202,7 +195,20 @@
     "app.audioModal.audioChoiceLabel": "តើ​អ្នក​ចង់​ចូលរួម​ដោយ​ប្រើ​សម្លេង​របៀប​ណា?",
     "app.audioModal.audioChoiceDesc": "ជ្រើសរើស​របៀប​ចូលរួម​សម្លេង​ក្នុង​ការ​ប្រជុំ​នេះ",
     "app.audioModal.closeLabel": "បិទ",
-    "app.audio.joinAudio": "ចូលរួម​ដោយ​ប្រើ​សម្លេង",
+    "app.audioModal.yes": "បាទ/ចាស",
+    "app.audioModal.no": "ទេ",
+    "app.audioModal.echoTestTitle": "នេះគឺជាការសាកល្បងអេកូឯកជន។ និយាយពាក្យពីរបី។ តើអ្នកឮសំឡេងទេ?",
+    "app.audioModal.settingsTitle": "ប្តូរ​ការ​កំណត់​​សម្រាប់សំឡេង",
+    "app.audioModal.connecting": "កំពុងភ្ជាប់",
+    "app.audioModal.connectingEchoTest": "កំពុងភ្ជាប់ទៅការសាកល្បងអេកូ",
+    "app.audioManager.joinedAudio": "អ្នកបានចូលរួមក្នុងសន្និសិតជាសម្លេង",
+    "app.audioManager.joinedEcho": "អ្នកបានចូលរួមក្នុងការសាកល្បងអេកូ",
+    "app.audioManager.leftAudio": "អ្នកបានចាកចេញពីសន្និសិតជាសម្លេង",
+    "app.audioManager.genericError": "កំហុសៈ កំហុសមួយបានកើតឡើង។ សូមព្យាយាមម្តងទៀត។",
+    "app.audioManager.connectionError": "កំហុសៈ កំហុសក្នុងការតភ្ជាប់",
+    "app.audioManager.requestTimeout": "កំហុសៈ មានការផុតកំណត់ក្នុងសំណើសុំ",
+    "app.audioManager.invalidTarget": "កំហុសៈ បានព្យាយាមស្នើសុំនូវអ្វីមួយទៅកាន់គោលដៅមិនត្រឹមត្រូវ",
+    "app.audio.joinAudio": "ប្រើ​សម្លេង",
     "app.audio.leaveAudio": "ចាកចេញ​ពី​ការ​សម្លេង",
     "app.audio.enterSessionLabel": "ចូល​វគ្គនេះ",
     "app.audio.playSoundLabel": "លេង​សម្លេង",
@@ -212,17 +218,19 @@
     "app.audio.audioSettings.microphoneSourceLabel": "ប្រភព​មីក្រូហ្វូន",
     "app.audio.audioSettings.speakerSourceLabel": "ប្រភព​ឧបករណ៍​បញ្ចេញ​សម្លេង",
     "app.audio.audioSettings.microphoneStreamLabel": "កម្រិត​សម្លេង",
+    "app.audio.audioSettings.retryLabel": "ព្យាយាមម្តងទៀត",
     "app.audio.listenOnly.backLabel": "ត្រឡប់",
     "app.audio.listenOnly.closeLabel": "បិទ",
-    "app.error.kicked": "អ្នក​ត្រូវ​បាន​ដក​ចេញ​ពី​ការ​ប្រជុំ",
-    "app.error.meeting.ended": "You have logged out of the conference",
+    "app.error.meeting.ended": "អ្នកបានចាកចេញពីសន្និសិត",
     "app.dropdown.close": "បិទ",
     "app.error.500": "អុញ! មាន​បញ្ហា​អ្វី​មួយ​ហើយ",
     "app.error.404": "រក​មិន​ឃើញ",
     "app.error.401": "មិន​អនុញ្ញាត",
-    "app.error.403": "ត្រូវ​បាន​ហាម​ឃាត់",    
-    "app.error.leaveLabel": "ចូល​ម្តង​ទៀត",    
-    "app.guest.waiting": "កំពុងរង់ចាំការយល់ព្រមដើម្បីចូលរួម"
+    "app.error.403": "ត្រូវ​បាន​ហាម​ឃាត់",
+    "app.error.leaveLabel": "ចូល​ម្តង​ទៀត",
+    "app.guest.waiting": "កំពុងរង់ចាំការយល់ព្រមដើម្បីចូលរួម",
+    "app.notification.recordingStart": "វគ្គនេះកំពុងត្រូវបានថតទុក",
+    "app.notification.recordingStop": "វគ្គនេះមិនកំពុងត្រូវបានថតទុកទៀតទេ"
 
 }
 
diff --git a/bigbluebutton-html5/private/locales/pt_BR.json b/bigbluebutton-html5/private/locales/pt_BR.json
index 00caa32a14f37e6fdedab57ad5ee5e5c0e5e5618..b295d4c1d4a0ba9a3e9dfcab3a0f51fe7c3460a4 100644
--- a/bigbluebutton-html5/private/locales/pt_BR.json
+++ b/bigbluebutton-html5/private/locales/pt_BR.json
@@ -1,6 +1,8 @@
 {
     "app.home.greeting": "Bem-vindo {0}! Sua apresentação começará em breve...",
     "app.chat.submitLabel": "Enviar Mensagem",
+    "app.chat.errorMinMessageLength": "Mensagem menor do que {0} caractere(s)",
+    "app.chat.errorMaxMessageLength": "Mensagem maior do que {0} caractere(s)",
     "app.chat.inputLabel": "Entrada de mensagem para o bate-papo {0}",
     "app.chat.inputPlaceholder": "Mensagem {0}",
     "app.chat.titlePublic": "Bate-papo público",
@@ -15,6 +17,7 @@
     "app.chat.dropdown.save": "Salvar",
     "app.chat.label": "Bate-papo",
     "app.chat.emptyLogLabel": "Registro do bate-papo vazio",
+    "app.chat.clearPublicChatMessage": "O histórico de bate-papo público foi apagado por um moderador",
     "app.userList.usersTitle": "Usuários",
     "app.userList.participantsTitle": "Participantes",
     "app.userList.messagesTitle": "Mensagens",
@@ -30,7 +33,6 @@
     "app.userList.menu.chat.label": "Bate-papo",
     "app.userList.menu.clearStatus.label": "Limpar status",
     "app.userList.menu.makePresenter.label": "Torná-lo apresentador",
-    "app.userList.menu.kickUser.label": "Expulsar usuário",
     "app.userList.menu.muteUserAudio.label": "Silenciar usuário",
     "app.userList.menu.unmuteUserAudio.label": "Desbloquear microfone do usuário",
     "app.userList.userAriaLabel": "Usuário : {0}  Papel: {1}  Pessoa: {2}  Status: {3}",
@@ -49,6 +51,27 @@
     "app.presentation.presentationToolbar.fitScreenDesc": "Exibir todo o slide",
     "app.presentation.presentationToolbar.zoomLabel": "Zoom",
     "app.presentation.presentationToolbar.zoomDesc": "Alterar o nível de zoom da apresentação",
+    "app.presentation.presentationToolbar.goToSlide":"Slide {0}",
+    "app.presentationUploder.title": "Apresentação",
+    "app.presentationUploder.message": "Como apresentador no BigBlueButton, você tem a capacidade de carregar qualquer documento do Office ou arquivo PDF. Para melhores resultados, recomendamos que se carregue arquivos em PDF.",
+    "app.presentationUploder.confirmLabel": "Iniciar",
+    "app.presentationUploder.confirmDesc": "Salve as alterações e inicie a apresentação",
+    "app.presentationUploder.dismissLabel": "Cancelar",
+    "app.presentationUploder.dismissDesc": "Feche a janela e descarte as alterações",
+    "app.presentationUploder.dropzoneLabel": "Arraste arquivos aqui para carregar",
+    "app.presentationUploder.browseFilesLabel": "ou procure arquivos",
+    "app.presentationUploder.fileToUpload": "Carregar arquivo...",
+    "app.presentationUploder.currentBadge": "Atual",
+    "app.presentationUploder.genericError": "Ops, algo deu errado",
+    "app.presentationUploder.upload.progress": "Carregando ({progress}%)",
+    "app.presentationUploder.upload.413": "O arquivo é muito grande",
+    "app.presentationUploder.conversion.conversionProcessingSlides": "Processando página {current} de {total}",
+    "app.presentationUploder.conversion.genericConversionStatus": "Convertendo arquivo...",
+    "app.presentationUploder.conversion.generatingThumbnail": "Gerando miniaturas...",
+    "app.presentationUploder.conversion.generatedSlides": "Slides gerados...",
+    "app.presentationUploder.conversion.generatingSvg": "Gerando imagens SVG...",
+    "app.presentationUploder.conversion.pageCountExceeded": "Ops, a contagem de páginas excedeu o limite",
+    "app.presentationUploder.conversion.timeout": "Ops, a conversão está demorando muito",
     "app.polling.pollingTitle": "Opções da enquete",
     "app.failedMessage": "Desculpe-nos, estamos com problemas na conexão com o servidor",
     "app.connectingMessage": "Conectando...",
@@ -85,7 +108,7 @@
     "app.actionsBar.muteLabel": "Silenciar",
     "app.actionsBar.unmuteLabel": "Falar",
     "app.actionsBar.camOffLabel": "Câmera desligada",
-    "app.actionsBar.raiseLabel": "Levantar",
+    "app.actionsBar.raiseLabel": "Levantar a mão",
     "app.actionsBar.label": "Barra de ações",
     "app.submenu.application.applicationSectionTitle": "Aplicação",
     "app.submenu.application.audioNotifyLabel": "Notificações de áudio para o bate-papo",
@@ -155,18 +178,18 @@
     "app.actionsBar.emojiMenu.statusTriggerLabel": "Status",
     "app.actionsBar.emojiMenu.awayLabel": "Ausente",
     "app.actionsBar.emojiMenu.awayDesc": "Mudar seu status para ausente",
-    "app.actionsBar.emojiMenu.raiseLabel": "Mão levantada",
-    "app.actionsBar.emojiMenu.raiseDesc": "Levante a mão para fazer uma pergunta",
-    "app.actionsBar.emojiMenu.undecidedLabel": "Indeciso",
-    "app.actionsBar.emojiMenu.undecidedDesc": "Mudar seu status para indeciso",
+    "app.actionsBar.emojiMenu.raiseHandLabel": "Levantar a mão",
+    "app.actionsBar.emojiMenu.raiseHandDesc": "Levante a mão para fazer uma pergunta",
+    "app.actionsBar.emojiMenu.neutralLabel": "Indeciso",
+    "app.actionsBar.emojiMenu.neutralDesc": "Mudar seu status para indeciso",
     "app.actionsBar.emojiMenu.confusedLabel": "Confuso",
     "app.actionsBar.emojiMenu.confusedDesc": "Mudar seu status para confuso",
     "app.actionsBar.emojiMenu.sadLabel": "Triste",
     "app.actionsBar.emojiMenu.sadDesc": "Mudar seu status para triste",
     "app.actionsBar.emojiMenu.happyLabel": "Feliz",
     "app.actionsBar.emojiMenu.happyDesc": "Mudar seu status para feliz",
-    "app.actionsBar.emojiMenu.clearLabel": "Limpar",
-    "app.actionsBar.emojiMenu.clearDesc": "Limpar seu status",
+    "app.actionsBar.emojiMenu.noneLabel": "Limpar",
+    "app.actionsBar.emojiMenu.noneDesc": "Limpar seu status",
     "app.actionsBar.emojiMenu.applauseLabel": "Aplauso",
     "app.actionsBar.emojiMenu.applauseDesc": "Mudar seu status para aplauso",
     "app.actionsBar.emojiMenu.thumbsUpLabel": "Positivo",
@@ -202,10 +225,24 @@
     "app.audioModal.audioChoiceLabel": "Como você gostaria de se juntar ao áudio?",
     "app.audioModal.audioChoiceDesc": "Selecione como se juntar ao áudio nesta reunião",
     "app.audioModal.closeLabel": "Fechar",
+    "app.audioModal.yes": "Sim",
+    "app.audioModal.no": "Não",
+    "app.audioModal.echoTestTitle": "Este é um teste privado de eco. Fale algumas palavras. Você consegue ouvir sua voz?",
+    "app.audioModal.settingsTitle": "Alterar as configurações de áudio",
+    "app.audioModal.helpTitle": "Houve um problema com seus dispositivos de mídia",
+    "app.audioModal.helpText": "Você autorizou o BigBlueButton a acessar seu microfone? Observe que uma caixa de diálogo deve abrir assim que você tentar participar da conferência de áudio, pedindo as permissões de acesso aos dispositivos de mídia, por favor conceda essa permissão de acesso para participar da conferência. Se isso não funcionar, tente alterar a permissão do microfone nas configurações do seu navegador.",
+    "app.audioModal.connecting": "Conectando",
+    "app.audioModal.connectingEchoTest": "Conectando ao teste de eco",
+    "app.audioManager.joinedAudio": "Você se juntou à conferência de áudio",
+    "app.audioManager.joinedEcho": "O teste de eco foi iniciado",
+    "app.audioManager.leftAudio": "Você deixou a conferência de áudio",
+    "app.audioManager.genericError": "Erro: Ocorreu um erro, tente novamente",
+    "app.audioManager.connectionError": "Erro: Erro de conexão",
+    "app.audioManager.requestTimeout": "Erro: Tempo limite de chamada",
+    "app.audioManager.invalidTarget": "Erro: Um alvo inválido foi especificado na chamada",
+    "app.audioManager.mediaError": "Erro: Houve um problema ao consultar seus dispositivos de mídia",
     "app.audio.joinAudio": "Ativar áudio",
     "app.audio.leaveAudio": "Desativar áudio",
-    "app.video.joinVideo": "Compartilhar câmera",
-    "app.video.leaveVideo": "Des-compartilhar câmera",
     "app.audio.enterSessionLabel": "Entrar na reunião",
     "app.audio.playSoundLabel": "Tocar som de teste",
     "app.audio.backLabel": "Voltar",
@@ -214,17 +251,23 @@
     "app.audio.audioSettings.microphoneSourceLabel": "Seleção do microfone",
     "app.audio.audioSettings.speakerSourceLabel": "Seleção do alto-falante",
     "app.audio.audioSettings.microphoneStreamLabel": "Seu volume da transmissão de áudio",
+    "app.audio.audioSettings.retryLabel": "Tente novamente",
     "app.audio.listenOnly.backLabel": "Voltar",
     "app.audio.listenOnly.closeLabel": "Fechar",
-    "app.error.kicked": "Você foi expulso da sala",
+    "app.audio.permissionsOverlay.title": "Permitir que o BigBlueButton acesse seus dispositivos de mídia",
+    "app.audio.permissionsOverlay.hint": "Precisamos que você nos permita acessar seus dispositivos de mídia para participar da conferência por voz :)",
     "app.error.meeting.ended": "Você saiu da conferência",
     "app.dropdown.close": "Fechar",
     "app.error.500": "Ops, algo deu errado",
     "app.error.404": "Não encontrado",
     "app.error.401": "Não autorizado",
-    "app.error.403": "Proibido",    
-    "app.error.leaveLabel": "Faça o login novamente",    
-    "app.guest.waiting": "Esperando aprovação para participar"
+    "app.error.403": "Proibido",
+    "app.error.leaveLabel": "Faça o login novamente",
+    "app.guest.waiting": "Esperando aprovação para participar",
+    "app.toast.chat.singular":"você tem {0} nova mensagem em {1}",
+    "app.toast.chat.plural":"você tem {0} novas mensagens em {1}",
+    "app.notification.recordingStart": "Esta sessão está sendo gravada",
+    "app.notification.recordingStop": "Esta sessão não está mais sendo gravada"
 
 }
 
diff --git a/bigbluebutton-html5/private/locales/ru_RU.json b/bigbluebutton-html5/private/locales/ru_RU.json
index 348031b89f8951c7a155ce31916b34ad8256350e..cacb7fc617aa8f8485bd40563e27ade731d0fdad 100644
--- a/bigbluebutton-html5/private/locales/ru_RU.json
+++ b/bigbluebutton-html5/private/locales/ru_RU.json
@@ -69,8 +69,6 @@
     "app.actionsBar.actionsDropdown.initPollLabel": "Начать опрос",
     "app.actionsBar.actionsDropdown.presentationDesc": "Загрузите вашу презентацию",
     "app.actionsBar.emojiMenu.statusTriggerLabel": "Статус",
-    "app.actionsBar.emojiMenu.clearLabel": "Сброс",
-    "app.actionsBar.emojiMenu.clearDesc": "Очистить статус",
     "app.actionsBar.emojiMenu.applauseLabel": "Апплодисменты",
     "app.audioNotification.closeLabel": "Закрыть",
     "app.breakoutJoinConfirmation.title": "Присоединиться к комнате групповой работы",
@@ -84,9 +82,8 @@
     "app.audio.backLabel": "Назад",
     "app.audio.listenOnly.backLabel": "Назад",
     "app.audio.listenOnly.closeLabel": "Закрыть",
-    "app.error.kicked": "Вас исключили из конференции",
     "app.dropdown.close": "Закрыть",
-    "app.error.500": "Упс что-то пошло не так",
+    "app.error.500": "Упс, что-то пошло не так"
 
 }
 
diff --git a/bigbluebutton-html5/private/locales/tr_TR.json b/bigbluebutton-html5/private/locales/tr_TR.json
new file mode 100644
index 0000000000000000000000000000000000000000..67c4a4a300af718232ee74be36702ffbef0857d2
--- /dev/null
+++ b/bigbluebutton-html5/private/locales/tr_TR.json
@@ -0,0 +1,273 @@
+{
+    "app.home.greeting": "HoÅŸ geldin {0}! Sunumunuz birazdan baÅŸlayacak...",
+    "app.chat.submitLabel": "Mesaj Gönder",
+    "app.chat.errorMinMessageLength": "Mesaj {0} karakter daha kısa",
+    "app.chat.errorMaxMessageLength": "Mesaj {0} karakter daha uzun",
+    "app.chat.inputLabel": "{0} sohbeti için mesaj verisi",
+    "app.chat.inputPlaceholder": "Mesaj {0}",
+    "app.chat.titlePublic": "Genel Sohbet",
+    "app.chat.titlePrivate": "{0} ile Özel Sohbet",
+    "app.chat.partnerDisconnected": "{0} görüşmeden ayrıldı",
+    "app.chat.closeChatLabel": "Kapat {0}",
+    "app.chat.hideChatLabel": "Gizle {0}",
+    "app.chat.moreMessages": "Mesajların devamı aşağıda",
+    "app.chat.dropdown.options": "Sohbet Seçenekleri",
+    "app.chat.dropdown.clear": "Temizle",
+    "app.chat.dropdown.copy": "Kopyala",
+    "app.chat.dropdown.save": "Kaydet",
+    "app.chat.label": "Sohbet",
+    "app.chat.emptyLogLabel": "Sohbet sistem kayıtları boş",
+    "app.chat.clearPublicChatMessage": "Genel sohbet geçmişi moderatör tarafından temizlendi",
+    "app.userList.usersTitle": "Kullanıcılar",
+    "app.userList.participantsTitle": "Katılımcılar",
+    "app.userList.messagesTitle": "Mesajlar",
+    "app.userList.presenter": "Sunucu",
+    "app.userList.you": "Siz",
+    "app.userList.locked": "Kilitli",
+    "app.userList.label": "Kullanıcı Listesi",
+    "app.userList.toggleCompactView.label": "Sıkıştırılmış görünüm moduna geç",
+    "app.userList.guest": "Misafir",
+    "app.userList.menuTitleContext": "Kullanılabilir Seçenekler",
+    "app.userList.chatListItem.unreadSingular": "{0} Yeni Mesaj",
+    "app.userList.chatListItem.unreadPlural": "{0} Yeni Mesaj",
+    "app.userList.menu.chat.label": "Sohbet",
+    "app.userList.menu.clearStatus.label": "Durum Temizle",
+    "app.userList.menu.makePresenter.label": "Sunucu Yap",
+    "app.userList.menu.muteUserAudio.label": "Kullanıcıyı sustur",
+    "app.userList.menu.unmuteUserAudio.label": "Kullanıcıyı konuştur",
+    "app.userList.userAriaLabel": "Kullanıcı : {0}  Rol: {1}  Kişi: {2}  Durum: {3}",
+    "app.userList.menu.promoteUser.label": "{0} kullanıcısını moderatör yap",
+    "app.userList.menu.demoteUser.label": "{0} kullanıcısını izleyici yap",
+    "app.media.label": "Medya",
+    "app.presentation.presentationToolbar.prevSlideLabel": "Önceki slayt",
+    "app.presentation.presentationToolbar.prevSlideDesc": "Sunumu önceki slayda değiştir",
+    "app.presentation.presentationToolbar.nextSlideLabel": "Sonraki slayt",
+    "app.presentation.presentationToolbar.nextSlideDesc": "Sunumu sonraki slayda deÄŸiÅŸtir",
+    "app.presentation.presentationToolbar.skipSlideLabel": "Slayt atla",
+    "app.presentation.presentationToolbar.skipSlideDesc": "Sunumu belirli slayda deÄŸiÅŸtir",
+    "app.presentation.presentationToolbar.fitWidthLabel": "Genişliğe sığdır",
+    "app.presentation.presentationToolbar.fitWidthDesc": "Slayt genişliğinde göster",
+    "app.presentation.presentationToolbar.fitScreenLabel": "Ekrana sığdır",
+    "app.presentation.presentationToolbar.fitScreenDesc": "Tüm slaydı göster",
+    "app.presentation.presentationToolbar.zoomLabel": "Odak",
+    "app.presentation.presentationToolbar.zoomDesc": "Sunumun odak seviyesini deÄŸiÅŸtir",
+    "app.presentation.presentationToolbar.goToSlide":"Slayt {0}",
+    "app.presentationUploder.title": "Sunum",
+    "app.presentationUploder.message": "BigBlueButton'da sunucu olarak herhangi bir ofis belgesini ya da PDF dosyasını yükleyebilirsiniz. En iyi sonuç için PDF dosyası yüklemenizi tavsiye ederiz.",
+    "app.presentationUploder.confirmLabel": "BaÅŸlat",
+    "app.presentationUploder.confirmDesc": "DeÄŸiÅŸiklikleri kaydet ve sunumu baÅŸlat",
+    "app.presentationUploder.dismissLabel": "Vazgeç",
+    "app.presentationUploder.dismissDesc": "Model penceresini kapatın ve değişiklikleri geri alın",
+    "app.presentationUploder.dropzoneLabel": "Yüklenecek dosyaları buraya sürükleyin",
+    "app.presentationUploder.browseFilesLabel": "ya da dosyalara göz at",
+    "app.presentationUploder.fileToUpload": "Yüklenecek...",
+    "app.presentationUploder.currentBadge": "Åžimdiki",
+    "app.presentationUploder.genericError": "Hops, birÅŸeyler ters gitti",
+    "app.presentationUploder.upload.progress": "Yükleniyor ({progress}%)",
+    "app.presentationUploder.upload.413": "Dosya çok büyük",
+    "app.presentationUploder.conversion.conversionProcessingSlides": "Sayfa oluÅŸturuluyor {current} / {total}",
+    "app.presentationUploder.conversion.genericConversionStatus": "Dosyayı dönüştürüyor...",
+    "app.presentationUploder.conversion.generatingThumbnail": "Küçük resimler oluşturuluyor...",
+    "app.presentationUploder.conversion.generatedSlides": "Slaytlar oluÅŸturuldu...",
+    "app.presentationUploder.conversion.generatingSvg": "SVG resimler oluÅŸturuluyor...",
+    "app.presentationUploder.conversion.pageCountExceeded": "Hops, sayfa sayısı limiti aştı",
+    "app.presentationUploder.conversion.timeout": "Hops, dönüştürme uzun zaman alıyor",
+    "app.polling.pollingTitle": "Oylama Seçenekleri",
+    "app.failedMessage": "Özür dileriz, sunucuya bağlanma sorunu var.",
+    "app.connectingMessage": "Bağlanıyor...",
+    "app.waitingMessage": "Bağlantı koptu. {0} saniye sonra tekrar bağlanmayı deneyecek...",
+    "app.navBar.settingsDropdown.optionsLabel": "Seçenekler",
+    "app.navBar.settingsDropdown.fullscreenLabel": "Tam ekran yap",
+    "app.navBar.settingsDropdown.settingsLabel": "Ayarları aç",
+    "app.navBar.settingsDropdown.aboutLabel": "Hakkında",
+    "app.navBar.settingsDropdown.leaveSessionLabel": "Çıkış",
+    "app.navBar.settingsDropdown.exitFullscreenLabel": "Tam ekrandan çık",
+    "app.navBar.settingsDropdown.fullscreenDesc": "Ayarlar menüsünü tam ekran yap",
+    "app.navBar.settingsDropdown.settingsDesc": "Genel ayarları değiştir",
+    "app.navBar.settingsDropdown.aboutDesc": "Kullanıcı bilgilerini göster",
+    "app.navBar.settingsDropdown.leaveSessionDesc": "Görüşmeden ayrıl",
+    "app.navBar.settingsDropdown.exitFullscreenDesc": "Tam ekran modundan çık",
+    "app.navBar.userListToggleBtnLabel": "Kullanıcı Listesini Değiştir",
+    "app.navBar.toggleUserList.newMessages": "yeni mesaj bildirimiyle",
+    "app.leaveConfirmation.title": "Oturumdan Ayrıl",
+    "app.leaveConfirmation.message": "Görüşmeden ayrılmak istiyor musunuz?",
+    "app.leaveConfirmation.confirmLabel": "Ayrıl",
+    "app.leaveConfirmation.confirmDesc": "Sizi görüşmeden çıkarır",
+    "app.leaveConfirmation.dismissLabel": "Vazgeç",
+    "app.leaveConfirmation.dismissDesc": "Ayrılma onayını reddeder ve kapatır",
+    "app.leaveConfirmation.endMeetingLabel": "Evet ve oturumu kapat",
+    "app.leaveConfirmation.endMeetingDesc": "Onayı kapatır ve görüşmeyi sonlandırır",
+    "app.about.title": "Hakkında",
+    "app.about.version": "İstemci Sürümü:",
+    "app.about.copyright": "Telif Hakkı:",
+    "app.about.confirmLabel": "TAMAM",
+    "app.about.confirmDesc": "TAMAM",
+    "app.about.dismissLabel": "Vazgeç",
+    "app.about.dismissDesc": "Kullanıcı bilgilerini kapat",
+    "app.actionsBar.changeStatusLabel": "Durum DeÄŸiÅŸtir",
+    "app.actionsBar.muteLabel": "Sustur",
+    "app.actionsBar.unmuteLabel": "KonuÅŸtur",
+    "app.actionsBar.camOffLabel": "Kamera Devre Dışı",
+    "app.actionsBar.raiseLabel": "El Kaldır",
+    "app.actionsBar.label": "Eylem Çubuğu",
+    "app.submenu.application.applicationSectionTitle": "Uygulama",
+    "app.submenu.application.audioNotifyLabel": "Sohbet sesli bildirimleri",
+    "app.submenu.application.pushNotifyLabel": "Sohbet anlık bildirimleri",
+    "app.submenu.application.fontSizeControlLabel": "Yazı büyüklüğü",
+    "app.submenu.application.increaseFontBtnLabel": "Uygulama Yazı Büyüklüğünü Artır",
+    "app.submenu.application.decreaseFontBtnLabel": "Uygulama Yazı Büyüklüğünü Azalt",
+    "app.submenu.application.languageLabel": "Uygulama Dili",
+    "app.submenu.application.ariaLanguageLabel": "Uygulama Dilini DeÄŸiÅŸtir",
+    "app.submenu.application.languageOptionLabel": "Dil seçin",
+    "app.submenu.application.noLocaleOptionLabel": "Aktif yerel ayar bulunamadı",
+    "app.submenu.audio.micSourceLabel": "Mikrofon kaynağı",
+    "app.submenu.audio.speakerSourceLabel": "Hoparlör kaynağı",
+    "app.submenu.audio.streamVolumeLabel": "Sesinizin seviyesi",
+    "app.submenu.video.title": "Video",
+    "app.submenu.video.videoSourceLabel": "Görüntü kaynağı",
+    "app.submenu.video.videoOptionLabel": "Görüntü kaynağını seç",
+    "app.submenu.video.videoQualityLabel": "Video Kalitesi",
+    "app.submenu.video.qualityOptionLabel": "Video kalitesini seç",
+    "app.submenu.video.participantsCamLabel": "Katılımcıların web kameraları görüntüleniyor",
+    "app.submenu.closedCaptions.closedCaptionsLabel": "Altyazı",
+    "app.submenu.closedCaptions.takeOwnershipLabel": "Sahiplik al",
+    "app.submenu.closedCaptions.languageLabel": "Dil",
+    "app.submenu.closedCaptions.localeOptionLabel": "Dil seçin",
+    "app.submenu.closedCaptions.noLocaleOptionLabel": "Aktif yerel ayar bulunamadı",
+    "app.submenu.closedCaptions.fontFamilyLabel": "Yazı tipi",
+    "app.submenu.closedCaptions.fontFamilyOptionLabel": "Yazı tipini Seç",
+    "app.submenu.closedCaptions.fontSizeLabel": "Yazı büyüklüğü",
+    "app.submenu.closedCaptions.fontSizeOptionLabel": "Yazı büyüklüğünü Seç",
+    "app.submenu.closedCaptions.backgroundColorLabel": "Arkalan rengi",
+    "app.submenu.closedCaptions.fontColorLabel": "Yazı rengi",
+    "app.submenu.participants.muteAllLabel": "Sunucu hariç tümünü sessiz yap",
+    "app.submenu.participants.lockAllLabel": "Tüm katılımcıları kilitle",
+    "app.submenu.participants.lockItemLabel": "Katılımcılar {0}",
+    "app.submenu.participants.lockMicDesc": "Tüm kilitli katılımcıların mikrofonunu devre dışı bırakır",
+    "app.submenu.participants.lockCamDesc": "Tüm kilitli katılımcıların web kamerasını devre dışı bırakır",
+    "app.submenu.participants.lockPublicChatDesc": "Tüm kilitli katılımcılar için genel sohbeti devre dışı bırakır",
+    "app.submenu.participants.lockPrivateChatDesc": "Tüm kilitli katılımcılar için özel sohbeti devre dışı bırakır",
+    "app.submenu.participants.lockLayoutDesc": "Tüm kilitli katılımcıların ekran görünümünü kilitler",
+    "app.submenu.participants.lockMicAriaLabel": "Mikrofon kilidi",
+    "app.submenu.participants.lockCamAriaLabel": "Web kamera kilidi",
+    "app.submenu.participants.lockPublicChatAriaLabel": "Genel sohbet kilidi",
+    "app.submenu.participants.lockPrivateChatAriaLabel": "Özel sohbet kilidi",
+    "app.submenu.participants.lockLayoutAriaLabel": "Görünüm kilidi",
+    "app.submenu.participants.lockMicLabel": "Mikrofon",
+    "app.submenu.participants.lockCamLabel": "Web Kamerası",
+    "app.submenu.participants.lockPublicChatLabel": "Genel Sohbet",
+    "app.submenu.participants.lockPrivateChatLabel": "Özel Sohbet",
+    "app.submenu.participants.lockLayoutLabel": "Görünüm",
+    "app.settings.applicationTab.label": "Uygulama ",
+    "app.settings.audioTab.label": "Ses",
+    "app.settings.videoTab.label": "Video",
+    "app.settings.closedcaptionTab.label": "Altyazı",
+    "app.settings.usersTab.label": "Katılımcılar",
+    "app.settings.main.label": "Ayarlar",
+    "app.settings.main.cancel.label": "Vazgeç",
+    "app.settings.main.cancel.label.description": "Değişiklikleri geri alır ve ayarlar menüsünü kapatır",
+    "app.settings.main.save.label": "Kaydet",
+    "app.settings.main.save.label.description": "Değişiklikleri kaydeder ve ayarlar menüsünü kapatır",
+    "app.actionsBar.actionsDropdown.actionsLabel": "Eylemler",
+    "app.actionsBar.actionsDropdown.presentationLabel": "Bir sunum yükle",
+    "app.actionsBar.actionsDropdown.initPollLabel": "Oylama baÅŸlat",
+    "app.actionsBar.actionsDropdown.desktopShareLabel": "Ekranını paylaş",
+    "app.actionsBar.actionsDropdown.presentationDesc": "Sunumunuzu yükleyin",
+    "app.actionsBar.actionsDropdown.initPollDesc": "Oylama baÅŸlat",
+    "app.actionsBar.actionsDropdown.desktopShareDesc": "Ekranını diğerleriyle paylaş",
+    "app.actionsBar.emojiMenu.statusTriggerLabel": "Durum",
+    "app.actionsBar.emojiMenu.awayLabel": "Dışarıda",
+    "app.actionsBar.emojiMenu.awayDesc": "Durumunu dışarıda yap",
+    "app.actionsBar.emojiMenu.raiseHandLabel": "El Kaldır",
+    "app.actionsBar.emojiMenu.raiseHandDesc": "Soru sormak için el kaldırın",
+    "app.actionsBar.emojiMenu.neutralLabel": "Kararsız",
+    "app.actionsBar.emojiMenu.neutralDesc": "Durumunu kararsız yap",
+    "app.actionsBar.emojiMenu.confusedLabel": "Şaşırmış",
+    "app.actionsBar.emojiMenu.confusedDesc": "Durumunu şaşırmış yap",
+    "app.actionsBar.emojiMenu.sadLabel": "Üzgün",
+    "app.actionsBar.emojiMenu.sadDesc": "Durumunu üzgün yap",
+    "app.actionsBar.emojiMenu.happyLabel": "Mutlu",
+    "app.actionsBar.emojiMenu.happyDesc": "Durumunu mutlu yap",
+    "app.actionsBar.emojiMenu.noneLabel": "Temizle",
+    "app.actionsBar.emojiMenu.noneDesc": "Durumunu temizle",
+    "app.actionsBar.emojiMenu.applauseLabel": "Alkış",
+    "app.actionsBar.emojiMenu.applauseDesc": "Durumunu alkış yap",
+    "app.actionsBar.emojiMenu.thumbsUpLabel": "BeÄŸendim",
+    "app.actionsBar.emojiMenu.thumbsUpDesc": "Durumunu beÄŸendi yap",
+    "app.actionsBar.emojiMenu.thumbsDownLabel": "BeÄŸenmedim",
+    "app.actionsBar.emojiMenu.thumbsDownDesc": "Durumunu beÄŸenmedi yap",
+    "app.actionsBar.currentStatusDesc": "ÅŸimdiki durum {0}",
+    "app.audioNotification.audioFailedError1001": "Hata 1001: WebSocket bağlantısı koptu",
+    "app.audioNotification.audioFailedError1002": "Hata 1002: WebSocket bağlantısı oluşturulamadı",
+    "app.audioNotification.audioFailedError1003": "Hata 1003: Web tarayıcının sürümü desteklenmiyor",
+    "app.audioNotification.audioFailedError1004": "Hata 1004: Arama hatası",
+    "app.audioNotification.audioFailedError1005": "Hata 1005: Arama beklenmedik şekilde sonlandı",
+    "app.audioNotification.audioFailedError1006": "Hata 1006: Arama zaman aşımına uğradı",
+    "app.audioNotification.audioFailedError1007": "Hata 1007: ICE Bilgi ve İçerik iletişimi başarısız oldu",
+    "app.audioNotification.audioFailedError1008": "Hata 1008: Aktarım başarısız oldu",
+    "app.audioNotification.audioFailedError1009": "Hata 1009: STUN/TURN sunucu bilgisi algılamadı",
+    "app.audioNotification.audioFailedError1010": "Hata 1010: ICE Bilgi ve İçerik iletişimi zaman aşımına uğradı",
+    "app.audioNotification.audioFailedError1011": "Hata 1011: ICE Bilgi ve İçerik toplanması zaman aşımına uğradı",
+    "app.audioNotification.audioFailedMessage": "Ses bağlantınız sağlanamadı",
+    "app.audioNotification.mediaFailedMessage": "Kullanıcının mikrofonuna erişim başarısız oldu. Yalnızca güvenli kaynaklara izin veriliyor.",
+    "app.audioNotification.closeLabel": "Kapat",
+    "app.breakoutJoinConfirmation.title": "Özel Odaya Katıl",
+    "app.breakoutJoinConfirmation.message": "Katılmak istiyor musunuz?",
+    "app.breakoutJoinConfirmation.confirmLabel": "Katıl",
+    "app.breakoutJoinConfirmation.confirmDesc": "Özel Odaya katılın",
+    "app.breakoutJoinConfirmation.dismissLabel": "Vazgeç",
+    "app.breakoutJoinConfirmation.dismissDesc": "Özel Odaya Katılımı reddeder ve kapatır",
+    "app.breakoutTimeRemainingMessage": "Özel Oda kalan süre: {0}",
+    "app.breakoutWillCloseMessage": "Süre bitti. Özel Oda birazdan kapanacak",
+    "app.calculatingBreakoutTimeRemaining": "Kalan süre hesaplanıyor...",
+    "app.audioModal.microphoneLabel": "Mikrofon",
+    "app.audioModal.listenOnlyLabel": "Yalnızca Dinle",
+    "app.audioModal.audioChoiceLabel": "Sesli katılımınızı nasıl yapmak istersiniz?",
+    "app.audioModal.audioChoiceDesc": "Bu görüşmede sesli katılımınızı nasıl yapmak istediğinizi seçin",
+    "app.audioModal.closeLabel": "Kapat",
+    "app.audioModal.yes": "Evet",
+    "app.audioModal.no": "Hayır",
+    "app.audioModal.echoTestTitle": "Bu bir özel ses testidir. Birkaç kelime konuşun. Sesinizi duydunuz mu?",
+    "app.audioModal.settingsTitle": "Ses ayarlarınızı değiştirin",
+    "app.audioModal.helpTitle": "Medya cihazlarınızla ilgili bir problemi oluştu",
+    "app.audioModal.helpText": "BigBlueButton'ın mikrofonunuza erişim talebini onayladınız mı? Sesli görüşmeye katılmak istediğinizde, medya cihazlarınıza erişim izniyle ilgili bir iletişim kutusu görünecektir, sesli görüşmeye katılabilmek için onay vermeniz gerekir. Eğer onay iletişim kutusu görünmediyse, web tarayıcınızın ayarlarındaki mikrofon izinlerini değiştirmeyi deneyin.",
+    "app.audioModal.connecting": "Bağlanıyor",
+    "app.audioModal.connectingEchoTest": "Ses testine bağlanılıyor",
+    "app.audioManager.joinedAudio": "Sesli görüşmeye katıldınız",
+    "app.audioManager.joinedEcho": "Ses yankı testine katıldınız",
+    "app.audioManager.leftAudio": "Sesli görüşmeden ayrıldınız",
+    "app.audioManager.genericError": "Hata: Bir hata oluştu, lütfen tekrar deneyin",
+    "app.audioManager.connectionError": "Hata: Bağlantı hatası",
+    "app.audioManager.requestTimeout": "Hata: İstek zaman aşımına uğradı",
+    "app.audioManager.invalidTarget": "Hata: Geçersiz hedeften talep denemesi hatası",
+    "app.audioManager.mediaError": "Hata: Medya cihazlarınıza erişim problemi oluştu",
+    "app.audio.joinAudio": "Sesli Katıl",
+    "app.audio.leaveAudio": "Sesli Katılımı Kapat",
+    "app.audio.enterSessionLabel": "Oturuma Katıl",
+    "app.audio.playSoundLabel": "Sesi Oynat",
+    "app.audio.backLabel": "Geri",
+    "app.audio.audioSettings.titleLabel": "Ses ayarlarınızı seçin",
+    "app.audio.audioSettings.descriptionLabel": "Web tarayıcınızda mikrofon paylaşımıyla ilgili iletişim kutusu görünecektir, onaylamayı unutmayınız.",
+    "app.audio.audioSettings.microphoneSourceLabel": "Mikrofon kaynağı",
+    "app.audio.audioSettings.speakerSourceLabel": "Hoparlör kaynağı",
+    "app.audio.audioSettings.microphoneStreamLabel": "Sesinizin seviyesi",
+    "app.audio.audioSettings.retryLabel": "Yeniden Dene",
+    "app.audio.listenOnly.backLabel": "Geri",
+    "app.audio.listenOnly.closeLabel": "Kapat",
+    "app.audio.permissionsOverlay.title": "BigBlueButton'un Medya Cihazlarınızı kullanmasına izin verin",
+    "app.audio.permissionsOverlay.hint": "Sizi sesli görüşmeye katabilmemiz için Medya Cihazlarınıza erişimimize izin vermeniz gerekir :)",
+    "app.error.meeting.ended": "Konferanstan ayrıldınız",
+    "app.dropdown.close": "Kapat",
+    "app.error.500": "Hops, birÅŸeyler ters gitti",
+    "app.error.404": "Bulunamadı",
+    "app.error.401": "Yetkisiz",
+    "app.error.403": "Yasaklı",
+    "app.error.leaveLabel": "Tekrar giriÅŸ yap",
+    "app.guest.waiting": "Katılım onayı bekleniyor",
+    "app.toast.chat.singular":"{1} için {0} yeni mesajınız var",
+    "app.toast.chat.plural":"{1} için {0} yeni mesajınız var",
+    "app.notification.recordingStart": "Bu oturum ÅŸu anda kaydediliyor",
+    "app.notification.recordingStop": "Bu oturum artık kaydedilmiyor"
+
+}
+
diff --git a/bigbluebutton-html5/private/locales/uk_UA.json b/bigbluebutton-html5/private/locales/uk_UA.json
index 78d601596b1bf990c023e5e84eba3fa8ff936e31..aa7a91a56aa7e9a4cbdd0b7c24bf099619f1ca53 100644
--- a/bigbluebutton-html5/private/locales/uk_UA.json
+++ b/bigbluebutton-html5/private/locales/uk_UA.json
@@ -29,7 +29,7 @@
     "app.actionsBar.changeStatusLabel": "Змінити статус",
     "app.actionsBar.muteLabel": "Вимкнути мікрофон",
     "app.actionsBar.unmuteLabel": "Увімкнути мікрофон",
-    "app.actionsBar.camOffLabel": "Вимкнути камеру",
-    "app.error.kicked": "Ви були виключени з конференції"
+    "app.actionsBar.camOffLabel": "Вимкнути камеру"
+
 }
 
diff --git a/bigbluebutton-html5/transifex.sh b/bigbluebutton-html5/transifex.sh
index e948ff24cdce77814493ff40b79d748163faf7a5..28fcf58e12b21ffeb6a414e0ad9780ce462017ad 100755
--- a/bigbluebutton-html5/transifex.sh
+++ b/bigbluebutton-html5/transifex.sh
@@ -4,6 +4,7 @@
 RED='\033[0;31m'
 GREEN='\033[1;32m'
 NC='\033[0m'
+SOURCE_LANGUAGE="en"
 
 if [ "$#" = 0 ]
 then
@@ -26,43 +27,46 @@ else
       for ARG in "$@"
       do
         if [ "$ARG" == "all"  ]
-	then
-	  AVAILABLE_TRANSLATIONS=$( echo "$PROJECT_INFO" | grep 'language_code' | cut -d':' -f2 | tr -d '[",]' )
+        then
+          AVAILABLE_TRANSLATIONS=$( echo "$PROJECT_INFO" | grep 'language_code' | cut -d':' -f2 | tr -d '[",]' )
 
           echo "$AVAILABLE_TRANSLATIONS" | while read l
-	  do
-	    LOCALE=$( echo "$l" | tr -d '[:space:]' )
-	    TRANSLATION=$(curl -L --user "$USER":"$PW" -X GET "https://www.transifex.com/api/2/project/bigbluebutton-html5/resource/enjson/translation/$LOCALE/?mode=onlytranslated&file")
-	    NO_EMPTY_STRINGS=$(echo "$TRANSLATION" | sed '/: *\"\"/D' | sed '/}$/D')
-	    if [ $(echo "$NO_EMPTY_STRINGS" | wc -l) == 1 ]
-	    then
-	      echo -e "${RED}WARN:${NC} translation file $LOCALE.json is empty\n${RED}WARN:${NC} $LOCALE.json not created"
-	      continue
-	    else
-	      NO_TRAILING_COMMA=$(echo "$NO_EMPTY_STRINGS" | sed  '$ s/,$//')
-	      echo "$NO_TRAILING_COMMA" > ./private/locales/"$LOCALE".json
-	      echo -e "\n}\n" >> ./private/locales/"$LOCALE".json
-	      echo -e "Added translation file $LOCALE.json : ${GREEN}✓${NC}"
-	    fi
-	  done
-	else
-	  TRANSLATION=$(curl -L --user "$USER":"$PW" -X GET "https://www.transifex.com/api/2/project/bigbluebutton-html5/resource/enjson/translation/$ARG/?mode=onlytranslated&file")
-	  if [ "$TRANSLATION" == "Not Found" ]
-	  then
-	    echo -e "${RED}Err${NC}: Translations not found for locale ->${RED}$ARG${NC}<-"
-	  else
-	    NO_EMPTY_STRINGS=$(echo "$TRANSLATION" | sed '/: *\"\"/D' | sed '/}$/D')
-	    if [ $(echo "$NO_EMPTY_STRINGS" | wc -l) == 1 ]
-	    then
-	      echo -e "${RED}WARN:${NC} translation file $ARG.json is empty\n${RED}WARN:${NC} $ARG.json not created"
-	    else
-	      NO_TRAILING_COMMA=$(echo "$NO_EMPTY_STRINGS" | sed  '$ s/,//')
-	      echo "$NO_TRAILING_COMMA" > ./private/locales/"$ARG".json
-	      echo -e "\n}\n" >> ./private/locales/"$ARG".json
-	      echo -e "Added translation file $ARG.json :${GREEN} ✓${NC}"
-	    fi
-	  fi
-	fi
+            do
+              LOCALE=$( echo "$l" | tr -d '[:space:]' )
+              if [ "$LOCALE" == "$SOURCE_LANGUAGE" ]; then
+                continue # do not pull the source file
+              fi
+              TRANSLATION=$(curl -L --user "$USER":"$PW" -X GET "https://www.transifex.com/api/2/project/bigbluebutton-html5/resource/enjson/translation/$LOCALE/?mode=onlytranslated&file")
+              NO_EMPTY_STRINGS=$(echo "$TRANSLATION" | sed '/: *\"\"/D' | sed '/}$/D')
+              if [ $(echo "$NO_EMPTY_STRINGS" | wc -l) == 1 ]
+              then
+                echo -e "${RED}WARN:${NC} translation file $LOCALE.json is empty\n${RED}WARN:${NC} $LOCALE.json not created"
+                continue
+              else
+                NO_TRAILING_COMMA=$(echo "$NO_EMPTY_STRINGS" | sed  '$ s/,$//')
+                echo "$NO_TRAILING_COMMA" > ./private/locales/"$LOCALE".json
+                echo -e "\n}\n" >> ./private/locales/"$LOCALE".json
+                echo -e "Added translation file $LOCALE.json : ${GREEN}✓${NC}"
+              fi
+            done
+        else
+          TRANSLATION=$(curl -L --user "$USER":"$PW" -X GET "https://www.transifex.com/api/2/project/bigbluebutton-html5/resource/enjson/translation/$ARG/?mode=onlytranslated&file")
+          if [ "$TRANSLATION" == "Not Found" ]
+          then
+            echo -e "${RED}Err${NC}: Translations not found for locale ->${RED}$ARG${NC}<-"
+          else
+            NO_EMPTY_STRINGS=$(echo "$TRANSLATION" | sed '/: *\"\"/D' | sed '/}$/D')
+            if [ $(echo "$NO_EMPTY_STRINGS" | wc -l) == 1 ]
+            then
+              echo -e "${RED}WARN:${NC} translation file $ARG.json is empty\n${RED}WARN:${NC} $ARG.json not created"
+            else
+              NO_TRAILING_COMMA=$(echo "$NO_EMPTY_STRINGS" | sed  '$ s/,//')
+              echo "$NO_TRAILING_COMMA" > ./private/locales/"$ARG".json
+              echo -e "\n}\n" >> ./private/locales/"$ARG".json
+              echo -e "Added translation file $ARG.json :${GREEN} ✓${NC}"
+            fi
+          fi
+        fi
       done
     fi
   fi
diff --git a/labs/bbb-webrtc-sfu/config/default.example.yml b/labs/bbb-webrtc-sfu/config/default.example.yml
index 3b9bbe8a29fa7cbbb171da6fcd190eeb7d7e5760..7a2ef971286760daf93a10d6d582ec25be1e7a3e 100644
--- a/labs/bbb-webrtc-sfu/config/default.example.yml
+++ b/labs/bbb-webrtc-sfu/config/default.example.yml
@@ -13,3 +13,7 @@ from-video: "from-video-sfu"
 to-video: "to-video-sfu"
 from-audio: "from-audio-sfu"
 to-audio: "to-audio-sfu"
+
+log:
+    filename: '/var/log/bigbluebutton/bbb-webrtc-sfu/bbb-webrtc-sfu.log'
+    level: 'verbose'
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/RedisWrapper.js b/labs/bbb-webrtc-sfu/lib/bbb/pubsub/RedisWrapper.js
index 94acc7db4eeea467c5133a3aaabbb92603f5373a..6fb1e0d2336cce44ce57bab39121fd7a56c8395c 100644
--- a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/RedisWrapper.js
+++ b/labs/bbb-webrtc-sfu/lib/bbb/pubsub/RedisWrapper.js
@@ -11,6 +11,7 @@ const redis = require('redis');
 const config = require('config');
 const Constants = require('../messages/Constants.js');
 const EventEmitter = require('events').EventEmitter;
+const Logger = require('../../utils/Logger');
 
 /* Public members */
 
@@ -46,7 +47,7 @@ module.exports = class RedisWrapper extends EventEmitter {
   startSubscriber () {
     let self = this;
     if (this.redisCli) {
-      console.log("  [RedisWrapper] Redis Client already exists");
+      Logger.warn("[RedisWrapper] Redis Client already exists");
       return;
     }
 
@@ -59,23 +60,21 @@ module.exports = class RedisWrapper extends EventEmitter {
 
     this.redisCli = redis.createClient(options);
 
-    console.log("  [RedisWrapper] Trying to subscribe to redis channel");
-
     this.redisCli.on("connect", () => {
-      // console.log(" [RedisWrapper] Connected to Redis Server.");
-      // DO SOMETHING
+      //TODO
     });
 
-    this.redisCli.on("error", (e) => {
-      console.error(" [RedisWrapper] " + e);
+    this.redisCli.on("error", (error) => {
+      Logger.error("[RedisWrapper] Wrapper returned an error", error);
     });
 
-    this.redisCli.on("reconnecting", (e) => {
-      // DO SOMETHING
+    this.redisCli.on("reconnecting", (msg) => {
+      Logger.warn("[RedisWrapper] Wrapper instance is reconnecting", msg);
+      //TODO
     });
 
     this.redisCli.on("psubscribe", (channel, count) => {
-      console.log(" [RedisWrapper] Successfully subscribed to pattern [" + channel + "]");
+      Logger.info("[RedisWrapper] Successfully subscribed to pattern [" + channel + "]");
     });
 
     this.redisCli.on("pmessage", this._onMessage.bind(this));
@@ -86,10 +85,8 @@ module.exports = class RedisWrapper extends EventEmitter {
 
     this.redisCli.psubscribe(this.subpattern);
 
-    console.log("  [RedisWrapper] Started Redis client at " + options.host + ":" + options.port +
+    Logger.info("[RedisWrapper] Started Redis client at " + options.host + ":" + options.port +
         " for subscription pattern: " + this.subpattern);
-
-    return ;
   }
 
   stopRedis (callback) {
diff --git a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js b/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js
index b99b9b855539ba1b7f3d600da522b7e89308f372..2f1ab86a13117feea80c84d12cbb18928372751c 100644
--- a/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js
+++ b/labs/bbb-webrtc-sfu/lib/bbb/pubsub/bbb-gw.js
@@ -12,6 +12,7 @@ const RedisWrapper = require('./RedisWrapper.js');
 const config = require('config');
 const util = require('util');
 const EventEmitter = require('events').EventEmitter;
+const Logger = require('../../utils/Logger');
 
 let instance = null;
 
@@ -38,11 +39,11 @@ module.exports = class BigBlueButtonGW extends EventEmitter {
     try {
       wrobj.startSubscriber();
       wrobj.on(C.REDIS_MESSAGE, this.incomingMessage.bind(this));
-      console.log("  [BigBlueButtonGW] Added redis client to this.subscribers[" + channel + "]");
+      Logger.info("[BigBlueButtonGW] Added redis client to this.subscribers[" + channel + "]");
       return Promise.resolve(wrobj);
     }
     catch (error) {
-      return Promise.reject("  [BigBlueButtonGW] Could not start redis client for channel " + channel);
+      return Promise.reject("[BigBlueButtonGW] Could not start redis client for channel " + channel);
     }
   }
 
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/ConnectionManager.js b/labs/bbb-webrtc-sfu/lib/connection-manager/ConnectionManager.js
index 653aada87fa2f5483643880c0e3fc6226ccccf80..7c435ad220de038dd6c39f57310da7ff8c482a0e 100644
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/ConnectionManager.js
+++ b/labs/bbb-webrtc-sfu/lib/connection-manager/ConnectionManager.js
@@ -7,15 +7,11 @@
 
 'use strict';
 
-// const express = require('express');
-// const session = require('express-session')
-// const wsModule = require('./websocket');
-
 const http = require('http');
-const fs = require('fs');
 const EventEmitter = require('events');
 const BigBlueButtonGW = require('../bbb/pubsub/bbb-gw');
 const C = require('../bbb/messages/Constants');
+const Logger = require('../utils/Logger');
 
 // Global variables
 module.exports = class ConnectionManager {
@@ -85,10 +81,10 @@ module.exports = class ConnectionManager {
         this._emitter.emit('response', data);
       });
 
-      console.log('  [ConnectionManager] Successfully subscribed to processes redis channels');
+      Logger.info('[ConnectionManager] Successfully subscribed to processes redis channels');
     }
     catch (err) {
-      console.log('  [ConnectionManager] ' + err);
+      Logger.info('[ConnectionManager] ' + err);
       this._stopAll;
     }
   }
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/HttpServer.js b/labs/bbb-webrtc-sfu/lib/connection-manager/HttpServer.js
index 8ec5a30fac3abeb8eda002809665d17662757929..8b49a75f47f5794c9a2d0f8afff13dfd572e0d4c 100644
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/HttpServer.js
+++ b/labs/bbb-webrtc-sfu/lib/connection-manager/HttpServer.js
@@ -3,6 +3,7 @@
 const http = require("http");
 const fs = require("fs");
 const config = require('config');
+const Logger = require('../utils/Logger');
 
 module.exports = class HttpServer {
 
@@ -23,7 +24,7 @@ module.exports = class HttpServer {
   }
 
   listen(callback) {
-    console.log(' [HttpServer] Listening in port ' + this.port);
+    Logger.info('[HttpServer] Listening in port ' + this.port);
     this.server.listen(this.port, callback);
   }
 
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/RedisConnectionManager.js b/labs/bbb-webrtc-sfu/lib/connection-manager/RedisConnectionManager.js
deleted file mode 100644
index 6c109baf75ac71b9c54a12f1ccca3f988a46ff90..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/RedisConnectionManager.js
+++ /dev/null
@@ -1,34 +0,0 @@
-'use strict';
-
-// incomplete
-
-module.exports = class RedisConnectionManager {
-
-  constructor(options) {
-
-    this._client = redis.createClient({options});
-    this._pubchannel = options.pubchannel;
-    this._subchannel = optiosn.subchannel;
-
-    if (options.pubchannel) {
-      this._client.on()
-    }
-
-    if (options.subchannel) {
-      this._client.on()
-    }
-
-    this._client.on()
-    // pub
-
-  }
-
-  setEventEmitter(emitter) {
-    this.emitter = emitter;
-  }
-
-  _onMessage() {
-
-  }
-
-}
diff --git a/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js b/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js
index 17ea6c3a1d0b672b48600fec053361eeb056bdc7..0dc0a6d37cd5ac920fa053967a161b3bd1dfe419 100644
--- a/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js
+++ b/labs/bbb-webrtc-sfu/lib/connection-manager/WebsocketConnectionManager.js
@@ -2,13 +2,11 @@
 
 const ws = require('ws');
 const C = require('../bbb/messages/Constants');
+const Logger = require('../utils/Logger');
 
-// initialization
+// ID counter
 let connectionIDCounter = 0;
 
-// when handling a new connection
-
-
 ws.prototype.setErrorCallback = function(callback) {
 
   this._errorCallback = callback;
@@ -19,13 +17,13 @@ ws.prototype.sendMessage = function(json) {
   let websocket = this;
 
   if (this._closeCode === 1000) {
-    console.log("  [WebsocketConnectionManager] Websocket closed, not sending");
-    this._errorCallback("Error: not opened");
+    Logger.error("[WebsocketConnectionManager] Websocket closed, not sending");
+    this._errorCallback("[WebsocketConnectionManager] Error: not opened");
   }
 
   return this.send(JSON.stringify(json), function(error) {
     if(error) {
-      console.log('  [WebsocketConnectionManager] server: Websocket error "' + error + '" on message "' + json.id + '"');
+      Logger.error('[WebsocketConnectionManager] Websocket error "' + error + '" on message "' + json.id + '"');
 
       websocket._errorCallback(error);
     }
@@ -45,7 +43,7 @@ module.exports = class WebsocketConnectionManager {
 
       ws.id = connectionIDCounter++;
 
-      console.log(" [WebsocketConnectionManager] New connection with id [ " + ws.id + " ]");
+      Logger.info("[WebsocketConnectionManager] New connection with id [ " + ws.id + " ]");
 
       ws.on('message', (data) => {
         let message = {};
@@ -80,7 +78,7 @@ module.exports = class WebsocketConnectionManager {
       ws.setErrorCallback(this._onError.bind(this));
 
       ws.on('close', (ev) => {
-        console.log('  [WebsocketConnectionManager] Closed connection on [' + ws.id + ']');
+        Logger.info('[WebsocketConnectionManager] Closed connection on [' + ws.id + ']');
         let message = {
           id: 'close',
           type: ws.route,
@@ -95,7 +93,7 @@ module.exports = class WebsocketConnectionManager {
       });
 
       ws.on('error', (err) => {
-        console.log('  [WebsocketConnectionManager] Connection error [' + ws.id + ']');
+        Logger.error('[WebsocketConnectionManager] Connection error [' + ws.id + ']');
         let message = {
           id: 'error',
           type: ws.route,
@@ -145,7 +143,7 @@ module.exports = class WebsocketConnectionManager {
   }
 
   _onError (err) {
-    console.log('  [WebsocketConnectionManager] Connection error');
+    Logger.error('[WebsocketConnectionManager] Connection error');
     let message = {
       id: 'error',
       voiceBridge: ws.sessionId,
@@ -155,7 +153,7 @@ module.exports = class WebsocketConnectionManager {
   }
 
   _onClose (err) {
-    console.log('  [WebsocketConnectionManager] Closed connection [' + this.id + ']');
+    Logger.info('[WebsocketConnectionManager] Closed connection [' + this.id + ']');
     let message = {
       id: 'close',
       voiceBridge: this.sessionId,
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/CoreProcess.js b/labs/bbb-webrtc-sfu/lib/mcs-core/CoreProcess.js
index ee03958e42a0d3d54b74e7c76a2a1fef19234b7a..9717a8807f42736294f5d24330fefad925e24488 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/CoreProcess.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/CoreProcess.js
@@ -1,11 +1,17 @@
+/*
+ * WIP: the mcs-core lib will be turned into a dependecy sometime in the near
+ * future, and it will probably act with a separate process that answers via
+ * its own redis channel
+ */
+const Logger = require('../../utils/Logger');
 const MCSApiStub = require('./media/MCSApiStub');
 
 process.on('uncaughtException', function (error) {
-  console.log(error.stack);
+  Logger.error("[mcs-core-process] Uncaught exception with error", error.stack);
 });
 
 process.on('disconnect',function() {
-  console.log("Parent exited!");
+  Logger.info("[mcs-core-process] Parent process exited!");
   process.kill();
 });
 
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/constants/Constants.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/constants/Constants.js
index 94f7acc9dc9f89aa14094232af1bb300e47468e7..d57795f299e00863de3763b033d9e3bc2b0818f6 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/constants/Constants.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/constants/Constants.js
@@ -1,7 +1,3 @@
-/*
- * (C) Copyright 2016 Mconf Tecnologia (http://mconf.com/)
- */
-
 /**
  * @classdesc
  * Message constants for the communication with BigBlueButton
@@ -53,8 +49,6 @@ exports.EVENT.MEDIA_STATE.FLOW_IN = "MediaFlowInStateChange"
 exports.EVENT.MEDIA_STATE.ENDOFSTREAM = "EndOfStream"
 exports.EVENT.MEDIA_STATE.ICE = "OnIceCandidate"
 
-
-
 // RTP params
 exports.SDP = {};
 exports.SDP.PARAMS = "params"
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MCSApiStub.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MCSApiStub.js
index 9c42ec7efe33f34cbba1536c409fd0943408d4c3..f7992ee7f850d64743d7e32a1ae7975bf017398e 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MCSApiStub.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MCSApiStub.js
@@ -1,11 +1,11 @@
 'use strict'
 
-var config = require('config');
-var C = require('../constants/Constants');
-// EventEmitter
-var util = require('util');
-var EventEmitter = require('events').EventEmitter;
-var MediaController = require('./MediaController.js');
+const config = require('config');
+const C = require('../constants/Constants');
+const util = require('util');
+const EventEmitter = require('events').EventEmitter;
+const MediaController = require('./MediaController.js');
+const Logger = require('../../../utils/Logger');
 
 let instance = null;
 
@@ -27,7 +27,7 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve(answer);
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       Promise.reject(err);
     }
   }
@@ -38,7 +38,7 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve(answer);
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       return Promise.reject(err);
     }
   }
@@ -49,7 +49,7 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve(answer);
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       return Promise.reject(err);
     }
   }
@@ -66,7 +66,7 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve(answer);
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       return Promise.reject(err);
     }
   }
@@ -77,7 +77,7 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve();
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       return Promise.reject(err);
     }
   }
@@ -96,7 +96,7 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve(answer);
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       return Promise.reject(err);
     }
   }
@@ -107,7 +107,7 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve();
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       return Promise.reject(err);
     }
   }
@@ -122,7 +122,7 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve(eventTag);
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       return Promise.reject();
     }
   }
@@ -133,10 +133,11 @@ module.exports = class MCSApiStub extends EventEmitter{
       return Promise.resolve(ack);
     }
     catch (err) {
-      console.log(err);
+      Logger.error(err);
       Promise.reject();
     }
   }
+
   setStrategy (strategy) {
     // TODO
   }
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MediaController.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MediaController.js
index b446aa2d8ebd1433568a10a934dad0f7988dc92f..c5047b2cb852d455b7ffea0e20c5b6c604813bd6 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MediaController.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/MediaController.js
@@ -2,11 +2,10 @@
 
 const config = require('config');
 const C = require('../constants/Constants');
-
+const Logger = require('../../../utils/Logger');
 // Model
 const SfuUser = require('../model/SfuUser');
 const Room = require('../model/Room.js');
-
 const EventEmitter = require('events').EventEmitter;
 
 /* PRIVATE ELEMENTS */
@@ -69,7 +68,7 @@ module.exports = class MediaController {
   }
 
   async join (roomId, type, params) {
-    console.log("[mcs] Join room => " + roomId + ' as ' + type);
+    Logger.info("[mcs-controller] Join room => " + roomId + ' as ' + type);
     try {
       let session;
       const room = await this.createRoomMCS(roomId);
@@ -84,18 +83,18 @@ module.exports = class MediaController {
         session = user.addUri(params.sdp);
       }
 
-      console.log("[mcs] Resolving user " + user.id);
+      Logger.info("[mcs-controller] Resolving user " + user.id);
       return Promise.resolve(user.id);
     }
     catch (err) {
-      console.log("[mcs] JOIN ERROR " + err);
-      return Promise.reject(new Error(err));
+      Logger.error("[mcs-controller] Join returned an error", err);
+      return Promise.reject(err);
     }
   }
 
   async leave (roomId, userId) {
     try {
-      console.log("  [mcs] User => " + userId + " wants to leave ");
+      Logger.info("[mcs-controller] User => " + userId + " wants to leave ");
       const room = this.getRoom(roomId);
       const user = this.getUserMCS(userId);
 
@@ -121,7 +120,9 @@ module.exports = class MediaController {
   }
 
   async publishnsubscribe (userId, sourceId, sdp, params) {
-    console.log("[mcs] pns");
+    Logger.info("[mcs-controller] PublishAndSubscribe from user", userId, "to source", sourceId);
+    Logger.debug("[mcs-controler] PublishAndSubscribe descriptor is", params.descriptor);
+
     let type = params.type;
     try {
       user = this.getUserMCS(userId);
@@ -139,42 +140,43 @@ module.exports = class MediaController {
       const answer = await user.startSession(session.id);
       await user.connect(sourceId, session.id);
 
-      console.log("[mcs] user with sdp session " + session.id);
+      Logger.info("[mcs-controller] PublishAndSubscribe return a SDP session with ID", session.id);
       return Promise.resolve({userId, sessionId});
     }
     catch (err) {
-      console.log("[mcs] PUBLISHNSUBSCRIBE ERROR " + err);
-      return Promise.reject(new Error(err));
+      Logger.error("[mcs-controller] PublishAndSubscribe returned an error", err);
+      return Promise.reject(err);
     }
   }
 
   async publish (userId, roomId, type, params) {
-    console.log("[mcs] publish");
+    Logger.info("[mcs-controller] Publish from user", userId, "to room", roomId);
+    Logger.debug("[mcs-controler] Publish descriptor is", params.descriptor);
+
     let session;
     // TODO handle mediaType
     let mediaType = params.mediaType;
     let answer;
 
     try {
-      console.log("  [mcs] Fetching user => " + userId);
 
       const user = await this.getUserMCS(userId);
 
-      console.log("  [mcs] Fetched user => " + user);
+      Logger.info("[mcs-controller] Fetched user", user.id);
 
       switch (type) {
         case "RtpEndpoint":
         case "WebRtcEndpoint":
           session = user.addSdp(params.descriptor, type);
           session.on('SESSION_STOPPED', (pubId) => {
-            console.log("  [mcs] SESSION ", session.id, " STOPPED ");
+            Logger.info("[mcs-controller] Media session", session.id, "stopped");
             if(pubId === session.id) {
               for (var sub in session.subscribedSessions) {
-                console.log("  [mcs] Unsubscribing session ", sub);
+                Logger.info("[mcs-controller] Unsubscribing session ", sub);
                 let subSession = this._mediaSessions[sub];
                 if (subSession) {
                   subSession.stop();
-                  this._mediaSessions[sub] = null;
+                  delete this._mediaSessions[sub];
                 }
               }
             }
@@ -188,11 +190,11 @@ module.exports = class MediaController {
           answer = await user.startSession(session.id);
           break;
 
-        default: return Promise.reject(new Error("[mcs] Invalid media type"));
+        default: return Promise.reject("[mcs-controller] Invalid media type");
       }
     }
     catch (err) {
-      console.log(err);
+      Logger.error('[mcs-controller] Publish failed with an error', err);
       return Promise.reject(err);
     }
 
@@ -208,7 +210,8 @@ module.exports = class MediaController {
   }
 
   async subscribe (userId, sourceId, type, params) {
-    console.log("  [mcs] subscribe");
+    Logger.info("[mcs-controller] Subscribe from user", userId, "to source", sourceId);
+    Logger.debug("[mcs-controler] Subscribe descriptor is", params.descriptor);
 
     let session;
     // TODO handle mediaType
@@ -217,15 +220,13 @@ module.exports = class MediaController {
     let sourceSession = this._mediaSessions[sourceId];
 
     if (typeof sourceSession === 'undefined') {
-      return Promise.reject(new Error("  [mcs] Media session " + sourceId + " was not found"));
+      return Promise.reject(new Error("[mcs-controller] Media session", sourceId, "was not found"));
     }
 
     try {
-      console.log("  [mcs] Fetching user => " + userId);
-
       const user = await this.getUserMCS(userId);
 
-      console.log("  [mcs] Fetched user => " + user);
+      Logger.info("[mcs-controller] Fetched user", user.id);
 
       switch (type) {
         case "RtpEndpoint":
@@ -235,7 +236,7 @@ module.exports = class MediaController {
           answer = await user.startSession(session.id);
           await sourceSession.connect(session._mediaElement);
           sourceSession.subscribedSessions.push(session.id);
-          console.log("  [mcs] ", sourceSession.id,  " subscribers list ", sourceSession.subscribedSessions);
+          Logger.info("[mcs-controller] Updated", sourceSession.id,  "subscribers list to", sourceSession.subscribedSessions);
           break;
         case "URI":
           session = user.addUri(params.descriptor, type);
@@ -244,11 +245,11 @@ module.exports = class MediaController {
 
           break;
 
-        default: return Promise.reject(new Error("[mcs] Invalid media type"));
+        default: return Promise.reject(new Error("[mcs-controller] Invalid media type"));
       }
     }
     catch (err) {
-      console.log(err);
+      Logger.error("[mcs-controller] Subscribe failed with an error", err);
       return Promise.reject(err);
     }
 
@@ -299,14 +300,14 @@ module.exports = class MediaController {
   async addIceCandidate (mediaId, candidate) {
     let session = this._mediaSessions[mediaId];
     if (typeof session === 'undefined') {
-      return Promise.reject(new Error("  [mcs] Media session " + mediaId + " was not found"));
+      return Promise.reject(new Error("[mcs-controller] Media session " + mediaId + " was not found"));
     }
     try {
       const ack = await session.addIceCandidate(candidate);
       return Promise.resolve(ack);
     }
     catch (err) {
-      console.log(err);
+      Logger.error("[mcs-controller] addIceCandidate failed with an error", err);
       return Promise.reject(err);
     }
   }
@@ -318,7 +319,7 @@ module.exports = class MediaController {
   async createRoomMCS (roomId)  {
     let self = this;
 
-    console.log("  [media] Creating new room with ID " + roomId);
+    Logger.info("[mcs-controller] Creating new room with ID", roomId);
 
     if(!self._rooms[roomId]) {
       self._rooms[roomId] = new Room(roomId);
@@ -334,17 +335,17 @@ module.exports = class MediaController {
   createUserMCS (roomId, type, params)  {
     let self = this;
     let user;
-    console.log("  [media] Creating a new user[" + type + "]");
+    Logger.info("[mcs-controller] Creating a new", type, "user at room", roomId);
 
     switch (type) {
       case C.USERS.SFU:
         user  = new SfuUser(roomId, type, this.emitter, params.userAgentString, params.sdp);
         break;
       case C.USERS.MCU:
-        console.log("  [media] createUserMCS MCU TODO");
+        Logger.info("[mcs-controller] createUserMCS MCU TODO");
         break;
       default:
-        console.log("  [controller] Unrecognized user type");
+        Logger.warn("[mcs-controller] Unrecognized user type");
     }
 
     if(!self._users[user.id]) {
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/media-server.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/media-server.js
index 6693beb97e4df4f160bc1b3beee78edb17bf532c..776dac4d96bad2a5b7b95333035ac4b865d07eb1 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/media-server.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/media/media-server.js
@@ -5,6 +5,7 @@ const config = require('config');
 const mediaServerClient = require('kurento-client');
 const util = require('util');
 const EventEmitter = require('events').EventEmitter;
+const Logger = require('../../../utils/Logger');
 
 let instance = null;
 
@@ -35,7 +36,6 @@ module.exports = class MediaServer extends EventEmitter {
         if (error) {
           reject(error);
         }
-        console.log("  [media] Retrieved media server client => " + client);
         resolve(client);
       });
     });
@@ -44,13 +44,13 @@ module.exports = class MediaServer extends EventEmitter {
   _getMediaPipeline (conference) {
     return new Promise((resolve, reject) => {
       if (this._mediaPipelines[conference]) {
-        console.log(' [media] Pipeline already exists. ' + JSON.stringify(this._mediaPipelines, null, 2));
+        Logger.warn('[mcs-media] Pipeline for', conference, ' already exists.');
         resolve(this._mediaPipelines[conference]);
       }
       else {
         this._mediaServer.create('MediaPipeline', (error, pipeline) => {
           if (error) {
-            console.log(error);
+            Logger.error('[mcs-media] Create MediaPipeline returned error', error);
             reject(error);
           }
           this._mediaPipelines[conference] = pipeline;
@@ -74,7 +74,7 @@ module.exports = class MediaServer extends EventEmitter {
         if (error) {
           return reject(error);
         }
-        console.log("  [MediaController] Created [" + type + "] media element: " + mediaElement.id);
+        Logger.info("[mcs-media] Created [" + type + "] media element: " + mediaElement.id);
         this._mediaElements[mediaElement.id] = mediaElement;
         return resolve(mediaElement);
       });
@@ -120,19 +120,19 @@ module.exports = class MediaServer extends EventEmitter {
             });
             break;
 
-          default: return reject("  [media] Invalid connect type");
+          default: return reject("[mcs-media] Invalid connect type");
         }
       });
     }
     else {
-      return Promise.reject("  [media] Failed to connect " + type + ": " + sourceId + " to " + sinkId);
+      return Promise.reject("[mcs-media] Failed to connect " + type + ": " + sourceId + " to " + sinkId);
     }
   }
 
   stop (elementId) {
     let mediaElement = this._mediaElements[elementId];
     if (typeof mediaElement !== 'undefined' && typeof mediaElement.release === 'function') {
-      console.log("  [media] Releasing endpoint => " + elementId);
+      Logger.info("[mcs-media] Releasing endpoint => " + elementId);
       mediaElement.release();
       this._mediaElements[elementId] = null;
     }
@@ -146,7 +146,7 @@ module.exports = class MediaServer extends EventEmitter {
     if (typeof mediaElement !== 'undefined' && typeof mediaElement.addIceCandidate === 'function' &&
         typeof candidate !== 'undefined') {
       mediaElement.addIceCandidate(candidate);
-      console.log("  [media] Added ICE candidate for => " + elementId);
+      Logger.debug("[mcs-media] Added ICE candidate for => " + elementId);
       return Promise.resolve();
     }
     else {
@@ -155,7 +155,7 @@ module.exports = class MediaServer extends EventEmitter {
   }
 
   gatherCandidates (elementId) {
-    console.log('  [media] Gathering ICE candidates for ' + elementId);
+    Logger.info('[mcs-media] Gathering ICE candidates for ' + elementId);
     let mediaElement = this._mediaElements[elementId];
 
     return new Promise((resolve, reject) => {
@@ -164,12 +164,12 @@ module.exports = class MediaServer extends EventEmitter {
           if (error) {
             return reject(new Error(error));
           }
-          console.log('  [media] Triggered ICE gathering for ' + elementId);
+          Logger.info('[mcs-media] Triggered ICE gathering for ' + elementId);
           return resolve(); 
         });
       }
       else {
-        return reject("  [MediaController/gatherCandidates] There is no element " + elementId);
+        return reject("[mcs-media] There is no element " + elementId);
       }
     });
   }
@@ -181,7 +181,7 @@ module.exports = class MediaServer extends EventEmitter {
       endpoint.setMinVideoRecvBandwidth(min);
       endpoint.setMaxVideoRecvBandwidth(max);
     } else {
-      return (" [MediaController/setInputBandwidth] There is no element " + elementId);
+      return ("[mcs-media] There is no element " + elementId);
     }
   }
 
@@ -192,7 +192,7 @@ module.exports = class MediaServer extends EventEmitter {
       endpoint.setMinVideoSendBandwidth(min);
       endpoint.setMaxVideoSendBandwidth(max);
     } else {
-      return (" [MediaController/setOutputBandwidth] There is no element " + elementId );
+      return ("[mcs-media] There is no element " + elementId );
     }
   }
 
@@ -203,7 +203,7 @@ module.exports = class MediaServer extends EventEmitter {
       endpoint.setMinOutputBitrate(min);
       endpoint.setMaxOutputBitrate(max);
     } else {
-      return (" [MediaController/setOutputBitrate] There is no element " + elementId);
+      return ("[mcs-media] There is no element " + elementId);
     }
   }
 
@@ -220,7 +220,7 @@ module.exports = class MediaServer extends EventEmitter {
         });
       }
       else {
-        return reject("  [MediaController/processOffer] There is no element " + elementId);
+        return reject("[mcs-media] There is no element " + elementId);
       }
     });
   }
@@ -256,7 +256,7 @@ module.exports = class MediaServer extends EventEmitter {
     let mediaElement = this._mediaElements[elementId];
     // TODO event type validator
     if (typeof mediaElement !== 'undefined' && mediaElement) {
-      console.log('  [media] Adding media state listener [' + eventTag + '] for ' + elementId);
+      Logger.debug('[mcs-media] Adding media state listener [' + eventTag + '] for ' + elementId);
       mediaElement.on(eventTag, (event) => {
         if (eventTag === C.EVENT.MEDIA_STATE.ICE) {
           event.candidate = mediaServerClient.getComplexType('IceCandidate')(event.candidate);
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js
index e532a3d7089e2dfafe12f1842bd7d3da10e31a03..1da857d04777447c86256efab1da03fdda3f16ef 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SdpSession.js
@@ -12,6 +12,7 @@ const EventEmitter = require('events').EventEmitter;
 const MediaServer = require('../media/media-server');
 const config = require('config');
 const kurentoUrl = config.get('kurentoUrl');
+const Logger = require('../../../utils/Logger');
 
 module.exports = class SdpSession extends EventEmitter {
   constructor(emitter, sdp = null, room, type = 'WebRtcEndpoint') {
@@ -41,10 +42,8 @@ module.exports = class SdpSession extends EventEmitter {
     try {
       const client = await this._MediaServer.init();
 
-      console.log("[SdpSession] start/cme");
+      Logger.info("[mcs-sdp-session] Starting new SDP session", this.id, "in room", this.room );
       this._mediaElement = await this._MediaServer.createMediaElement(this.room, this._type);
-      console.log("[SdpSession] start/po " + this._mediaElement);
-
       this._MediaServer.trackMediaState(this._mediaElement, this._type);
       this._MediaServer.on(C.EVENT.MEDIA_STATE.MEDIA_EVENT+this._mediaElement, (event) => {
         setTimeout(() => {
@@ -73,7 +72,7 @@ module.exports = class SdpSession extends EventEmitter {
     try {
       await this._MediaServer.stop(this._mediaElement);
       this._status = C.STATUS.STOPPED;
-      console.log("  [SdpSession] Session ", this.id, " is going to stop...");
+      Logger.info("[mcs-sdp-session] Session ", this.id, " is going to stop...");
       this.emit('SESSION_STOPPED', this.id);
       Promise.resolve();
     }
@@ -83,12 +82,11 @@ module.exports = class SdpSession extends EventEmitter {
     }
   }
 
-
   // TODO move to parent Session
   // TODO handle connection type
   async connect (sinkId) {
     try {
-      console.log("  [SdpSession] Connecting " + this._mediaElement + " => " + sinkId);
+      Logger.info("[mcs-sdp-session] Connecting " + this._mediaElement + " => " + sinkId);
       await this._MediaServer.connect(this._mediaElement, sinkId, 'ALL');
       return Promise.resolve();
     }
@@ -113,7 +111,7 @@ module.exports = class SdpSession extends EventEmitter {
   }
 
   handleError (err) {
-    console.log(err);
+    Logger.error("[mcs-sdp-session] SFU SDP Session received an error", err);
     this._status = C.STATUS.STOPPED;
   }
 }
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SfuUser.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SfuUser.js
index 86cced861c78564e0ac7789395a7e599593a503d..049eea9c41e6a3fe5a16cf6f4ed5b34bfe7cb9d4 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SfuUser.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/SfuUser.js
@@ -10,13 +10,13 @@ const C = require('../constants/Constants');
 const SdpWrapper = require('../utils/SdpWrapper');
 const SdpSession = require('../model/SdpSession');
 const UriSession = require('../model/UriSession');
+const Logger = require('../../../utils/Logger');
 
 module.exports = class SfuUser extends User {
   constructor(_roomId, type, emitter, userAgentString = C.STRING.ANONYMOUS, sdp = null, uri = null) {
     super(_roomId);
     // {SdpWrapper} SdpWrapper
     this._sdp;
-    // {Object} hasAudio, hasVideo, hasContent
     this._mediaSessions = {}
     this.userAgentString;
     this.emitter = emitter;
@@ -43,7 +43,7 @@ module.exports = class SfuUser extends User {
     }
     catch (err) {
       this.handleError(err);
-      Promise.reject(new Error(err));
+      Promise.reject(err);
     }
   }
 
@@ -52,7 +52,7 @@ module.exports = class SfuUser extends User {
     let session = new SdpSession(this.emitter, sdp, this.roomId, type);
     this.emitter.emit(C.EVENT.NEW_SESSION+this.id, session.id);
     session.on("SESSION_STOPPED", (sessId) => {
-      console.log("  [SfuUser] Session ", sessId, "stopped, cleaning it...");
+      Logger.info("[mcs-sfu-user] Session ", sessId, "stopped, cleaning it...");
       if (sessId === session.id) {
         this._mediaSessions[sessId] = null;
       }
@@ -63,13 +63,12 @@ module.exports = class SfuUser extends User {
       this._mediaSessions[session.id] = {};
     }
     this._mediaSessions[session.id] = session; 
-    console.log("[SfuUser] Added SDP " + session.id);
+    Logger.info("[mcs-sfu-user] Added new SDP session", session.id, "to user", this.id);
 
     return session;
   }
 
   async startSession (sessionId) {
-    console.log("[SfuUser] starting session " + sessionId);
     let session = this._mediaSessions[sessionId];
   
     try {
@@ -78,7 +77,7 @@ module.exports = class SfuUser extends User {
     }
     catch (err) {
       this.handleError(err);
-      return Promise.reject(new Error(err));
+      return Promise.reject(err);
     }
   }
 
@@ -91,7 +90,7 @@ module.exports = class SfuUser extends User {
     } 
     catch (err) {
       this.handleError(err);
-      Promise.reject(new Error(err));
+      Promise.reject(err);
     }
   }
 
@@ -103,7 +102,7 @@ module.exports = class SfuUser extends User {
     } 
     catch (err) {
       this.handleError(err);
-      Promise.reject(new Error(err));
+      Promise.reject(err);
     }
   }
 
@@ -114,7 +113,7 @@ module.exports = class SfuUser extends User {
     } 
     catch (err) {
       this.handleError(err);
-      Promise.reject(new Error(err));
+      Promise.reject(err);
     }
   }
 
@@ -125,12 +124,12 @@ module.exports = class SfuUser extends User {
     } 
     catch (err) {
       this.handleError(err);
-      Promise.reject(new Error(err));
+      Promise.reject(err);
     }
   }
 
   async stopSession (sessionId) {
-    console.log("  [SfuUser] Stopping session => " + sessionId);
+    Logger.info("[mcs-sfu-user] Stopping session => " + sessionId);
     let session = this._mediaSessions[sessionId];
 
     try {
@@ -140,7 +139,7 @@ module.exports = class SfuUser extends User {
     }
     catch (err) {
       this.handleError(err);
-      Promise.reject(new Error(err));
+      Promise.reject(err);
     }
   }
 
@@ -148,24 +147,23 @@ module.exports = class SfuUser extends User {
     let session = this._mediaSessions[sourceId];
     if(session) {
       try {
-        console.log(" [SfuUser] Connecting sessions " + sourceId + "=>" + sinkId);
+        Logger.info("[mcs-sfu-user] Connecting sessions " + sourceId + "=>" + sinkId);
         await session.connect(sinkId);
         return Promise.resolve();
       }
       catch (err) {
         this.handleError(err);
-        return Promise.reject(new Error(err));
+        return Promise.reject(err);
       }
     }
     else {
-      return Promise.reject(new Error("  [SfuUser] Source session " + sourceId + " not found"));
+      return Promise.reject(new Error("[mcs-sfu-user] Source session " + sourceId + " not found"));
     }
   }
 
   async leave () {
     let sessions = Object.keys(this._mediaSessions);
-    console.log("  [SfuUser] User sessions will be killed");
-    console.log(sessions);
+    Logger.info("[mcs-sfu-user] User sessions will be killed");
 
     try {
       for (var session in sessions) {
@@ -176,12 +174,12 @@ module.exports = class SfuUser extends User {
     }
     catch (err) {
       this.handleError(err);
-      Promise.reject(new Error(err));
+      Promise.reject(err);
     }
   }
 
   handleError (err) {
-    console.log(err);
+    Logger.error("[mcs-sfu-user] SFU User received error", err);
     this._status = C.STATUS.STOPPED;
   }
 }
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/UriSession.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/UriSession.js
index 8193a56524e10a0958248e3abb95a0106e6312c2..de0af958e0a425573efee084fd362ae0ad4a8cdb 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/UriSession.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/model/UriSession.js
@@ -9,6 +9,7 @@ const C = require('../constants/Constants');
 const rid = require('readable-id');
 const EventEmitter = require('events').EventEmitter;
 const MediaServer = require('../media/media-server');
+const Logger = require('../../../utils/Logger');
 
 module.exports = class UriSession extends EventEmitter {
   constructor(uri = null) {
@@ -29,14 +30,13 @@ module.exports = class UriSession extends EventEmitter {
     this._status = C.STATUS.STARTING;
     try {
       const mediaElement = await MediaServer.createMediaElement(this.id, C.MEDIA_TYPE.URI);
-      console.log("start/cme");
       await MediaServer.play(this.id);
       this._status = C.STATUS.STARTED;
       return Promise.resolve();
     }
     catch (err) {
       this.handleError(err);
-      return Promise.reject(new Error(err));
+      return Promise.reject(err);
     }
   }
 
@@ -50,7 +50,7 @@ module.exports = class UriSession extends EventEmitter {
     }
     catch (err) {
       this.handleError(err);
-      return Promise.reject(new Error(err));
+      return Promise.reject(err);
     }
   }
 
@@ -62,12 +62,12 @@ module.exports = class UriSession extends EventEmitter {
     }
     catch (err) {
       this.handleError(err);
-      return Promise.reject(new Error(err));
+      return Promise.reject(err);
     }
   }
 
   handleError (err) {
-    console.log(err);
+    Logger.error(err);
     this._status = C.STATUS.STOPPED;
   }
 }
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js
index eea0d58895e7424e145df30a93d7a20fe6db1a29..da33a3cd8f52096dc178a3e71f2a4e692edd7668 100644
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js
+++ b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/SdpWrapper.js
@@ -84,7 +84,6 @@ module.exports = class SdpWrapper {
 
   getVideoParameters (sdp) {
     var res = transform.parse(sdp);
-    console.log("  [sdp] getVideoParameters => " + JSON.stringify(res, null, 2));
     var params = {};
     params.fmtp = "";
     params.codecId = 96;
@@ -94,7 +93,6 @@ module.exports = class SdpWrapper {
         if (typeof ml.fmtp[0] != 'undefined' && ml.fmtp) {
           params.codecId = ml.fmtp[0].payload;
           params.fmtp = ml.fmtp[0].config;
-          console.log("  [sdp] getVideoParameters fmtp => " + JSON.stringify(params));
           return params;
         }
       }
@@ -151,7 +149,6 @@ module.exports = class SdpWrapper {
     res.media = res.media.filter(function (ml) { return ml.type == "video"}); //&& ml.invalid[0].value != 'content:slides'});
     var mangledSdp = transform.write(res);
     if (typeof mangledSdp != undefined && mangledSdp && mangledSdp != "") {
-      console.log("  [sdp] MAIN VIDEO SDP => " + mangledSdp);
       return mangledSdp;
     }
     else {
@@ -183,7 +180,6 @@ module.exports = class SdpWrapper {
           let fmtpConfig = transform.parseParams(fmtp.config);
           let profileId = fmtpConfig['profile-level-id'];
           if(typeof profileId !== 'undefined' && parseInt(profileId, 16) > parseInt(maxProfileLevel, 16)) {
-            console.log("  [sdp] Filtering profile " + parseInt(profileId, 16) + ". Higher than max "+ parseInt(maxProfileLevel, 16));
             pt = fmtp.payload;
             delete ml.fmtp[idx];
             ml.rtp = ml.rtp.filter((rtp) => { return rtp.payload != pt});
diff --git a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/sdp-utils.js b/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/sdp-utils.js
deleted file mode 100644
index 11b06b0bcf49d721be79203de85fe307962b74a7..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/mcs-core/lib/utils/sdp-utils.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/**
- * @classdesc
- * Utils class for SDP generation
- */
-
-module.exports.generateSdp = function(remote_ip_address, remote_video_port) {
-  return "v=0\r\n"
-    + "o=- 0 0 IN IP4 " + remote_ip_address + "\r\n"
-    + "s=No Name\r\n"
-    + "c=IN IP4 " + remote_ip_address + "\r\n"
-    + "t=0 0\r\n"
-    + "m=video " + remote_video_port + " RTP/AVP 96\r\n"
-    + "a=rtpmap:96 H264/90000\r\n"
-    + "a=ftmp:96 packetization-mode=0\r\n";
-}
-
-/**
- * Generates a video SDP given the media specs
- * @param  {string} sourceIpAddress The source IP address of the media
- * @param  {string} sourceVideoPort The source video port of the media
- * @param  {string} codecId         The ID of the codec
- * @param  {string} sendReceive     The SDP flag of the media flow
- * direction, 'sendonly', 'recvonly' or 'sendrecv'
- * @param {String} rtpProfile       The RTP profile of the RTP Endpoint
- * @param {String} codecName        The name of the codec used for the RTP
- * Endpoint
- * @param {String} codecRate        The codec rate
- * @return {string}                 The Session Descriptor for the media
- */
-module.exports.generateVideoSdp = function (sourceIpAddress, sourceVideoPort, codecId, sendReceive, rtpProfile, codecName, codecRate, fmtp) {
-  return 'm=video ' + sourceVideoPort + ' ' + rtpProfile + ' ' + codecId + '\r\n'
-    + 'a=' + sendReceive + '\r\n'
-    + 'c=IN IP4 ' + sourceIpAddress + '\r\n'
-    + 'a=rtpmap:' + codecId + ' ' + codecName + '/' + codecRate + '\r\n'
-    + 'a=fmtp:' + codecId + ' ' + fmtp + '\r\n';
-};
-
diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js b/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js
index 024bb7bf4e9eaf5a1ff8dcf5a7a888bcf9f6e27b..cfc72d55996d74682ccf84c6d07b7d80e9efc0a2 100644
--- a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js
+++ b/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareManager.js
@@ -10,7 +10,7 @@
 const BigBlueButtonGW = require('../bbb/pubsub/bbb-gw');
 const Screenshare = require('./screenshare');
 const C = require('../bbb/messages/Constants');
-// Global variables
+const Logger = require('../utils/Logger');
 
 module.exports = class ScreenshareManager {
   constructor (logger) {
@@ -29,19 +29,17 @@ module.exports = class ScreenshareManager {
       this._redisGateway = await this._bbbGW.addSubscribeChannel(C.TO_SCREENSHARE);
       const transcode = await this._bbbGW.addSubscribeChannel(C.FROM_BBB_TRANSCODE_SYSTEM_CHAN);
       this._redisGateway.on(C.REDIS_MESSAGE, this._onMessage.bind(this));
-      console.log('  [ScreenshareManager] Successfully subscribed to redis channel');
     }
     catch (error) {
-      console.log('  [ScreenshareManager] Could not connect to transcoder redis channel, finishing app...');
-      console.log(error);
+      Logger.error('[ScreenshareManager] Could not connect to transcoder redis channel, finishing screensharing app with error', error);
       this.stopAll();
     }
   }
 
-  _onMessage(_message) {
-    console.log('  [ScreenshareManager] Received message => ');
+  _onMessage(message) {
+    Logger.debug('[ScreenshareManager] Received message [' + message.id + '] from connection', message.connectionId);
+
     let session;
-    let message = _message;
 
     let sessionId = message.voiceBridge;
     let connectionId = message.connectionId;
@@ -75,7 +73,7 @@ module.exports = class ScreenshareManager {
 
         // starts presenter by sending sessionID, websocket and sdpoffer
         session._startPresenter(sessionId, message.sdpOffer, (error, sdpAnswer) => {
-          console.log("  [ScreenshareManager] Started presenter " + sessionId);
+          Logger.info("[ScreenshareManager] Started presenter ", sessionId, " for connection", connectionId);
           if (error) {
             this._bbbGW.publish(JSON.stringify({
               connectionId: session._id,
@@ -93,15 +91,18 @@ module.exports = class ScreenshareManager {
             sdpAnswer : sdpAnswer
           }), C.FROM_SCREENSHARE);
 
-          console.log("  [ScreenshareManager]  [websocket] Sending presenterResponse \n" + sdpAnswer);
+          Logger.info("[ScreenshareManager] Sending presenterResponse to presenter", sessionId, "for connection", session._id);
         });
         break;
 
       case 'viewer':
-        console.log("  [ScreenshareManager][viewer] Session output \n " + session);
         if (message.sdpOffer && message.voiceBridge) {
           if (session) {
-            session._startViewer(message.connectionId, message.voiceBridge, message.sdpOffer, connectionId,
+            Logger.info("[ScreenshareManager] Starting screenshare viewer at", message.voiceBridge, " for viewer with connection ", message.connectionId);
+            session._startViewer(message.connectionId,
+                message.voiceBridge,
+                message.sdpOffer,
+                connectionId,
                 this._screenshareSessions[message.voiceBridge]._presenterEndpoint);
           } else {
             // TODO ERROR HANDLING
@@ -110,12 +111,12 @@ module.exports = class ScreenshareManager {
         break;
 
       case 'stop':
-        console.log('[' + message.id + '] connection ' + sessionId);
+        Logger.info('[ScreenshareManager] Received stop message for session', sessionId, "at connection", connectionId);
 
         if (session) {
           session._stop(sessionId);
         } else {
-          console.log(" [stop] Why is there no session on STOP?");
+          Logger.warn("[ScreenshareManager] There was no screensharing session on stop for", sessionId);
         }
         break;
 
@@ -123,28 +124,27 @@ module.exports = class ScreenshareManager {
         if (session) {
           session.onIceCandidate(message.candidate);
         } else {
-          console.log(" [iceCandidate] Why is there no session on ICE CANDIDATE?");
+          Logger.warn("[ScreenshareManager] There was no screensharing session for onIceCandidate for", sessionId, ". There should be a queue here");
         }
         break;
 
       case 'viewerIceCandidate':
-        console.log("[viewerIceCandidate] Session output => " + session);
         if (session) {
           session.onViewerIceCandidate(message.candidate, connectionId);
         } else {
-          console.log("[iceCandidate] Why is there no session on ICE CANDIDATE?");
+          Logger.warn("[ScreenshareManager] There was no screensharing session for onIceCandidate for", sessionId + ". There should be a queue here");
         }
         break;
 
       case 'close':
-        console.log('  [ScreenshareManager] Connection ' + connectionId + ' closed');
+        Logger.info('[ScreenshareManager] Connection ' + connectionId + ' closed');
 
         if (message.role === 'presenter' && this._screenshareSessions[sessionId]) {
-          console.log("  [ScreenshareManager] Stopping presenter " + sessionId);
+          Logger.info("[ScreenshareManager] Stopping presenter " + sessionId);
           this._stopSession(sessionId);
         }
         if (message.role === 'viewer' && typeof session !== 'undefined') {
-          console.log("  [ScreenshareManager] Stopping viewer " + sessionId);
+          Logger.info("[ScreenshareManager] Stopping viewer " + sessionId);
           session.stopViewer(message.connectionId);
         }
         break;
@@ -153,14 +153,14 @@ module.exports = class ScreenshareManager {
         this._bbbGW.publish(JSON.stringify({
           connectionId: session._id? session._id : 'none',
           id : 'error',
-          message: 'Invald message ' + message
+          message: 'Invalid message ' + message
         }), C.FROM_SCREENSHARE);
         break;
     }
   }
 
   _stopSession(sessionId) {
-    console.log(' [>] Stopping session ' + sessionId);
+    Logger.info('[ScreenshareManager] Stopping session ' + sessionId);
 
     if (typeof this._screenshareSessions === 'undefined' || typeof sessionId === 'undefined') {
       return;
@@ -175,7 +175,7 @@ module.exports = class ScreenshareManager {
   }
 
   stopAll() {
-    console.log('\n [x] Stopping everything! ');
+    Logger.info('[ScreenshareManager] Stopping everything! ');
 
     if (typeof this._screenshareSessions === 'undefined') {
       return;
diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareProcess.js b/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareProcess.js
index 223bde09dfb129381ca98bb591e1ecb83291af16..a53152f4f7142f14af315c7c6a4aeb7bff57fed6 100644
--- a/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareProcess.js
+++ b/labs/bbb-webrtc-sfu/lib/screenshare/ScreenshareProcess.js
@@ -1,10 +1,23 @@
 const ScreenshareManager = require('./ScreenshareManager');
+const Logger = require('../utils/Logger');
+const config = require('config');
+
+if (config.get('acceptSelfSignedCertificate')) {
+  process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;
+}
 
 let c = new ScreenshareManager();
-c.start();
 
-process.on('uncaughtException', function (error) {
-  console.log(error.stack);
+process.on('uncaughtException', (error) => {
+  Logger.error('[ScreenshareProcess] Uncaught exception ', error.stack);
 });
 
 process.on('disconnect', c.stopAll);
+
+// Added this listener to identify unhandled promises, but we should start making
+// sense of those as we find them
+process.on('unhandledRejection', (reason, p) => {
+  Logger.error('[ScreenshareProcess] Unhandled Rejection at: Promise', p, 'reason:', reason);
+});
+
+c.start();
diff --git a/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js b/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js
index df3df06f1c5470a449e64c899ea9995f8e1d4ae8..b089b1565c4bcd97b6b0756c37d27cee66e2b7d7 100644
--- a/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js
+++ b/labs/bbb-webrtc-sfu/lib/screenshare/screenshare.js
@@ -1,5 +1,5 @@
 /*
-* Lucas Fialho Zawacki
+ * Lucas Fialho Zawacki
  * Paulo Renato Lanzarin
  * (C) Copyright 2017 Bigbluebutton
  *
@@ -7,7 +7,6 @@
 
 'use strict'
 
-// Imports
 const C = require('../bbb/messages/Constants');
 const MediaHandler = require('../media-handler');
 const Messaging = require('../bbb/messages/Messaging');
@@ -18,15 +17,13 @@ const MCSApi = require('../mcs-core/lib/media/MCSApiStub');
 const config = require('config');
 const kurentoIp = config.get('kurentoIp');
 const localIpAddress = config.get('localIpAddress');
+const Logger = require('../utils/Logger');
 
-// Global stuff
+// Global MCS endpoints mapping. These hashes maps IDs generated by the mcs-core
+// lib to the ones generate in the ScreenshareManager
 var sharedScreens = {};
 var rtpEndpoints = {};
 
-if (config.get('acceptSelfSignedCertificate')) {
-  process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;
-}
-
 module.exports = class Screenshare {
   constructor(id, bbbgw, voiceBridge, caller = 'caller', vh, vw, meetingId) {
     this.mcs = new MCSApi();
@@ -52,13 +49,33 @@ module.exports = class Screenshare {
         this.mcs.addIceCandidate(this._presenterEndpoint, _candidate);
       }
       catch (err)   {
-        console.log(err);
+        Logger.error("[screenshare] ICE candidate could not be added to media controller.", err);
       }
     }
     else {
       this._presenterCandidatesQueue.push(_candidate);
     }
-  };
+  }
+
+  onViewerIceCandidate(candidate, callerName) {
+    if (this._viewersEndpoint[callerName]) {
+      try {
+        this.flushCandidatesQueue(this._viewersEndpoint[callerName], this._viewersCandidatesQueue[callerName]);
+        this.mcs.addIceCandidate(this._viewersEndpoint[callerName], candidate);
+      }
+      catch (err)   {
+        Logger.error("[screenshare] Viewer ICE candidate could not be added to media controller.", err);
+      }
+    }
+    else {
+      if (!this._viewersCandidatesQueue[callerName]) {
+        this._viewersCandidatesQueue[callerName] = [];
+      }
+      this._viewersCandidatesQueue[callerName].push(candidate);
+    }
+  }
+
+
 
   flushCandidatesQueue (mediaId, queue) {
     if (this.mediaId) {
@@ -69,7 +86,7 @@ module.exports = class Screenshare {
         }
       }
       catch (err) {
-        console.log(err);
+        Logger.error("[screenshare] ICE candidate could not be added to media controller.", err);
       }
     }
   }
@@ -77,16 +94,16 @@ module.exports = class Screenshare {
   mediaStateRtp (event) {
     let msEvent = event.event;
 
-    console.log('  [screenshare] ' + msEvent.type + '[' + msEvent.state + ']' + ' for endpoint ' + this._id);
-
     switch (event.eventTag) {
       case "MediaStateChanged":
         break;
 
       case "MediaFlowOutStateChange":
+        Logger.info('[screenshare]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session ',  event.id);
         break;
 
       case "MediaFlowInStateChange":
+        Logger.info('[screenshare]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session ',  event.id);
         if (msEvent.state === 'FLOWING') {
           this._onRtpMediaFlowing();
         }
@@ -95,18 +112,18 @@ module.exports = class Screenshare {
         }
         break;
 
-      default: console.log("  [video] Unrecognized event");
+      default: Logger.warn("[screenshare] Unrecognized event", event);
     }
   }
 
   mediaStateWebRtc (event, id) {
     let msEvent = event.event;
 
-    console.log('  [screenshare] ' + msEvent.type + '[' + msEvent.state + ']' + ' for endpoint ' + this._id);
-
     switch (event.eventTag) {
       case "OnIceCandidate":
         let candidate = msEvent.candidate;
+        Logger.debug('[screenshare] Received ICE candidate from mcs-core for media session', event.id, '=>', candidate);
+
         this._BigBlueButtonGW.publish(JSON.stringify({
           connectionId: id,
           id : 'iceCandidate',
@@ -120,12 +137,11 @@ module.exports = class Screenshare {
         break;
 
       case "MediaFlowOutStateChange":
-        break;
-
       case "MediaFlowInStateChange":
+        Logger.info('[screenshare]', msEvent.type, '[' + msEvent.state? msEvent.state : 'UNKNOWN_STATE' + ']', 'for media session',  event.id);
         break;
 
-      default: console.log("  [video] Unrecognized event");
+      default: Logger.warn("[screenshare] Unrecognized event", event);
     }
   }
 
@@ -135,15 +151,16 @@ module.exports = class Screenshare {
 
     // Force H264 on Firefox and Chrome
     sdpOffer = h264_sdp.transform(sdpOffer);
-    console.log(" [screenshare] Starting presenter " + id + " at voiceBridge " + this._voiceBridge);
+    Logger.info("[screenshare] Starting presenter", id , "at session", this._voiceBridge);
 
     try {
       this.userId = await this.mcs.join(this._meetingId, 'SFU', {});
-      console.log("  [video] Join returned => " + this.userId);
+      Logger.info("[screenshare] MCS Join for", this._id, "returned", this.userId);
+
     }
-    catch (err) {
-      console.log("  [video] MCS join returned error => " + err);
-      return callback(err);
+    catch (error) {
+      Logger.error("[screenshare] MCS Join returned error =>", error);
+      return callback(error);
     }
 
     try {
@@ -158,11 +175,10 @@ module.exports = class Screenshare {
         this.mediaStateWebRtc(event, this._id)
       });
 
-      console.log("  [video] Publish returned => " + this._presenterEndpoint);
-
+      Logger.info("[screenshare] MCS publish for user", this.userId, "returned", this._presenterEndpoint);
     }
     catch (err) {
-      console.log("  [video] MCS publish returned error => " + err);
+      Logger.error("[screenshare] MCS publish returned error =>", err);
       return callback(err);
     }
 
@@ -181,51 +197,33 @@ module.exports = class Screenshare {
 
       this.mcs.on('MediaEvent' + this._ffmpegEndpoint, this.mediaStateRtp.bind(this));
 
-      console.log("  [video] Subscribe returned => " + this._ffmpegEndpoint);
+      Logger.info("[screenshare] MCS subscribe for user", this.userId, "returned", this._ffmpegEndpoint);
 
       return callback(null, presenterSdpAnswer);
     }
     catch (err) {
-      console.log("  [video] MCS subscribe returned error => " + err);
+      Logger.error("[screenshare] MCS subscribe returned error =>", err);
       return callback(err);
     }
   }
 
-  onViewerIceCandidate(candidate, callerName) {
-    if (this._viewersEndpoint[callerName]) {
-      try {
-        this.flushCandidatesQueue(this._viewersEndpoint[callerName], this._viewersCandidatesQueue[callerName]);
-        this.mcs.addIceCandidate(this._viewersEndpoint[callerName], candidate);
-      }
-      catch (err)   {
-        console.log(err);
-      }
-    }
-    else {
-      if (!this._viewersCandidatesQueue[callerName]) {
-        this._viewersCandidatesQueue[callerName] = [];
-      }
-      this._viewersCandidatesQueue[callerName].push(candidate);
-    }
-  }
-
-  async _startViewer(connectionId, voiceBridge, sdp, callerName, presenterEndpoint, callback) {
+    async _startViewer(connectionId, voiceBridge, sdp, callerName, presenterEndpoint, callback) {
+    Logger.info("[screenshare] Starting viewer", callerName, "for voiceBridge", this._voiceBridge);
+    // TODO refactor the callback handling
     let _callback = function(){};
     let sdpAnswer, sdpOffer;
-    console.log("  [screenshare] Starting viewer " + callerName + " for voiceBridge " + this._voiceBridge);
 
     sdpOffer = h264_sdp.transform(sdp);
     sdpOffer = sdp;
-
     this._viewersCandidatesQueue[callerName] = [];
 
-
     try {
       const retSource = await this.mcs.subscribe(this.userId, sharedScreens[voiceBridge], 'WebRtcEndpoint', {descriptor: sdpOffer});
 
       this._viewersEndpoint[callerName] = retSource.sessionId;
       sdpAnswer = retSource.answer;
       this.flushCandidatesQueue(this._viewersEndpoint[callerName], this._viewersCandidatesQueue[callerName]);
+
       this.mcs.on('MediaEvent' + this._viewersEndpoint[callerName], (event) => {
         this.mediaStateWebRtc(event, connectionId);
       });
@@ -237,17 +235,16 @@ module.exports = class Screenshare {
         response: "accepted"
       }), C.FROM_SCREENSHARE);
 
-      console.log(" Sent sdp message to client with callerName:" + callerName);
-      console.log("  [screenshare] Subscribe returned => " + this._viewersEndpoint[callerName]);
+      Logger.info("[screenshare] MCS subscribe returned for user", this.userId, "returned", this._viewersEndpoint[callerName]);
     }
     catch (err) {
-      console.log("  [screenshare] MCS publish returned error => " + err);
+      Logger.error("[screenshare] MCS publish returned error =>", err);
       return _callback(err);
     }
   }
 
   async _stop() {
-    console.log(' [stop] Releasing endpoints for ' + this.userId);
+    Logger.info('[screnshare] Stopping and releasing endpoints for MCS user', this.userId);
 
     this._stopScreensharing();
 
@@ -261,7 +258,7 @@ module.exports = class Screenshare {
         return;
       }
       catch (err) {
-        console.log(err);
+        Logger.error('[screenshare] MCS returned an error when trying to leave =>', err);
         return;
       }
     }
@@ -288,7 +285,7 @@ module.exports = class Screenshare {
   }
 
   _onRtpMediaFlowing() {
-    console.log("  [screenshare] Media FLOWING for meeting => " + this._meetingId);
+    Logger.info("[screenshare] RTP Media FLOWING for meeting", this._meetingId);
     let strm = Messaging.generateStartTranscoderRequestMessage(this._meetingId, this._meetingId, this._rtpParams);
 
     // Interoperability: capturing 1.1 start_transcoder_reply messages
@@ -310,7 +307,7 @@ module.exports = class Screenshare {
   };
 
   _stopRtmpBroadcast (meetingId) {
-    console.log("  [screenshare] _stopRtmpBroadcast for meeting => " + meetingId);
+    Logger.info("[screenshare] _stopRtmpBroadcast for meeting", meetingId);
     if(this._meetingId === meetingId) {
       // TODO correctly assemble this timestamp
       let timestamp = now.format('hhmmss');
@@ -321,7 +318,7 @@ module.exports = class Screenshare {
   }
 
   _startRtmpBroadcast (meetingId, output) {
-    console.log("  [screenshare] _startRtmpBroadcast for meeting => " + meetingId);
+    Logger.info("[screenshare] _startRtmpBroadcast for meeting", + meetingId);
     if(this._meetingId === meetingId) {
       // TODO correctly assemble this timestamp
       let timestamp = now.format('hhmmss');
@@ -334,12 +331,12 @@ module.exports = class Screenshare {
   }
 
   _onRtpMediaNotFlowing() {
-    console.log("  [screenshare] TODO RTP NOT_FLOWING");
+    Logger.warn("[screenshare] TODO RTP NOT_FLOWING");
   }
 
   async stopViewer(id) {
     let viewer = this._viewersEndpoint[id];
-    console.log(' [stop] Releasing endpoints for ' + viewer);
+    Logger.info('[screenshare] Releasing endpoints for', viewer);
 
     if (viewer) {
       try {
@@ -349,7 +346,7 @@ module.exports = class Screenshare {
         return;
       }
       catch (err) {
-        console.log(err);
+        Logger.error('[screenshare] MCS returned error when trying to unsubscribe', err);
         return;
       }
     }
diff --git a/labs/bbb-webrtc-sfu/lib/utils/Logger.js b/labs/bbb-webrtc-sfu/lib/utils/Logger.js
new file mode 100644
index 0000000000000000000000000000000000000000..8fc044596794abe65730faf7cbf2458cb4286a0e
--- /dev/null
+++ b/labs/bbb-webrtc-sfu/lib/utils/Logger.js
@@ -0,0 +1,47 @@
+'use strict';
+
+const Winston = require('winston');
+const Logger = new Winston.Logger();
+const config = require('config');
+const path = require('path');
+Winston.transports.DailyRotateFile = require('winston-daily-rotate-file');
+
+const LOG_CONFIG = config.get('log') || {};
+const { level } = LOG_CONFIG;
+let filename = LOG_CONFIG.filename;
+
+Logger.configure({
+  levels: { error: 0, warn: 1, info: 2, verbose: 3, debug: 4 },
+  colors: {
+    error: 'red',
+    warn: 'yellow',
+    info: 'green',
+    verbose: 'cyan',
+    debug: 'magenta',
+  },
+});
+
+Logger.add(Winston.transports.Console, {
+  timestamp:true,
+  prettyPrint: false,
+  humanReadableUnhandledException: true,
+  colorize: true,
+  handleExceptions: false,
+  silent: false,
+  stringify: (obj) => JSON.stringify(obj),
+  level,
+});
+
+
+if (filename) {
+  Logger.add(Winston.transports.DailyRotateFile, {
+    filename,
+    prettyPrint: true,
+    datePattern: '.yyyy-dd-MM',
+    prepend: false,
+    stringify: (obj) => JSON.stringify(obj), // single lines
+    level,
+  });
+}
+
+module.exports = Logger;
diff --git a/labs/bbb-webrtc-sfu/lib/video/VideoManager.js b/labs/bbb-webrtc-sfu/lib/video/VideoManager.js
index 7796972786f18ac247d14f751ab5a85ac235ec05..ef4eadf257ebed94efd14392f4f39c46a09bd8b0 100755
--- a/labs/bbb-webrtc-sfu/lib/video/VideoManager.js
+++ b/labs/bbb-webrtc-sfu/lib/video/VideoManager.js
@@ -9,6 +9,7 @@
 const BigBlueButtonGW = require('../bbb/pubsub/bbb-gw');
 const Video = require('./video');
 const C = require('../bbb/messages/Constants');
+const Logger = require('../utils/Logger');
 
 let sessions = {};
 
@@ -20,71 +21,60 @@ let redisGateway;
 bbbGW.addSubscribeChannel(C.TO_VIDEO).then((gw) => {
   redisGateway = gw;
   redisGateway.on(C.REDIS_MESSAGE, _onMessage);
-  console.log('  [VideoManager] Successfully subscribed to redis channel ' + C.TO_VIDEO);
-
 });
 
-var _onMessage = function (_message) {
+let _onMessage = async function (_message) {
   let message = _message;
   let sessionId = message.connectionId;
   let video;
   let role = message.role? message.role : 'any';
   let cameraId = message.cameraId;
   let shared = false;
-  let iceQueue = {};
+  let iceQueues = {};
+  let iceQueue;
 
-  if (message.role == 'share') {
+  if (!message.cameraId) {
+    console.log("  [VideoManager] Undefined message.cameraId for session ", sessionId);
+    return;
+  }
+
+  if (message.role === 'share') {
     shared = true;
+    cameraId += '-shared';
   }
 
   if (!sessions[sessionId]) {
     sessions[sessionId] = {};
   }
 
-  switch (role) {
-    case 'share':
-      if (message.cameraId && typeof sessions[sessionId][message.cameraId+'-shared'] !== 'undefined' &&  sessions[sessionId][message.cameraId+'-shared']) {
-        video = sessions[sessionId][message.cameraId+'-shared'];
-      }
-      break;
-    case 'viewer':
-      if (message.cameraId && sessions[sessionId][message.cameraId]) {
-        video = sessions[sessionId][message.cameraId];
-      }
-    case 'any':
-      if (message.cameraId && typeof sessions[sessionId][message.cameraId+'-shared'] !== 'undefined' &&  sessions[sessionId][message.cameraId+'-shared']) {
-        video = sessions[sessionId][message.cameraId+'-shared'];
-      }
-      else if (message.cameraId && sessions[sessionId][message.cameraId]) {
-        video = sessions[sessionId][message.cameraId];
-      }
+  if (!iceQueues[sessionId]) {
+      iceQueues[sessionId] = {};
+  }
 
-      break;
+  if (sessions[sessionId][cameraId]) {
+    video = sessions[sessionId][cameraId];
+  }
+
+  if (iceQueues[sessionId][cameraId]) {
+    iceQueue = iceQueues[sessionId][cameraId] ;
   }
 
   switch (message.id) {
     case 'start':
-      console.log('[' + message.id + '] connection ' + sessionId + " message => " + JSON.stringify(message, null, 2));
+      Logger.info('[VideoManager] Received message [' + message.id + '] from connection ' + sessionId);
+      Logger.debug('[VideoManager] Message =>', JSON.stringify(message, null, 2));
 
       video = new Video(bbbGW, message.cameraId, shared, message.connectionId);
 
       // Empty ice queue after starting video
-      if (iceQueue[message.cameraId]) {
+      if (iceQueue) {
         let candidate;
-        while(candidate = iceQueue[message.cameraId].pop()) {
+        while(candidate = iceQueue.pop()) {
           video.onIceCandidate(cand);
         }
       }
 
-      switch (role) {
-        case 'share':
-          sessions[sessionId][message.cameraId+'-shared']= video;
-          break;
-        case 'viewer':
-          sessions[sessionId][message.cameraId] = video;
-          break;
-        default: console.log(" [VideoManager] Unknown role? ", role);
-      }
+      sessions[sessionId][cameraId] = video;
 
       video.start(message.sdpOffer, (error, sdpAnswer) => {
         if (error) {
@@ -111,13 +101,10 @@ var _onMessage = function (_message) {
       break;
 
     case 'stop':
-
-      console.log('[' + message.id + '] connection ' + sessionId + " with message => " + JSON.stringify(message, null, 2));
-
       if (video) {
-        stopVideo(sessionId, role, cameraId);
+        stopVideo(sessionId, role, message.cameraId);
       } else {
-        console.log(" [stop] Why is there no video on STOP?");
+        Logger.warn("[VideoManager] There is no video instance named", cameraId, "to stop");
       }
       break;
 
@@ -126,17 +113,18 @@ var _onMessage = function (_message) {
       if (video) {
         video.onIceCandidate(message.candidate);
       } else {
-        console.log(" [iceCandidate] Queueing ice candidate for later in video " + message.cameraId);
-
-        if (!iceQueue[message.cameraId]) {
-          iceQueue[message.cameraId] = [];
+        Logger.info("[VideoManager] Queueing ice candidate for later in video", cameraId);
+        if (!iceQueue) {
+          iceQueues[sessionId][cameraId] = [];
+          iceQueue = iceQueues[sessionId][cameraId];
         }
-        iceQueue[message.cameraId].push(message.candidate);
+
+        iceQueue.push(message.candidate);
       }
       break;
 
     case 'close':
-      console.log(" [vide] Closing session for sessionId: " + sessionId);
+      Logger.info("[VideoManager] Closing session for sessionId: ", sessionId);
 
       stopSession(sessionId);
 
@@ -168,13 +156,13 @@ let stopSession = async function(sessionId) {
 }
 
 let stopVideo = async function(sessionId, role, cameraId) {
-  console.log('  [VideoManager/x] Stopping session ' + sessionId + " with role " + role + " for camera " + cameraId);
+  Logger.info('[VideoManager/x] Stopping session ' + sessionId + " with role " + role + " for camera " + cameraId);
 
   try {
     if (role === 'share') {
       var sharedVideo = sessions[sessionId][cameraId+'-shared'];
       if (sharedVideo) {
-        console.log('  [VideoManager] Stopping sharer [', sessionId, '][', cameraId,']');
+        Logger.info('[VideoManager] Stopping sharer [', sessionId, '][', cameraId,']');
         await sharedVideo.stop();
         delete sessions[sessionId][cameraId+'-shared'];
       }
@@ -182,19 +170,19 @@ let stopVideo = async function(sessionId, role, cameraId) {
     else if (role === 'viewer') {
       var video = sessions[sessionId][cameraId];
       if (video) {
-        console.log('  [VideoManager] Stopping viewer [', sessionId, '][', cameraId,']');
+        Logger.info('[VideoManager] Stopping viewer [', sessionId, '][', cameraId,']');
         await video.stop();
         delete sessions[sessionId][cameraId];
       }
     }
   }
   catch (err) {
-    console.log("  [VideoManager] Stop error => ", err);
+    Logger.error("[VideoManager] Stop error => ", err);
   }
 }
 
 let stopAll = function() {
-  console.log('  [Video/x] Stopping everything! ');
+  Logger.info('[VideoManager] Stopping everything! ');
 
   if (sessions == null) {
     return;
@@ -210,15 +198,16 @@ let stopAll = function() {
 }
 
 let logAvailableSessions = function() {
-  if(typeof sessions !== 'undefined' && sessions) {
-    console.log("  [VideoManager] Available sessions are =>");
+  if(sessions) {
+    Logger.info("[VideoManager] Available sessions are =>");
     let sessionMainKeys = Object.keys(sessions);
     for (var k in sessions) {
-      if(typeof sessions[k] !== 'undefined' && sessions[k]) {
-        console.log('  [VideoManager] Session[', k,'] => ', Object.keys(sessions[k]));
+      if(sessions[k]) {
+        Logger.info('[VideoManager] Session[', k,'] => ', Object.keys(sessions[k]));
       }
     }
   }
+
 }
 
 process.on('SIGTERM', stopAll);
diff --git a/labs/bbb-webrtc-sfu/lib/video/VideoProcess.js b/labs/bbb-webrtc-sfu/lib/video/VideoProcess.js
index b6add57d4fbd68c5ce2de4cf12a4fd710016be06..1e06fea87527f0fcedd0040df0c4508c9399ab73 100644
--- a/labs/bbb-webrtc-sfu/lib/video/VideoProcess.js
+++ b/labs/bbb-webrtc-sfu/lib/video/VideoProcess.js
@@ -1,9 +1,24 @@
+const Logger = require('../utils/Logger');
+const config = require('config');
+
+if (config.get('acceptSelfSignedCertificate')) {
+  process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;
+}
+
+// This basically starts the video Manager routines which listens the connection
+// manager messages routed to "to-sfu-video"
 const VideoManager = require('./VideoManager');
 
-process.on('uncaughtException', function (error) {
-  console.log(error.stack);
+process.on('uncaughtException', (error) => {
+  Logger.error('[VideoProcess] Uncaught exception ', error.stack);
+});
+
+process.on('disconnect', () => {
+  Logger.info("[VideoProcess] Parent process disconnected!");
 });
 
-process.on('disconnect',function() {
-  console.log("Parent exited!");
+// Added this listener to identify unhandled promises, but we should start making
+// sense of those as we find them
+process.on('unhandledRejection', (reason, p) => {
+  Logger.error('[VideoProcess] Unhandled Rejection at: Promise', p, 'reason:', reason);
 });
diff --git a/labs/bbb-webrtc-sfu/lib/video/video.js b/labs/bbb-webrtc-sfu/lib/video/video.js
index b99077321b18855d86db5ecc5301aa09af7cc744..ec2802a213a52dcb6587e2d2222bb78236b64836 100644
--- a/labs/bbb-webrtc-sfu/lib/video/video.js
+++ b/labs/bbb-webrtc-sfu/lib/video/video.js
@@ -1,16 +1,13 @@
 'use strict';
-// Global stuff
-var sharedWebcams = {};
 
 const kurento = require('kurento-client');
 const config = require('config');
 const kurentoUrl = config.get('kurentoUrl');
 const MCSApi = require('../mcs-core/lib/media/MCSApiStub');
 const C = require('../bbb/messages/Constants');
+const Logger = require('../utils/Logger');
 
-if (config.get('acceptSelfSignedCertificate')) {
-  process.env.NODE_TLS_REJECT_UNAUTHORIZED=0;
-}
+var sharedWebcams = {};
 
 module.exports = class Video {
   constructor(_bbbGW, _id, _shared, _sessionId) {
@@ -23,8 +20,10 @@ module.exports = class Video {
     this.role = this.shared? 'share' : 'view'
     this.webRtcEndpoint = null;
     this.mediaId = null;
+    this.iceQueue = null;
 
     this.candidatesQueue = [];
+    this.notFlowingTimeout = null;
   }
 
   onIceCandidate (_candidate) {
@@ -34,7 +33,7 @@ module.exports = class Video {
         this.mcs.addIceCandidate(this.mediaId, _candidate);
       }
       catch (err)   {
-        console.log(err);
+        Logger.error("[video] ICE candidate could not be added to media controller.", err);
       }
     }
     else {
@@ -51,7 +50,7 @@ module.exports = class Video {
         }
       }
       catch (err) {
-        console.log(err);
+        Logger.error("[video] ICE candidate could not be added to media controller.", err);
       }
     }
   }
@@ -62,8 +61,8 @@ module.exports = class Video {
     switch (event.eventTag) {
 
       case "OnIceCandidate":
-        //console.log("  [video] Sending ICE candidate to user => " + this.id);
         let candidate = msEvent.candidate;
+        Logger.debug("[video] Sending ICE candidate to user", this.id, "with candidate", candidate);
         this.bbbGW.publish(JSON.stringify({
           connectionId: this.sessionId,
           type: 'video',
@@ -79,18 +78,29 @@ module.exports = class Video {
 
       case "MediaFlowOutStateChange":
       case "MediaFlowInStateChange":
-        console.log(' [video] ' + msEvent.type + '[' + msEvent.state + ']' + ' for endpoint ' + this.id);
+        Logger.info('[video] ' + msEvent.type + '[' + msEvent.state + ']' + ' for media session', event.id, "for video", this.id);
 
         if (msEvent.state === 'NOT_FLOWING') {
-          this.bbbGW.publish(JSON.stringify({
-            connectionId: this.sessionId,
-            type: 'video',
-            role: this.role,
-            id : 'playStop',
-            cameraId: this.id,
-          }), C.FROM_VIDEO);
+          Logger.warn("Setting up a timeout for " + this.sessionId + " camera " + this.id);
+          if (!this.notFlowingTimeout) {
+            this.notFlowingTimeout = setTimeout(() => {
+              this.bbbGW.publish(JSON.stringify({
+                connectionId: this.sessionId,
+                type: 'video',
+                role: this.role,
+                id : 'playStop',
+                cameraId: this.id,
+              }), C.FROM_VIDEO);
+            }, config.get('mediaFlowTimeoutDuration'));
+          }
         }
         else if (msEvent.state === 'FLOWING') {
+          if (this.notFlowingTimeout) {
+            Logger.warn("Received a media flow before stopping " + this.sessionId + " camera " + this.id);
+            clearTimeout(this.notFlowingTimeout);
+            this.notFlowingTimeout = null;
+          }
+
           this.bbbGW.publish(JSON.stringify({
             connectionId: this.sessionId,
             type: 'video',
@@ -102,17 +112,17 @@ module.exports = class Video {
 
         break;
 
-      default: console.log("  [video] Unrecognized event");
+      default: Logger.warn("[video] Unrecognized event");
     }
   }
 
   async start (sdpOffer, callback) {
-    console.log("  [video] start");
+    Logger.info("[video] Starting video instance for", this.id);
     let sdpAnswer;
 
     try {
       this.userId = await this.mcs.join(this.meetingId, 'SFU', {});
-      console.log("  [video] Join returned => " + this.userId);
+      Logger.info("[video] MCS join for", this.id, "returned", this.userId);
 
       if (this.shared) {
         const ret = await this.mcs.publish(this.userId, this.meetingId, 'WebRtcEndpoint', {descriptor: sdpOffer});
@@ -123,7 +133,7 @@ module.exports = class Video {
         this.flushCandidatesQueue();
         this.mcs.on('MediaEvent' + this.mediaId, this.mediaState.bind(this));
 
-        console.log("  [video] Publish returned => " + this.mediaId);
+        Logger.info("[video] MCS publish for user", this.userId, "returned", this.mediaId);
 
         return callback(null, sdpAnswer);
       }
@@ -135,25 +145,31 @@ module.exports = class Video {
         this.flushCandidatesQueue();
         this.mcs.on('MediaEvent' + this.mediaId, this.mediaState.bind(this));
 
-        console.log("  [video] Subscribe for user ", this.userId, " returned => " + this.mediaId);
+        Logger.info("[video] MCS subscribe for user", this.userId, "returned", this.mediaId);
 
         return callback(null, sdpAnswer);
       }
     }
     catch (err) {
-      console.log("  [video] MCS returned error => " + err);
+      Logger.error("[video] MCS returned error => " + err);
       return callback(err);
     }
   };
 
   async stop () {
-    console.log(' [stop] Releasing endpoints for user ' + this.userId + ' at room ' + this.meetingId);
+    Logger.info('[video] Releasing endpoints for user', this.userId, 'at room', this.meetingId);
 
     try {
       await this.mcs.leave(this.meetingId, this.userId);
       if (this.shared) {
         sharedWebcams[this.id] = null;
       }
+
+      if (this.notFlowingTimeout) {
+        clearTimeout(this.notFlowingTimeout);
+        this.notFlowingTimeout = null;
+      }
+
       this._candidatesQueue = null;
       Promise.resolve();
     }
diff --git a/labs/bbb-webrtc-sfu/lib/video/websocket.js b/labs/bbb-webrtc-sfu/lib/video/websocket.js
deleted file mode 100644
index c4fe9f6f18b220e8b4c43be58ec75004a6430124..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/video/websocket.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Simple wrapper around the ws library
- *
- */
-
-var ws = require('ws');
-
-ws.prototype.sendMessage = function(json) {
-
-  return this.send(JSON.stringify(json), function(error) {
-    if(error)
-      console.log(' [server] Websocket error "' + error + '" on message "' + json.id + '"');
-  });
-
-};
-
-
-module.exports = ws;
\ No newline at end of file
diff --git a/labs/bbb-webrtc-sfu/lib/websocket.js b/labs/bbb-webrtc-sfu/lib/websocket.js
deleted file mode 100644
index c4fe9f6f18b220e8b4c43be58ec75004a6430124..0000000000000000000000000000000000000000
--- a/labs/bbb-webrtc-sfu/lib/websocket.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Simple wrapper around the ws library
- *
- */
-
-var ws = require('ws');
-
-ws.prototype.sendMessage = function(json) {
-
-  return this.send(JSON.stringify(json), function(error) {
-    if(error)
-      console.log(' [server] Websocket error "' + error + '" on message "' + json.id + '"');
-  });
-
-};
-
-
-module.exports = ws;
\ No newline at end of file
diff --git a/labs/bbb-webrtc-sfu/package-lock.json b/labs/bbb-webrtc-sfu/package-lock.json
index 8fbfe4227510eb9e880d5bf83dc0de9fa24fb80e..c2cab4e85ec27fd894aa519fc30604b52e6da702 100644
--- a/labs/bbb-webrtc-sfu/package-lock.json
+++ b/labs/bbb-webrtc-sfu/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "bbb-webrtc-sfu",
-  "version": "0.0.2",
+  "version": "0.0.3",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -49,6 +49,11 @@
         "nan": "2.7.0"
       }
     },
+    "colors": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
+      "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs="
+    },
     "commander": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/commander/-/commander-2.1.0.tgz",
@@ -63,6 +68,11 @@
         "os-homedir": "1.0.2"
       }
     },
+    "cycle": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz",
+      "integrity": "sha1-IegLK+hYD5i0aPN5QwZisEbDStI="
+    },
     "double-ended-queue": {
       "version": "2.1.0-0",
       "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
@@ -88,6 +98,11 @@
       "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
       "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
     },
+    "eyes": {
+      "version": "0.1.8",
+      "resolved": "https://registry.npmjs.org/eyes/-/eyes-0.1.8.tgz",
+      "integrity": "sha1-Ys8SAjTGg3hdkCNIqADvPgzCC8A="
+    },
     "hoek": {
       "version": "5.0.2",
       "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.2.tgz",
@@ -111,6 +126,11 @@
         "punycode": "2.1.0"
       }
     },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+    },
     "joi": {
       "version": "13.0.2",
       "resolved": "https://registry.npmjs.org/joi/-/joi-13.0.2.tgz",
@@ -205,16 +225,36 @@
       "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
       "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
     },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "requires": {
+        "minimist": "0.0.8"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "0.0.8",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+          "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+        }
+      }
+    },
     "moment": {
-      "version": "2.19.2",
-      "resolved": "https://registry.npmjs.org/moment/-/moment-2.19.2.tgz",
-      "integrity": "sha512-Rf6jiHPEfxp9+dlzxPTmRHbvoFXsh2L/U8hOupUMpnuecHQmI6cF6lUbJl3QqKPko1u6ujO+FxtcajLVfLpAtA=="
+      "version": "2.20.1",
+      "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz",
+      "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg=="
     },
     "nan": {
       "version": "2.7.0",
       "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz",
       "integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY="
     },
+    "nanoid": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-1.0.1.tgz",
+      "integrity": "sha512-BXapDjcA0QjUPLBqcC5EcvwB8LMOY7zXf3UqDGp93R73PoMOfipmRVxpTogAhtqViE/pJzP9bS+jGK31rzkE2w=="
+    },
     "options": {
       "version": "0.0.6",
       "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
@@ -243,6 +283,14 @@
       "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
       "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0="
     },
+    "readable-id": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/readable-id/-/readable-id-1.0.0.tgz",
+      "integrity": "sha512-RXwuv4YQNYByl+PpQVA4PR4H+aGTWOtpRx56LrxJ2Ypxf96u9WaIdKGOCqu7MPBt8iqQkYPQUk4KGbL55n78YQ==",
+      "requires": {
+        "nanoid": "1.0.1"
+      }
+    },
     "redis": {
       "version": "2.8.0",
       "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz",
@@ -278,6 +326,11 @@
       "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
       "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
     },
+    "stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA="
+    },
     "through": {
       "version": "2.3.8",
       "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
@@ -317,11 +370,6 @@
         }
       }
     },
-    "uuid": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
-      "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
-    },
     "websocket-stream": {
       "version": "0.5.1",
       "resolved": "https://registry.npmjs.org/websocket-stream/-/websocket-stream-0.5.1.tgz",
@@ -350,6 +398,34 @@
         }
       }
     },
+    "winston": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/winston/-/winston-2.4.0.tgz",
+      "integrity": "sha1-gIBQuT1SZh7Z+2wms/DIJnCLCu4=",
+      "requires": {
+        "async": "1.0.0",
+        "colors": "1.0.3",
+        "cycle": "1.0.3",
+        "eyes": "0.1.8",
+        "isstream": "0.1.2",
+        "stack-trace": "0.0.10"
+      },
+      "dependencies": {
+        "async": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz",
+          "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k="
+        }
+      }
+    },
+    "winston-daily-rotate-file": {
+      "version": "1.7.2",
+      "resolved": "https://registry.npmjs.org/winston-daily-rotate-file/-/winston-daily-rotate-file-1.7.2.tgz",
+      "integrity": "sha1-ZQK/opeCT9mC2l5WR8dThXjS+aA=",
+      "requires": {
+        "mkdirp": "0.5.1"
+      }
+    },
     "ws": {
       "version": "3.3.2",
       "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.2.tgz",
diff --git a/labs/bbb-webrtc-sfu/package.json b/labs/bbb-webrtc-sfu/package.json
index e34571864c335e92e9c96fee040200379f4140bf..0c380aa82af781c39a673d8359b2350fd78b5206 100644
--- a/labs/bbb-webrtc-sfu/package.json
+++ b/labs/bbb-webrtc-sfu/package.json
@@ -1,6 +1,6 @@
 {
   "name": "bbb-webrtc-sfu",
-  "version": "0.0.2",
+  "version": "0.0.3",
   "private": true,
   "scripts": {
     "start": "node server.js"
@@ -8,13 +8,15 @@
   "dependencies": {
     "joi": "^13.0.2",
     "kurento-client": "git+https://github.com/Kurento/kurento-client-js.git#master",
-    "moment": "^2.19.2",
+    "moment": "^2.19.3",
     "redis": "^2.8.0",
     "sdp-transform": "^2.3.0",
     "readable-id": "^1.0.0",
     "ws": "^3.3.2",
     "config": "^1.26.1",
-    "js-yaml": "^3.8.3"
+    "js-yaml": "^3.8.3",
+    "winston": "^2.4.0",
+    "winston-daily-rotate-file": "^1.7.2"
   },
   "optionalDependencies": {}
 }
diff --git a/labs/bbb-webrtc-sfu/server.js b/labs/bbb-webrtc-sfu/server.js
index 3252a2b96febc93847754de12567273fafc6893f..27c1b10e1c056a162b089c62fc79981f527d848b 100755
--- a/labs/bbb-webrtc-sfu/server.js
+++ b/labs/bbb-webrtc-sfu/server.js
@@ -10,6 +10,7 @@ const HttpServer = require('./lib/connection-manager/HttpServer');
 const server = new HttpServer();
 const WebsocketConnectionManager = require('./lib/connection-manager/WebsocketConnectionManager');
 const cp = require('child_process');
+const Logger = require('./lib/utils/Logger');
 
 let screenshareProc = cp.fork('./lib/screenshare/ScreenshareProcess', {
     // Pass over all of the environment.
@@ -26,16 +27,16 @@ let videoProc = cp.fork('./lib/video/VideoProcess.js', {
 });
 
 let onMessage = function (message) {
-  console.log('event','child message',this.pid,message);
+  Logger.info('event','child message',this.pid,message);
 };
 
 let onError = function(e) {
-  console.log('event','child error',this.pid,e);
+  Logger.error('event','child error',this.pid,e);
 };
 
 let onDisconnect = function(e) {
-  console.log(e);
-  console.log('event','child disconnect',this.pid,'killing...');
+  Logger.info(e);
+  Logger.info('event','child disconnect',this.pid,'killing...');
   this.kill();
 };
 
@@ -47,21 +48,27 @@ videoProc.on('message',onMessage);
 videoProc.on('error',onError);
 videoProc.on('disconnect',onDisconnect);
 
-const CM = new ConnectionManager(screenshareProc, videoProc);
-
-let websocketManager = new WebsocketConnectionManager(server.getServerObject(), '/bbb-webrtc-sfu');
-
 process.on('SIGTERM', process.exit)
 process.on('SIGINT', process.exit)
-process.on('uncaughtException', function (error) {
-  console.log(error.stack);
+
+process.on('uncaughtException', (error) => {
+  Logger.error('[MainProcess] Uncaught exception', error.stack);
   process.exit('1');
 });
 
+// Added this listener to identify unhandled promises, but we should start making
+// sense of those as we find them
+process.on('unhandledRejection', (reason, p) => {
+  Logger.error('[MainProcess] Unhandled Rejection at: Promise', p, 'reason:', reason);
+});
+
+const CM = new ConnectionManager(screenshareProc, videoProc);
+
+let websocketManager = new WebsocketConnectionManager(server.getServerObject(), '/bbb-webrtc-sfu');
 
 CM.setHttpServer(server);
 CM.addAdapter(websocketManager);
 
 CM.listen(() => {
-  console.log(" [SERVER] Server started");
+  Logger.info("[MainProcess] Server started");
 });