diff --git a/app/css/styles.css b/app/css/styles.css index 9212705..93bf87a 100644 --- a/app/css/styles.css +++ b/app/css/styles.css @@ -54,7 +54,6 @@ nav { line-height: 2em; background-color: #252831; text-align:center; - /*max-width:900px;*/ } nav h1 { margin: auto; @@ -128,6 +127,16 @@ nav h1 a { display: none; } +.favButton { + background-image: none; + border: none; + font-size: 20pt; +} + +.favSpan[aria-pressed=true] { + color : orange; +} + /* ====================== Restaurant Listing ====================== */ #restaurants-list { background-color: #f3f3f3; @@ -251,6 +260,19 @@ nav h1 a { padding-top: 5px; line-height:1.5em; } +#reviewButton, #submitReview { + background-color: #252831; + border-bottom: 3px solid #eee; + color: #fff; + font-size: 12pt; + margin: 0 auto; + padding: 15px; + text-align: center; + text-decoration: none; + text-transform: uppercase; + display: flex; + justify-content: center; +} #reviews-list { padding:0px; } @@ -284,7 +306,13 @@ nav h1 a { width: 100%; border-radius: 10px 0px 0px 0px; } -#reviewer-comments { +#reviewer-comments, input { padding-left: 15px; padding-right: 15px; } + +label { + padding : 10px; +} + + diff --git a/app/js/dbhelper.js b/app/js/dbhelper.js index 6997965..93052a1 100644 --- a/app/js/dbhelper.js +++ b/app/js/dbhelper.js @@ -1,46 +1,59 @@ +/* + * Constants + */ +// Change this to your server port +const port = 1337; +const dbPromise = idb.open('restaurantReviews', 3, upgradeDb => { + switch(upgradeDb.oldVersion) { + case 0: upgradeDb.createObjectStore("restaurantData", {keyPath: "id"}); + case 1: upgradeDb.createObjectStore("reviewData", {keypath: "id"}).createIndex("restaurant_id", "restaurant_id"); + case 2: upgradeDb.createObjectStore("updateData", {keyPath: "id", autoIncrement: true}); + } +}); + /* * Common database helper functions. */ - class DBHelper { /* - * Database URL. - * Change this to restaurants location on your server. + * Database URLs. */ - static get DATABASE_URL() { - const port = 1337 // Change this to your server port - return `http://localhost:${port}/restaurants`; - } + static get DATABASE_URL() { return `http://localhost:${port}/restaurants`; } + + static get DATABASE_URL_REVIEWS() { return `http://localhost:${port}/reviews`; } /* * Fetch all restaurants. */ static fetchRestaurants(callback) { + console.log(`In fetchRestaurants - callback: ${callback}`); + let requestURL = DBHelper.DATABASE_URL; + // console.log(`Request URL: ${requestURL}`); // Fetch restaurant data from server - fetch(DBHelper.DATABASE_URL) + fetch(requestURL, {method: "GET"}) .then(function(response) { // If response returns ok, return json of restaurant data if (response.ok) return response.json(); // If not returned, there is an error - or offline mode - throw new Error("Fetch repsponse Error"); + // throw new Error("Fetch response Error in fetchRestaurants"); }) .then(function(restaurantData) { callback(null, restaurantData); }) .catch(function(error) { - console.log("In fetchRestaurants catch, error:", error.message); - // Retrieve data from IndexedDB - idb.open('restaurantReviews', 1) - .then(db => { - return db.transaction("restaurantData") - .objectStore("restaurantData") - .getAll(); - }) - .then(restaurantData => { - callback(null,restaurantData); - }); + console.log("In fetchRestaurants catch, error: ", error.message); + // // Retrieve data from IndexedDB + // idb.open('restaurantReviews', 1) + // .then(db => { + // return db.transaction("restaurantData") + // .objectStore("restaurantData") + // .getAll(); + // }) + // .then(restaurantData => { + // callback(null,restaurantData); + // }); }); } @@ -48,6 +61,7 @@ class DBHelper { * Fetch a restaurant by its ID. */ static fetchRestaurantById(id, callback) { + console.log(`In fetchRestaurantsById - id: ${id}, callback: ${callback}`); // fetch all restaurants with proper error handling. DBHelper.fetchRestaurants((error, restaurants) => { if (error) { @@ -63,6 +77,7 @@ class DBHelper { }); } + /* * Fetch restaurants by a cuisine type with proper error handling. */ @@ -180,4 +195,174 @@ class DBHelper { return marker; } + /* + * Fetch reviews by restaurant ID + */ + static fetchReviewsById(id) { + let requestURL = DBHelper.DATABASE_URL_REVIEWS + "/?restaurant_id=" + id; + console.log(`In DBHelper.fetchReviewsById - request: ${requestURL}, id: ${id}`); + fetch(requestURL, {method: "GET"}) + .then(function(response) { + if (response.ok) return response.json(); + + //throw new Error("Fetch response Error in fetchReviewsBy...ID") + }) + .then(function(reviewData) { + // If fetch successful + console.log(reviewData); + //dbPromise.putReviews(reviewData); + return reviewData; + }) + .catch(function(error) { + console.log("In fetchReviewsBy...ID catch, error:", error.message); + // // Error handling + // console.log(`Error in fetch reviews by ID: ${error}, checking idb...`); + // if (idbReviews.length < 1) return null; + // return idbReviews; + }); + } + + /* + * Function to update the Restaurant Data stored in idb store: restaurantData + */ + static updateRestaurantCache(id, update) { + console.log(`In updateRestaurantCache - id: ${id}, update: ${update}`); + let dbPromise = idb.open("restaurantReviews"); + + // Update all restaurant data + dbPromise.then(function(db) { + //let restaurantStore = + db.transaction("restaurantData", "readwrite").objectStore("restaurantData").get("-1") + .then(function(value) { + if(!value) { + console.log("No value, update all, in updateRestaurantCache"); + return; + } + let restaurants = value.data.filter(r => r.id === id); + let updaterestaurant = restaurants[0]; + if (!updaterestaurant) return; + // Update restaurant with new data + Object.keys(update).forEach(key => { updaterestaurant[key] = update[key]; }); + + // Store updated information back in idb + dbPromise.then(function(db) { + let trans = db.transaction("restaurantData", "readwrite").objectStore("restaurantData").put({id:"-1", data: value.data}); + return trans.complete; + }) + }) + }) + + // Update individual restaurant data + dbPromise.then(function(db) { + db.transaction("restaurantData", "readwrite").objectStore("restaurantData").get(id + "") + .then(function(value) { + if(!value) { + console.log("No value, update individual, in updateRestaurantCache"); + return; + } + let updaterestaurant = value.data; + if (!updaterestaurant) return; + // Update restaurant wiht new data + Object.keys(update).forEach(key => { updaterestaurant[key] = update[key] }); + + // Store updated information back in idb + dbPromise.then(function(db) { + let trans = db.transaction("restaurantData", "readwrite").objectStore("restaurantData").put({id: id + "", data: value.data}); + return trans.complete; + }) + }) + }) + } + + /* + * Function to update the Reviews Data stored in idb store: reviewData + */ + static updateReviewCache(id, update) { + console.log(`In updateReviewCache - id: ${id}, update: ${update}`); + let dbPromise = idb.open("restaurantReviews"); + + dbPromise.then(function(db) { + let trans = db.transaction("reviewData", "readwrite").objectStore("reviewData").put({id: Date.now(), "restaurant_id": id, data: update}); + return trans.complete; + }) + } + + /* + * Function to update data being held in idb for updates, store: updateData + * Updated data is put in this store regardless of on/off-line status. + */ + static addToUpdateQueue(url, method, update) { + console.log(`In addToUpdateQueue - url: ${url}, method: ${method}, update: ${update}`); + let dbPromise = idb.open("restaurantReviews"); + dbPromise.then(function(db) { + db.transaction("updateData", "readwrite").objectStore("updateData").put({ data: { url, method, update } }) + }) + .catch(function(error) { + console.log("In addToUpdateQueue catch, error: ", error.message); + }) + // TODO : attempt push of updates + .then(DBHelper.pushUpdates()); + } + + /* + * Function to push updates in the idb update store to the server. + */ + static pushUpdates() { + console.log(`In pushUpdates`); + let dbPromise = idb.open("restaurantReviews"); + dbPromise.then(function(db) { + db.transaction("updateData", "readwrite").objectStore("updateData").openCursor() + .then(function(cursor) { + // No updates, so get outta here! + if(!cursor) return; + let update = cursor.value.data; + + // check for bad records? See in testing + + let params = { body: JSON.stringify(update.body), method: update.method }; + + fetch(update.url, params) + .then(function(response) { + // Can't update right now, so get outta here! + if (!response.ok) return; + }) + .then(function() { + // Response came back ok! + db.transaction("updateData", "readwrite").objectStore("updateData").openCursor() + .then(function(cursor) { + cursor.delete() + // Recursive call to push next update record. Will retrun in next call if empty. + .then(function() { + console.log("Record deleted, calling next..."); + DBHelper.pushUpdates(); + }) + }) + }) + }) + .catch(function(error) { + console.log("In pushUpdates catch, error: ", error.message); + return; + }) + }) + } + + /* + * Function for saving a new review. + */ + static saveReview(id, name, rating, comments, date/*, callback*/) { + let url = `${DBHelper.DATABASE_URL_REVIEWS}`; + let method = "POST"; + let body = { + restaurant_id: id, + name: name, + rating: rating, + comments: comments, + createdAt: date + }; + console.log(`In saveReview - url: ${url}, method: ${method}, body: ${body}`); + DBHelper.updateReviewCache(id, body); + DBHelper.addToUpdateQueue(url, method, body); + //callback(null, null); + } + } diff --git a/app/js/main.js b/app/js/main.js index 40f76c2..e72c34d 100644 --- a/app/js/main.js +++ b/app/js/main.js @@ -1,15 +1,13 @@ -let restaurants, - neighborhoods, - cuisines -var map -var markers = [] +let restaurants, neighborhoods, cuisines; +var map; +var markers = []; /* * Fetch neighborhoods and cuisines as soon as the page is loaded. */ document.addEventListener('DOMContentLoaded', (event) => { - fetchNeighborhoods(); - fetchCuisines(); + fetchNeighborhoods(); + fetchCuisines(); }); /* @@ -81,6 +79,7 @@ window.initMap = () => { scrollwheel: false }); updateRestaurants(); + DBHelper.pushUpdates(); } /* @@ -151,6 +150,18 @@ createRestaurantHTML = (restaurant) => { name.innerHTML = restaurant.name; li.append(name); + // Inserting favorite here + const favButton = document.createElement('button'); + favButton.className = 'favButton'; + let isFavorite = (restaurant.is_favorite && restaurant.is_favorite.toString() === "true") ? true : false; + //console.log(`${restaurant.name}, ${restaurant.is_favorite}`); + favButton.setAttribute('aria-pressed', isFavorite); + favButton.setAttribute('aria-label', `Make ${restaurant.name} a favorite!`); + favButton.innerHTML = isFavorite ? '♥' : '♡'; + favButton.onclick = event => favoriteClicked(restaurant, favButton); + + li.append(favButton); + const neighborhood = document.createElement('p'); neighborhood.innerHTML = restaurant.neighborhood; li.append(neighborhood); @@ -167,6 +178,35 @@ createRestaurantHTML = (restaurant) => { return li } +/* + * Handler for favorite button being clicked + */ +favoriteClicked = (restaurant, button) => { + //console.log(`Data: ${restaurant.name}, ${restaurant.is_favorite}, ${button}`); + //console.log(`favClicked. Entering state: ${button.getAttribute("aria-pressed")}`); + + // Get current fav state + let fav = (button.getAttribute("aria-pressed") && button.getAttribute("aria-pressed") === "true") ? true : false; + + let requestURL = `${DBHelper.DATABASE_URL}/${restaurant.id}/?is_favorite=${!fav}`; + let requestMethod = "PUT"; + DBHelper.updateRestaurantCache(restaurant.id, {"is_favorite": !fav}); + DBHelper.addToUpdateQueue(requestURL, requestMethod); + //return fetch(`${DBHelper.DATABASE_URL}/restaurants/${restaurant.id}/?is_favorite=${!fav}`, {method: 'PUT'}) + //.then(response => { + // if(!response.ok) return Promise.reject("Favorite could not be updated."); + // return response.json(); + //}).then(updatedRestaurant => { + // Update restaurant on idb + // dbPromise.putRestaurants(updatedRestaurant, true); + // Change state of toggle button + //console.log(`Exiting state: ${!fav}`); + button.setAttribute('aria-pressed', !fav); + button.innerHTML = !fav ? '♥' : '♡'; + button.onclick = event => favoriteClicked(restaurant, button); + //}); +} + /* * Add markers for current restaurants to the map. */ diff --git a/app/js/restaurant_info.js b/app/js/restaurant_info.js index e46bab6..10429b0 100644 --- a/app/js/restaurant_info.js +++ b/app/js/restaurant_info.js @@ -18,6 +18,7 @@ window.initMap = () => { DBHelper.mapMarkerForRestaurant(self.restaurant, self.map); } }); + DBHelper.pushUpdates(); } /* @@ -30,7 +31,7 @@ fetchRestaurantFromURL = (callback) => { } const id = getParameterByName('id'); if (!id) { // no id found in URL - error = 'No restaurant id in URL' + let error = 'No restaurant id in URL' callback(error, null); } else { DBHelper.fetchRestaurantById(id, (error, restaurant) => { @@ -52,6 +53,18 @@ fillRestaurantHTML = (restaurant = self.restaurant) => { const name = document.getElementById('restaurant-name'); name.innerHTML = restaurant.name; + // Inserting favorite here + const favButton = document.createElement('button'); + favButton.className = 'favButton'; + let isFavorite = (restaurant.is_favorite && restaurant.is_favorite.toString() === "true") ? true : false; + //console.log(`${restaurant.name}, ${restaurant.is_favorite}`); + favButton.setAttribute('aria-pressed', isFavorite); + favButton.setAttribute('aria-label', `Make ${restaurant.name} a favorite!`); + favButton.innerHTML = isFavorite ? '♥' : '♡'; + favButton.onclick = event => favoriteClicked(restaurant, favButton); + + name.appendChild(favButton); + const address = document.getElementById('restaurant-address'); address.innerHTML = restaurant.address; @@ -71,7 +84,38 @@ fillRestaurantHTML = (restaurant = self.restaurant) => { fillRestaurantHoursHTML(); } // fill reviews - fillReviewsHTML(); + //fillReviewsHTML(); + console.log(`In fillRestaurantHTML, about to call fetch then fill with id: ${restaurant.id}`); + DBHelper.fetchReviewsById(restaurant.id).then(fillReviewsHTML(reviews)); +} + + /* + * Handling favorite button clicked. + */ +favoriteClicked = (restaurant, button) => { + //console.log(`Data: ${restaurant.name}, ${restaurant.is_favorite}, ${button}`); + //console.log(`favClicked. Entering state: ${button.getAttribute("aria-pressed")}`); + + // Get current fav state + let fav = (button.getAttribute("aria-pressed") && button.getAttribute("aria-pressed") === "true") ? true : false; + + let requestURL = `${DBHelper.DATABASE_URL}/${restaurant.id}/?is_favorite=${!fav}`; + let requestMethod = "PUT"; + DBHelper.updateRestaurantCache(restaurant.id, {"is_favorite": !fav}); + DBHelper.addToUpdateQueue(requestURL, requestMethod); + //return fetch(`${DBHelper.DATABASE_URL}/${restaurant.id}/?is_favorite=${!fav}`, {method: 'PUT'}) + //.then(response => { + // if(!response.ok) return Promise.reject("Favorite could not be updated."); + // return response.json(); + //}).then(updatedRestaurant => { + // Update restaurant on idb + // dbPromise.putRestaurants(updatedRestaurant, true); + // Change state of toggle button + //console.log(`Exiting state: ${!fav}`); + button.setAttribute('aria-pressed', !fav); + button.innerHTML = !fav ? '♥' : '♡'; + button.onclick = event => favoriteClicked(restaurant, button); + //}); } /* @@ -97,14 +141,21 @@ fillRestaurantHoursHTML = (operatingHours = self.restaurant.operating_hours) => /* * Create all reviews HTML and add them to the webpage. */ -fillReviewsHTML = (reviews = self.restaurant.reviews) => { +fillReviewsHTML = (reviews) => { + console.log("In fillReviewsHTML ", reviews); const container = document.getElementById('reviews-container'); const title = document.createElement('h3'); title.innerHTML = 'Reviews'; container.appendChild(title); + const addReview = document.createElement('button'); + addReview.innerHTML = 'Add a Review'; + addReview.id = "reviewButton"; + addReview.onclick = addReviewForm; + container.appendChild(addReview); + if (!reviews) { - const noReviews = document.createElement('p'); + const noReviews = document.createElement('h3'); noReviews.innerHTML = 'No reviews yet!'; container.appendChild(noReviews); return; @@ -182,3 +233,107 @@ getParameterByName = (name, url) => { return ''; return decodeURIComponent(results[2].replace(/\+/g, ' ')); } + +// Adding Reviews ========================================================== + +/* + * Handle button click for adding a review + */ +addReviewForm = () => { + let addReviewButton = document.getElementById("reviewButton"); + addReviewButton.style.display = "none"; + const reviewList = document.getElementById('reviews-list'); + reviewList.appendChild(reviewForm()); + document.getElementById("name").focus(); + +} + +/* + * Returns a form to append to th list of reviews for input. + */ +reviewForm = () => { + let formContainer = document.createElement('li'); + let form = document.createElement('form'); + form.id = "reviewForm"; + + let title = document.createElement('p'); + title.innerHTML = "New Review"; + title.id = "reviewer-name"; + form.appendChild(title); + + let p = document.createElement('p'); + let name = document.createElement('input'); + let nameLabel = document.createElement('label'); + nameLabel.setAttribute('for', 'name'); + nameLabel.innerHTML = 'First Name: '; + name.id = "name" + name.setAttribute('type', 'text'); + p.appendChild(nameLabel); + p.appendChild(name); + form.appendChild(p); + + p = document.createElement('p'); + let selectLabel = document.createElement('label'); + selectLabel.setAttribute('for', 'rating'); + selectLabel.innerText = "Your rating: "; + p.appendChild(selectLabel); + let select = document.createElement('select'); + select.id = "rating"; + select.name = "rating"; + select.classList.add('rating'); + ["--", 1,2,3,4,5].forEach(number => { + const option = document.createElement('option'); + option.value = number; + option.innerHTML = number; + if (number === "--") option.selected = true; + select.appendChild(option); + }); + p.appendChild(select); + form.appendChild(p); + + p = document.createElement('p'); + let comments = document.createElement('textarea'); + let commentsLabel = document.createElement('label'); + commentsLabel.setAttribute('for', 'comments'); + commentsLabel.innerHTML = 'Comments: '; + comments.id = "comments"; + comments.setAttribute('rows', '10'); + p.appendChild(commentsLabel); + p.appendChild(comments); + p.style.display = "flex"; + p.style.alignItems = "center"; + form.appendChild(p); + + p = document.createElement('p'); + let submitButton = document.createElement('button'); + submitButton.id = "submitReview"; + submitButton.setAttribute('type', 'submit'); + submitButton.innerHTML = "Submit Review"; + p.appendChild(submitButton); + form.appendChild(p); + + form.onsubmit = handleSubmit; + formContainer.appendChild(form); + return formContainer; +} + +handleSubmit = (e) => { + // Takes care of submission cancelation + e.preventDefault(); + //console.log("in handleSubmit"); + let id = self.restaurant.id; + let name = document.getElementById("name").value; + let rating = document.getElementById("rating").value + 0; + let comments = document.getElementById("comments").value; + + DBHelper.saveReview(id, name, rating, comments, Date.now()); + // Get rid of the form + let form = document.getElementById("reviewForm"); + form.parentNode.removeChild(form); + // Put the 'Add Review' button back. + let addReviewButton = document.getElementById("reviewButton"); + addReviewButton.style.display = "block"; + +} + + diff --git a/app/restaurant.html b/app/restaurant.html index 5ba41ac..6fc9723 100644 --- a/app/restaurant.html +++ b/app/restaurant.html @@ -70,7 +70,7 @@

- + diff --git a/app/sw.js b/app/sw.js index 787cd25..ae19f19 100644 --- a/app/sw.js +++ b/app/sw.js @@ -1,11 +1,13 @@ -// Service Worker +/* + * Service Worker + */ -// Include DBHelper function for fetching restaurants and putting in indexedDB -self.importScripts('js/dbhelper.js', 'js/idb.js'); +// Include DBHelper functions for fetching restaurants and putting in indexedDB +self.importScripts('./js/dbhelper.js', './js/idb.js'); -// Data -var myCache = "restaurantReview_050"; -var cacheFiles = [ +// Cache Information +var myCache = 'restaurantReview_301'; +var cacheFiles = [ '/index.html', '/restaurant.html', '/css/styles.css', @@ -17,57 +19,149 @@ var cacheFiles = [ '/js/idb.js' ]; -// Event Listener for install - caching the files -self.addEventListener("install", function(event) { - - //console.log('In eventListener for install, event: ', event) - event.waitUntil(caches.open(myCache).then(function(cache) { +// IDB Information +const dbPromise = idb.open('restaurantReviews', 3, upgradeDb => { + switch(upgradeDb.oldVersion) { + case 0: upgradeDb.createObjectStore('restaurantData', {keyPath: 'id'}); + case 1: upgradeDb.createObjectStore('reviewData', {keypath: 'id'}).createIndex('restaurant_id', 'restaurant_id'); + case 2: upgradeDb.createObjectStore('updateData', {keyPath: 'id', autoIncrement: true}); + } +}); +/* + * Event Listener for install - caching the files + */ +self.addEventListener('install', function(event) { + console.log('In eventListener for install, event: ', event) + event.waitUntil(caches.open(myCache) + .then(function(cache) { return cache.addAll(cacheFiles) - .then( function() { console.log('Cache worked'); } ) - .catch(function(error) { - - console.log("Caching failed, error: ", error); - }); + .then(function() { console.log('Cache worked!'); } ) + .catch(function(error) { console.log('Caching failed, error: ', error); } ); })); }); -// Event Lstener for fetch - pull files from cache and update with fetch is possible +/* + * Event Listener for fetch - pull files from cache and update with fetch is possible + */ self.addEventListener('fetch', function(event) { - //console.log('In eventListener for fetch, event: ', event) + console.log('In eventListener for fetch, event: ', event); + // Separating fetch requests + let requestURL = new URL(event.request.url); + if (requestURL.port === '1337') { + let id = requestURL.searchParams.get('restaurant_id') - 0; + if(!id) { + if(requestURL.pathname.indexOf('restaurants')) { + let pathArr = requestURL.pathname.split('/'); + id = pathArr[pathArr.length - 1] === 'restaurants' ? '-1' : pathArr[pathArr.length -1]; + } + else { id = requestURL.searchParams.get('restaurant_id'); } + apiFetch(event, id); + } + else { + let cacheRequest = event.request; + if(cacheRequest.url.indexOf('restaurant.html') > -1) cacheRequest = new Request('restaurant.html'); + cacheFetch(event, cacheRequest); } + } +}); + +function apiFetch(event, id) { + console.log(`In apiFetch - event: ${event} id: ${id}`); + if (event.request.method == 'POST' || event.request.method == 'PUT') { + // Post & Put methods are not cached. Process request without further action. + return fetch(event.request) + .then(function(response) { return response.json(); }); + } - event.respondWith( - caches.match(event.request).then(function(response) { + // Restaurant and Review information are now being kept in separate stores: restaurantData & reviewData - return response || fetch(event.request).then(function(fetchResponse) { + // Restaurant Request ------------------------------------------------------------------------------- + if(event.request.url.indexOf('restaurants') > -1) { + event.respondWith(dbPromise.then(function(db) { + return db.transaction('restaurantData').objectStore('restaurantData').get(id); + }) + .then(function(data) { + return (data && data.data) || fetch(event.request) - return caches.open(myCache).then(function(cache) { + .then(function(response) { + return dbPromise - cache.put(event.request, fetchResponse.clone()); - return fetchResponse; + .then(function(db) { + db.transaction('restaurantData', 'readwrite').objectStore('restaurantData').put({ id: id, data: response.json() }); + return response.json(); + }); }); - }) }) - ); -}); + .then(function(endResponse) { return new Response(JSON.stringify(endResponse)); }) + .catch(function(error) { console.log(`In apiFetch catch-restaurantData, error: ${error.message}`); })); + } -// Event Listener for activate - -self.addEventListener('activate', event => { - console.log("Event trigger - activate"); - DBHelper.fetchRestaurants((error, restaurants) => { - if (error) { - callback(error, null); - } else { - // Could use switch statement here to update IDB. Curretn Data set is static, needs just one init/. - idb.open('restaurantReviews', 1, upgradeDB => { - // If not there already, add restaurant data - if(!upgradeDB.objectStoreNames.contains('restaurantData')) { - let objStore = upgradeDB.createObjectStore('restaurantData', {keyPath: 'id'}); - console.log(restaurants); - restaurants.map(restaurant => objStore.add(restaurant)); - } + // Review Request ----------------------------------------------------------------------------------- + event.respondWith(dbPromise.then(function(db) { + return db.transaction('reviewData').objectStore('reviewData').index('restaurant_id').getAll(id); + }) + .then(function(data) { + return (data && data.data) || fetch(event.request) + + .then(function(response) { + return dbPromise + + .then(function(db) { + let store = db.transaction('reviewData', 'readwrite').objectStore('reviewData'); + response.json().forEach(function(review) { + store.put({id: review.id, 'restaurant_id': review.restaurant_id, data: review}); + }) + return response.json(); + }); }); + }) + .then(function(endResponse) { + if(endResponse[0].data) { + let formatted = endResponse.map(review => review.data); + return new Response(JSON.stringify(formatted)); } - }); -}); + return new Response(JSON.stringify(endResponse)); + }) + .catch(function(error) { console.log(`In apiFetch catch-reviewData, error: ${error.message}`); })); +} + +function cacheFetch(event, request) { + console.log(`In cacheFetch - event: ${event} request: ${request}`); + // Check the cache before fetching. + // If fetched, store in the cache. + event.respondWith(caches.match(request)) + .then(function(response) { + return response || fetch(event.request) + + .then(function(fetchResponse) { + return caches.open(myCache) + + .then(function(cache) { + if(fetchResponse.url.indexOf('browsersync') === -1) cache.put(event.request, fetchResponse.clone()); + return fetchResponse; + }); + }) + .catch(function(error) { console.log(`In cacheFetch catch, error: ${error.message}`); }); + }) +} + +// /* +// * Event Listener for activate +// */ +// self.addEventListener('activate', event => { +// console.log('Event trigger - activate'); +// DBHelper.fetchRestaurants((error, restaurants) => { +// if (error) { +// callback(error, null); +// } else { +// const dbPromise = idb.open('restaurantReviews', 3, upgradeDb => { +// switch(upgradeDb.oldVersion) { +// case 0: upgradeDb.createObjectStore('restaurantData', {keyPath: 'id'}); +// case 1: upgradeDb.createObjectStore('reviewData', {keypath: 'id'}).createIndex('restaurant_id', 'restaurant_id'); +// case 2: upgradeDb.createObjectStore('updateData', {keyPath: 'id', autoIncrement: true}); +// } +// }); +// } +// }); +// }); diff --git a/dist/css/styles.css b/dist/css/styles.css index bb20901..f979917 100644 --- a/dist/css/styles.css +++ b/dist/css/styles.css @@ -1 +1 @@ -@charset "utf-8";body,p,td,th{font-family:Arial,Helvetica,sans-serif;font-size:12pt;color:#333;line-height:1.5em}body{background-color:#fdfdfd;margin:0;position:relative}li,ul{font-family:Arial,Helvetica,sans-serif;font-size:12pt;color:#333}a{color:orange;text-decoration:none}a:focus,a:hover{color:#3397db;text-decoration:underline}a img{border:none 0 #fff}h1,h2,h3,h4,h5,h6{font-family:Arial,Helvetica,sans-serif;margin:0}hr{width:80%}#maincontent{min-height:100%}#footer{max-width:100%;background-color:#252831;color:#aaa;font-size:10pt;letter-spacing:1px;padding:25px;text-align:center;text-transform:uppercase}nav{line-height:2em;background-color:#252831;text-align:center}nav h1{margin:auto;padding:15px}nav h1 a{color:#fff;font-size:14pt;font-weight:200;letter-spacing:10px;text-transform:uppercase}#breadcrumb{padding:10px 40px 16px;list-style:none;background-color:#eee;font-size:14px;margin:0}#breadcrumb li{display:inline}#breadcrumb li+li:before{padding:8px;color:#000;content:"/\00a0"}#breadcrumb li a{color:#024c92;text-decoration:none}#breadcrumb li a:hover{color:#01447e;text-decoration:underline}#map{height:400px;width:100%;background-color:#ccc}.filter-options{width:100%;background-color:#252831;align-items:center}.filter-options h2{color:#fff;font-weight:400;line-height:1.5em;margin:0 20px}.filter-options select{background-color:#fff;border:1px solid #fff;font-family:Arial,sans-serif;font-size:12pt;height:35px;letter-spacing:0;margin:10px;padding:0 10px;width:200px}.aria-label{display:none}#restaurants-list{background-color:#f3f3f3;list-style:outside none none;margin:0;padding:30px 15px 60px;text-align:center}#restaurants-list li{background-color:#fff;border:1px solid #ccc;font-family:Arial,sans-serif;margin:16px;min-height:380px;padding:10px;max-width:310px;display:inline-block;text-align:center}#restaurants-list .restaurant-img{background-color:#ccc;display:block;margin:0;max-width:100%;min-height:100%;min-width:100%}#restaurants-list li h3{color:#8a4600;font-family:Arial,sans-serif;font-size:14pt;font-weight:200;letter-spacing:0;line-height:1.3em;margin:20px 0 10px;text-transform:uppercase}#restaurants-list p{margin:0;font-size:12pt}#restaurants-list li a{background-color:#252831;border-bottom:3px solid #eee;color:#fff;display:inline-block;font-size:12pt;margin:15px 0 10px;padding:8px 30px 10px;text-align:center;text-decoration:none;text-transform:uppercase}.inside header{top:0;max-width:100%}.inside #map-container{background:#00f none repeat scroll 0 0;max-width:100%}.inside #footer{bottom:0}#restaurant-name{color:#8a4600;font-family:Arial,sans-serif;font-size:22pt;font-weight:200;letter-spacing:0;margin:20px 0 20px;text-transform:uppercase;line-height:1.1}#restaurant-img{width:90%;padding-bottom:10px;max-width:960px;border-radius:20px 0 20px 0}#restaurant-address{font-size:14pt;margin:10px 0}#restaurant-container{text-align:center}#restaurant-cuisine{background-color:#333;color:#ddd;font-size:14pt;font-weight:300;letter-spacing:10px;margin:0 0 20px;padding:2px 0;text-align:center;text-transform:uppercase;width:100%}#restaurant-hours{margin-left:auto;margin-right:auto;text-align:left;padding-bottom:15px}#restaurant-hours th{line-height:1.2em}#restaurant-container,#reviews-container{border-bottom:1px solid #d9d9d9;border-top:1px solid #fff}#reviews-container h3{color:#8a4600;font-size:24pt;font-weight:300;text-align:center;padding-bottom:5px;padding-top:5px;line-height:1.5em}#reviews-list{padding:0}#reviews-list li{background-color:#fff;border:2px solid #f3f3f3;display:block;list-style-type:none;padding:0;overflow:hidden;position:relative;width:85%;max-width:600px;margin-left:auto;margin-right:auto;margin-bottom:20px;border-radius:0 0 10px 0}#reviews-list li p{text-indent:10px}#restaurant-hours td{color:#666}#reviewer-name{background-color:#333;color:#ddd;font-size:14pt;font-weight:300;margin:0;width:100%;border-radius:10px 0 0 0}#reviewer-comments{padding-left:15px;padding-right:15px} \ No newline at end of file +@charset "utf-8";body,p,td,th{font-family:Arial,Helvetica,sans-serif;font-size:12pt;color:#333;line-height:1.5em}body{background-color:#fdfdfd;margin:0;position:relative}li,ul{font-family:Arial,Helvetica,sans-serif;font-size:12pt;color:#333}a{color:orange;text-decoration:none}a:focus,a:hover{color:#3397db;text-decoration:underline}a img{border:none 0 #fff}h1,h2,h3,h4,h5,h6{font-family:Arial,Helvetica,sans-serif;margin:0}hr{width:80%}#maincontent{min-height:100%}#footer{max-width:100%;background-color:#252831;color:#aaa;font-size:10pt;letter-spacing:1px;padding:25px;text-align:center;text-transform:uppercase}nav{line-height:2em;background-color:#252831;text-align:center}nav h1{margin:auto;padding:15px}nav h1 a{color:#fff;font-size:14pt;font-weight:200;letter-spacing:10px;text-transform:uppercase}#breadcrumb{padding:10px 40px 16px;list-style:none;background-color:#eee;font-size:14px;margin:0}#breadcrumb li{display:inline}#breadcrumb li+li:before{padding:8px;color:#000;content:"/\00a0"}#breadcrumb li a{color:#024c92;text-decoration:none}#breadcrumb li a:hover{color:#01447e;text-decoration:underline}#map{height:400px;width:100%;background-color:#ccc}.filter-options{width:100%;background-color:#252831;align-items:center}.filter-options h2{color:#fff;font-weight:400;line-height:1.5em;margin:0 20px}.filter-options select{background-color:#fff;border:1px solid #fff;font-family:Arial,sans-serif;font-size:12pt;height:35px;letter-spacing:0;margin:10px;padding:0 10px;width:200px}.aria-label{display:none}.favButton{background-image:none;border:none;font-size:20pt}.favSpan[aria-pressed=true]{color:orange}#restaurants-list{background-color:#f3f3f3;list-style:outside none none;margin:0;padding:30px 15px 60px;text-align:center}#restaurants-list li{background-color:#fff;border:1px solid #ccc;font-family:Arial,sans-serif;margin:16px;min-height:380px;padding:10px;max-width:310px;display:inline-block;text-align:center}#restaurants-list .restaurant-img{background-color:#ccc;display:block;margin:0;max-width:100%;min-height:100%;min-width:100%}#restaurants-list li h3{color:#8a4600;font-family:Arial,sans-serif;font-size:14pt;font-weight:200;letter-spacing:0;line-height:1.3em;margin:20px 0 10px;text-transform:uppercase}#restaurants-list p{margin:0;font-size:12pt}#restaurants-list li a{background-color:#252831;border-bottom:3px solid #eee;color:#fff;display:inline-block;font-size:12pt;margin:15px 0 10px;padding:8px 30px 10px;text-align:center;text-decoration:none;text-transform:uppercase}.inside header{top:0;max-width:100%}.inside #map-container{background:#00f none repeat scroll 0 0;max-width:100%}.inside #footer{bottom:0}#restaurant-name{color:#8a4600;font-family:Arial,sans-serif;font-size:22pt;font-weight:200;letter-spacing:0;margin:20px 0 20px;text-transform:uppercase;line-height:1.1}#restaurant-img{width:90%;padding-bottom:10px;max-width:960px;border-radius:20px 0 20px 0}#restaurant-address{font-size:14pt;margin:10px 0}#restaurant-container{text-align:center}#restaurant-cuisine{background-color:#333;color:#ddd;font-size:14pt;font-weight:300;letter-spacing:10px;margin:0 0 20px;padding:2px 0;text-align:center;text-transform:uppercase;width:100%}#restaurant-hours{margin-left:auto;margin-right:auto;text-align:left;padding-bottom:15px}#restaurant-hours th{line-height:1.2em}#restaurant-container,#reviews-container{border-bottom:1px solid #d9d9d9;border-top:1px solid #fff}#reviews-container h3{color:#8a4600;font-size:24pt;font-weight:300;text-align:center;padding-bottom:5px;padding-top:5px;line-height:1.5em}#reviewButton,#submitReview{background-color:#252831;border-bottom:3px solid #eee;color:#fff;font-size:12pt;margin:0 auto;padding:15px;text-align:center;text-decoration:none;text-transform:uppercase;display:flex;justify-content:center}#reviews-list{padding:0}#reviews-list li{background-color:#fff;border:2px solid #f3f3f3;display:block;list-style-type:none;padding:0;overflow:hidden;position:relative;width:85%;max-width:600px;margin-left:auto;margin-right:auto;margin-bottom:20px;border-radius:0 0 10px 0}#reviews-list li p{text-indent:10px}#restaurant-hours td{color:#666}#reviewer-name{background-color:#333;color:#ddd;font-size:14pt;font-weight:300;margin:0;width:100%;border-radius:10px 0 0 0}#reviewer-comments,input{padding-left:15px;padding-right:15px}label{padding:10px} \ No newline at end of file diff --git a/dist/index.html b/dist/index.html index bc6657f..df37f52 100644 --- a/dist/index.html +++ b/dist/index.html @@ -1 +1 @@ -Restaurant Reviews

Filter Results

\ No newline at end of file +Restaurant Reviews

Filter Results

\ No newline at end of file diff --git a/dist/js/dbhelper.js b/dist/js/dbhelper.js index 63cfc8b..6381b7e 100644 --- a/dist/js/dbhelper.js +++ b/dist/js/dbhelper.js @@ -1 +1 @@ -class DBHelper{static get DATABASE_URL(){return"http://localhost:1337/restaurants"}static fetchRestaurants(t){fetch(DBHelper.DATABASE_URL).then(function(t){if(t.ok)return t.json();throw new Error("Fetch repsponse Error")}).then(function(e){t(null,e)}).catch(function(e){console.log("In fetchRestaurants catch, error:",e.message),idb.open("restaurantReviews",1).then(t=>t.transaction("restaurantData").objectStore("restaurantData").getAll()).then(e=>{t(null,e)})})}static fetchRestaurantById(t,e){DBHelper.fetchRestaurants((n,r)=>{if(n)e(n,null);else{const n=r.find(e=>e.id==t);n?e(null,n):e("Restaurant does not exist",null)}})}static fetchRestaurantByCuisine(t,e){DBHelper.fetchRestaurants((n,r)=>{if(n)e(n,null);else{const n=r.filter(e=>e.cuisine_type==t);e(null,n)}})}static fetchRestaurantByNeighborhood(t,e){DBHelper.fetchRestaurants((n,r)=>{if(n)e(n,null);else{const n=r.filter(e=>e.neighborhood==t);e(null,n)}})}static fetchRestaurantByCuisineAndNeighborhood(t,e,n){DBHelper.fetchRestaurants((r,a)=>{if(r)n(r,null);else{let r=a;"all"!=t&&(r=r.filter(e=>e.cuisine_type==t)),"all"!=e&&(r=r.filter(t=>t.neighborhood==e)),n(null,r)}})}static fetchNeighborhoods(t){DBHelper.fetchRestaurants((e,n)=>{if(e)t(e,null);else{const e=n.map((t,e)=>n[e].neighborhood),r=e.filter((t,n)=>e.indexOf(t)==n);t(null,r)}})}static fetchCuisines(t){DBHelper.fetchRestaurants((e,n)=>{if(e)t(e,null);else{const e=n.map((t,e)=>n[e].cuisine_type),r=e.filter((t,n)=>e.indexOf(t)==n);t(null,r)}})}static urlForRestaurant(t){return`./restaurant.html?id=${t.id}`}static imageUrlForRestaurant(t){return`/img/${t.photograph}`}static mapMarkerForRestaurant(t,e){return new google.maps.Marker({position:t.latlng,title:t.name,url:DBHelper.urlForRestaurant(t),map:e,animation:google.maps.Animation.DROP})}} \ No newline at end of file +const port=1337,dbPromise=idb.open("restaurantReviews",3,e=>{switch(e.oldVersion){case 0:e.createObjectStore("restaurantData",{keyPath:"id"});case 1:e.createObjectStore("reviewData",{keypath:"id"}).createIndex("restaurant_id","restaurant_id");case 2:e.createObjectStore("updateData",{keyPath:"id",autoIncrement:!0})}});class DBHelper{static get DATABASE_URL(){return`http://localhost:${port}/restaurants`}static get DATABASE_URL_REVIEWS(){return`http://localhost:${port}/reviews`}static fetchRestaurants(e){console.log(`In fetchRestaurants - callback: ${e}`);let t=DBHelper.DATABASE_URL;fetch(t,{method:"GET"}).then(function(e){if(e.ok)return e.json()}).then(function(t){e(null,t)}).catch(function(e){console.log("In fetchRestaurants catch, error: ",e.message)})}static fetchRestaurantById(e,t){console.log(`In fetchRestaurantsById - id: ${e}, callback: ${t}`),DBHelper.fetchRestaurants((a,n)=>{if(a)t(a,null);else{const a=n.find(t=>t.id==e);a?t(null,a):t("Restaurant does not exist",null)}})}static fetchRestaurantByCuisine(e,t){DBHelper.fetchRestaurants((a,n)=>{if(a)t(a,null);else{const a=n.filter(t=>t.cuisine_type==e);t(null,a)}})}static fetchRestaurantByNeighborhood(e,t){DBHelper.fetchRestaurants((a,n)=>{if(a)t(a,null);else{const a=n.filter(t=>t.neighborhood==e);t(null,a)}})}static fetchRestaurantByCuisineAndNeighborhood(e,t,a){DBHelper.fetchRestaurants((n,r)=>{if(n)a(n,null);else{let n=r;"all"!=e&&(n=n.filter(t=>t.cuisine_type==e)),"all"!=t&&(n=n.filter(e=>e.neighborhood==t)),a(null,n)}})}static fetchNeighborhoods(e){DBHelper.fetchRestaurants((t,a)=>{if(t)e(t,null);else{const t=a.map((e,t)=>a[t].neighborhood),n=t.filter((e,a)=>t.indexOf(e)==a);e(null,n)}})}static fetchCuisines(e){DBHelper.fetchRestaurants((t,a)=>{if(t)e(t,null);else{const t=a.map((e,t)=>a[t].cuisine_type),n=t.filter((e,a)=>t.indexOf(e)==a);e(null,n)}})}static urlForRestaurant(e){return`./restaurant.html?id=${e.id}`}static imageUrlForRestaurant(e){return`/img/${e.photograph}`}static mapMarkerForRestaurant(e,t){return new google.maps.Marker({position:e.latlng,title:e.name,url:DBHelper.urlForRestaurant(e),map:t,animation:google.maps.Animation.DROP})}static fetchReviewsById(e){let t=DBHelper.DATABASE_URL_REVIEWS+"/?restaurant_id="+e;console.log(`In DBHelper.fetchReviewsById - request: ${t}, id: ${e}`),fetch(t,{method:"GET"}).then(function(e){if(e.ok)return e.json()}).then(function(e){return console.log(e),e}).catch(function(e){console.log("In fetchReviewsBy...ID catch, error:",e.message)})}static updateRestaurantCache(e,t){console.log(`In updateRestaurantCache - id: ${e}, update: ${t}`);let a=idb.open("restaurantReviews");a.then(function(n){n.transaction("restaurantData","readwrite").objectStore("restaurantData").get("-1").then(function(n){if(!n)return void console.log("No value, update all, in updateRestaurantCache");let r=n.data.filter(t=>t.id===e)[0];r&&(Object.keys(t).forEach(e=>{r[e]=t[e]}),a.then(function(e){return e.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:"-1",data:n.data}).complete}))})}),a.then(function(n){n.transaction("restaurantData","readwrite").objectStore("restaurantData").get(e+"").then(function(n){if(!n)return void console.log("No value, update individual, in updateRestaurantCache");let r=n.data;r&&(Object.keys(t).forEach(e=>{r[e]=t[e]}),a.then(function(t){return t.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:e+"",data:n.data}).complete}))})})}static updateReviewCache(e,t){console.log(`In updateReviewCache - id: ${e}, update: ${t}`),idb.open("restaurantReviews").then(function(a){return a.transaction("reviewData","readwrite").objectStore("reviewData").put({id:Date.now(),restaurant_id:e,data:t}).complete})}static addToUpdateQueue(e,t,a){console.log(`In addToUpdateQueue - url: ${e}, method: ${t}, update: ${a}`),idb.open("restaurantReviews").then(function(n){n.transaction("updateData","readwrite").objectStore("updateData").put({data:{url:e,method:t,update:a}})}).catch(function(e){console.log("In addToUpdateQueue catch, error: ",e.message)}).then(DBHelper.pushUpdates())}static pushUpdates(){console.log("In pushUpdates"),idb.open("restaurantReviews").then(function(e){e.transaction("updateData","readwrite").objectStore("updateData").openCursor().then(function(t){if(!t)return;let a=t.value.data,n={body:JSON.stringify(a.body),method:a.method};fetch(a.url,n).then(function(e){e.ok}).then(function(){e.transaction("updateData","readwrite").objectStore("updateData").openCursor().then(function(e){e.delete().then(function(){console.log("Record deleted, calling next..."),DBHelper.pushUpdates()})})})}).catch(function(e){console.log("In pushUpdates catch, error: ",e.message)})})}static saveReview(e,t,a,n,r){let o=`${DBHelper.DATABASE_URL_REVIEWS}`,s={restaurant_id:e,name:t,rating:a,comments:n,createdAt:r};console.log(`In saveReview - url: ${o}, method: POST, body: ${s}`),DBHelper.updateReviewCache(e,s),DBHelper.addToUpdateQueue(o,"POST",s)}} \ No newline at end of file diff --git a/dist/js/main.js b/dist/js/main.js index 38843e4..31ba433 100644 --- a/dist/js/main.js +++ b/dist/js/main.js @@ -1 +1 @@ -let restaurants,neighborhoods,cuisines;var map,markers=[];document.addEventListener("DOMContentLoaded",e=>{fetchNeighborhoods(),fetchCuisines()}),fetchNeighborhoods=(()=>{DBHelper.fetchNeighborhoods((e,t)=>{e?console.error(e):(self.neighborhoods=t,fillNeighborhoodsHTML())})}),fillNeighborhoodsHTML=((e=self.neighborhoods)=>{const t=document.getElementById("neighborhoods-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),fetchCuisines=(()=>{DBHelper.fetchCuisines((e,t)=>{e?console.error(e):(self.cuisines=t,fillCuisinesHTML())})}),fillCuisinesHTML=((e=self.cuisines)=>{const t=document.getElementById("cuisines-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),window.initMap=(()=>{self.map=new google.maps.Map(document.getElementById("map"),{zoom:12,center:{lat:40.722216,lng:-73.987501},scrollwheel:!1}),updateRestaurants()}),updateRestaurants=(()=>{const e=document.getElementById("cuisines-select"),t=document.getElementById("neighborhoods-select"),n=e.selectedIndex,s=t.selectedIndex,r=e[n].value,a=t[s].value;DBHelper.fetchRestaurantByCuisineAndNeighborhood(r,a,(e,t)=>{e?console.error(e):(resetRestaurants(t),fillRestaurantsHTML())})}),resetRestaurants=(e=>{self.restaurants=[],document.getElementById("restaurants-list").innerHTML="",self.markers.forEach(e=>e.setMap(null)),self.markers=[],self.restaurants=e}),fillRestaurantsHTML=((e=self.restaurants)=>{const t=document.getElementById("restaurants-list");e.forEach(e=>{t.append(createRestaurantHTML(e))}),addMarkersToMap()}),createRestaurantHTML=(e=>{const t=document.createElement("li"),n=document.createElement("img");n.className="restaurant-img",n.src=`/img/${e.id}@1x.webp`,n.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,n.alt=`Image of ${e.name} restaurant`,t.append(n);const s=document.createElement("h3");s.innerHTML=e.name,t.append(s);const r=document.createElement("p");r.innerHTML=e.neighborhood,t.append(r);const a=document.createElement("p");a.innerHTML=e.address,t.append(a);const o=document.createElement("a");return o.innerHTML="View Details",o.href=DBHelper.urlForRestaurant(e),t.append(o),t}),addMarkersToMap=((e=self.restaurants)=>{e.forEach(e=>{const t=DBHelper.mapMarkerForRestaurant(e,self.map);google.maps.event.addListener(t,"click",()=>{window.location.href=t.url}),self.markers.push(t)})}); \ No newline at end of file +let restaurants,neighborhoods,cuisines;var map,markers=[];document.addEventListener("DOMContentLoaded",e=>{fetchNeighborhoods(),fetchCuisines()}),fetchNeighborhoods=(()=>{DBHelper.fetchNeighborhoods((e,t)=>{e?console.error(e):(self.neighborhoods=t,fillNeighborhoodsHTML())})}),fillNeighborhoodsHTML=((e=self.neighborhoods)=>{const t=document.getElementById("neighborhoods-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),fetchCuisines=(()=>{DBHelper.fetchCuisines((e,t)=>{e?console.error(e):(self.cuisines=t,fillCuisinesHTML())})}),fillCuisinesHTML=((e=self.cuisines)=>{const t=document.getElementById("cuisines-select");e.forEach(e=>{const n=document.createElement("option");n.innerHTML=e,n.value=e,t.append(n)})}),window.initMap=(()=>{self.map=new google.maps.Map(document.getElementById("map"),{zoom:12,center:{lat:40.722216,lng:-73.987501},scrollwheel:!1}),updateRestaurants(),DBHelper.pushUpdates()}),updateRestaurants=(()=>{const e=document.getElementById("cuisines-select"),t=document.getElementById("neighborhoods-select"),n=e.selectedIndex,s=t.selectedIndex,r=e[n].value,a=t[s].value;DBHelper.fetchRestaurantByCuisineAndNeighborhood(r,a,(e,t)=>{e?console.error(e):(resetRestaurants(t),fillRestaurantsHTML())})}),resetRestaurants=(e=>{self.restaurants=[],document.getElementById("restaurants-list").innerHTML="",self.markers.forEach(e=>e.setMap(null)),self.markers=[],self.restaurants=e}),fillRestaurantsHTML=((e=self.restaurants)=>{const t=document.getElementById("restaurants-list");e.forEach(e=>{t.append(createRestaurantHTML(e))}),addMarkersToMap()}),createRestaurantHTML=(e=>{const t=document.createElement("li"),n=document.createElement("img");n.className="restaurant-img",n.src=`/img/${e.id}@1x.webp`,n.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,n.alt=`Image of ${e.name} restaurant`,t.append(n);const s=document.createElement("h3");s.innerHTML=e.name,t.append(s);const r=document.createElement("button");r.className="favButton";let a=!(!e.is_favorite||"true"!==e.is_favorite.toString());r.setAttribute("aria-pressed",a),r.setAttribute("aria-label",`Make ${e.name} a favorite!`),r.innerHTML=a?"♥":"♡",r.onclick=(t=>favoriteClicked(e,r)),t.append(r);const o=document.createElement("p");o.innerHTML=e.neighborhood,t.append(o);const i=document.createElement("p");i.innerHTML=e.address,t.append(i);const l=document.createElement("a");return l.innerHTML="View Details",l.href=DBHelper.urlForRestaurant(e),t.append(l),t}),favoriteClicked=((e,t)=>{let n=!(!t.getAttribute("aria-pressed")||"true"!==t.getAttribute("aria-pressed")),s=`${DBHelper.DATABASE_URL}/${e.id}/?is_favorite=${!n}`;DBHelper.updateRestaurantCache(e.id,{is_favorite:!n}),DBHelper.addToUpdateQueue(s,"PUT"),t.setAttribute("aria-pressed",!n),t.innerHTML=n?"♡":"♥",t.onclick=(n=>favoriteClicked(e,t))}),addMarkersToMap=((e=self.restaurants)=>{e.forEach(e=>{const t=DBHelper.mapMarkerForRestaurant(e,self.map);google.maps.event.addListener(t,"click",()=>{window.location.href=t.url}),self.markers.push(t)})}); \ No newline at end of file diff --git a/dist/js/restaurant_info.js b/dist/js/restaurant_info.js index e60d699..bbc33ce 100644 --- a/dist/js/restaurant_info.js +++ b/dist/js/restaurant_info.js @@ -1 +1 @@ -let restaurant;var map;window.initMap=(()=>{fetchRestaurantFromURL((e,t)=>{e?console.error(e):(self.map=new google.maps.Map(document.getElementById("map"),{zoom:16,center:t.latlng,scrollwheel:!1}),fillBreadcrumb(),DBHelper.mapMarkerForRestaurant(self.restaurant,self.map))})}),fetchRestaurantFromURL=(e=>{if(self.restaurant)return void e(null,self.restaurant);const t=getParameterByName("id");t?DBHelper.fetchRestaurantById(t,(t,n)=>{self.restaurant=n,n?(fillRestaurantHTML(),e(null,n)):console.error(t)}):(error="No restaurant id in URL",e(error,null))}),fillRestaurantHTML=((e=self.restaurant)=>{document.getElementById("restaurant-name").innerHTML=e.name,document.getElementById("restaurant-address").innerHTML=e.address;const t=document.getElementById("restaurant-img");t.className="restaurant-img",t.src=`/img/${e.id}@1x.webp`,t.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,t.alt=e.alt_text,document.getElementById("restaurant-cuisine").innerHTML=e.cuisine_type,e.operating_hours&&fillRestaurantHoursHTML(),fillReviewsHTML()}),fillRestaurantHoursHTML=((e=self.restaurant.operating_hours)=>{const t=document.getElementById("restaurant-hours");for(let n in e){const r=document.createElement("tr"),a=document.createElement("th");a.innerHTML=n,r.appendChild(a);const l=document.createElement("td");l.innerHTML=e[n],r.appendChild(l),t.appendChild(r)}}),fillReviewsHTML=((e=self.restaurant.reviews)=>{const t=document.getElementById("reviews-container"),n=document.createElement("h3");if(n.innerHTML="Reviews",t.appendChild(n),!e){const e=document.createElement("p");return e.innerHTML="No reviews yet!",void t.appendChild(e)}const r=document.getElementById("reviews-list");e.forEach(e=>{r.appendChild(createReviewHTML(e))}),t.appendChild(r)}),createReviewHTML=(e=>{const t=document.createElement("li"),n=document.createElement("p");n.id="reviewer-name",n.innerHTML=e.name,t.appendChild(n);const r=document.createElement("p");r.innerHTML=e.date,t.appendChild(r);const a=document.createElement("p");a.innerHTML=`Rating: ${e.rating}`,t.appendChild(a);const l=document.createElement("p");var d="";for(i=0;i{const t=document.getElementById("breadcrumb"),n=document.createElement("li");n.setAttribute("aria-current","page"),n.innerHTML=e.name,t.appendChild(n)}),getParameterByName=((e,t)=>{t||(t=window.location.href),e=e.replace(/[\[\]]/g,"\\$&");const n=new RegExp(`[?&]${e}(=([^&#]*)|&|#|$)`).exec(t);return n?n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):"":null}); \ No newline at end of file +let restaurant;var map;window.initMap=(()=>{fetchRestaurantFromURL((e,t)=>{e?console.error(e):(self.map=new google.maps.Map(document.getElementById("map"),{zoom:16,center:t.latlng,scrollwheel:!1}),fillBreadcrumb(),DBHelper.mapMarkerForRestaurant(self.restaurant,self.map))}),DBHelper.pushUpdates()}),fetchRestaurantFromURL=(e=>{if(self.restaurant)return void e(null,self.restaurant);const t=getParameterByName("id");if(t)DBHelper.fetchRestaurantById(t,(t,n)=>{self.restaurant=n,n?(fillRestaurantHTML(),e(null,n)):console.error(t)});else{e("No restaurant id in URL",null)}}),fillRestaurantHTML=((e=self.restaurant)=>{const t=document.getElementById("restaurant-name");t.innerHTML=e.name;const n=document.createElement("button");n.className="favButton";let r=!(!e.is_favorite||"true"!==e.is_favorite.toString());n.setAttribute("aria-pressed",r),n.setAttribute("aria-label",`Make ${e.name} a favorite!`),n.innerHTML=r?"♥":"♡",n.onclick=(t=>favoriteClicked(e,n)),t.appendChild(n),document.getElementById("restaurant-address").innerHTML=e.address;const a=document.getElementById("restaurant-img");a.className="restaurant-img",a.src=`/img/${e.id}@1x.webp`,a.srcset=`/img/${e.id}@1x.webp 300w,\n /img/${e.id}@2x.webp 600w,\n /img/${e.id}@3x.webp 900w`,a.alt=e.alt_text,document.getElementById("restaurant-cuisine").innerHTML=e.cuisine_type,e.operating_hours&&fillRestaurantHoursHTML(),console.log(`In fillRestaurantHTML, about to call fetch then fill with id: ${e.id}`),DBHelper.fetchReviewsById(e.id).then(fillReviewsHTML(reviews))}),favoriteClicked=((e,t)=>{let n=!(!t.getAttribute("aria-pressed")||"true"!==t.getAttribute("aria-pressed")),r=`${DBHelper.DATABASE_URL}/${e.id}/?is_favorite=${!n}`;DBHelper.updateRestaurantCache(e.id,{is_favorite:!n}),DBHelper.addToUpdateQueue(r,"PUT"),t.setAttribute("aria-pressed",!n),t.innerHTML=n?"♡":"♥",t.onclick=(n=>favoriteClicked(e,t))}),fillRestaurantHoursHTML=((e=self.restaurant.operating_hours)=>{const t=document.getElementById("restaurant-hours");for(let n in e){const r=document.createElement("tr"),a=document.createElement("th");a.innerHTML=n,r.appendChild(a);const i=document.createElement("td");i.innerHTML=e[n],r.appendChild(i),t.appendChild(r)}}),fillReviewsHTML=(e=>{console.log("In fillReviewsHTML ",e);const t=document.getElementById("reviews-container"),n=document.createElement("h3");n.innerHTML="Reviews",t.appendChild(n);const r=document.createElement("button");if(r.innerHTML="Add a Review",r.id="reviewButton",r.onclick=addReviewForm,t.appendChild(r),!e){const e=document.createElement("h3");return e.innerHTML="No reviews yet!",void t.appendChild(e)}const a=document.getElementById("reviews-list");e.forEach(e=>{a.appendChild(createReviewHTML(e))}),t.appendChild(a)}),createReviewHTML=(e=>{const t=document.createElement("li"),n=document.createElement("p");n.id="reviewer-name",n.innerHTML=e.name,t.appendChild(n);const r=document.createElement("p");r.innerHTML=e.date,t.appendChild(r);const a=document.createElement("p");a.innerHTML=`Rating: ${e.rating}`,t.appendChild(a);const l=document.createElement("p");var d="";for(i=0;i{const t=document.getElementById("breadcrumb"),n=document.createElement("li");n.setAttribute("aria-current","page"),n.innerHTML=e.name,t.appendChild(n)}),getParameterByName=((e,t)=>{t||(t=window.location.href),e=e.replace(/[\[\]]/g,"\\$&");const n=new RegExp(`[?&]${e}(=([^&#]*)|&|#|$)`).exec(t);return n?n[2]?decodeURIComponent(n[2].replace(/\+/g," ")):"":null}),addReviewForm=(()=>{document.getElementById("reviewButton").style.display="none",document.getElementById("reviews-list").appendChild(reviewForm()),document.getElementById("name").focus()}),reviewForm=(()=>{let e=document.createElement("li"),t=document.createElement("form");t.id="reviewForm";let n=document.createElement("p");n.innerHTML="New Review",n.id="reviewer-name",t.appendChild(n);let r=document.createElement("p"),a=document.createElement("input"),i=document.createElement("label");i.setAttribute("for","name"),i.innerHTML="First Name: ",a.id="name",a.setAttribute("type","text"),r.appendChild(i),r.appendChild(a),t.appendChild(r),r=document.createElement("p");let l=document.createElement("label");l.setAttribute("for","rating"),l.innerText="Your rating: ",r.appendChild(l);let d=document.createElement("select");d.id="rating",d.name="rating",d.classList.add("rating"),["--",1,2,3,4,5].forEach(e=>{const t=document.createElement("option");t.value=e,t.innerHTML=e,"--"===e&&(t.selected=!0),d.appendChild(t)}),r.appendChild(d),t.appendChild(r),r=document.createElement("p");let m=document.createElement("textarea"),o=document.createElement("label");o.setAttribute("for","comments"),o.innerHTML="Comments: ",m.id="comments",m.setAttribute("rows","10"),r.appendChild(o),r.appendChild(m),r.style.display="flex",r.style.alignItems="center",t.appendChild(r),r=document.createElement("p");let c=document.createElement("button");return c.id="submitReview",c.setAttribute("type","submit"),c.innerHTML="Submit Review",r.appendChild(c),t.appendChild(r),t.onsubmit=handleSubmit,e.appendChild(t),e}),handleSubmit=(e=>{e.preventDefault();let t=self.restaurant.id,n=document.getElementById("name").value,r=document.getElementById("rating").value+0,a=document.getElementById("comments").value;DBHelper.saveReview(t,n,r,a,Date.now());let i=document.getElementById("reviewForm");i.parentNode.removeChild(i),document.getElementById("reviewButton").style.display="block"}); \ No newline at end of file diff --git a/dist/restaurant.html b/dist/restaurant.html index 7e19a1b..d816338 100644 --- a/dist/restaurant.html +++ b/dist/restaurant.html @@ -1 +1 @@ -Restaurant Info

    \ No newline at end of file +Restaurant Info

      \ No newline at end of file diff --git a/dist/sw.js b/dist/sw.js index 79cb93d..cdb96d4 100644 --- a/dist/sw.js +++ b/dist/sw.js @@ -1 +1 @@ -self.importScripts("js/dbhelper.js","js/idb.js");var myCache="restaurantReview_050",cacheFiles=["/index.html","/restaurant.html","/css/styles.css","/img/","/js/dbhelper.js","/js/main.js","/js/restaurant_info.js","/js/swregister.js","/js/idb.js"];self.addEventListener("install",function(e){e.waitUntil(caches.open(myCache).then(function(e){return e.addAll(cacheFiles).then(function(){console.log("Cache worked")}).catch(function(e){console.log("Caching failed, error: ",e)})}))}),self.addEventListener("fetch",function(e){e.respondWith(caches.match(e.request).then(function(t){return t||fetch(e.request).then(function(t){return caches.open(myCache).then(function(n){return n.put(e.request,t.clone()),t})})}))}),self.addEventListener("activate",e=>{console.log("Event trigger - activate"),DBHelper.fetchRestaurants((e,t)=>{e?callback(e,null):idb.open("restaurantReviews",1,e=>{if(!e.objectStoreNames.contains("restaurantData")){let n=e.createObjectStore("restaurantData",{keyPath:"id"});console.log(t),t.map(e=>n.add(e))}})})}); \ No newline at end of file +self.importScripts("./js/dbhelper.js","./js/idb.js");var myCache="restaurantReview_301",cacheFiles=["/index.html","/restaurant.html","/css/styles.css","/img/","/js/dbhelper.js","/js/main.js","/js/restaurant_info.js","/js/swregister.js","/js/idb.js"];const dbPromise=idb.open("restaurantReviews",3,e=>{switch(e.oldVersion){case 0:e.createObjectStore("restaurantData",{keyPath:"id"});case 1:e.createObjectStore("reviewData",{keypath:"id"}).createIndex("restaurant_id","restaurant_id");case 2:e.createObjectStore("updateData",{keyPath:"id",autoIncrement:!0})}});function apiFetch(e,t){if(console.log(`In apiFetch - event: ${e} id: ${t}`),"POST"==e.request.method||"PUT"==e.request.method)return fetch(e.request).then(function(e){return e.json()});e.request.url.indexOf("restaurants")>-1&&e.respondWith(dbPromise.then(function(e){return e.transaction("restaurantData").objectStore("restaurantData").get(t)}).then(function(n){return n&&n.data||fetch(e.request).then(function(e){return dbPromise.then(function(n){return n.transaction("restaurantData","readwrite").objectStore("restaurantData").put({id:t,data:e.json()}),e.json()})})}).then(function(e){return new Response(JSON.stringify(e))}).catch(function(e){console.log(`In apiFetch catch-restaurantData, error: ${e.message}`)})),e.respondWith(dbPromise.then(function(e){return e.transaction("reviewData").objectStore("reviewData").index("restaurant_id").getAll(t)}).then(function(t){return t&&t.data||fetch(e.request).then(function(e){return dbPromise.then(function(t){let n=t.transaction("reviewData","readwrite").objectStore("reviewData");return e.json().forEach(function(e){n.put({id:e.id,restaurant_id:e.restaurant_id,data:e})}),e.json()})})}).then(function(e){if(e[0].data){let t=e.map(e=>e.data);return new Response(JSON.stringify(t))}return new Response(JSON.stringify(e))}).catch(function(e){console.log(`In apiFetch catch-reviewData, error: ${e.message}`)}))}function cacheFetch(e,t){console.log(`In cacheFetch - event: ${e} request: ${t}`),e.respondWith(caches.match(t)).then(function(t){return t||fetch(e.request).then(function(t){return caches.open(myCache).then(function(n){return-1===t.url.indexOf("browsersync")&&n.put(e.request,t.clone()),t})}).catch(function(e){console.log(`In cacheFetch catch, error: ${e.message}`)})})}self.addEventListener("install",function(e){console.log("In eventListener for install, event: ",e),e.waitUntil(caches.open(myCache).then(function(e){return e.addAll(cacheFiles).then(function(){console.log("Cache worked!")}).catch(function(e){console.log("Caching failed, error: ",e)})}))}),self.addEventListener("fetch",function(e){console.log("In eventListener for fetch, event: ",e);let t=new URL(e.request.url);if("1337"===t.port){let n=t.searchParams.get("restaurant_id")-0;if(n){let t=e.request;t.url.indexOf("restaurant.html")>-1&&(t=new Request("restaurant.html")),cacheFetch(e,t)}else{if(t.pathname.indexOf("restaurants")){let e=t.pathname.split("/");n="restaurants"===e[e.length-1]?"-1":e[e.length-1]}else n=t.searchParams.get("restaurant_id");apiFetch(e,n)}}}); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 86e2dea..249ded6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,63 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "accepts": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz", @@ -14,12 +71,36 @@ "negotiator": "0.6.1" } }, + "acorn": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.2.tgz", + "integrity": "sha512-GXmKIvbrN3TV7aVqAzVFaMW8F8wzVX7voEBRO3bDA64+EX37YSayggRJP5Xig6HYHBkWKpFg9W5gg6orklubhg==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.0.tgz", + "integrity": "sha512-XkB50fn0MURDyww9+UYL3c1yLbOBz0ZFvrdYlGB8l+Ije1oSC75qAqrzSPjYQbdnQUzhlUGNKuesryAv0gxZOg==", + "dev": true + }, "after": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", "dev": true }, + "ajv": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.4.tgz", + "integrity": "sha512-4Wyjt8+t6YszqaXnLDfMmG/8AlO5Zbcsy3ATHncCzjW/NoPzAId8AK6749Ybjmdt+kUY1gP60fCu46oDxPv/mg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, "ansi-colors": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz", @@ -38,6 +119,12 @@ "ansi-wrap": "0.1.0" } }, + "ansi-escapes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", + "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "dev": true + }, "ansi-gray": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", @@ -75,104 +162,13 @@ "dev": true }, "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" - }, - "dependencies": { - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "^1.0.1" - } - }, - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" - } - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "^0.1.0" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "^1.0.0" - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "^2.0.0", - "array-unique": "^0.2.1", - "braces": "^1.8.2", - "expand-brackets": "^0.1.4", - "extglob": "^0.3.1", - "filename-regex": "^2.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.1", - "kind-of": "^3.0.2", - "normalize-path": "^2.0.1", - "object.omit": "^2.0.0", - "parse-glob": "^3.0.4", - "regex-cache": "^0.4.2" - } - } + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" } }, "archive-type": { @@ -203,7 +199,6 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, - "optional": true, "requires": { "sprintf-js": "~1.0.2" } @@ -277,6 +272,12 @@ "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", "dev": true }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", @@ -704,9 +705,9 @@ } }, "binary-extensions": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz", - "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=", + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz", + "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==", "dev": true }, "bl": { @@ -752,9 +753,9 @@ } }, "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz", + "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig==", "dev": true }, "boolbase": { @@ -803,32 +804,35 @@ } }, "browser-sync": { - "version": "2.24.6", - "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.24.6.tgz", - "integrity": "sha512-3cVW8Ft3sPQ1t9gqZXBDZhTyRce8NW4wf5KzpCYcg6fWjPbyt+vZLvEo+sTq7c7eNQhi8lInQWbjIFEpoM2f7Q==", + "version": "2.26.3", + "resolved": "https://registry.npmjs.org/browser-sync/-/browser-sync-2.26.3.tgz", + "integrity": "sha512-VLzpjCA4uXqfzkwqWtMM6hvPm2PNHp2RcmzBXcbi6C9WpkUhhFb8SVAr4CFrCsFxDg+oY6HalOjn8F+egyvhag==", "dev": true, "requires": { - "browser-sync-ui": "v1.0.1", + "browser-sync-client": "^2.26.2", + "browser-sync-ui": "^2.26.2", "bs-recipes": "1.3.4", - "chokidar": "1.7.0", + "bs-snippet-injector": "^2.0.1", + "chokidar": "^2.0.4", "connect": "3.6.6", - "connect-history-api-fallback": "^1.5.0", + "connect-history-api-fallback": "^1", "dev-ip": "^1.0.1", - "easy-extender": "2.3.2", - "eazy-logger": "3.0.2", + "easy-extender": "^2.3.4", + "eazy-logger": "^3", "etag": "^1.8.1", "fresh": "^0.5.2", "fs-extra": "3.0.1", "http-proxy": "1.15.2", - "immutable": "3.8.2", - "localtunnel": "1.9.0", + "immutable": "^3", + "localtunnel": "1.9.1", "micromatch": "2.3.11", - "opn": "4.0.2", + "opn": "5.3.0", "portscanner": "2.1.1", "qs": "6.2.3", "raw-body": "^2.3.2", "resp-modifier": "6.0.2", "rx": "4.1.0", + "send": "0.16.2", "serve-index": "1.9.1", "serve-static": "1.13.2", "server-destroy": "1.0.1", @@ -928,17 +932,29 @@ } } }, + "browser-sync-client": { + "version": "2.26.2", + "resolved": "https://registry.npmjs.org/browser-sync-client/-/browser-sync-client-2.26.2.tgz", + "integrity": "sha512-FEuVJD41fI24HJ30XOT2RyF5WcnEtdJhhTqeyDlnMk/8Ox9MZw109rvk9pdfRWye4soZLe+xcAo9tHSMxvgAdw==", + "dev": true, + "requires": { + "etag": "1.8.1", + "fresh": "0.5.2", + "mitt": "^1.1.3", + "rxjs": "^5.5.6" + } + }, "browser-sync-ui": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-1.0.1.tgz", - "integrity": "sha512-RIxmwVVcUFhRd1zxp7m2FfLnXHf59x4Gtj8HFwTA//3VgYI3AKkaQAuDL8KDJnE59XqCshxZa13JYuIWtZlKQg==", + "version": "2.26.2", + "resolved": "https://registry.npmjs.org/browser-sync-ui/-/browser-sync-ui-2.26.2.tgz", + "integrity": "sha512-LF7GMWo8ELOE0eAlxuRCfnGQT1ZxKP9flCfGgZdXFc6BwmoqaJHlYe7MmVvykKkXjolRXTz8ztXAKGVqNwJ3EQ==", "dev": true, "requires": { "async-each-series": "0.1.1", - "connect-history-api-fallback": "^1.1.0", - "immutable": "^3.7.6", + "connect-history-api-fallback": "^1", + "immutable": "^3", "server-destroy": "1.0.1", - "socket.io-client": "2.0.4", + "socket.io-client": "^2.0.4", "stream-throttle": "^0.1.3" }, "dependencies": { @@ -956,6 +972,12 @@ "integrity": "sha1-DS1NSKcYyMBEdp/cT4lZLci2lYU=", "dev": true }, + "bs-snippet-injector": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/bs-snippet-injector/-/bs-snippet-injector-2.0.1.tgz", + "integrity": "sha1-YbU5PxH1JVntEgaTEANDtu2wTdU=", + "dev": true + }, "buffer-alloc": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", @@ -1153,12 +1175,27 @@ } } }, + "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" + } + }, "callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", "dev": true }, + "callsites": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true + }, "camel-case": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", @@ -1216,49 +1253,50 @@ "supports-color": "^2.0.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", + "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { - "anymatch": "^1.3.0", + "anymatch": "^2.0.0", "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", + "braces": "^2.3.0", + "fsevents": "^1.2.2", + "glob-parent": "^3.1.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", + "is-glob": "^4.0.0", + "lodash.debounce": "^4.0.8", + "normalize-path": "^2.1.1", "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "readdirp": "^2.0.0", + "upath": "^1.0.5" }, "dependencies": { - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "^2.0.0" - } - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "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": "^1.0.0" + "is-extglob": "^2.1.1" } } } }, + "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 + }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", @@ -1299,6 +1337,21 @@ } } }, + "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 + }, "cliui": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", @@ -1529,6 +1582,12 @@ "integrity": "sha1-oJX+B7IEZZVfL6/Si11yvM2UnUQ=", "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 + }, "convert-source-map": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", @@ -2203,6 +2262,12 @@ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", "dev": true }, + "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 + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -2323,6 +2388,15 @@ "integrity": "sha1-p2o+0YVb56ASu4rBbLgPPADcKPA=", "dev": true }, + "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-serializer": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz", @@ -2729,18 +2803,18 @@ } }, "easy-extender": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.2.tgz", - "integrity": "sha1-PTJI/r4rFZYHMW2PnPSRwWZIIh0=", + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/easy-extender/-/easy-extender-2.3.4.tgz", + "integrity": "sha512-8cAwm6md1YTiPpOvDULYJL4ZS6WfM5/cTeVVh4JsvyYZAoqlRVUpHL9Gr5Fy7HA6xcSZicUia3DeAgO3Us8E+Q==", "dev": true, "requires": { - "lodash": "^3.10.1" + "lodash": "^4.17.10" }, "dependencies": { "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", "dev": true } } @@ -2776,9 +2850,9 @@ } }, "engine.io": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.0.tgz", - "integrity": "sha512-mRbgmAtQ4GAlKwuPnnAvXXwdPhEx+jkc0OBCLrXuD/CRvwNK3AxRSnqK4FSqmAMRRHryVJP8TopOvmEaA64fKw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.2.1.tgz", + "integrity": "sha512-+VlKzHzMhaU+GsCIg4AoXF1UdDFjHHwMmMKqMJNDNLlUlejz58FCy4LBqB2YVJskHGYl06BatYWKP2TVdVXE5w==", "dev": true, "requires": { "accepts": "~1.3.4", @@ -2801,9 +2875,9 @@ } }, "engine.io-client": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", + "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -2825,82 +2899,487 @@ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", "dev": true, "requires": { - "ms": "2.0.0" + "ms": "2.0.0" + } + } + } + }, + "engine.io-parser": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz", + "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==", + "dev": true, + "requires": { + "after": "0.8.2", + "arraybuffer.slice": "~0.0.7", + "base64-arraybuffer": "0.1.5", + "blob": "0.0.5", + "has-binary2": "~1.0.2" + } + }, + "entities": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", + "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", + "dev": true, + "optional": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", + "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", + "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.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.1" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "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 + }, + "eslint": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.8.0.tgz", + "integrity": "sha512-Zok6Bru3y2JprqTNm14mgQ15YQu/SMDkWdnmHfFg770DIUlmMFd/gqqzCHekxzjHZJxXv3tmTpH0C1icaYJsRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.5.3", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^2.1.0", + "eslint-scope": "^4.0.0", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^4.0.0", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^2.0.0", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "imurmurhash": "^0.1.4", + "inquirer": "^6.1.0", + "is-resolvable": "^1.1.0", + "js-yaml": "^3.12.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.5", + "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", + "regexpp": "^2.0.1", + "require-uncached": "^1.0.3", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.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 + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz", + "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "globals": { + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz", + "integrity": "sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA==", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha512-PIt2cnwmPfL4hKNwqeiuz4bKfnzHTBv6HyVgjahA6mPLwPDzjDWrplJBMjHUFxku/N3FlmrbyPclad+I+4mJ3A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "eslint-config-google": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-google/-/eslint-config-google-0.11.0.tgz", + "integrity": "sha512-z541Fs5TFaY7/35v/z100InQ2f3V2J7e3u/0yKrnImgsHjh6JWgSRngfC/mZepn/+XN16jUydt64k//kxXc1fw==", + "dev": true + }, + "eslint-config-standard": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-12.0.0.tgz", + "integrity": "sha512-COUz8FnXhqFitYj4DTqHzidjIL/t4mumGZto5c7DrBpvWoie+Sn3P4sLEzUGeYhRElWuFEf8K1S1EfvD1vixCQ==", + "dev": true + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz", + "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^1.0.0" + } + }, + "eslint-plugin-es": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-1.3.1.tgz", + "integrity": "sha512-9XcVyZiQRVeFjqHw8qHNDAZcQLqaHlOGGpeYqzYh8S4JYCWTCO3yzyen8yVmA5PratfzTRWDwCOFphtDEG+w/w==", + "dev": true, + "requires": { + "eslint-utils": "^1.3.0", + "regexpp": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.14.0.tgz", + "integrity": "sha512-FpuRtniD/AY6sXByma2Wr0TXvXJ4nA/2/04VPlfpmUDPOpOY264x+ILiwnrk/k4RINgDAyFZByxqPUbSQ5YE7g==", + "dev": true, + "requires": { + "contains-path": "^0.1.0", + "debug": "^2.6.8", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.1", + "eslint-module-utils": "^2.2.0", + "has": "^1.0.1", + "lodash": "^4.17.4", + "minimatch": "^3.0.3", + "read-pkg-up": "^2.0.0", + "resolve": "^1.6.0" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "graceful-fs": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.13.tgz", + "integrity": "sha512-a3u3Sck0c7/X622CIqiU0q/eRmhEOssVa3jkrfRRxxHPzaW1EcZgsQt87zKipdteGmFEKGGBvIBPr13pCB2HYw==", + "dev": true + }, + "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": "http://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.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "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.0.0" + } + }, + "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.3.2", + "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.0.0", + "read-pkg": "^2.0.0" } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true } } }, - "engine.io-parser": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "eslint-plugin-node": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-8.0.0.tgz", + "integrity": "sha512-Y+ln8iQ52scz9+rSPnSWRaAxeWaoJZ4wIveDR0vLHkuSZGe44Vk1J4HX7WvEP5Cm+iXPE8ixo7OM7gAO3/OKpQ==", "dev": true, "requires": { - "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary2": "~1.0.2" + "eslint-plugin-es": "^1.3.1", + "eslint-utils": "^1.3.1", + "ignore": "^5.0.2", + "minimatch": "^3.0.4", + "resolve": "^1.8.1", + "semver": "^5.5.0" + }, + "dependencies": { + "ignore": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.0.3.tgz", + "integrity": "sha512-jJ7mKezpwiCj29DWDPORNJ6P90RpT2i4kfKLxioSb0VcGnoWuib5eg9dOXR45bghMYxVNUeKoJR1UGJ/sS3Oqw==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + } } }, - "entities": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz", - "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=", - "dev": true, - "optional": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } + "eslint-plugin-promise": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.0.1.tgz", + "integrity": "sha512-Si16O0+Hqz1gDHsys6RtFRrW7cCTB6P7p3OJmKp3Y3dxpQE2qwOA7d3xnV+0mBmrPoi0RBnxlCKvqu70te6wjg==", + "dev": true }, - "es-abstract": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.12.0.tgz", - "integrity": "sha512-C8Fx/0jFmV5IPoMOFPA9P9G5NtqW+4cOPit3MIuvR2t7Ag2K15EJTpxnHAYTzL+aYQJIESYeXZmDBfOBE1HcpA==", - "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" - } + "eslint-plugin-standard": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-4.0.0.tgz", + "integrity": "sha512-OwxJkR6TQiYMmt1EsNRMe5qG3GsbjlcOhbGUBY4LtavF9DsLaTcoR+j2Tdjqi23oUwKNUqX7qcn5fPStafMdlA==", + "dev": true }, - "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=", + "eslint-scope": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.0.tgz", + "integrity": "sha512-1G6UTDi7Jc1ELFwnR58HV4fK9OQK4S6N985f166xqXxpjU6plxFISJa2Ba9KCQuFa8RCnj/lSFJbHo7UFDBnUA==", "dev": true, "requires": { - "is-callable": "^1.1.1", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" } }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", "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-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", "dev": true }, + "espree": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-4.1.0.tgz", + "integrity": "sha512-I5BycZW6FCVIub93TeVY1s7vjhP9CY6cXCznIRfiig7nRviKZYdRnj/sHEWC6A7WE9RDWOFq9+7OsWSYz8qv2w==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", "dev": true, - "optional": true + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "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", @@ -3114,6 +3593,28 @@ } } }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -3190,6 +3691,24 @@ "time-stamp": "^1.0.0" } }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "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 + }, "fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -3217,6 +3736,24 @@ } } }, + "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.2.1", + "object-assign": "^4.0.1" + }, + "dependencies": { + "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 + } + } + }, "file-type": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-4.4.0.tgz", @@ -3349,13 +3886,82 @@ "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", "dev": true }, + "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.1", + "del": "^2.0.2", + "graceful-fs": "^4.1.2", + "write": "^0.2.1" + }, + "dependencies": { + "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.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "rimraf": "^2.2.8" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "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.1", + "arrify": "^1.0.0", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.13.tgz", + "integrity": "sha512-a3u3Sck0c7/X622CIqiU0q/eRmhEOssVa3jkrfRRxxHPzaW1EcZgsQt87zKipdteGmFEKGGBvIBPr13pCB2HYw==", + "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 + } + } + }, "follow-redirects": { - "version": "1.5.7", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.7.tgz", - "integrity": "sha512-NONJVIFiX7Z8k2WxfqBjtwqMifx7X42ORLFrOZ2LTKGj71G3C0kfdyTqGqr8fx5zSX6Foo/D95dgGWbPUiwnew==", + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz", + "integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==", "dev": true, "requires": { - "debug": "^3.1.0" + "debug": "=3.1.0" }, "dependencies": { "debug": { @@ -3965,6 +4571,12 @@ "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 + }, "gaze": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/gaze/-/gaze-0.5.2.tgz", @@ -4030,6 +4642,17 @@ "inherits": "2", "minimatch": "^2.0.1", "once": "^1.3.0" + }, + "dependencies": { + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "^1.0.0" + } + } } }, "glob-base": { @@ -4092,6 +4715,15 @@ "unique-stream": "^1.0.0" }, "dependencies": { + "minimatch": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", + "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "dev": true, + "requires": { + "brace-expansion": "^1.0.0" + } + }, "readable-stream": { "version": "1.0.34", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", @@ -5126,6 +5758,12 @@ "safer-buffer": ">= 2.1.2 < 3" } }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, "imagemin": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-5.3.1.tgz", @@ -5223,6 +5861,12 @@ "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=", "dev": true }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, "indent-string": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", @@ -5260,6 +5904,113 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true }, + "inquirer": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.0.tgz", + "integrity": "sha512-QIEQG4YyQ2UYZGDC4srMZ7BjHOmNk1lR2JQj5UknBapklm6WHA+VVH7N+sUdX3A7NeCfGF8o4X1S3Ao7nAcIeg==", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.0", + "figures": "^2.0.0", + "lodash": "^4.17.10", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.1.0", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "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 + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", + "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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" + } + }, + "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 + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "rxjs": { + "version": "6.3.3", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.3.3.tgz", + "integrity": "sha512-JTWmoY9tWCs7zvIk/CvRjhjGaOd+OVBM987mxFo+OW66cGpdKjZcpmc74ES1sB//7Kl/PAe8+wEakuhG4pcgOw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "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" + } + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "interpret": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz", @@ -5594,6 +6345,12 @@ "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", "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-redirect": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", @@ -5618,6 +6375,12 @@ "is-unc-path": "^1.0.0" } }, + "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", @@ -5685,6 +6448,12 @@ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", "dev": true }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, "is-zip": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-zip/-/is-zip-1.0.0.tgz", @@ -5744,6 +6513,12 @@ "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "json-stable-stringify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", @@ -5753,6 +6528,12 @@ "jsonify": "~0.0.0" } }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json5": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", @@ -5845,6 +6626,16 @@ "invert-kv": "^1.0.0" } }, + "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" + } + }, "liftoff": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", @@ -5898,13 +6689,13 @@ } }, "localtunnel": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.0.tgz", - "integrity": "sha512-wCIiIHJ8kKIcWkTQE3m1VRABvsH2ZuOkiOpZUofUCf6Q42v3VIZ+Q0YfX1Z4sYDRj0muiKL1bLvz1FeoxsPO0w==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/localtunnel/-/localtunnel-1.9.1.tgz", + "integrity": "sha512-HWrhOslklDvxgOGFLxi6fQVnvpl6XdX4sPscfqMZkzi3gtt9V7LKBWYvNUcpHSVvjwCQ6xzXacVvICNbNcyPnQ==", "dev": true, "requires": { "axios": "0.17.1", - "debug": "2.6.8", + "debug": "2.6.9", "openurl": "1.1.1", "yargs": "6.6.0" }, @@ -5915,15 +6706,6 @@ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", "dev": true }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, "yargs": { "version": "6.6.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", @@ -5947,6 +6729,24 @@ } } }, + "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": "1.0.2", "resolved": "https://registry.npmjs.org/lodash/-/lodash-1.0.2.tgz", @@ -6007,6 +6807,12 @@ "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", "dev": true }, + "lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", + "dev": true + }, "lodash.escape": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", @@ -6318,27 +7124,33 @@ "dev": true }, "mime-db": { - "version": "1.35.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.35.0.tgz", - "integrity": "sha512-JWT/IcCTsB0Io3AhWUMjRqucrHSPsSf2xKLaRldJVULioggvkJvggZ3VXNNSRkCddE6D+BUI4HEIZIA2OjwIvg==", + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", "dev": true }, "mime-types": { - "version": "2.1.19", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.19.tgz", - "integrity": "sha512-P1tKYHVSZ6uFo26mtnve4HQFE3koh1UWVkp8YUC+ESBHe945xWSoXuHHiGarDqcEZ+whpCDnlNw5LON0kLo+sw==", + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", "dev": true, "requires": { - "mime-db": "~1.35.0" + "mime-db": "~1.37.0" } }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", + "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.0.0" + "brace-expansion": "^1.1.7" } }, "minimist": { @@ -6347,6 +7159,12 @@ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true }, + "mitt": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-1.1.3.tgz", + "integrity": "sha512-mUDCnVNsAi+eD6qA0HkRkwYczbLHJ49z17BGe2PYRhZL4wpZUFZGJHU7/5tmvohoma+Hdn0Vh/oJTiPEmgSruA==", + "dev": true + }, "mixin-deep": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", @@ -6415,10 +7233,16 @@ "duplexer2": "0.0.2" } }, + "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.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", + "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", "dev": true, "optional": true }, @@ -6447,12 +7271,24 @@ "integrity": "sha512-Q29yeg9aFKwhLVdkTAejM/HvYG0Y1Am1+HUkFQGn5k2j8GS+v60TVmZh6nujpEAj/qql+wGUrlryO8bF+b1jEg==", "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 + }, "negotiator": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz", "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=", "dev": true }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, "no-case": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", @@ -6692,21 +7528,26 @@ "dev": true }, "opn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/opn/-/opn-4.0.2.tgz", - "integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=", + "version": "5.3.0", + "resolved": "http://registry.npmjs.org/opn/-/opn-5.3.0.tgz", + "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==", "dev": true, "requires": { - "object-assign": "^4.0.1", - "pinkie-promise": "^2.0.0" - }, - "dependencies": { - "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 - } + "is-wsl": "^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.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" } }, "optipng-bin": { @@ -6771,6 +7612,24 @@ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", "dev": true }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "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.1.0" + } + }, "p-map": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", @@ -6783,6 +7642,12 @@ "integrity": "sha1-SxoROZoRUgpneQ7loMHViB1r7+k=", "dev": true }, + "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 + }, "param-case": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", @@ -6908,8 +7773,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true, - "optional": true + "dev": true }, "path-parse": { "version": "1.0.6", @@ -6978,6 +7842,15 @@ "pinkie": "^2.0.0" } }, + "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.0.0" + } + }, "plugin-error": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", @@ -6999,6 +7872,12 @@ "irregular-plurals": "^1.0.0" } }, + "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 + }, "portscanner": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/portscanner/-/portscanner-2.1.1.tgz", @@ -7015,6 +7894,12 @@ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", "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", @@ -7051,6 +7936,12 @@ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true }, + "progress": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", + "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", + "dev": true + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -7058,6 +7949,12 @@ "dev": true, "optional": true }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, "q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -7196,15 +8093,14 @@ } }, "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "minimatch": "^3.0.2", - "readable-stream": "^2.0.2", - "set-immediate-shim": "^1.0.1" + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" }, "dependencies": { "graceful-fs": { @@ -7219,15 +8115,6 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "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.7" - } - }, "readable-stream": { "version": "2.3.6", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", @@ -7298,6 +8185,12 @@ "safe-regex": "^1.1.0" } }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, "relateurl": { "version": "0.2.7", "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", @@ -7349,6 +8242,16 @@ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", "dev": true }, + "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.0" + } + }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -7374,6 +8277,12 @@ "global-modules": "^1.0.0" } }, + "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", @@ -7388,15 +8297,25 @@ "requires": { "debug": "^2.2.0", "minimatch": "^3.0.2" + } + }, + "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.0", + "signal-exit": "^3.0.2" }, "dependencies": { - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "mimic-fn": "^1.0.0" } } } @@ -7441,12 +8360,30 @@ } } }, + "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 }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "dev": true, + "requires": { + "symbol-observable": "1.0.1" + } + }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", @@ -7638,7 +8575,6 @@ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", "dev": true, - "optional": true, "requires": { "shebang-regex": "^1.0.0" } @@ -7647,8 +8583,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true, - "optional": true + "dev": true }, "sigmund": { "version": "1.0.1", @@ -7668,6 +8603,23 @@ "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "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" + }, + "dependencies": { + "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 + } + } + }, "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", @@ -7797,64 +8749,6 @@ "requires": { "ms": "2.0.0" } - }, - "engine.io-client": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.2.1.tgz", - "integrity": "sha512-y5AbkytWeM4jQr7m/koQLc5AxpRKC1hEVUb/s1FUAWEJq5AzJJ4NLvzuKPuxtDi5Mq755WuDvZ6Iv2rXj4PTzw==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "~3.3.1", - "xmlhttprequest-ssl": "~1.5.4", - "yeast": "0.1.2" - } - }, - "isarray": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz", - "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=", - "dev": true - }, - "socket.io-client": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", - "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", - "dev": true, - "requires": { - "backo2": "1.0.2", - "base64-arraybuffer": "0.1.5", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "engine.io-client": "~3.2.0", - "has-binary2": "~1.0.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "socket.io-parser": "~3.2.0", - "to-array": "0.1.4" - } - }, - "socket.io-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", - "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "debug": "~3.1.0", - "isarray": "2.0.1" - } } } }, @@ -7865,35 +8759,46 @@ "dev": true }, "socket.io-client": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz", - "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.1.1.tgz", + "integrity": "sha512-jxnFyhAuFxYfjqIgduQlhzqTcOEQSn+OHKVfAxWaNWa7ecP7xSNk2Dx/3UEsDcY7NcFafxvNvKPmmO7HTwTxGQ==", "dev": true, "requires": { "backo2": "1.0.2", "base64-arraybuffer": "0.1.5", "component-bind": "1.0.0", "component-emitter": "1.2.1", - "debug": "~2.6.4", - "engine.io-client": "~3.1.0", + "debug": "~3.1.0", + "engine.io-client": "~3.2.0", + "has-binary2": "~1.0.2", "has-cors": "1.1.0", "indexof": "0.0.1", "object-component": "0.0.3", "parseqs": "0.0.5", "parseuri": "0.0.5", - "socket.io-parser": "~3.1.1", + "socket.io-parser": "~3.2.0", "to-array": "0.1.4" + }, + "dependencies": { + "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" + } + } } }, "socket.io-parser": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.2.0.tgz", + "integrity": "sha512-FYiBx7rc/KORMJlgsXysflWx/RIvtqZbyGLlHZvjfmPTPeuD/I8MaW7cfFrj5tRltICJdgwflhfZ3NVVbVLFQA==", "dev": true, "requires": { "component-emitter": "1.2.1", "debug": "~3.1.0", - "has-binary2": "~1.0.2", "isarray": "2.0.1" }, "dependencies": { @@ -7999,8 +8904,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true, - "optional": true + "dev": true }, "squeak": { "version": "1.3.0", @@ -8283,6 +9187,63 @@ "util.promisify": "~1.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 + }, + "table": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/table/-/table-5.1.0.tgz", + "integrity": "sha512-e542in22ZLhD/fOIuXs/8yDZ9W61ltF8daM88rkRNtgTIct+vI2fTnAyu/Db2TCfEcI8i7mjZz6meLq0nW7TYg==", + "dev": true, + "requires": { + "ajv": "^6.5.3", + "lodash": "^4.17.10", + "slice-ansi": "1.0.0", + "string-width": "^2.1.1" + }, + "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 + }, + "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 + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "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" + } + }, + "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" + } + } + } + }, "tar-stream": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", @@ -8401,6 +9362,12 @@ } } }, + "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 + }, "tfunk": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/tfunk/-/tfunk-3.1.0.tgz", @@ -8411,6 +9378,12 @@ "object-path": "^0.9.0" } }, + "through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, "through2": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", @@ -8493,6 +9466,15 @@ "integrity": "sha1-lYYL/MXHbCd/j4Mm/Q9bLiDrohc=", "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" + } + }, "to-absolute-glob": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-0.1.1.tgz", @@ -8600,12 +9582,27 @@ "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", "dev": true }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, "tunnel-agent": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.4.3.tgz", "integrity": "sha1-Y3PbdpCf5XDgjXNYM2Xtgop07us=", "dev": 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": { + "prelude-ls": "~1.1.2" + } + }, "typedarray": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", @@ -8784,12 +9781,27 @@ "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4=", "dev": true }, + "upath": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true + }, "upper-case": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", "dev": true }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", @@ -9035,6 +10047,12 @@ "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", "dev": true }, + "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", @@ -9060,6 +10078,15 @@ "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" + } + }, "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", diff --git a/package.json b/package.json index ccf226c..e7ac935 100644 --- a/package.json +++ b/package.json @@ -23,8 +23,15 @@ "homepage": "https://github.com/Piinks/MobileWebSpecialistND#readme", "devDependencies": { "babel-core": "^6.26.3", - "browser-sync": "^2.24.6", + "browser-sync": "^2.26.3", "del": "^3.0.0", + "eslint": "^5.8.0", + "eslint-config-google": "^0.11.0", + "eslint-config-standard": "^12.0.0", + "eslint-plugin-import": "^2.14.0", + "eslint-plugin-node": "^8.0.0", + "eslint-plugin-promise": "^4.0.1", + "eslint-plugin-standard": "^4.0.0", "gulp": "^3.9.1", "gulp-babel": "^7.0.1", "gulp-cache": "^1.0.2",