From 1250f3fd5e1b89eac4e1172018b8e355bf249b5b Mon Sep 17 00:00:00 2001 From: Mo Bitar Date: Thu, 19 Jul 2018 22:25:14 -0500 Subject: [PATCH] Session history --- .../javascripts/app/controllers/editor.js | 4 +- .../app/directives/views/menuRow.js | 2 +- .../directives/views/revisionPreviewModal.js | 49 + .../directives/views/sessionHistoryMenu.js | 72 ++ .../app/services/actionsManager.js | 8 +- .../app/services/sessionHistory.js | 213 +++++ app/assets/stylesheets/app/_modals.scss | 7 + app/assets/stylesheets/app/_stylekit-sub.scss | 6 + .../revision-preview-modal.html.haml | 13 + .../directives/session-history-menu.html.haml | 31 + app/assets/templates/editor.html.haml | 4 + package-lock.json | 888 +----------------- package.json | 2 +- 13 files changed, 456 insertions(+), 843 deletions(-) create mode 100644 app/assets/javascripts/app/directives/views/revisionPreviewModal.js create mode 100644 app/assets/javascripts/app/directives/views/sessionHistoryMenu.js create mode 100644 app/assets/javascripts/app/services/sessionHistory.js create mode 100644 app/assets/templates/directives/revision-preview-modal.html.haml create mode 100644 app/assets/templates/directives/session-history-menu.html.haml diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index b6943eb37..922115c29 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -22,7 +22,9 @@ angular.module('app') } } }) - .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager, syncManager, modelManager, themeManager, componentManager, storageManager) { + .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager, syncManager, modelManager, themeManager, componentManager, storageManager, sessionHistory) { + + this.showSessionHistory = true; this.spellcheck = true; this.componentManager = componentManager; diff --git a/app/assets/javascripts/app/directives/views/menuRow.js b/app/assets/javascripts/app/directives/views/menuRow.js index 468212fd2..cb6c791e7 100644 --- a/app/assets/javascripts/app/directives/views/menuRow.js +++ b/app/assets/javascripts/app/directives/views/menuRow.js @@ -7,7 +7,7 @@ class MenuRow { this.scope = { circle: "=", label: "=", - subtite: "=", + subtitle: "=", hasButton: "=", buttonText: "=", buttonClass: "=", diff --git a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js new file mode 100644 index 000000000..b83c7067e --- /dev/null +++ b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js @@ -0,0 +1,49 @@ +class RevisionPreviewModal { + + constructor() { + this.restrict = "E"; + this.templateUrl = "directives/revision-preview-modal.html"; + this.scope = { + revision: "=", + show: "=", + callback: "=" + }; + } + + link($scope, el, attrs) { + + $scope.dismiss = function() { + el.remove(); + } + } + + controller($scope, modelManager, syncManager) { + 'ngInject'; + + $scope.restore = function(asCopy) { + if(!asCopy && !confirm("Are you sure you want to replace the current note's contents with what you see in this preview?")) { + return; + } + + var item; + if(asCopy) { + var contentCopy = Object.assign({}, $scope.revision.content); + if(contentCopy.title) { contentCopy.title += " (copy)"; } + item = modelManager.createItem({content_type: "Note", content: contentCopy}); + modelManager.addItem(item); + } else { + item = modelManager.findItem($scope.revision.itemUuid); + item.content = Object.assign({}, $scope.revision.content); + item.mapContentToLocalProperties(item.content); + } + item.setDirty(true); + syncManager.sync(); + + $scope.dismiss(); + } + + } + +} + +angular.module('app').directive('revisionPreviewModal', () => new RevisionPreviewModal); diff --git a/app/assets/javascripts/app/directives/views/sessionHistoryMenu.js b/app/assets/javascripts/app/directives/views/sessionHistoryMenu.js new file mode 100644 index 000000000..859c32680 --- /dev/null +++ b/app/assets/javascripts/app/directives/views/sessionHistoryMenu.js @@ -0,0 +1,72 @@ +class SessionHistoryMenu { + + constructor() { + this.restrict = "E"; + this.templateUrl = "directives/session-history-menu.html"; + this.scope = { + item: "=" + }; + } + + controller($scope, modelManager, sessionHistory, actionsManager, $timeout) { + 'ngInject'; + + $scope.diskEnabled = sessionHistory.diskEnabled; + + $scope.reloadHistory = function() { + $scope.history = sessionHistory.historyForItem($scope.item); + } + $scope.reloadHistory(); + + $scope.openRevision = function(revision) { + actionsManager.presentRevisionPreviewModal(revision); + } + + $scope.classForRevision = function(revision) { + var vector = revision.operationVector(); + if(vector == 0) { + return "default"; + } else if(vector == 1) { + return "success"; + } else if(vector == -1) { + return "danger"; + } + } + + $scope.clearItemHistory = function() { + if(!confirm("Are you sure you want to delete the local session history for this note?")) { + return; + } + + sessionHistory.clearItemHistory($scope.item).then(() => { + $timeout(() => { + $scope.reloadHistory(); + }) + }); + } + + $scope.clearAllHistory = function() { + if(!confirm("Are you sure you want to delete the local session history for all notes?")) { + return; + } + + sessionHistory.clearAllHistory().then(() => { + $timeout(() => { + $scope.reloadHistory(); + }) + }); + } + + $scope.toggleDiskSaving = function() { + sessionHistory.toggleDiskSaving().then(() => { + $timeout(() => { + $scope.diskEnabled = sessionHistory.diskEnabled; + }) + }); + } + + } + +} + +angular.module('app').directive('sessionHistoryMenu', () => new SessionHistoryMenu); diff --git a/app/assets/javascripts/app/services/actionsManager.js b/app/assets/javascripts/app/services/actionsManager.js index 017b16b40..7790262cf 100644 --- a/app/assets/javascripts/app/services/actionsManager.js +++ b/app/assets/javascripts/app/services/actionsManager.js @@ -198,8 +198,14 @@ class ActionsManager { }) } - presentPasswordModal(callback) { + presentRevisionPreviewModal(revision) { + var scope = this.$rootScope.$new(true); + scope.revision = revision; + var el = this.$compile( "" )(scope); + angular.element(document.body).append(el); + } + presentPasswordModal(callback) { var scope = this.$rootScope.$new(true); scope.type = "password"; scope.title = "Decryption Assistance"; diff --git a/app/assets/javascripts/app/services/sessionHistory.js b/app/assets/javascripts/app/services/sessionHistory.js new file mode 100644 index 000000000..dd45f0c04 --- /dev/null +++ b/app/assets/javascripts/app/services/sessionHistory.js @@ -0,0 +1,213 @@ +class SessionHistory { + + constructor(modelManager, storageManager, authManager, passcodeManager, $timeout) { + this.modelManager = modelManager; + this.storageManager = storageManager; + this.authManager = authManager; + this.passcodeManager = passcodeManager; + this.$timeout = $timeout; + + this.loadFromDisk().then(() => { + this.modelManager.addItemSyncObserver("session-history", "Note", (allItems, validItems, deletedItems, source, sourceKey) => { + for(let item of allItems) { + this.addRevision(item); + } + }); + }) + } + + async encryptionParams() { + let offline = this.authManager.offline(); + let auth_params = offline ? this.passcodeManager.passcodeAuthParams() : await this.authManager.getAuthParams(); + let keys = offline ? this.passcodeManager.keys() : await this.authManager.keys(); + return {keys, auth_params}; + } + + addRevision(item) { + var added = this.historyContainer.addRevision(item); + + if(added) { + if(this.diskTimeout) {this.$timeout.cancel(this.diskTimeout)}; + this.diskTimeout = this.$timeout(() => { + this.saveToDisk(); + }, 1000) + } + } + + historyForItem(item) { + return this.historyContainer.historyForItem(item); + } + + async clearItemHistory(item) { + delete this.historyContainer.clearItemHistory(item); + return this.saveToDisk(); + } + + async clearAllHistory() { + this.historyContainer.clearAllHistory(); + return this.storageManager.removeItem("sessionHistory"); + } + + async toggleDiskSaving() { + this.diskEnabled = !this.diskEnabled; + + if(this.diskEnabled) { + this.storageManager.setItem("persistSessionHistory", JSON.stringify(true)); + this.saveToDisk(); + } else { + this.storageManager.removeItem("persistSessionHistory"); + } + } + + async saveToDisk() { + if(!this.diskEnabled) { + return; + } + let encryptionParams = await this.encryptionParams(); + var itemParams = new SFItemParams(this.historyContainer, encryptionParams.keys, encryptionParams.auth_params); + itemParams.paramsForSync().then((syncParams) => { + console.log("Saving to disk", syncParams); + this.storageManager.setItem("sessionHistory", JSON.stringify(syncParams)); + }) + } + + async loadFromDisk() { + var diskValue = await this.storageManager.getItem("persistSessionHistory"); + if(diskValue) { + this.diskEnabled = JSON.parse(diskValue); + } + + var historyValue = await this.storageManager.getItem("sessionHistory"); + if(historyValue) { + historyValue = JSON.parse(historyValue); + let encryptionParams = await this.encryptionParams(); + await SFJS.itemTransformer.decryptItem(historyValue, encryptionParams.keys); + var historyContainer = new HistoryContainer(historyValue); + this.historyContainer = historyContainer; + } else { + this.historyContainer = new HistoryContainer(); + } + } +} + +class HistoryContainer extends SFItem { + constructor(json_obj) { + super(json_obj); + + if(!this.content.itemsDictionary) { + this.content.itemsDictionary = {}; + } + + var objectKeys = Object.keys(this.content.itemsDictionary); + objectKeys.forEach((key) => { + var value = this.content.itemsDictionary[key]; + this.content.itemsDictionary[key] = new ItemHistory(value); + }); + } + + addRevision(item) { + if(!this.content.itemsDictionary[item.uuid]) { + this.content.itemsDictionary[item.uuid] = new ItemHistory(); + } + var itemHistory = this.content.itemsDictionary[item.uuid]; + return itemHistory.addRevision(item); + } + + historyForItem(item) { + return this.content.itemsDictionary[item.uuid]; + } + + clearItemHistory(item) { + delete this.content.itemsDictionary[item.uuid]; + } + + clearAllHistory() { + this.content.itemsDictionary = {}; + } +} + +class ItemHistory { + + constructor(json_obj = {}) { + if(!this.revisions) { + this.revisions = []; + } + if(json_obj.revisions) { + for(var revision of json_obj.revisions) { + this.revisions.push(new NoteRevision(revision, this.revisions[this.revisions.length - 1], revision.date)); + } + } + } + + addRevision(item) { + var previousRevision = this.revisions[this.revisions.length - 1]; + var prospectiveRevision = new NoteRevision(item, previousRevision, item.updated_at); + if(prospectiveRevision.isSameAsRevision(previousRevision)) { + return; + } + this.revisions.push(prospectiveRevision); + return prospectiveRevision; + } + +} + +class ItemRevision { + + constructor(item, previousRevision, date) { + if(typeof(date) == "string") { + this.date = new Date(date); + } else { + this.date = date; + } + this.itemUuid = item.uuid; + this.hasPreviousRevision = previousRevision != null; + this.content = Object.assign({}, item.content); + } + + isSameAsRevision(revision) { + if(!revision) { + return false; + } + return JSON.stringify(this.content) === JSON.stringify(revision.content); + } + +} + +class NoteRevision extends ItemRevision { + constructor(item, previousRevision, date) { + super(item, previousRevision, date); + if(previousRevision) { + this.textCharDiffLength = this.content.text.length - previousRevision.content.text.length; + } else { + this.textCharDiffLength = this.content.text.length; + } + } + + previewTitle() { + return this.date.toLocaleString(); + } + + operationVector() { + if(!this.hasPreviousRevision || this.textCharDiffLength == 0) { + return 0; + } else if(this.textCharDiffLength < 0) { + return -1; + } else { + return 1; + } + } + + previewSubTitle() { + if(!this.hasPreviousRevision) { + return `${this.textCharDiffLength} characters loaded` + } else if(this.textCharDiffLength < 0) { + return `${this.textCharDiffLength * -1} characters removed` + } else if(this.textCharDiffLength > 0) { + return `${this.textCharDiffLength} characters added` + } else { + return "Title changed" + } + } +} + +angular.module('app').service('sessionHistory', SessionHistory); diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index 03675a20f..ffe6415f4 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -16,6 +16,13 @@ font-size: 16px; } +#item-preview-modal { + > .content { + width: 800px; + height: 500px; + } +} + .panel { background-color: white; } diff --git a/app/assets/stylesheets/app/_stylekit-sub.scss b/app/assets/stylesheets/app/_stylekit-sub.scss index 07a0f0255..b0a9285e1 100644 --- a/app/assets/stylesheets/app/_stylekit-sub.scss +++ b/app/assets/stylesheets/app/_stylekit-sub.scss @@ -53,3 +53,9 @@ color: $blue-color; } } + +#session-history-menu { + .menu-panel .row .sublabel.opaque { + opacity: 1.0 + } +} diff --git a/app/assets/templates/directives/revision-preview-modal.html.haml b/app/assets/templates/directives/revision-preview-modal.html.haml new file mode 100644 index 000000000..1e9b5f107 --- /dev/null +++ b/app/assets/templates/directives/revision-preview-modal.html.haml @@ -0,0 +1,13 @@ +.modal.medium#item-preview-modal + .content + .sn-component + .panel + .header + %h1.title Preview + .horizontal-group + %a.close-button.info{"ng-click" => "restore(false)"} Restore + %a.close-button.info{"ng-click" => "restore(true)"} Restore as copy + %a.close-button.info{"ng-click" => "dismiss(); $event.stopPropagation()"} Close + .content.selectable + %h2 {{revision.content.title}} + %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{revision.content.text}} diff --git a/app/assets/templates/directives/session-history-menu.html.haml b/app/assets/templates/directives/session-history-menu.html.haml new file mode 100644 index 000000000..46814a076 --- /dev/null +++ b/app/assets/templates/directives/session-history-menu.html.haml @@ -0,0 +1,31 @@ +.sn-component#session-history-menu + .menu-panel.dropdown-menu + .header + .column + %h4.title {{history.revisions.length || 'No'}} revisions + %h4{"ng-click" => "showOptions = !showOptions; $event.stopPropagation();"} + %a Options + + %div{"ng-if" => "showOptions"} + %menu-row{"label" => "'Clear note local history'", "ng-click" => "clearItemHistory(); $event.stopPropagation();"} + %menu-row{"label" => "'Clear all local history'", "ng-click" => "clearAllHistory(); $event.stopPropagation();"} + %menu-row{"label" => "(diskEnabled ? 'Disable' : 'Enable') + ' saving history to disk'", "ng-click" => "toggleDiskSaving(); $event.stopPropagation();"} + .sublabel + May increase app loading speed and memory footprint. + + %menu-row{"ng-repeat" => "revision in history.revisions", + "ng-click" => "openRevision(revision); $event.stopPropagation();", + "label" => "revision.previewTitle()"} + .sublabel.opaque{"ng-class" => "classForRevision(revision)"} + {{revision.previewSubTitle()}} + +.modal.medium-text.medium{"ng-if" => "renderData.showRenderModal", "ng-click" => "$event.stopPropagation();"} + .content + .sn-component + .panel + .header + %h1.title Preview + %a.close-button.info{"ng-click" => "renderData.showRenderModal = false; $event.stopPropagation();"} Close + .content.selectable + %h2 {{renderData.title}} + %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{renderData.text}} diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index 9d8bb27e2..5a822c08a 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -50,6 +50,10 @@ .label Actions %actions-menu{"ng-if" => "ctrl.showExtensions", "item" => "ctrl.note"} + .item{"ng-click" => "ctrl.showSessionHistory = !ctrl.showSessionHistory; ctrl.showMenu = false; ctrl.showEditorMenu = false;", "click-outside" => "ctrl.showSessionHistory = false;", "is-open" => "ctrl.showSessionHistory"} + .label Session History + %session-history-menu{"ng-if" => "ctrl.showSessionHistory", "item" => "ctrl.note"} + .editor-content#editor-content{"ng-if" => "ctrl.noteReady && !ctrl.note.errorDecrypting"} %panel-resizer.left{"panel-id" => "'editor-content'", "on-resize-finish" => "ctrl.onPanelResizeFinish","control" => "ctrl.resizeControl", "min-width" => 300, "property" => "'left'", "hoverable" => "true"} diff --git a/package-lock.json b/package-lock.json index f554e9860..699858226 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8921,23 +8921,7 @@ }, "assert": { "version": "1.4.1", - "bundled": true, - "requires": { - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "bundled": true - }, - "util": { - "version": "0.10.3", - "bundled": true, - "requires": { - "inherits": "2.0.1" - } - } - } + "bundled": true }, "assertion-error": { "version": "1.1.0", @@ -9014,16 +8998,9 @@ "babel-runtime": "6.26.0", "babel-types": "6.26.0", "detect-indent": "4.0.0", - "jsesc": "1.3.0", "lodash": "4.17.10", "source-map": "0.5.7", "trim-right": "1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "bundled": true - } } }, "babel-helper-builder-binary-assignment-operator-visitor": { @@ -9400,14 +9377,7 @@ "bundled": true, "requires": { "babel-runtime": "6.26.0", - "core-js": "2.5.6", - "regenerator-runtime": "0.10.5" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.10.5", - "bundled": true - } + "core-js": "2.5.6" } }, "babel-preset-env": { @@ -9502,12 +9472,6 @@ "requires": { "core-js": "2.5.6", "regenerator-runtime": "0.11.1" - }, - "dependencies": { - "regenerator-runtime": { - "version": "0.11.1", - "bundled": true - } } }, "babel-template": { @@ -9721,24 +9685,9 @@ "version": "3.1.1", "bundled": true, "requires": { - "JSONStream": "0.10.0", "browserify-cache-api": "3.0.1", "through2": "2.0.3", "xtend": "4.0.1" - }, - "dependencies": { - "JSONStream": { - "version": "0.10.0", - "bundled": true, - "requires": { - "jsonparse": "0.0.5", - "through": "2.3.8" - } - }, - "jsonparse": { - "version": "0.0.5", - "bundled": true - } } }, "browserify-rsa": { @@ -9911,16 +9860,9 @@ "version": "0.8.0", "bundled": true, "requires": { - "convert-source-map": "1.1.3", "inline-source-map": "0.6.2", "lodash.memoize": "3.0.4", "source-map": "0.5.7" - }, - "dependencies": { - "convert-source-map": { - "version": "1.1.3", - "bundled": true - } } }, "commander": { @@ -10113,14 +10055,7 @@ "bundled": true, "requires": { "acorn-node": "1.5.2", - "defined": "1.0.0", - "minimist": "1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } + "defined": "1.0.0" } }, "diff": { @@ -10301,23 +10236,7 @@ }, "findup-sync": { "version": "0.3.0", - "bundled": true, - "requires": { - "glob": "5.0.15" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "bundled": true, - "requires": { - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - } - } + "bundled": true }, "for-in": { "version": "1.0.2", @@ -10351,460 +10270,7 @@ "bundled": true, "optional": true, "requires": { - "nan": "2.10.0", - "node-pre-gyp": "0.10.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "optional": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.3.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "debug": { - "version": "2.6.9", - "bundled": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.5.1", - "bundled": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "optional": true, - "requires": { - "minipass": "2.2.4" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "optional": true, - "requires": { - "aproba": "1.2.0", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "optional": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.21", - "bundled": true, - "optional": true, - "requires": { - "safer-buffer": "2.1.2" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "optional": true, - "requires": { - "minimatch": "3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "optional": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "requires": { - "brace-expansion": "1.1.11" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true - }, - "minipass": { - "version": "2.2.4", - "bundled": true, - "requires": { - "safe-buffer": "5.1.1", - "yallist": "3.0.2" - } - }, - "minizlib": { - "version": "1.1.0", - "bundled": true, - "optional": true, - "requires": { - "minipass": "2.2.4" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "needle": { - "version": "2.2.0", - "bundled": true, - "optional": true, - "requires": { - "debug": "2.6.9", - "iconv-lite": "0.4.21", - "sax": "1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.10.0", - "bundled": true, - "optional": true, - "requires": { - "detect-libc": "1.0.3", - "mkdirp": "0.5.1", - "needle": "2.2.0", - "nopt": "4.0.1", - "npm-packlist": "1.1.10", - "npmlog": "4.1.2", - "rc": "1.2.7", - "rimraf": "2.6.2", - "semver": "5.5.0", - "tar": "4.4.1" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "optional": true, - "requires": { - "abbrev": "1.1.1", - "osenv": "0.1.5" - } - }, - "npm-bundled": { - "version": "1.0.3", - "bundled": true, - "optional": true - }, - "npm-packlist": { - "version": "1.1.10", - "bundled": true, - "optional": true, - "requires": { - "ignore-walk": "3.0.1", - "npm-bundled": "1.0.3" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "optional": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "rc": { - "version": "1.2.7", - "bundled": true, - "optional": true, - "requires": { - "deep-extend": "0.5.1", - "ini": "1.3.5", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "optional": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "2.0.0", - "safe-buffer": "5.1.1", - "string_decoder": "1.1.1", - "util-deprecate": "1.0.2" - } - }, - "rimraf": { - "version": "2.6.2", - "bundled": true, - "optional": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.1.1", - "bundled": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "optional": true - }, - "semver": { - "version": "5.5.0", - "bundled": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "optional": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "optional": true - }, - "tar": { - "version": "4.4.1", - "bundled": true, - "optional": true, - "requires": { - "chownr": "1.0.1", - "fs-minipass": "1.2.5", - "minipass": "2.2.4", - "minizlib": "1.1.0", - "mkdirp": "0.5.1", - "safe-buffer": "5.1.1", - "yallist": "3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "optional": true - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "optional": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true - }, - "yallist": { - "version": "3.0.2", - "bundled": true - } + "nan": "2.10.0" } }, "function-bind": { @@ -10891,8 +10357,6 @@ "eventemitter2": "0.4.14", "exit": "0.1.2", "findup-sync": "0.3.0", - "glob": "7.0.6", - "grunt-cli": "1.2.0", "grunt-known-options": "1.1.0", "grunt-legacy-log": "1.0.2", "grunt-legacy-util": "1.0.0", @@ -10902,30 +10366,6 @@ "nopt": "3.0.6", "path-is-absolute": "1.0.1", "rimraf": "2.2.8" - }, - "dependencies": { - "glob": { - "version": "7.0.6", - "bundled": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "grunt-cli": { - "version": "1.2.0", - "bundled": true, - "requires": { - "findup-sync": "0.3.0", - "grunt-known-options": "1.1.0", - "nopt": "3.0.6", - "resolve": "1.1.7" - } - } } }, "grunt-babel": { @@ -10939,22 +10379,12 @@ "version": "5.3.0", "bundled": true, "requires": { - "async": "2.6.1", "browserify": "16.2.2", "browserify-incremental": "3.1.1", "glob": "7.1.2", "lodash": "4.17.10", "resolve": "1.1.7", "watchify": "3.11.0" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "bundled": true, - "requires": { - "lodash": "4.17.10" - } - } } }, "grunt-contrib-concat": { @@ -10980,19 +10410,9 @@ "version": "1.1.0", "bundled": true, "requires": { - "async": "2.6.1", "gaze": "1.1.3", "lodash": "4.17.10", "tiny-lr": "1.1.1" - }, - "dependencies": { - "async": { - "version": "2.6.1", - "bundled": true, - "requires": { - "lodash": "4.17.10" - } - } } }, "grunt-known-options": { @@ -11013,14 +10433,7 @@ "version": "1.0.0", "bundled": true, "requires": { - "chalk": "1.1.3", - "lodash": "4.3.0" - }, - "dependencies": { - "lodash": { - "version": "4.3.0", - "bundled": true - } + "chalk": "1.1.3" } }, "grunt-legacy-util": { @@ -11031,53 +10444,22 @@ "exit": "0.1.2", "getobject": "0.1.0", "hooker": "0.2.3", - "lodash": "4.3.0", "underscore.string": "3.2.3", "which": "1.2.14" - }, - "dependencies": { - "lodash": { - "version": "4.3.0", - "bundled": true - } } }, "grunt-newer": { "version": "1.3.0", "bundled": true, "requires": { - "async": "1.5.2", - "rimraf": "2.6.2" - }, - "dependencies": { - "rimraf": { - "version": "2.6.2", - "bundled": true, - "requires": { - "glob": "7.1.2" - } - } + "async": "1.5.2" } }, "gzip-size": { "version": "1.0.0", "bundled": true, "requires": { - "browserify-zlib": "0.1.4", "concat-stream": "1.6.2" - }, - "dependencies": { - "browserify-zlib": { - "version": "0.1.4", - "bundled": true, - "requires": { - "pako": "0.2.9" - } - }, - "pako": { - "version": "0.2.9", - "bundled": true - } } }, "has": { @@ -11157,14 +10539,7 @@ "requires": { "depd": "1.1.2", "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": "1.5.0" - }, - "dependencies": { - "statuses": { - "version": "1.5.0", - "bundled": true - } + "setprototypeof": "1.1.0" } }, "http-parser-js": { @@ -11371,14 +10746,7 @@ "bundled": true, "requires": { "inherits": "2.0.3", - "isarray": "2.0.4", "stream-splicer": "2.0.0" - }, - "dependencies": { - "isarray": { - "version": "2.0.4", - "bundled": true - } } }, "lazy-cache": { @@ -11461,18 +10829,11 @@ "decamelize": "1.2.0", "loud-rejection": "1.6.0", "map-obj": "1.0.1", - "minimist": "1.2.0", "normalize-package-data": "2.4.0", "object-assign": "4.1.1", "read-pkg-up": "1.0.1", "redent": "1.0.0", "trim-newlines": "1.0.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } } }, "micromatch": { @@ -11538,31 +10899,13 @@ "requires": { "browser-stdout": "1.3.1", "commander": "2.15.1", - "debug": "3.1.0", "diff": "3.5.0", "escape-string-regexp": "1.0.5", "glob": "7.1.2", "growl": "1.10.5", "he": "1.1.1", "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "bundled": true, - "requires": { - "ms": "2.0.0" - } - }, - "supports-color": { - "version": "5.4.0", - "bundled": true, - "requires": { - "has-flag": "3.0.0" - } - } + "mkdirp": "0.5.1" } }, "module-deps": { @@ -11579,20 +10922,10 @@ "inherits": "2.0.3", "parents": "1.0.1", "readable-stream": "2.3.6", - "resolve": "1.8.1", "stream-combiner2": "1.1.1", "subarg": "1.0.0", "through2": "2.0.3", "xtend": "4.0.1" - }, - "dependencies": { - "resolve": { - "version": "1.8.1", - "bundled": true, - "requires": { - "path-parse": "1.0.5" - } - } } }, "ms": { @@ -11860,19 +11193,7 @@ "version": "3.0.0", "bundled": true, "requires": { - "is-number": "4.0.0", - "kind-of": "6.0.2", "math-random": "1.0.1" - }, - "dependencies": { - "is-number": { - "version": "4.0.0", - "bundled": true - }, - "kind-of": { - "version": "6.0.2", - "bundled": true - } } }, "randombytes": { @@ -11898,14 +11219,7 @@ "version": "1.1.7", "bundled": true, "requires": { - "bytes": "1.0.0", - "string_decoder": "0.10.31" - }, - "dependencies": { - "string_decoder": { - "version": "0.10.31", - "bundled": true - } + "bytes": "1.0.0" } }, "read-only-stream": { @@ -12080,14 +11394,7 @@ "mime": "1.4.1", "ms": "2.0.0", "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" - }, - "dependencies": { - "statuses": { - "version": "1.4.0", - "bundled": true - } + "range-parser": "1.2.0" } }, "serve-static": { @@ -12258,16 +11565,7 @@ }, "subarg": { "version": "1.0.0", - "bundled": true, - "requires": { - "minimist": "1.2.0" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true - } - } + "bundled": true }, "supports-color": { "version": "2.0.0", @@ -12304,20 +11602,10 @@ "bundled": true, "requires": { "body": "5.1.0", - "debug": "3.1.0", "faye-websocket": "0.10.0", "livereload-js": "2.3.0", "object-assign": "4.1.1", "qs": "6.5.2" - }, - "dependencies": { - "debug": { - "version": "3.1.0", - "bundled": true, - "requires": { - "ms": "2.0.0" - } - } } }, "to-arraybuffer": { @@ -12392,14 +11680,7 @@ "version": "0.11.0", "bundled": true, "requires": { - "punycode": "1.3.2", "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "bundled": true - } } }, "user-home": { @@ -12492,16 +11773,9 @@ "version": "3.10.0", "bundled": true, "requires": { - "camelcase": "1.2.1", "cliui": "2.1.0", "decamelize": "1.2.0", "window-size": "0.1.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "bundled": true - } } } } @@ -13153,11 +12427,7 @@ }, "assert": { "version": "1.4.1", - "bundled": true, - "requires": { - "util": "0.10.3" - }, - "dependencies": {} + "bundled": true }, "assertion-error": { "version": "1.1.0", @@ -13234,12 +12504,10 @@ "babel-runtime": "6.26.0", "babel-types": "6.26.0", "detect-indent": "4.0.0", - "jsesc": "1.3.0", "lodash": "4.17.10", "source-map": "0.5.7", "trim-right": "1.0.1" - }, - "dependencies": {} + } }, "babel-helper-builder-binary-assignment-operator-visitor": { "version": "6.24.1", @@ -13615,10 +12883,8 @@ "bundled": true, "requires": { "babel-runtime": "6.26.0", - "core-js": "2.5.6", - "regenerator-runtime": "0.10.5" - }, - "dependencies": {} + "core-js": "2.5.6" + } }, "babel-preset-env": { "version": "1.7.0", @@ -13712,8 +12978,7 @@ "requires": { "core-js": "2.5.6", "regenerator-runtime": "0.11.1" - }, - "dependencies": {} + } }, "babel-template": { "version": "6.26.0", @@ -13926,12 +13191,10 @@ "version": "3.1.1", "bundled": true, "requires": { - "JSONStream": "0.10.0", "browserify-cache-api": "3.0.1", "through2": "2.0.3", "xtend": "4.0.1" - }, - "dependencies": {} + } }, "browserify-rsa": { "version": "4.0.1", @@ -14103,12 +13366,10 @@ "version": "0.8.0", "bundled": true, "requires": { - "convert-source-map": "1.1.3", "inline-source-map": "0.6.2", "lodash.memoize": "3.0.4", "source-map": "0.5.7" - }, - "dependencies": {} + } }, "commander": { "version": "2.15.1", @@ -14300,10 +13561,8 @@ "bundled": true, "requires": { "acorn-node": "1.5.2", - "defined": "1.0.0", - "minimist": "1.2.0" - }, - "dependencies": {} + "defined": "1.0.0" + } }, "diff": { "version": "3.5.0", @@ -14483,11 +13742,7 @@ }, "findup-sync": { "version": "0.3.0", - "bundled": true, - "requires": { - "glob": "5.0.15" - }, - "dependencies": {} + "bundled": true }, "for-in": { "version": "1.0.2", @@ -14521,10 +13776,8 @@ "bundled": true, "optional": true, "requires": { - "nan": "2.10.0", - "node-pre-gyp": "0.10.0" - }, - "dependencies": {} + "nan": "2.10.0" + } }, "function-bind": { "version": "1.1.1", @@ -14610,8 +13863,6 @@ "eventemitter2": "0.4.14", "exit": "0.1.2", "findup-sync": "0.3.0", - "glob": "7.0.6", - "grunt-cli": "1.2.0", "grunt-known-options": "1.1.0", "grunt-legacy-log": "1.0.2", "grunt-legacy-util": "1.0.0", @@ -14621,8 +13872,7 @@ "nopt": "3.0.6", "path-is-absolute": "1.0.1", "rimraf": "2.2.8" - }, - "dependencies": {} + } }, "grunt-babel": { "version": "6.0.0", @@ -14635,15 +13885,13 @@ "version": "5.3.0", "bundled": true, "requires": { - "async": "2.6.1", "browserify": "16.2.2", "browserify-incremental": "3.1.1", "glob": "7.1.2", "lodash": "4.17.10", "resolve": "1.1.7", "watchify": "3.11.0" - }, - "dependencies": {} + } }, "grunt-contrib-concat": { "version": "1.0.1", @@ -14668,12 +13916,10 @@ "version": "1.1.0", "bundled": true, "requires": { - "async": "2.6.1", "gaze": "1.1.3", "lodash": "4.17.10", "tiny-lr": "1.1.1" - }, - "dependencies": {} + } }, "grunt-known-options": { "version": "1.1.0", @@ -14693,10 +13939,8 @@ "version": "1.0.0", "bundled": true, "requires": { - "chalk": "1.1.3", - "lodash": "4.3.0" - }, - "dependencies": {} + "chalk": "1.1.3" + } }, "grunt-legacy-util": { "version": "1.0.0", @@ -14706,29 +13950,23 @@ "exit": "0.1.2", "getobject": "0.1.0", "hooker": "0.2.3", - "lodash": "4.3.0", "underscore.string": "3.2.3", "which": "1.2.14" - }, - "dependencies": {} + } }, "grunt-newer": { "version": "1.3.0", "bundled": true, "requires": { - "async": "1.5.2", - "rimraf": "2.6.2" - }, - "dependencies": {} + "async": "1.5.2" + } }, "gzip-size": { "version": "1.0.0", "bundled": true, "requires": { - "browserify-zlib": "0.1.4", "concat-stream": "1.6.2" - }, - "dependencies": {} + } }, "has": { "version": "1.0.1", @@ -14807,10 +14045,8 @@ "requires": { "depd": "1.1.2", "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": "1.5.0" - }, - "dependencies": {} + "setprototypeof": "1.1.0" + } }, "http-parser-js": { "version": "0.4.13", @@ -15016,10 +14252,8 @@ "bundled": true, "requires": { "inherits": "2.0.3", - "isarray": "2.0.4", "stream-splicer": "2.0.0" - }, - "dependencies": {} + } }, "lazy-cache": { "version": "1.0.4", @@ -15101,14 +14335,12 @@ "decamelize": "1.2.0", "loud-rejection": "1.6.0", "map-obj": "1.0.1", - "minimist": "1.2.0", "normalize-package-data": "2.4.0", "object-assign": "4.1.1", "read-pkg-up": "1.0.1", "redent": "1.0.0", "trim-newlines": "1.0.0" - }, - "dependencies": {} + } }, "micromatch": { "version": "2.3.11", @@ -15173,17 +14405,14 @@ "requires": { "browser-stdout": "1.3.1", "commander": "2.15.1", - "debug": "3.1.0", "diff": "3.5.0", "escape-string-regexp": "1.0.5", "glob": "7.1.2", "growl": "1.10.5", "he": "1.1.1", "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "5.4.0" - }, - "dependencies": {} + "mkdirp": "0.5.1" + } }, "module-deps": { "version": "6.1.0", @@ -15199,13 +14428,11 @@ "inherits": "2.0.3", "parents": "1.0.1", "readable-stream": "2.3.6", - "resolve": "1.8.1", "stream-combiner2": "1.1.1", "subarg": "1.0.0", "through2": "2.0.3", "xtend": "4.0.1" - }, - "dependencies": {} + } }, "ms": { "version": "2.0.0", @@ -15472,11 +14699,8 @@ "version": "3.0.0", "bundled": true, "requires": { - "is-number": "4.0.0", - "kind-of": "6.0.2", "math-random": "1.0.1" - }, - "dependencies": {} + } }, "randombytes": { "version": "2.0.6", @@ -15501,10 +14725,8 @@ "version": "1.1.7", "bundled": true, "requires": { - "bytes": "1.0.0", - "string_decoder": "0.10.31" - }, - "dependencies": {} + "bytes": "1.0.0" + } }, "read-only-stream": { "version": "2.0.0", @@ -15678,10 +14900,8 @@ "mime": "1.4.1", "ms": "2.0.0", "on-finished": "2.3.0", - "range-parser": "1.2.0", - "statuses": "1.4.0" - }, - "dependencies": {} + "range-parser": "1.2.0" + } }, "serve-static": { "version": "1.13.2", @@ -15851,11 +15071,7 @@ }, "subarg": { "version": "1.0.0", - "bundled": true, - "requires": { - "minimist": "1.2.0" - }, - "dependencies": {} + "bundled": true }, "supports-color": { "version": "2.0.0", @@ -15892,13 +15108,11 @@ "bundled": true, "requires": { "body": "5.1.0", - "debug": "3.1.0", "faye-websocket": "0.10.0", "livereload-js": "2.3.0", "object-assign": "4.1.1", "qs": "6.5.2" - }, - "dependencies": {} + } }, "to-arraybuffer": { "version": "1.0.1", @@ -15972,10 +15186,8 @@ "version": "0.11.0", "bundled": true, "requires": { - "punycode": "1.3.2", "querystring": "0.2.0" - }, - "dependencies": {} + } }, "user-home": { "version": "1.1.1", @@ -16067,12 +15279,10 @@ "version": "3.10.0", "bundled": true, "requires": { - "camelcase": "1.2.1", "cliui": "2.1.0", "decamelize": "1.2.0", "window-size": "0.1.0" - }, - "dependencies": {} + } } } }, diff --git a/package.json b/package.json index 0b66c8a4b..7e4395968 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "karma-phantomjs-launcher": "^1.0.2", "sn-stylekit": "1.0.15", "standard-file-js": "0.3.2", - "sn-models": "0.1.0", + "sn-models": "file:~/Desktop/sn-models", "connect": "^3.6.6", "mocha": "^5.2.0", "serve-static": "^1.13.2",