[CORD-2338] Single command to run E2E tests

Change-Id: Id8db22b2b496ca16d20d2c4d0739d9b9042540db
diff --git a/Jenkinsfile b/Jenkinsfile
index a3bb485..44fabb1 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -10,59 +10,34 @@
 
 timeout (time: 240) {
     node ("${targetVM}") {
-       stage 'Checkout cord repo'
-       checkout changelog: false, poll: false, scm: [$class: 'RepoScm', currentBranch: true, manifestBranch: params.branch, manifestRepositoryUrl: 'https://gerrit.opencord.org/manifest', quiet: true]
+      stage 'Checkout cord repo'
+      checkout changelog: false, poll: false, scm: [$class: 'RepoScm', currentBranch: true, manifestBranch: params.branch, manifestRepositoryUrl: 'https://gerrit.opencord.org/manifest', quiet: true]
 
-       dir('orchestration/xos-gui') {
-            try {
+      dir('build') {
+        stage 'Build Mock R-CORD Config'
+        sh 'make PODCONFIG=rcord-local.yml config'
+        sh 'make build'
+      }
+      dir('orchestration/xos-gui') {
+        try {
 
-                stage 'Install Node Modules'
-                sh 'npm install'
+            stage 'Install npm packages'
+            sh 'npm install'
 
-                stage 'Check Code Style'
-                sh 'npm run lint'
-
-                stage 'Run Unit Tests'
-                sh 'npm test'
-
-                // stage 'Build GUI docker container'
-                // sh 'docker pull nginx'
-                // sh 'docker tag nginx nginx:candidate'
-                // sh 'docker build --no-cache -t xosproject/xos-gui .'
-                // sh 'docker run -p 4000:4000 --net=host --name xos-gui -d xosproject/xos-gui'
-            } catch (err) {
-                currentBuild.result = 'FAILURE'
-                step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: 'teo@onlab.us', sendToIndividuals: true])
-            }
-       }
-       dir('build/platform-install') {
-            stage 'Build Mock R-CORD Config'
-            sh 'ansible-playbook -i inventory/mock-rcord deploy-xos-playbook.yml'
-       }
-       dir('orchestration/xos-gui') {
-            try {
-                stage 'Run E2E Tests'
-                sh 'UI_URL=127.0.0.1:4000/xos/# protractor conf/protractor.conf.js'
-                currentBuild.result = 'SUCCESS'
-            } catch (err) {
-                currentBuild.result = 'FAILURE'
-                step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: 'teo@onlab.us', sendToIndividuals: true])
-            } finally {
-               stage 'Cleanup'
-               dir('build/platform-install') {
-                    sh 'ansible-playbook -i inventory/mock-rcord teardown-playbook.yml'
-                    sh """
-                    docker rmi -f xosproject/xos-synchronizer-base:candidate || true
-                    docker rmi -f xosproject/xos-client:candidate || true
-                    docker rmi -f xosproject/xos-corebuilder:candidate || true
-                    docker rmi -f xosproject/xos-ui:candidate || true
-                    docker rmi -f xosproject/xos:candidate || true
-                    docker rmi -f xosproject/gui-extension-sample:candidate || true
-                    docker rmi -f xosproject/chameleon:candidate || true
-                    """
-                    echo "RESULT: ${currentBuild.result}"
-               }
-            }
-       }
+            stage 'Run E2E Tests'
+            sh 'UI_URL=127.0.0.1/xos/# npm run test:e2e'
+            currentBuild.result = 'SUCCESS'
+        } catch (err) {
+            currentBuild.result = 'FAILURE'
+            step([$class: 'Mailer', notifyEveryUnstableBuild: true, recipients: 'teo@onlab.us', sendToIndividuals: true])
+        } finally {
+           stage 'Cleanup'
+           dir('build') {
+                sh 'make clean-local'
+                sh 'make clean-genconfig'
+                echo "RESULT: ${currentBuild.result}"
+           }
+        }
+      }
     }
 }
\ No newline at end of file
diff --git a/conf/protractor.conf.jenkins.js b/conf/protractor.conf.jenkins.js
index a0dd938..b3ea2cc 100644
--- a/conf/protractor.conf.jenkins.js
+++ b/conf/protractor.conf.jenkins.js
@@ -15,16 +15,29 @@
  * limitations under the License.
  */
 
+const SpecReporter = require('jasmine-spec-reporter').SpecReporter;
 
 exports.config = {
-  seleniumServerJar: '/home/teone/selenium/selenium-server-standalone-2.44.0.jar',
+  seleniumAddress: 'http://localhost:4444/wd/hub',
   capabilities: {
-    'browserName': 'firefox'
+    browserName: 'firefox',
+    'moz:firefoxOptions': {
+       args: [ "--headless" ]
+     }
   },
   specs: [
     '../e2e/**/*.spec.js'
   ],
+  onPrepare: function () {
+    jasmine.getEnv().addReporter(new SpecReporter({
+      spec: {
+        displayStacktrace: true
+      }
+    }));
+  },
   jasmineNodeOpts: {
-    showColors: true
+    print: function() {},
+    showColors: true,
+    allScriptsTimeout: 40000
   }
 };
\ No newline at end of file
diff --git a/conf/protractor.conf.js b/conf/protractor.conf.js
index b3e9fac..feaf440 100644
--- a/conf/protractor.conf.js
+++ b/conf/protractor.conf.js
@@ -26,6 +26,9 @@
     keyboard: '../e2e/keyboard-shortcuts/*.spec.js',
     crud: '../e2e/crud/*.spec.js'
   },
+  capabilities: {
+    'browserName': 'chrome'
+  },
   onPrepare: function () {
     jasmine.getEnv().addReporter(new SpecReporter({
       spec: {
@@ -36,7 +39,6 @@
   jasmineNodeOpts: {
     print: function() {},
     showColors: true, // Use colors in the command line report.
-    defaultTimeoutInterval: (parseInt(process.env.TIMEOUT, 10) + 1000) || 30 * 1000
   },
   allScriptsTimeout: parseInt(process.env.TIMEOUT, 10) || 10 * 1000
 };
\ No newline at end of file
diff --git a/conf/proxy.js b/conf/proxy.js
index 8eb4fee..ad94635 100644
--- a/conf/proxy.js
+++ b/conf/proxy.js
@@ -18,9 +18,7 @@
 
 const httpProxy = require('http-proxy');
 
-const target = process.env.PROXY || '127.0.0.1:8080';
-
-console.info(`Proxying request to: ${target}`);
+const target = process.env.PROXY || '127.0.0.1:9101';
 
 const proxy = httpProxy.createProxyServer({
   target: `http://${target}`,
diff --git a/docs/developer/tests.md b/docs/developer/tests.md
index 04af0fa..938ccf7 100644
--- a/docs/developer/tests.md
+++ b/docs/developer/tests.md
@@ -27,36 +27,20 @@
 
 These tests can be found in the `e2e` folder.
 
-> NOTE: Require protractor to be installed as a global module.
-
-### Setup
-
-```shell
-webdriver-manager update
-webdriver-manager start
-```
-
-#### Run the tests
+### Run the tests
 
 > NOTE: These tests are designed to work with the Mock R-CORD config
 
-```shell
-protractor conf/protractor.conf.js
+```bash
+npm run test:e2e
 ```
-
+ 
 Other paramenters you can pass are:
 
 | Variable Name | Description                                                  |
 |---------------|--------------------------------------------------------------|
-| UI_URL        | Address of the GUI (deaults to `http://192.168.46.100/spa/#` |
+| UI_URL        | Address of the GUI (deaults to `http://127.0.0.1:4000/xos/#` |
 | UI_PWD        | Password to login (needed only for remote connections)       |
 | TIMEOUT       | Time allowed for each test                                   |
-
-### Test suites
-
-If you need to run test for only a particural suite you can use:
-
-`protractor conf/protractor.conf.js --suite login`
-
-Suites are defined in `cong/protractor.conf.js`
-
+| PT_ARGS		| Extra arguments for Protractor, eg: "--suite dashboard" (Suites are defined in `conf/protractor.conf.js`)     |
+| PT_CONF       | The path of the config file (eg: "./conf/protractor.conf.js")          
diff --git a/e2e/crud/crud.po.js b/e2e/crud/crud.po.js
index 6372fc5..78589d4 100644
--- a/e2e/crud/crud.po.js
+++ b/e2e/crud/crud.po.js
@@ -19,19 +19,21 @@
 module.exports = new function(){
 
   // list view
-  this.tableRows = element.all(by.repeater('item in vm.data'));
-  this.tableColumn = element(by.repeater('item in vm.data').row(0))
-                      .all(by.repeater('col in vm.columns'));
+  this.tableRows = element.all(by.css('tbody > tr'));
+  this.tableColumn = element(by.css('tbody > tr:first-child'))
+                      .all(by.css('td'));
 
-  this.actionsColumn = element(by.repeater('item in vm.data').row(0))
+  this.actionsColumn = element(by.css('tbody > tr:first-child'))
     .element(by.css('td:last-child'));
 
-  this.deleteBtn = this.actionsColumn.all(by.tagName('a'));
+  this.deleteBtn = this.actionsColumn.all(by.css('a[title="delete"'));
+  this.detailBtn = this.actionsColumn.all(by.css('a[title="details"'));
 
   this.addBtn = element(by.linkText('Add'));
 
   // detail page
   this.formInputs = element.all(by.repeater('field in vm.config.inputs'));
+  this.nameInput = element.all(by.css('xos-form input')).first()
   this.formBtn = element(by.buttonText('Save'));
 
   this.nameField = element(by.css('[name="name"]'));
diff --git a/e2e/crud/crud.spec.js b/e2e/crud/crud.spec.js
index 0137990..4eecc62 100644
--- a/e2e/crud/crud.spec.js
+++ b/e2e/crud/crud.spec.js
@@ -19,10 +19,34 @@
 const user = require('../test_helpers/user');
 const page = require('./crud.po');
 const config = require('../test_helpers/config');
+const backend = require('../test_helpers/backend');
+
+let testNode;
 
 describe('XOS CRUD Page', function() {
 
   beforeEach((done) => {
+    const nodesUrl = `/xosapi/v1/core/nodes`;
+
+    const _testNode = {
+      name: 'test-p',
+      site_deployment_id: 1
+    }
+
+    backend.deleteAllModels(nodesUrl)
+    .then(() => {
+      return backend.createModel(nodesUrl, _testNode)
+    })
+    .then((node) => {
+      testNode = node;
+      done();
+    })
+    .catch(e => {
+      done(e);
+    })
+  });
+
+  beforeEach((done) => {
     user.login()
       .then(() => {
         done();
@@ -34,9 +58,10 @@
       browser.get(`${config.url}/core/nodes/`);
     });
     it('should have a table', () => {
-      expect(page.tableRows.count()).toBe(2);
-      expect(page.tableColumn.count()).toBe(4);
-      expect(page.deleteBtn.count()).toBe(1); // per row
+      expect(page.tableRows.count()).toBe(1);
+      expect(page.tableColumn.count()).toBe(6);
+      expect(page.deleteBtn.count()).toBe(1);
+      expect(page.detailBtn.count()).toBe(1);
     });
 
     it('should have an add button', () => {
@@ -50,10 +75,11 @@
 
     describe('for an existing model', () => {
       beforeEach(() => {
-        browser.get(`${config.url}/core/nodes/1`);
+        browser.get(`${config.url}/core/nodes/${testNode.id}`);
       });
-      it('should have a form', () => {
-        expect(page.formInputs.count()).toBe(4);
+      it('should load the correct model', () => {
+        expect(page.formInputs.count()).toBe(2);
+        expect(page.nameInput.getAttribute('value')).toBe(testNode.name);
         expect(page.formBtn.isPresent()).toBeTruthy();
       });
 
diff --git a/e2e/dashboard/dashboard.po.js b/e2e/dashboard/dashboard.po.js
index 714be20..074a2e8 100644
--- a/e2e/dashboard/dashboard.po.js
+++ b/e2e/dashboard/dashboard.po.js
@@ -18,8 +18,8 @@
 
 module.exports = new function(){
 
-  this.graphTitle = element(by.css('xos-coarse-tenancy-graph h1'));
-  this.graphSvg = element(by.css('xos-coarse-tenancy-graph svg'));
+  this.graphTitle = element(by.css('xos-service-graph h1'));
+  this.graphSvg = element(by.css('xos-service-graph svg'));
 
   this.summaryTitle = element(by.css('xos-dashboard > .row > .col-xs-12 > h2'));
   this.summaryBoxes = element.all(by.css('.panel.panel-filled'));
diff --git a/e2e/keyboard-shortcuts/shortcut.spec.js b/e2e/keyboard-shortcuts/shortcut.spec.js
index ce0f52a..a4cf974 100644
--- a/e2e/keyboard-shortcuts/shortcut.spec.js
+++ b/e2e/keyboard-shortcuts/shortcut.spec.js
@@ -25,7 +25,12 @@
     user.login();
   });
 
-  it('should open the side panel when ? is pressed', () => {
+  it('should open the side panel when / is pressed', () => {
+    page.pressKey('/');
+    expect(page.sidePanel.getAttribute('class')).toMatch('open');
+  });
+
+  xit('should open the side panel when ? is pressed', () => {
     page.pressKey('?');
     expect(page.sidePanel.getAttribute('class')).toMatch('open');
   });
diff --git a/e2e/login/login.spec.js b/e2e/login/login.spec.js
index 56090be..95dbb63 100644
--- a/e2e/login/login.spec.js
+++ b/e2e/login/login.spec.js
@@ -25,6 +25,7 @@
 describe('XOS Login page', function() {
 
   beforeEach(() => {
+    browser.manage().deleteAllCookies();
     browser.get(`${config.url}/login`);
   });
 
diff --git a/e2e/test_helpers/backend.js b/e2e/test_helpers/backend.js
new file mode 100644
index 0000000..5a57b89
--- /dev/null
+++ b/e2e/test_helpers/backend.js
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const request = require('request-promise');
+const config = require('../test_helpers/config');
+const user = require('../test_helpers/user');
+const P = require('bluebird');
+const baseUrl = config.url.replace('/xos/#', '');
+
+const auth = {
+  'auth': {
+    'user': user.username,
+    'pass': user.pwd.replace('\n', ''),
+  }
+};
+
+const _getIds = (list) => {
+	return list.map(i => i.id);
+}
+
+const _parseRes = (res) => JSON.parse(res);
+
+const getModels = P.promisify((url, done) => {
+	request.get(`${ baseUrl + url }`, auth)
+	.then(res => {
+		return done(null, _parseRes(res));
+	})
+	.catch(e => {
+		return done(e);
+	});
+});
+
+const deleteModel = P.promisify((url, id, done) => {
+	request.delete(`${ baseUrl +url }/${id}`, auth)
+	.then(res => {
+		return done(null, res);
+	})
+	.catch(e => {
+		return done(e);
+	});
+});
+
+const deleteAllModels = P.promisify((url, done) => {
+	getModels(url)
+	.then(res => {
+		if (res.items.length === 0) {
+			return done(null);
+		}
+		const ids = _getIds(res.items);
+		const promises = [];
+		ids.forEach(id => {
+			promises.push(deleteModel(url, id));
+		})
+
+		return P.all(promises)
+	})
+	.then(res => {
+		done(null, res);
+	})
+	.catch(e => {
+		return done(e);
+	});
+});
+
+const createModel = P.promisify((url, data, done) => {
+	request({
+		uri: baseUrl + url,
+		method: 'POST',
+		json: data,
+		auth: auth.auth
+	})
+	.then(res => {
+		return done(null, res);
+	})
+	.catch(err => {
+		return done(err);
+	})
+})
+
+// getModels(`/xosapi/v1/core/nodes`).then(console.log);
+
+// createModel(`/xosapi/v1/core/nodes`, {name: 'test-p', site_deployment_id: 1});
+
+module.exports = {
+	getModels: getModels,
+	deleteAllModels: deleteAllModels,
+	createModel: createModel,
+	deleteModel: deleteModel
+}
\ No newline at end of file
diff --git a/e2e/test_helpers/config.js b/e2e/test_helpers/config.js
index eea60b1..d90b3cc 100644
--- a/e2e/test_helpers/config.js
+++ b/e2e/test_helpers/config.js
@@ -16,4 +16,4 @@
  */
 
 
-exports.url = process.env.UI_URL || 'http://192.168.46.100/xos/#';
\ No newline at end of file
+exports.url = process.env.UI_URL || 'http://127.0.0.1:4000/xos/#';
\ No newline at end of file
diff --git a/e2e/test_helpers/user.js b/e2e/test_helpers/user.js
index 9a6f09a..11ac4f8 100644
--- a/e2e/test_helpers/user.js
+++ b/e2e/test_helpers/user.js
@@ -17,6 +17,7 @@
 
 
 const fs = require('fs');
+const path = require('path');
 const config = require('./config');
 const P = require('bluebird');
 
@@ -28,7 +29,7 @@
     return process.env.UI_PWD;
   }
 
-  const pwdFile = fs.readFileSync('../../build/platform-install/credentials/xosadmin@opencord.org', 'utf8');
+  const pwdFile = fs.readFileSync(path.join(__dirname, '../../../../build/platform-install/credentials/xosadmin@opencord.org'), 'utf8');
   return pwdFile;
 };
 
diff --git a/gulp_tasks/misc.js b/gulp_tasks/misc.js
index befe6a0..d5bc9e3 100644
--- a/gulp_tasks/misc.js
+++ b/gulp_tasks/misc.js
@@ -15,14 +15,11 @@
  * limitations under the License.
  */
 
-
 const path = require('path');
 
 const gulp = require('gulp');
 const del = require('del');
 const filter = require('gulp-filter');
-const rename = require('gulp-rename');
-const replace = require('gulp-replace');
 
 const conf = require('../conf/gulp.conf');
 
@@ -43,14 +40,3 @@
     .pipe(fileFilter)
     .pipe(gulp.dest(conf.paths.dist));
 }
-
-function other() {
-  const fileFilter = filter(file => file.stat.isFile());
-
-  return gulp.src([
-    path.join(conf.paths.src, '/**/*'),
-    path.join(`!${conf.paths.src}`, '/**/*.{scss,ts,html}')
-  ])
-    .pipe(fileFilter)
-    .pipe(gulp.dest(conf.paths.dist));
-}
diff --git a/gulp_tasks/protractor.js b/gulp_tasks/protractor.js
new file mode 100644
index 0000000..0d0727b
--- /dev/null
+++ b/gulp_tasks/protractor.js
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+
+ * http://www.apache.org/licenses/LICENSE-2.0
+
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+const gulp = require('gulp');
+const gulpProtractorAngular = require('gulp-angular-protractor');
+
+const args = process.env.PT_ARGS ? process.env.PT_ARGS.split(' ') : [];
+const conf = process.env.PT_CONF || './conf/protractor.conf.jenkins.js'
+
+
+gulp.task('protractor', callback => {
+
+  gulp
+    .src(['./e2e/**/*.js'])
+    .pipe(gulpProtractorAngular({
+      configFile: conf,
+      debug: false,
+      autoStartStopServer: true,
+      verbose: false,
+      args: args
+    }))
+    .on('error', e => {
+      console.log(e);
+    })
+    .on('end', callback);
+});
diff --git a/package-lock.json b/package-lock.json
index b3f17b4..bde451c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3,6 +3,24 @@
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
+    "@types/node": {
+      "version": "6.0.92",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.92.tgz",
+      "integrity": "sha512-awEYSSTn7dauwVCYSx2CJaPTu0Z1Ht2oR1b2AD3CYao6ZRb+opb6EL43fzmD7eMFgMHzTBWSUzlWSD+S8xN0Nw==",
+      "dev": true
+    },
+    "@types/q": {
+      "version": "0.0.32",
+      "resolved": "https://registry.npmjs.org/@types/q/-/q-0.0.32.tgz",
+      "integrity": "sha1-vShOV8hPEyXacCur/IKlMoGQwMU=",
+      "dev": true
+    },
+    "@types/selenium-webdriver": {
+      "version": "2.53.43",
+      "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-2.53.43.tgz",
+      "integrity": "sha512-UBYHWph6P3tutkbXpW6XYg9ZPbTKjw/YC2hGG1/GEvWwTbvezBUv3h+mmUFw79T3RFPnmedpiXdOBbXX+4l0jg==",
+      "dev": true
+    },
     "abbrev": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
@@ -42,6 +60,12 @@
         }
       }
     },
+    "adm-zip": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/adm-zip/-/adm-zip-0.4.4.tgz",
+      "integrity": "sha1-ph7VrmkFw66lizplfSUDMJEFJzY=",
+      "dev": true
+    },
     "after": {
       "version": "0.8.2",
       "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
@@ -743,6 +767,23 @@
         "inherits": "2.0.3"
       }
     },
+    "blocking-proxy": {
+      "version": "0.0.5",
+      "resolved": "https://registry.npmjs.org/blocking-proxy/-/blocking-proxy-0.0.5.tgz",
+      "integrity": "sha1-RikF4Nz76pcPQao3Ij3anAexkSs=",
+      "dev": true,
+      "requires": {
+        "minimist": "1.2.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
     "bluebird": {
       "version": "3.5.1",
       "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
@@ -3278,6 +3319,18 @@
         "time-stamp": "1.1.0"
       }
     },
+    "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",
@@ -4938,6 +4991,521 @@
         "toposort": "0.2.12"
       }
     },
+    "gulp-angular-protractor": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/gulp-angular-protractor/-/gulp-angular-protractor-1.1.1.tgz",
+      "integrity": "sha1-1TYVNN0Rv339ZLVVVMPyOllLO6Y=",
+      "dev": true,
+      "requires": {
+        "event-stream": "https://registry.npmjs.org/event-stream/-/event-stream-3.1.5.tgz",
+        "gulp-util": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.1.tgz",
+        "lodash": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz"
+      },
+      "dependencies": {
+        "event-stream": {
+          "version": "https://registry.npmjs.org/event-stream/-/event-stream-3.1.5.tgz",
+          "integrity": "sha1-bLpaOuAqfkln1lrQTvElAqL/9mw=",
+          "dev": true,
+          "requires": {
+            "duplexer": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+            "from": "http://registry.npmjs.org/from/-/from-0.1.3.tgz",
+            "map-stream": "http://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+            "pause-stream": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+            "split": "https://registry.npmjs.org/split/-/split-0.2.10.tgz",
+            "stream-combiner": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+            "through": "https://registry.npmjs.org/through/-/through-2.3.6.tgz"
+          },
+          "dependencies": {
+            "duplexer": {
+              "version": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+              "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+              "dev": true
+            },
+            "from": {
+              "version": "http://registry.npmjs.org/from/-/from-0.1.3.tgz",
+              "integrity": "sha1-72OsIGKsMqz3hi4NQLRLiW8i87w=",
+              "dev": true
+            },
+            "map-stream": {
+              "version": "http://registry.npmjs.org/map-stream/-/map-stream-0.1.0.tgz",
+              "integrity": "sha1-5WqpTEyAVaFkBKBnS3jyFffI4ZQ=",
+              "dev": true
+            },
+            "pause-stream": {
+              "version": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+              "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
+              "dev": true,
+              "requires": {
+                "through": "https://registry.npmjs.org/through/-/through-2.3.6.tgz"
+              }
+            },
+            "split": {
+              "version": "https://registry.npmjs.org/split/-/split-0.2.10.tgz",
+              "integrity": "sha1-Zwl8YB1pfOE2j0GPBs0gHPBSGlc=",
+              "dev": true,
+              "requires": {
+                "through": "https://registry.npmjs.org/through/-/through-2.3.6.tgz"
+              }
+            },
+            "stream-combiner": {
+              "version": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.0.4.tgz",
+              "integrity": "sha1-TV5DPBhSYd3mI8o/RMWGvPXErRQ=",
+              "dev": true,
+              "requires": {
+                "duplexer": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz"
+              }
+            },
+            "through": {
+              "version": "https://registry.npmjs.org/through/-/through-2.3.6.tgz",
+              "integrity": "sha1-JmgcD1JGcQIdTinffDa84tDs8ug=",
+              "dev": true
+            }
+          }
+        },
+        "gulp-util": {
+          "version": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.1.tgz",
+          "integrity": "sha1-ghSJTQXCu2zH9VRJGKUd34gYDwA=",
+          "dev": true,
+          "requires": {
+            "chalk": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
+            "dateformat": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.11.tgz",
+            "lodash": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz",
+            "lodash._reinterpolate": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz",
+            "lodash.template": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz",
+            "minimist": "https://registry.npmjs.org/minimist/-/minimist-1.1.0.tgz",
+            "multipipe": "http://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
+            "through2": "https://registry.npmjs.org/through2/-/through2-0.6.3.tgz",
+            "vinyl": "http://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz"
+          },
+          "dependencies": {
+            "chalk": {
+              "version": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz",
+              "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=",
+              "dev": true,
+              "requires": {
+                "ansi-styles": "http://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
+                "escape-string-regexp": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz",
+                "has-ansi": "http://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+                "strip-ansi": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+                "supports-color": "http://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz"
+              },
+              "dependencies": {
+                "ansi-styles": {
+                  "version": "http://registry.npmjs.org/ansi-styles/-/ansi-styles-1.1.0.tgz",
+                  "integrity": "sha1-6uy/Zs1waIJ2Cy9GkVgrj1XXp94=",
+                  "dev": true
+                },
+                "escape-string-regexp": {
+                  "version": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.2.tgz",
+                  "integrity": "sha1-Tbwv5nTnGUnK8/smlc5/LcHZqNE=",
+                  "dev": true
+                },
+                "has-ansi": {
+                  "version": "http://registry.npmjs.org/has-ansi/-/has-ansi-0.1.0.tgz",
+                  "integrity": "sha1-hPJlqujA5qiKEtcCKJS3VoiUxi4=",
+                  "dev": true,
+                  "requires": {
+                    "ansi-regex": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
+                  },
+                  "dependencies": {
+                    "ansi-regex": {
+                      "version": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
+                      "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
+                      "dev": true
+                    }
+                  }
+                },
+                "strip-ansi": {
+                  "version": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz",
+                  "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=",
+                  "dev": true,
+                  "requires": {
+                    "ansi-regex": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz"
+                  },
+                  "dependencies": {
+                    "ansi-regex": {
+                      "version": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz",
+                      "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=",
+                      "dev": true
+                    }
+                  }
+                },
+                "supports-color": {
+                  "version": "http://registry.npmjs.org/supports-color/-/supports-color-0.2.0.tgz",
+                  "integrity": "sha1-2S3iaU6z9nMjlz1649i1W0wiGQo=",
+                  "dev": true
+                }
+              }
+            },
+            "dateformat": {
+              "version": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.11.tgz",
+              "integrity": "sha1-8ny+56ASu/uC6gUVYtOXf2CT27E=",
+              "dev": true,
+              "requires": {
+                "get-stdin": "https://registry.npmjs.org/get-stdin/-/get-stdin-3.0.2.tgz",
+                "meow": "https://registry.npmjs.org/meow/-/meow-2.0.0.tgz"
+              },
+              "dependencies": {
+                "get-stdin": {
+                  "version": "https://registry.npmjs.org/get-stdin/-/get-stdin-3.0.2.tgz",
+                  "integrity": "sha1-wc7SS5A5s43thb3xYeV3E7bdSr4=",
+                  "dev": true
+                },
+                "meow": {
+                  "version": "https://registry.npmjs.org/meow/-/meow-2.0.0.tgz",
+                  "integrity": "sha1-j1MKjs9dQNP0tN+Tw0cpAPuiqPE=",
+                  "dev": true,
+                  "requires": {
+                    "camelcase-keys": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz",
+                    "indent-string": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.0.tgz",
+                    "minimist": "https://registry.npmjs.org/minimist/-/minimist-1.1.0.tgz",
+                    "object-assign": "https://registry.npmjs.org/object-assign/-/object-assign-1.0.0.tgz"
+                  },
+                  "dependencies": {
+                    "camelcase-keys": {
+                      "version": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-1.0.0.tgz",
+                      "integrity": "sha1-vRoRv5sxoc5JNJOpMN4aC69K1+w=",
+                      "dev": true,
+                      "requires": {
+                        "camelcase": "https://registry.npmjs.org/camelcase/-/camelcase-1.0.2.tgz",
+                        "map-obj": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.0.tgz"
+                      },
+                      "dependencies": {
+                        "camelcase": {
+                          "version": "https://registry.npmjs.org/camelcase/-/camelcase-1.0.2.tgz",
+                          "integrity": "sha1-eRLqwdSWg2eCyXbC1z6HTcVPLq8=",
+                          "dev": true
+                        },
+                        "map-obj": {
+                          "version": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.0.tgz",
+                          "integrity": "sha1-vL32dWdYdjwYLa954YCUovHIV2Y=",
+                          "dev": true
+                        }
+                      }
+                    },
+                    "indent-string": {
+                      "version": "https://registry.npmjs.org/indent-string/-/indent-string-1.2.0.tgz",
+                      "integrity": "sha1-TXR3l9ZnRb1UxqKJ9c4Z9RdQpLk=",
+                      "dev": true,
+                      "requires": {
+                        "get-stdin": "https://registry.npmjs.org/get-stdin/-/get-stdin-3.0.2.tgz",
+                        "minimist": "https://registry.npmjs.org/minimist/-/minimist-1.1.0.tgz",
+                        "repeating": "https://registry.npmjs.org/repeating/-/repeating-1.1.1.tgz"
+                      },
+                      "dependencies": {
+                        "repeating": {
+                          "version": "https://registry.npmjs.org/repeating/-/repeating-1.1.1.tgz",
+                          "integrity": "sha1-Lf5x+wuveCSejsalN+w91j9IuyI=",
+                          "dev": true,
+                          "requires": {
+                            "is-finite": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.0.tgz",
+                            "meow": "https://registry.npmjs.org/meow/-/meow-2.0.0.tgz"
+                          },
+                          "dependencies": {
+                            "is-finite": {
+                              "version": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.0.tgz",
+                              "integrity": "sha1-Kx260RYs3Kak3InxKy89rhI5MoI=",
+                              "dev": true
+                            }
+                          }
+                        }
+                      }
+                    },
+                    "object-assign": {
+                      "version": "https://registry.npmjs.org/object-assign/-/object-assign-1.0.0.tgz",
+                      "integrity": "sha1-5l3Idm07R7S4MHRlyDEdoDCwcKY=",
+                      "dev": true
+                    }
+                  }
+                }
+              }
+            },
+            "lodash._reinterpolate": {
+              "version": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz",
+              "integrity": "sha1-TxInqlqHEfxjL1sHofRgequLMiI=",
+              "dev": true
+            },
+            "lodash.template": {
+              "version": "https://registry.npmjs.org/lodash.template/-/lodash.template-2.4.1.tgz",
+              "integrity": "sha1-nmEQB+32KRKal0qzxIuBez4c8g0=",
+              "dev": true,
+              "requires": {
+                "lodash._escapestringchar": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz",
+                "lodash._reinterpolate": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz",
+                "lodash.defaults": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz",
+                "lodash.escape": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz",
+                "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
+                "lodash.templatesettings": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz",
+                "lodash.values": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz"
+              },
+              "dependencies": {
+                "lodash._escapestringchar": {
+                  "version": "https://registry.npmjs.org/lodash._escapestringchar/-/lodash._escapestringchar-2.4.1.tgz",
+                  "integrity": "sha1-7P4iYYoq3lC/7qQ5N+Ud9m8O23I=",
+                  "dev": true
+                },
+                "lodash.defaults": {
+                  "version": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-2.4.1.tgz",
+                  "integrity": "sha1-p+iIXwXmiFEUS24SqPNngCa8TFQ=",
+                  "dev": true,
+                  "requires": {
+                    "lodash._objecttypes": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
+                    "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz"
+                  },
+                  "dependencies": {
+                    "lodash._objecttypes": {
+                      "version": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
+                      "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=",
+                      "dev": true
+                    }
+                  }
+                },
+                "lodash.escape": {
+                  "version": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz",
+                  "integrity": "sha1-LOEsXghNsKV92l5dHu659dF1o7Q=",
+                  "dev": true,
+                  "requires": {
+                    "lodash._escapehtmlchar": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz",
+                    "lodash._reunescapedhtml": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz",
+                    "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz"
+                  },
+                  "dependencies": {
+                    "lodash._escapehtmlchar": {
+                      "version": "https://registry.npmjs.org/lodash._escapehtmlchar/-/lodash._escapehtmlchar-2.4.1.tgz",
+                      "integrity": "sha1-32fDu2t+jh6DGrSL+geVuSr+iZ0=",
+                      "dev": true,
+                      "requires": {
+                        "lodash._htmlescapes": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz"
+                      },
+                      "dependencies": {
+                        "lodash._htmlescapes": {
+                          "version": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz",
+                          "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=",
+                          "dev": true
+                        }
+                      }
+                    },
+                    "lodash._reunescapedhtml": {
+                      "version": "https://registry.npmjs.org/lodash._reunescapedhtml/-/lodash._reunescapedhtml-2.4.1.tgz",
+                      "integrity": "sha1-dHxPxAED6zu4oJduVx96JlnpO6c=",
+                      "dev": true,
+                      "requires": {
+                        "lodash._htmlescapes": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz",
+                        "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz"
+                      },
+                      "dependencies": {
+                        "lodash._htmlescapes": {
+                          "version": "https://registry.npmjs.org/lodash._htmlescapes/-/lodash._htmlescapes-2.4.1.tgz",
+                          "integrity": "sha1-MtFL8IRLbeb4tioFG09nwii2JMs=",
+                          "dev": true
+                        }
+                      }
+                    }
+                  }
+                },
+                "lodash.keys": {
+                  "version": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz",
+                  "integrity": "sha1-SN6kbfj/djKxDXBrissmWR4rNyc=",
+                  "dev": true,
+                  "requires": {
+                    "lodash._isnative": "http://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz",
+                    "lodash._shimkeys": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz",
+                    "lodash.isobject": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz"
+                  },
+                  "dependencies": {
+                    "lodash._isnative": {
+                      "version": "http://registry.npmjs.org/lodash._isnative/-/lodash._isnative-2.4.1.tgz",
+                      "integrity": "sha1-PqZAS3hKe+g2x7V1gOHN95sUgyw=",
+                      "dev": true
+                    },
+                    "lodash._shimkeys": {
+                      "version": "https://registry.npmjs.org/lodash._shimkeys/-/lodash._shimkeys-2.4.1.tgz",
+                      "integrity": "sha1-bpzJZm/wgfC1psl4uD4kLmlJ0gM=",
+                      "dev": true,
+                      "requires": {
+                        "lodash._objecttypes": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz"
+                      },
+                      "dependencies": {
+                        "lodash._objecttypes": {
+                          "version": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
+                          "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=",
+                          "dev": true
+                        }
+                      }
+                    },
+                    "lodash.isobject": {
+                      "version": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-2.4.1.tgz",
+                      "integrity": "sha1-Wi5H/mmVPx7mMafrof5k0tBlWPU=",
+                      "dev": true,
+                      "requires": {
+                        "lodash._objecttypes": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz"
+                      },
+                      "dependencies": {
+                        "lodash._objecttypes": {
+                          "version": "https://registry.npmjs.org/lodash._objecttypes/-/lodash._objecttypes-2.4.1.tgz",
+                          "integrity": "sha1-fAt/admKH3ZSn4kLDNsbTf7BHBE=",
+                          "dev": true
+                        }
+                      }
+                    }
+                  }
+                },
+                "lodash.templatesettings": {
+                  "version": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-2.4.1.tgz",
+                  "integrity": "sha1-6nbHXRHrhtTb6JqDiTu4YZKaxpk=",
+                  "dev": true,
+                  "requires": {
+                    "lodash._reinterpolate": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-2.4.1.tgz",
+                    "lodash.escape": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-2.4.1.tgz"
+                  }
+                },
+                "lodash.values": {
+                  "version": "https://registry.npmjs.org/lodash.values/-/lodash.values-2.4.1.tgz",
+                  "integrity": "sha1-q/UUQ2s8twUAFieXjLzzCxKA7qQ=",
+                  "dev": true,
+                  "requires": {
+                    "lodash.keys": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-2.4.1.tgz"
+                  }
+                }
+              }
+            },
+            "minimist": {
+              "version": "https://registry.npmjs.org/minimist/-/minimist-1.1.0.tgz",
+              "integrity": "sha1-zfIl6ImPhAolje1E/JF3Z3Cv3JM=",
+              "dev": true
+            },
+            "multipipe": {
+              "version": "http://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz",
+              "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=",
+              "dev": true,
+              "requires": {
+                "duplexer2": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz"
+              },
+              "dependencies": {
+                "duplexer2": {
+                  "version": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz",
+                  "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=",
+                  "dev": true,
+                  "requires": {
+                    "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz"
+                  },
+                  "dependencies": {
+                    "readable-stream": {
+                      "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.13.tgz",
+                      "integrity": "sha1-9u73ZPUUyJ4rniMUanW6EGdW0j4=",
+                      "dev": true,
+                      "requires": {
+                        "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz",
+                        "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+                        "isarray": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+                        "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+                      },
+                      "dependencies": {
+                        "core-util-is": {
+                          "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz",
+                          "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=",
+                          "dev": true
+                        },
+                        "inherits": {
+                          "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+                          "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+                          "dev": true
+                        },
+                        "isarray": {
+                          "version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+                          "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+                          "dev": true
+                        },
+                        "string_decoder": {
+                          "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+                          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+                          "dev": true
+                        }
+                      }
+                    }
+                  }
+                }
+              }
+            },
+            "vinyl": {
+              "version": "http://registry.npmjs.org/vinyl/-/vinyl-0.4.6.tgz",
+              "integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
+              "dev": true,
+              "requires": {
+                "clone": "http://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
+                "clone-stats": "http://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz"
+              },
+              "dependencies": {
+                "clone": {
+                  "version": "http://registry.npmjs.org/clone/-/clone-0.2.0.tgz",
+                  "integrity": "sha1-xhJqkK1Pctv1rNskPMN3JP6T/B8=",
+                  "dev": true
+                },
+                "clone-stats": {
+                  "version": "http://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz",
+                  "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=",
+                  "dev": true
+                }
+              }
+            }
+          }
+        },
+        "lodash": {
+          "version": "https://registry.npmjs.org/lodash/-/lodash-2.4.1.tgz",
+          "integrity": "sha1-W3cjA03aTSYuWkb7LFjXzCL3FCA=",
+          "dev": true
+        },
+        "through2": {
+          "version": "https://registry.npmjs.org/through2/-/through2-0.6.3.tgz",
+          "integrity": "sha1-eVKS/enyVMKjaLOPnMXRvUZjr7Y=",
+          "dev": true,
+          "requires": {
+            "readable-stream": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz",
+            "xtend": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz"
+          },
+          "dependencies": {
+            "readable-stream": {
+              "version": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.33.tgz",
+              "integrity": "sha1-OjYN1mwbHX/UcFOJhg7aHQ9hEmw=",
+              "dev": true,
+              "requires": {
+                "core-util-is": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz",
+                "inherits": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+                "isarray": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+                "string_decoder": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz"
+              },
+              "dependencies": {
+                "core-util-is": {
+                  "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.1.tgz",
+                  "integrity": "sha1-awcIWu+aPMrG7lO/nT3wwVIaVTg=",
+                  "dev": true
+                },
+                "inherits": {
+                  "version": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
+                  "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+                  "dev": true
+                },
+                "isarray": {
+                  "version": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+                  "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+                  "dev": true
+                },
+                "string_decoder": {
+                  "version": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+                  "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+                  "dev": true
+                }
+              }
+            },
+            "xtend": {
+              "version": "https://registry.npmjs.org/xtend/-/xtend-4.0.0.tgz",
+              "integrity": "sha1-i8Nv+Hrtvnzp6vC8o2sjVKdDhA8=",
+              "dev": true
+            }
+          }
+        }
+      }
+    },
     "gulp-angular-templatecache": {
       "version": "1.9.1",
       "resolved": "https://registry.npmjs.org/gulp-angular-templatecache/-/gulp-angular-templatecache-1.9.1.tgz",
@@ -5393,6 +5961,12 @@
         }
       }
     },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+      "dev": true
+    },
     "har-validator": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-2.0.6.tgz",
@@ -5899,6 +6473,12 @@
       "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw==",
       "dev": true
     },
+    "immediate": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
+      "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=",
+      "dev": true
+    },
     "immutable": {
       "version": "3.8.1",
       "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.1.tgz",
@@ -6484,6 +7064,12 @@
         "colors": "1.1.2"
       }
     },
+    "jasminewd2": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/jasminewd2/-/jasminewd2-2.2.0.tgz",
+      "integrity": "sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4=",
+      "dev": true
+    },
     "jquery": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.1.1.tgz",
@@ -6542,6 +7128,12 @@
       "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
       "dev": true
     },
+    "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",
@@ -6609,6 +7201,65 @@
         }
       }
     },
+    "jszip": {
+      "version": "3.1.5",
+      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.1.5.tgz",
+      "integrity": "sha512-5W8NUaFRFRqTOL7ZDDrx5qWHJyBXy6velVudIzQUSoqAAYqzSh2Z7/m0Rf1QbmQJccegD0r+YZxBjzqoBiEeJQ==",
+      "dev": true,
+      "requires": {
+        "core-js": "2.3.0",
+        "es6-promise": "3.0.2",
+        "lie": "3.1.1",
+        "pako": "1.0.6",
+        "readable-stream": "2.0.6"
+      },
+      "dependencies": {
+        "core-js": {
+          "version": "2.3.0",
+          "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz",
+          "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=",
+          "dev": true
+        },
+        "es6-promise": {
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz",
+          "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=",
+          "dev": true
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+          "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+          "dev": true
+        },
+        "pako": {
+          "version": "1.0.6",
+          "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz",
+          "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==",
+          "dev": true
+        },
+        "readable-stream": {
+          "version": "2.0.6",
+          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz",
+          "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=",
+          "dev": true,
+          "requires": {
+            "core-util-is": "1.0.2",
+            "inherits": "2.0.3",
+            "isarray": "1.0.0",
+            "process-nextick-args": "1.0.7",
+            "string_decoder": "0.10.31",
+            "util-deprecate": "1.0.2"
+          }
+        },
+        "string_decoder": {
+          "version": "0.10.31",
+          "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+          "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+          "dev": true
+        }
+      }
+    },
     "karma": {
       "version": "1.6.0",
       "resolved": "https://registry.npmjs.org/karma/-/karma-1.6.0.tgz",
@@ -7059,6 +7710,15 @@
         "type-check": "0.3.2"
       }
     },
+    "lie": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
+      "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=",
+      "dev": true,
+      "requires": {
+        "immediate": "3.0.6"
+      }
+    },
     "liftoff": {
       "version": "2.3.0",
       "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz",
@@ -7156,6 +7816,40 @@
           "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
           "dev": true
         },
+        "qs": {
+          "version": "6.3.2",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
+          "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+          "dev": true
+        },
+        "request": {
+          "version": "2.78.0",
+          "resolved": "https://registry.npmjs.org/request/-/request-2.78.0.tgz",
+          "integrity": "sha1-4cjew0bhyBkjskrNszfxHeyr6cw=",
+          "dev": true,
+          "requires": {
+            "aws-sign2": "0.6.0",
+            "aws4": "1.6.0",
+            "caseless": "0.11.0",
+            "combined-stream": "1.0.5",
+            "extend": "3.0.1",
+            "forever-agent": "0.6.1",
+            "form-data": "2.1.4",
+            "har-validator": "2.0.6",
+            "hawk": "3.1.3",
+            "http-signature": "1.1.1",
+            "is-typedarray": "1.0.0",
+            "isstream": "0.1.2",
+            "json-stringify-safe": "5.0.1",
+            "mime-types": "2.1.17",
+            "node-uuid": "1.4.8",
+            "oauth-sign": "0.8.2",
+            "qs": "6.3.2",
+            "stringstream": "0.0.5",
+            "tough-cookie": "2.3.3",
+            "tunnel-agent": "0.4.3"
+          }
+        },
         "yargs": {
           "version": "3.29.0",
           "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.29.0.tgz",
@@ -8048,7 +8742,7 @@
         "nopt": "3.0.6",
         "npmlog": "4.1.2",
         "osenv": "0.1.4",
-        "request": "2.78.0",
+        "request": "2.83.0",
         "rimraf": "2.6.2",
         "semver": "5.3.0",
         "tar": "2.2.1",
@@ -8136,7 +8830,7 @@
         "nan": "2.7.0",
         "node-gyp": "3.6.2",
         "npmlog": "4.1.2",
-        "request": "2.78.0",
+        "request": "2.83.0",
         "sass-graph": "2.2.4"
       },
       "dependencies": {
@@ -13320,6 +14014,12 @@
       "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=",
       "dev": true
     },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+      "dev": true
+    },
     "phantomjs-prebuilt": {
       "version": "2.1.14",
       "resolved": "https://registry.npmjs.org/phantomjs-prebuilt/-/phantomjs-prebuilt-2.1.14.tgz",
@@ -14131,6 +14831,82 @@
         "any-promise": "1.3.0"
       }
     },
+    "protractor": {
+      "version": "5.2.0",
+      "resolved": "https://registry.npmjs.org/protractor/-/protractor-5.2.0.tgz",
+      "integrity": "sha1-0/ObGV6F81Oa2djLZWCp0rYyl8Q=",
+      "dev": true,
+      "requires": {
+        "@types/node": "6.0.92",
+        "@types/q": "0.0.32",
+        "@types/selenium-webdriver": "2.53.43",
+        "blocking-proxy": "0.0.5",
+        "chalk": "1.1.3",
+        "glob": "7.1.2",
+        "jasmine": "2.5.3",
+        "jasminewd2": "2.2.0",
+        "optimist": "0.6.1",
+        "q": "1.4.1",
+        "saucelabs": "1.3.0",
+        "selenium-webdriver": "3.6.0",
+        "source-map-support": "0.4.18",
+        "webdriver-js-extender": "1.0.0",
+        "webdriver-manager": "12.0.6"
+      },
+      "dependencies": {
+        "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
+        },
+        "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"
+          }
+        },
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "q": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/q/-/q-1.4.1.tgz",
+          "integrity": "sha1-VXBbzZPF82c1MMLCy8DCs63cKG4=",
+          "dev": true
+        },
+        "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.4",
+            "minimist": "1.2.0",
+            "q": "1.4.1",
+            "request": "2.83.0",
+            "rimraf": "2.6.2",
+            "semver": "5.4.1",
+            "xml2js": "0.4.19"
+          }
+        }
+      }
+    },
     "prr": {
       "version": "0.0.0",
       "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
@@ -14719,37 +15495,172 @@
       }
     },
     "request": {
-      "version": "2.78.0",
-      "resolved": "https://registry.npmjs.org/request/-/request-2.78.0.tgz",
-      "integrity": "sha1-4cjew0bhyBkjskrNszfxHeyr6cw=",
+      "version": "2.83.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz",
+      "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==",
       "dev": true,
       "requires": {
-        "aws-sign2": "0.6.0",
+        "aws-sign2": "0.7.0",
         "aws4": "1.6.0",
-        "caseless": "0.11.0",
+        "caseless": "0.12.0",
         "combined-stream": "1.0.5",
         "extend": "3.0.1",
         "forever-agent": "0.6.1",
-        "form-data": "2.1.4",
-        "har-validator": "2.0.6",
-        "hawk": "3.1.3",
-        "http-signature": "1.1.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",
-        "node-uuid": "1.4.8",
         "oauth-sign": "0.8.2",
-        "qs": "6.3.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.4.3"
+        "tunnel-agent": "0.6.0",
+        "uuid": "3.1.0"
       },
       "dependencies": {
+        "ajv": {
+          "version": "5.5.1",
+          "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz",
+          "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=",
+          "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"
+          }
+        },
+        "assert-plus": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+          "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+          "dev": true
+        },
+        "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=",
+          "dev": true
+        },
+        "boom": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
+          "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+          "dev": true,
+          "requires": {
+            "hoek": "4.2.0"
+          }
+        },
+        "caseless": {
+          "version": "0.12.0",
+          "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+          "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+          "dev": true
+        },
+        "cryptiles": {
+          "version": "3.1.2",
+          "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
+          "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+          "dev": true,
+          "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==",
+              "dev": true,
+              "requires": {
+                "hoek": "4.2.0"
+              }
+            }
+          }
+        },
+        "form-data": {
+          "version": "2.3.1",
+          "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
+          "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
+          "dev": true,
+          "requires": {
+            "asynckit": "0.4.0",
+            "combined-stream": "1.0.5",
+            "mime-types": "2.1.17"
+          }
+        },
+        "har-validator": {
+          "version": "5.0.3",
+          "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
+          "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
+          "dev": true,
+          "requires": {
+            "ajv": "5.5.1",
+            "har-schema": "2.0.0"
+          }
+        },
+        "hawk": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
+          "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+          "dev": true,
+          "requires": {
+            "boom": "4.3.1",
+            "cryptiles": "3.1.2",
+            "hoek": "4.2.0",
+            "sntp": "2.1.0"
+          }
+        },
+        "hoek": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
+          "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==",
+          "dev": true
+        },
+        "http-signature": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+          "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+          "dev": true,
+          "requires": {
+            "assert-plus": "1.0.0",
+            "jsprim": "1.4.1",
+            "sshpk": "1.13.1"
+          }
+        },
         "qs": {
-          "version": "6.3.2",
-          "resolved": "https://registry.npmjs.org/qs/-/qs-6.3.2.tgz",
-          "integrity": "sha1-51vV9uJoEioqDgvaYwslUMFmUCw=",
+          "version": "6.5.1",
+          "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+          "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+          "dev": true
+        },
+        "sntp": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz",
+          "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==",
+          "dev": true,
+          "requires": {
+            "hoek": "4.2.0"
+          }
+        },
+        "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.1.1"
+          }
+        },
+        "uuid": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz",
+          "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==",
           "dev": true
         }
       }
@@ -14763,6 +15674,27 @@
         "throttleit": "1.0.0"
       }
     },
+    "request-promise": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/request-promise/-/request-promise-4.2.2.tgz",
+      "integrity": "sha1-0epG1lSm7k+O5qT+oQGMIpEZBLQ=",
+      "dev": true,
+      "requires": {
+        "bluebird": "3.5.1",
+        "request-promise-core": "1.1.1",
+        "stealthy-require": "1.1.1",
+        "tough-cookie": "2.3.3"
+      }
+    },
+    "request-promise-core": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
+      "integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
+      "dev": true,
+      "requires": {
+        "lodash": "4.17.4"
+      }
+    },
     "require-directory": {
       "version": "2.1.1",
       "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
@@ -15068,6 +16000,15 @@
         "object-assign": "4.1.1"
       }
     },
+    "saucelabs": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/saucelabs/-/saucelabs-1.3.0.tgz",
+      "integrity": "sha1-0kDoAJ33+ocwbsRXimm6O1xCT+4=",
+      "dev": true,
+      "requires": {
+        "https-proxy-agent": "1.0.0"
+      }
+    },
     "sax": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
@@ -15095,6 +16036,29 @@
         }
       }
     },
+    "selenium-webdriver": {
+      "version": "3.6.0",
+      "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-3.6.0.tgz",
+      "integrity": "sha512-WH7Aldse+2P5bbFBO4Gle/nuQOdVwpHMTL6raL3uuBj/vPG07k6uzt3aiahu352ONBr5xXh0hDlM3LhtXPOC4Q==",
+      "dev": true,
+      "requires": {
+        "jszip": "3.1.5",
+        "rimraf": "2.6.2",
+        "tmp": "0.0.30",
+        "xml2js": "0.4.19"
+      },
+      "dependencies": {
+        "tmp": {
+          "version": "0.0.30",
+          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.30.tgz",
+          "integrity": "sha1-ckGdSovn1s51FI/YsyTlk6cRwu0=",
+          "dev": true,
+          "requires": {
+            "os-tmpdir": "1.0.2"
+          }
+        }
+      }
+    },
     "semver": {
       "version": "5.4.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
@@ -15526,6 +16490,15 @@
         "urix": "0.1.0"
       }
     },
+    "source-map-support": {
+      "version": "0.4.18",
+      "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
+      "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
+      "dev": true,
+      "requires": {
+        "source-map": "0.5.7"
+      }
+    },
     "source-map-url": {
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz",
@@ -15616,6 +16589,12 @@
       "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4=",
       "dev": true
     },
+    "stealthy-require": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+      "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+      "dev": true
+    },
     "stream-browserify": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz",
@@ -16901,6 +17880,53 @@
         "defaults": "1.0.3"
       }
     },
+    "webdriver-js-extender": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/webdriver-js-extender/-/webdriver-js-extender-1.0.0.tgz",
+      "integrity": "sha1-gcUzqeM9W/tZe05j4s2yW1R3dRU=",
+      "dev": true,
+      "requires": {
+        "@types/selenium-webdriver": "2.53.43",
+        "selenium-webdriver": "2.53.3"
+      },
+      "dependencies": {
+        "sax": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/sax/-/sax-0.6.1.tgz",
+          "integrity": "sha1-VjsZx8HeiS4Jv8Ty/DDjwn8JUrk=",
+          "dev": true
+        },
+        "selenium-webdriver": {
+          "version": "2.53.3",
+          "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-2.53.3.tgz",
+          "integrity": "sha1-0p/1qVff8aG0ncRXdW5OS/vc4IU=",
+          "dev": true,
+          "requires": {
+            "adm-zip": "0.4.4",
+            "rimraf": "2.6.2",
+            "tmp": "0.0.24",
+            "ws": "1.1.2",
+            "xml2js": "0.4.4"
+          }
+        },
+        "tmp": {
+          "version": "0.0.24",
+          "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.24.tgz",
+          "integrity": "sha1-1qXhmNFKmDXMby18PZ4wJCjIzxI=",
+          "dev": true
+        },
+        "xml2js": {
+          "version": "0.4.4",
+          "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.4.tgz",
+          "integrity": "sha1-MREBAAMAiuGSQOuhdJe1fHKcVV0=",
+          "dev": true,
+          "requires": {
+            "sax": "0.6.1",
+            "xmlbuilder": "8.2.2"
+          }
+        }
+      }
+    },
     "webpack": {
       "version": "2.1.0-beta.20",
       "resolved": "https://registry.npmjs.org/webpack/-/webpack-2.1.0-beta.20.tgz",
@@ -17181,6 +18207,24 @@
       "integrity": "sha1-ZGV4SKIP/F31g6Qq2KJ3tFErvE0=",
       "dev": true
     },
+    "xml2js": {
+      "version": "0.4.19",
+      "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
+      "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
+      "dev": true,
+      "requires": {
+        "sax": "1.2.4",
+        "xmlbuilder": "9.0.4"
+      },
+      "dependencies": {
+        "xmlbuilder": {
+          "version": "9.0.4",
+          "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz",
+          "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8=",
+          "dev": true
+        }
+      }
+    },
     "xmlbuilder": {
       "version": "8.2.2",
       "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz",
diff --git a/package.json b/package.json
index f5adc11..ff4108c 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
     "gitbook-cli": "^2.3.0",
     "gulp": "gulpjs/gulp#4ed9a4a3275559c73a396eff7e1fde3824951ebb",
     "gulp-angular-filesort": "1.1.1",
+    "gulp-angular-protractor": "^1.0.0",
     "gulp-angular-templatecache": "1.9.1",
     "gulp-filter": "4.0.0",
     "gulp-htmlmin": "1.3.0",
@@ -84,7 +85,10 @@
     "node-sass": "3.13.1",
     "phantomjs-prebuilt": "2.1.14",
     "postcss-loader": "0.8.2",
+    "protractor": "^5.1.2",
     "remap-istanbul": "0.9.5",
+    "request": "2.83.0",
+    "request-promise": "^4.2.2",
     "resolve-url-loader": "1.6.1",
     "sass-loader": "3.2.3",
     "style-loader": "0.13.2",
@@ -105,7 +109,7 @@
     "serve:dist:watch": "gulp serve:dist:watch",
     "test": "gulp test",
     "test:auto": "gulp test:auto",
-    "test:e2e": "protractor conf/protractor.conf.js",
+    "test:e2e": "gulp protractor",
     "config": "gulp config",
     "lint": "tslint -c ./tslint.json 'src/**/*.ts'",
     "docs": "gitbook serve"