Merge https://github.com/miracl/milagro-mfa-js-client
diff --git a/README.md b/README.md
index 3eb634b..9173e12 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,14 @@
 
 The Mobile App is a JavaScript application, much similar to the PIN Pad. The Mobile App also carries out the operations needed to register and authenticate an end-user, but the user is authenticated to a browser session, rather than to a session on the mobile device.
 
+##Building automatically the PIN Pad
+You can run the following script to install all dependencies for you and build both the PIN PAD and Mobile App
+```
+    > ./build.sh
+```
+It is building with default Milagro theme.
+The built apps should be placed in `<work-dir>/build/out/browser` and `<work-dir>/build/out/mobile`.
+
 ##Building the PIN Pad
 
 1. NOTE: You might have to update your package distribution system. For Ubuntu you would need to do: `sudo apt-get update`
diff --git a/browser/bower.json b/browser/bower.json
index 2d4f014..80e55f4 100644
--- a/browser/bower.json
+++ b/browser/bower.json
@@ -7,7 +7,7 @@
   ],

   "dependencies": {

     "milagro-crypto": "https://github.com/miracl/milagro-crypto.git#1.0.0",

-    "milagro-mfa-js-lib": "https://github.com/miracl/milagro-mfa-js-lib.git#1.0.0",

+    "milagro-mfa-js-lib": "https://github.com/miracl/milagro-mfa-js-lib.git#1.1.0",

     "qrcodejs": "0.1.0",

     "handlebars": "~3.0.3"

   },

diff --git a/browser/js/mpin.js b/browser/js/mpin.js
index 52079bc..2892fb4 100644
--- a/browser/js/mpin.js
+++ b/browser/js/mpin.js
@@ -21,10 +21,9 @@
 
 (function () {
   "use strict";
-  var lang = {}, hlp = {}, loader, MPIN_URL_BASE, IMAGES_PATH, CSS_FILENAME, TEMPLATE_NAME;
+  var lang = {}, hlp = {}, loader, MPIN_URL_BASE, IMAGES_PATH, CSS_FILENAME;
   MPIN_URL_BASE = "%URL_BASE%";
-  TEMPLATE_NAME = "%TEMPLATE_NAME%";
-  IMAGES_PATH = MPIN_URL_BASE + "/images/" + TEMPLATE_NAME + "/";
+  IMAGES_PATH = MPIN_URL_BASE + "/images/";
 
   CSS_FILENAME = "main.css";
 
@@ -74,7 +73,8 @@
       }
 
       self.mpinLib = new mpinjs({
-        server: mpinServer
+        server: mpinServer,
+        authProtocols: options.authProtocols || ""
       });
 
       domID = options.targetElement;
@@ -439,7 +439,6 @@
     this.mpinLib.cancelMobileAuth();
   };
 
-  //	Access NUMBER
   mpin.prototype.renderMobile = function () {
     var callbacks = {}, self = this;
 
@@ -454,6 +453,43 @@
       self.clrInterval.call(self);
       self.renderHome.call(self, evt);
     };
+
+    callbacks.mpin_action_setup = function () {
+      self.clrInterval.call(self);
+      if (self.opts.mobileConfigURL) {
+        self.renderMobileConfig.call(self);
+      } else {
+        self.renderMobileSetup.call(self);
+      }
+    };
+
+    callbacks.mpin_desktop = function () {
+      self.clrInterval.call(self);
+      self.renderDesktop.call(self);
+    };
+
+    this.render("mobile-qr", callbacks, {mobileOnly: !this.opts.mobileOnly});
+
+    setTimeout(function () {
+      self.getQrParams.call(self);
+    }, 0);
+  };
+
+  //	Access NUMBER
+  mpin.prototype.renderMobileAN = function () {
+    var callbacks = {}, self = this;
+
+    this.clrInterval();
+
+    if (this.opts.requestOTP === "1") {
+      this.renderMobileSetup();
+      return;
+    }
+
+    callbacks.mpin_home = function (evt) {
+      self.clrInterval.call(self);
+      self.renderHome.call(self, evt);
+    };
     callbacks.mpin_action_setup = function () {
       self.clrInterval.call(self);
       if (self.opts.mobileConfigURL) {
@@ -488,6 +524,8 @@
     }, 0);
   };
 
+
+
   mpin.prototype.renderHelp = function (tmplName, callbacks, tmplData) {
     var k, self = this;
     tmplData = tmplData || {};
@@ -603,7 +641,7 @@
     //set Temporary params if enter email and then press tooltip without submit request...
     function setTemp () {
       self.tmp || (self.tmp = {});
-      self.tmp.setupEmail = document.getElementById("emailInput").value;
+      self.tmp.setupEmail = document.getElementById("emailInput").value.toLowerCase();
       if (self.opts.setDeviceName) {
         self.tmp.setupDeviceName = document.getElementById("deviceInput").value;
       }
@@ -671,7 +709,7 @@
     //set Temporary params if enter email and then press tooltip without submit request...
     function setTemp () {
       self.tmp || (self.tmp = {});
-      self.tmp.setup2Email = document.getElementById("emailInput").value;
+      self.tmp.setup2Email = document.getElementById("emailInput").value.toLowerCase();
       if (self.opts.setDeviceName) {
         self.tmp.setup2DeviceName = document.getElementById("deviceInput").value;
       }
@@ -984,6 +1022,27 @@
     this.clrInterval.call(this);
   };
 
+  mpin.prototype.getQrParams = function () {
+    var self = this;
+    this.mpinLib.getQrUrl("", function (err, data) {
+      var qrElem, expireAfter;
+      if (err) {
+        self.error(4010);
+      }
+
+      var qrElem = document.getElementById("mp_qrcode");
+      new QRCode(qrElem, {
+        text: data.qrUrl,
+        width: 158,
+        height: 158
+      });
+
+      expireAfter = data.ttlSeconds;
+
+      self._getAccess.call(self, expireAfter);
+    });
+  };
+
   mpin.prototype.getAccessNumber = function () {
     var self = this, drawTimer, timerEl, timer2d, totalSec, timerExpire, expire;
 
@@ -1057,9 +1116,30 @@
       }
 
       self.successLogin.call(self, accData);
+    }, function (accData) {
+        return self.updateStatus(accData);;
     });
   };
 
+  mpin.prototype.updateStatus = function (statusData) {
+    var statusText;
+
+    switch (statusData.status) {
+      case "wid":
+        statusText = "<span>Code scanned.<br/>Waiting for authentication...</span>";
+        break;
+      case "user":
+        statusText = "<span>Authenticating user:<br/>" + statusData.userId + "</span>";
+        break;
+      case "expired":
+        statusText = "<span>Authentication expired!</span>";
+        break;
+    }
+
+    document.getElementById("mp_qrcode").removeAttribute('title');
+    statusText && (document.getElementById("mp_qrcode").innerHTML = statusText);
+  };
+
   mpin.prototype.renderMobileSetup = function () {
     var callbacks = {}, self = this, qrElem, mobileBtnText = "";
     callbacks.mpin_home = function () {
@@ -1335,7 +1415,7 @@
   };
   mpin.prototype.renderSetupDone = function () {
     var callbacks = {}, self = this, userId;
-    userId =  this.readIdentity() || this.identity;
+    userId = this.readIdentity() || this.identity;
     callbacks.mpin_home = function () {
       self.renderHome.call(self);
     };
@@ -1712,7 +1792,7 @@
   mpin.prototype.actionSetupHome = function (uId) {
     var self = this, _email, _deviceName, _deviceNameInput, removeError, elems = [];
 
-    _email = (uId) ? uId : document.getElementById("emailInput").value;
+    _email = (uId) ? uId : document.getElementById("emailInput").value.toLowerCase();
     _deviceNameInput = (document.getElementById("deviceInput")) ? document.getElementById("deviceInput").value.trim() : "";
 
     if ((_email.length === 0 || !this.opts.identityCheckRegex.test(_email)) && !(this.opts.prerollid)) {
@@ -2302,6 +2382,7 @@
     "signin_btn_mobile1": "Sign in with Smartphone",
     "signin_mobile_btn_text": "Sign in with your Smartphone",
     "signin_mobile_header": "Sign in with your phone",
+    "scan_mobile_header": "Scan with the M-Pin app",
     "signin_mobile_btn_text2": "Sign in with phone",
     "signin_button_mobile": "Sign in with Phone",
     "signin_btn_mobile2": "(This is a PUBLIC device I DO NOT trust)",
diff --git a/browser/themes/milagro/sass/_template.scss b/browser/themes/milagro/sass/_template.scss
index e956bb0..d9dfd9d 100644
--- a/browser/themes/milagro/sass/_template.scss
+++ b/browser/themes/milagro/sass/_template.scss
@@ -367,6 +367,13 @@
 @mixin buttons-box() {
 	padding: 5% 5%;
 	z-index: 99;
+	
+	.qrCodeArea {
+		width: 160px;
+		height: 160px;
+		display: block;
+		margin: 0 auto 20px;
+	}
 }
 
 @mixin mpin-input-field () {
diff --git a/browser/themes/milagro/views/mobile-qr.handlebars b/browser/themes/milagro/views/mobile-qr.handlebars
new file mode 100644
index 0000000..8109e1d
--- /dev/null
+++ b/browser/themes/milagro/views/mobile-qr.handlebars
@@ -0,0 +1,33 @@
+<div class="mpinHeader mpMobileColor">
+    <div class="mpinLogo"></div>
+	<div class="mpinHome mpPointer" id="mpin_home"></div>
+</div>
+
+<div class="mpinHeaderBig mpPaddTop10 mpPaddBot10 mpMobColor">
+	{{txt "scan_mobile_header"}}
+</div>
+
+<div class="mpinMain mpNoHeight">
+	<div class="mpinBtnBox mpNoPadding">
+		
+		<span id="mp_qrcode" class="qrCodeArea">
+		</span>
+		
+		<div class="mpinButton mpinMobileBtn mpinBtnClick" id="mpin_action_setup">
+			{{txt "mobile_button_setup"}}
+		</div>
+		
+		{{#if data.mobileOnly }}
+			<div class="mpinButton mpinButtonDark mpinBtnClick" id="mpin_desktop">
+				{{txt "mobile_button_signin2"}}
+			</div>
+		{{/if}}
+		
+	</div>
+</div>
+
+
+<div class="mpinFooter mpMobileFooter">
+	<div class="mpinPowered"></div>
+	<div class="mpinHelpHub"></div>
+</div>
\ No newline at end of file
diff --git a/build.sh b/build.sh
new file mode 100755
index 0000000..e6d99e6
--- /dev/null
+++ b/build.sh
@@ -0,0 +1,47 @@
+#!/usr/bin/env bash
+
+BASE_DIR=$(pwd)
+
+function install_needed_tools {
+    # update package manager cache
+    sudo apt-get update
+
+    # install node package manager npm
+    sudo apt-get install npm curl git
+
+    sudo npm config set prefix /usr/local
+
+    sudo npm install -g n
+    sudo n 0.10.33
+
+    # Install grunt
+    sudo npm install -g grunt-cli
+
+    # Install handlebars
+    sudo npm install -g handlebars@3.0.1
+
+    # install bower
+    sudo npm install -g bower
+}
+
+function build_mpin {
+    APP_TYPE=$1
+    cd "$BASE_DIR/$APP_TYPE"
+
+    # Install required modules for Node
+    sudo npm install
+
+    # Create settings.json
+    cp settings.json_build settings.json
+
+    # Build the app
+    grunt build
+}
+
+install_needed_tools
+
+# Build browser mpin
+build_mpin browser
+
+# Build mobile mpin
+build_mpin mobile
diff --git a/mobile/js/main.js b/mobile/js/main.js
index 488ec78..970122c 100644
--- a/mobile/js/main.js
+++ b/mobile/js/main.js
@@ -1682,7 +1682,7 @@
 
         var _email, _deviceName, _deviceNameInput, _reqData = {}, self = this, elems = [], removeError;
 
-        _email = (uId) ? uId : document.getElementById("emailInput").value;
+        _email = (uId) ? uId : document.getElementById("emailInput").value.toLowerCase();
 
         if (_email.length === 0 || !this.opts.emailCheckRegex.test(_email)) {
             document.getElementById("emailInput").focus();