diff --git a/Gemfile b/Gemfile index af629c959..1fc8424e9 100644 --- a/Gemfile +++ b/Gemfile @@ -23,6 +23,8 @@ gem 'sdoc', '~> 0.4.0', group: :doc # Used for 'respond_to' feature gem 'responders', '~> 2.0' +gem 'tzinfo-data' + group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug' diff --git a/Gemfile.lock b/Gemfile.lock index 1056e5c0b..117dd64aa 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -76,6 +76,7 @@ GEM erubi (1.7.1) execjs (2.7.0) ffi (1.9.23) + ffi (1.9.23-x64-mingw32) globalid (0.4.1) activesupport (>= 4.2.0) haml (5.0.4) @@ -99,6 +100,8 @@ GEM nio4r (2.3.0) nokogiri (1.8.2) mini_portile2 (~> 2.3.0) + nokogiri (1.8.2-x64-mingw32) + mini_portile2 (~> 2.3.0) non-stupid-digest-assets (1.0.9) sprockets (>= 2.0) puma (3.11.4) @@ -172,6 +175,8 @@ GEM tilt (2.0.8) tzinfo (1.2.5) thread_safe (~> 0.1) + tzinfo-data (1.2018.7) + tzinfo (>= 1.0.0) uglifier (4.1.10) execjs (>= 0.3.0, < 3) web-console (3.5.1) @@ -185,6 +190,7 @@ GEM PLATFORMS ruby + x64-mingw32 DEPENDENCIES bower-rails (~> 0.10.0) @@ -207,8 +213,9 @@ DEPENDENCIES sdoc (~> 0.4.0) secure_headers spring + tzinfo-data uglifier web-console (= 3.5.1) BUNDLED WITH - 1.16.3 + 1.17.1 diff --git a/Gruntfile.js b/Gruntfile.js index f35fa3316..a4c4cbf0f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,7 +5,7 @@ module.exports = function(grunt) { watch: { haml: { files: ['app/assets/templates/**/*.haml'], - tasks: ['newer:haml', 'ngtemplates', 'concat:app', 'babel', 'browserify', 'concat:dist'], + tasks: ['newer:haml', 'ngtemplates', 'concat:app', 'babel', 'browserify', 'concat:dist', 'ngAnnotate'], options: { spawn: false, }, @@ -166,6 +166,6 @@ module.exports = function(grunt) { grunt.registerTask('default', ['haml', 'ngtemplates', 'sass', 'concat:app', 'babel', 'browserify', 'concat:lib', 'concat:dist', 'ngAnnotate', 'concat:css', 'uglify']); - grunt.registerTask('vendor', ['concat:app', 'babel', 'browserify', + grunt.registerTask('vendor', ['concat:app', 'sass', 'babel', 'browserify', 'concat:lib', 'concat:dist', 'ngAnnotate', 'concat:css', 'uglify']); }; diff --git a/app/assets/javascripts/app/controllers/editor.js b/app/assets/javascripts/app/controllers/editor.js index 1edba4c77..b1b196bb6 100644 --- a/app/assets/javascripts/app/controllers/editor.js +++ b/app/assets/javascripts/app/controllers/editor.js @@ -22,10 +22,12 @@ angular.module('app') } } }) - .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager, syncManager, modelManager, themeManager, componentManager, storageManager, sessionHistory) { + .controller('EditorCtrl', function ($sce, $timeout, authManager, $rootScope, actionsManager, + syncManager, modelManager, themeManager, componentManager, storageManager, sessionHistory, privilegesManager) { this.spellcheck = true; this.componentManager = componentManager; + this.componentStack = []; $rootScope.$on("sync:taking-too-long", function(){ this.syncTakingTooLong = true; @@ -87,11 +89,14 @@ angular.module('app') } }); - // Observe editor changes to see if the current note should update its editor modelManager.addItemSyncObserver("editor-component-observer", "SN|Component", (allItems, validItems, deletedItems, source) => { if(!this.note) { return; } + // Reload componentStack in case new ones were added or removed + this.reloadComponentStackArray(); + + // Observe editor changes to see if the current note should update its editor var editors = allItems.filter(function(item) { return item.isEditor(); }); @@ -157,24 +162,7 @@ angular.module('app') } this.editorForNote = function(note) { - let editors = componentManager.componentsForArea("editor-editor"); - for(var editor of editors) { - if(editor.isExplicitlyEnabledForItem(note)) { - return editor; - } - } - - // No editor found for note. Use default editor, if note does not prefer system editor - if(!note.getAppDataItem("prefersPlainEditor")) { - return editors.filter((e) => {return e.isDefaultEditor()})[0]; - } - } - - this.onEditorMenuClick = function() { - // App bar menu item click - this.showEditorMenu = !this.showEditorMenu; - this.showMenu = false; - this.showExtensions = false; + return componentManager.editorForNote(note); } this.closeAllMenus = function() { @@ -183,6 +171,17 @@ angular.module('app') this.showExtensions = false; } + this.toggleMenu = function(menu) { + this[menu] = !this[menu]; + + let allMenus = ['showMenu', 'showEditorMenu', 'showExtensions', 'showSessionHistory']; + for(var candidate of allMenus) { + if(candidate != menu) { + this[candidate] = false; + } + } + } + this.editorMenuOnSelect = function(component) { if(!component || component.area == "editor-editor") { // if plain editor or other editor @@ -329,7 +328,7 @@ angular.module('app') } this.showSavingStatus = function() { - this.noteStatus = $sce.trustAsHtml("Saving..."); + this.noteStatus = {message: "Saving..."}; } this.showAllChangesSavedStatus = function() { @@ -340,7 +339,7 @@ angular.module('app') if(authManager.offline()) { status += " (offline)"; } - this.noteStatus = $sce.trustAsHtml(status); + this.noteStatus = {message: status}; } this.showErrorStatus = function(error) { @@ -352,7 +351,7 @@ angular.module('app') } this.saveError = true; this.syncTakingTooLong = false; - this.noteStatus = $sce.trustAsHtml(`${error.message}
${error.desc}`) + this.noteStatus = error; } this.contentChanged = function() { @@ -382,16 +381,28 @@ angular.module('app') } } - this.deleteNote = function() { - if(this.note.locked) { - alert("This note is locked. If you'd like to delete it, unlock it, and try again."); - return; + this.deleteNote = async function() { + let run = () => { + $timeout(() => { + if(this.note.locked) { + alert("This note is locked. If you'd like to delete it, unlock it, and try again."); + return; + } + + let title = this.note.safeTitle().length ? `'${this.note.title}'` : "this note"; + if(confirm(`Are you sure you want to delete ${title}?`)) { + this.remove()(this.note); + this.showMenu = false; + } + }); } - let title = this.note.safeTitle().length ? `'${this.note.title}'` : "this note"; - if(confirm(`Are you sure you want to delete ${title}?`)) { - this.remove()(this.note); - this.showMenu = false; + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionDeleteNote)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionDeleteNote, () => { + run(); + }); + } else { + run(); } } @@ -405,6 +416,18 @@ angular.module('app') this.changesMade({dontUpdateClientModified: true, dontUpdatePreviews: true}); } + this.toggleProtectNote = function() { + this.note.content.protected = !this.note.content.protected; + this.changesMade({dontUpdateClientModified: true, dontUpdatePreviews: true}); + + // Show privilegesManager if Protection is not yet set up + privilegesManager.actionHasPrivilegesConfigured(PrivilegesManager.ActionViewProtectedNotes).then((configured) => { + if(!configured) { + privilegesManager.presentPrivilegesManagementModal(); + } + }) + } + this.toggleNotePreview = function() { this.note.content.hidePreview = !this.note.content.hidePreview; this.changesMade({dontUpdateClientModified: true, dontUpdatePreviews: true}); @@ -499,7 +522,7 @@ angular.module('app') this.loadPreferences = function() { this.monospaceFont = authManager.getUserPrefValue("monospaceFont", "monospace"); this.spellcheck = authManager.getUserPrefValue("spellcheck", true); - this.marginResizersEnabled = authManager.getUserPrefValue("marginResizersEnabled", false); + this.marginResizersEnabled = authManager.getUserPrefValue("marginResizersEnabled", true); if(!document.getElementById("editor-content")) { // Elements have not yet loaded due to ng-if around wrapper @@ -601,7 +624,9 @@ angular.module('app') this.reloadComponentContext(); } }, contextRequestHandler: (component) => { - return this.note; + if(component == this.selectedEditor || this.componentStack.includes(component)) { + return this.note; + } }, focusHandler: (component, focused) => { if(component.isEditor() && focused) { this.closeAllMenus(); @@ -662,9 +687,18 @@ angular.module('app') } }}); + this.reloadComponentStackArray = function() { + this.componentStack = componentManager.componentsForArea("editor-stack").sort((a, b) => { + // Careful here. For some reason (probably because re-assigning array everytime quickly destroys componentView elements, causing deallocs), + // sorting by updated_at (or any other property that may always be changing) + // causes weird problems with ext communication when changing notes or activating/deactivating in quick succession + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + }); + } + this.reloadComponentContext = function() { // componentStack is used by the template to ng-repeat - this.componentStack = componentManager.componentsForArea("editor-stack"); + this.reloadComponentStackArray(); /* In the past, we were doing this looping code even if the note wasn't currently defined. The problem is if an editor stack item loaded first, requested to stream items, and the note was undefined, @@ -679,7 +713,7 @@ angular.module('app') if(this.note) { for(var component of this.componentStack) { if(component.active) { - component.hidden = component.isExplicitlyDisabledForItem(this.note); + component.hidden = !component.isExplicitlyEnabledForItem(this.note); } } } @@ -690,13 +724,15 @@ angular.module('app') } this.toggleStackComponentForCurrentItem = function(component) { - if(component.hidden) { + // If it's hidden, we want to show it + // If it's not active, then hidden won't be set, and we mean to activate and show it. + if(component.hidden || !component.active) { // Unhide, associate with current item component.hidden = false; + this.associateComponentWithCurrentNote(component); if(!component.active) { componentManager.activateComponent(component); } - this.associateComponentWithCurrentNote(component); componentManager.contextItemDidChangeInArea("editor-stack"); } else { // not hidden, hide diff --git a/app/assets/javascripts/app/controllers/footer.js b/app/assets/javascripts/app/controllers/footer.js index d408d1be4..15fcd07f2 100644 --- a/app/assets/javascripts/app/controllers/footer.js +++ b/app/assets/javascripts/app/controllers/footer.js @@ -23,7 +23,8 @@ angular.module('app') } }) .controller('FooterCtrl', function ($rootScope, authManager, modelManager, $timeout, dbManager, - syncManager, storageManager, passcodeManager, componentManager, singletonManager, nativeExtManager) { + syncManager, storageManager, passcodeManager, componentManager, singletonManager, nativeExtManager, + privilegesManager) { authManager.checkForSecurityUpdate().then((available) => { this.securityUpdateAvailable = available; @@ -137,11 +138,70 @@ angular.module('app') this.componentManager = componentManager; this.rooms = []; + this.themesWithIcons = []; modelManager.addItemSyncObserver("room-bar", "SN|Component", (allItems, validItems, deletedItems, source) => { this.rooms = modelManager.components.filter((candidate) => {return candidate.area == "rooms" && !candidate.deleted}); }); + modelManager.addItemSyncObserver("footer-bar-themes", "SN|Theme", (allItems, validItems, deletedItems, source) => { + let themes = modelManager.validItemsForContentType("SN|Theme").filter((candidate) => { + return !candidate.deleted && candidate.content.package_info.dock_icon; + }).sort((a, b) => { + return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; + }); + + let differ = themes.length != this.themesWithIcons.length; + + this.themesWithIcons = themes; + + if(differ) { + this.reloadDockShortcuts(); + } + }); + + this.reloadDockShortcuts = function() { + let shortcuts = []; + for(var theme of this.themesWithIcons) { + var icon = theme.content.package_info.dock_icon; + if(!icon) { + continue; + } + shortcuts.push({ + component: theme, + icon: icon + }) + } + + this.dockShortcuts = shortcuts.sort((a, b) => { + // circles first, then images + + var aType = a.icon.type; + var bType = b.icon.type; + + if(aType == bType) { + return 0; + } else if(aType == "circle" && bType == "svg") { + return -1; + } else if(bType == "circle" && aType == "svg") { + return 1; + } + }); + } + + this.initSvgForShortcut = function(shortcut) { + var id = "dock-svg-" + shortcut.component.uuid; + var element = document.getElementById(id); + var parser = new DOMParser(); + var svg = shortcut.component.content.package_info.dock_icon.source; + var doc = parser.parseFromString(svg, "image/svg+xml"); + element.appendChild(doc.documentElement); + } + + this.selectShortcut = function(shortcut) { + componentManager.toggleComponent(shortcut.component); + } + componentManager.registerHandler({identifier: "roomBar", areas: ["rooms", "modal"], activationHandler: (component) => { // RIP: There used to be code here that checked if component.active was true, and if so, displayed the component. // However, we no longer want to persist active state for footer extensions. If you open Extensions on one computer, @@ -172,7 +232,31 @@ angular.module('app') } } - this.selectRoom = function(room) { - room.showRoom = !room.showRoom; + this.selectRoom = async function(room) { + let run = () => { + $timeout(() => { + room.showRoom = !room.showRoom; + }) + } + + if(!room.showRoom) { + // About to show, check if has privileges + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageExtensions)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageExtensions, () => { + run(); + }); + } else { + run(); + } + } else { + run(); + } + } + + this.clickOutsideAccountMenu = function() { + if(privilegesManager.authenticationInProgress()) { + return; + } + this.showAccountMenu = false; } }); diff --git a/app/assets/javascripts/app/controllers/home.js b/app/assets/javascripts/app/controllers/home.js index 6d8805094..0c155635f 100644 --- a/app/assets/javascripts/app/controllers/home.js +++ b/app/assets/javascripts/app/controllers/home.js @@ -1,6 +1,7 @@ angular.module('app') .controller('HomeCtrl', function ($scope, $location, $rootScope, $timeout, modelManager, - dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager, migrationManager) { + dbManager, syncManager, authManager, themeManager, passcodeManager, storageManager, migrationManager, + privilegesManager) { storageManager.initialize(passcodeManager.hasPasscode(), authManager.isEphemeralSession()); @@ -10,6 +11,17 @@ angular.module('app') $rootScope.$broadcast('new-update-available', version); } + $rootScope.$on("panel-resized", (event, info) => { + if(info.panel == "notes") { this.notesCollapsed = info.collapsed; } + if(info.panel == "tags") { this.tagsCollapsed = info.collapsed; } + + let appClass = ""; + if(this.notesCollapsed) { appClass += "collapsed-notes"; } + if(this.tagsCollapsed) { appClass += " collapsed-tags"; } + + $scope.appClass = appClass; + }) + /* Used to avoid circular dependencies where syncManager cannot be imported but rootScope can */ $rootScope.sync = function(source) { syncManager.sync(); @@ -83,14 +95,14 @@ angular.module('app') syncManager.loadLocalItems().then(() => { $timeout(() => { $scope.allTag.didLoad = true; - $rootScope.$broadcast("initial-data-loaded"); + $rootScope.$broadcast("initial-data-loaded"); // This needs to be processed first before sync is called so that singletonManager observers function properly. + syncManager.sync(); + // refresh every 30s + setInterval(function () { + syncManager.sync(); + }, 30000); }) - syncManager.sync(); - // refresh every 30s - setInterval(function () { - syncManager.sync(); - }, 30000); }); authManager.addEventHandler((event) => { @@ -196,7 +208,7 @@ angular.module('app') modelManager.setItemToBeDeleted(tag); syncManager.sync().then(() => { // force scope tags to update on sub directives - $scope.safeApply(); + $rootScope.safeApply(); }); } } @@ -218,7 +230,7 @@ angular.module('app') Shared Callbacks */ - $scope.safeApply = function(fn) { + $rootScope.safeApply = function(fn) { var phase = this.$root.$$phase; if(phase == '$apply' || phase == '$digest') this.$eval(fn); @@ -250,7 +262,7 @@ angular.module('app') // when deleting items while ofline, we need to explictly tell angular to refresh UI setTimeout(function () { $rootScope.notifyDelete(); - $scope.safeApply(); + $rootScope.safeApply(); }, 50); } else { $timeout(() => { diff --git a/app/assets/javascripts/app/controllers/lockScreen.js b/app/assets/javascripts/app/controllers/lockScreen.js index e38eff9f6..8f3a9efd0 100644 --- a/app/assets/javascripts/app/controllers/lockScreen.js +++ b/app/assets/javascripts/app/controllers/lockScreen.js @@ -41,7 +41,6 @@ class LockScreen { }) } } - } angular.module('app').directive('lockScreen', () => new LockScreen); diff --git a/app/assets/javascripts/app/controllers/notes.js b/app/assets/javascripts/app/controllers/notes.js index 8fc2ca944..374560039 100644 --- a/app/assets/javascripts/app/controllers/notes.js +++ b/app/assets/javascripts/app/controllers/notes.js @@ -31,7 +31,8 @@ angular.module('app') } } }) - .controller('NotesCtrl', function (authManager, $timeout, $rootScope, modelManager, storageManager, desktopManager) { + .controller('NotesCtrl', function (authManager, $timeout, $rootScope, modelManager, + storageManager, desktopManager, privilegesManager) { this.panelController = {}; this.searchSubmitted = false; @@ -44,6 +45,7 @@ angular.module('app') let prevSortValue = this.sortBy; this.sortBy = authManager.getUserPrefValue("sortBy", "created_at"); + this.sortReverse = authManager.getUserPrefValue("sortReverse", false); if(this.sortBy == "updated_at") { // use client_updated_at instead @@ -55,7 +57,6 @@ angular.module('app') this.selectFirstNote(); }) } - this.sortDescending = this.sortBy != "title"; this.showArchived = authManager.getUserPrefValue("showArchived", false); this.hidePinned = authManager.getUserPrefValue("hidePinned", false); @@ -66,14 +67,18 @@ angular.module('app') let width = authManager.getUserPrefValue("notesPanelWidth"); if(width) { this.panelController.setWidth(width); + if(this.panelController.isCollapsed()) { + $rootScope.$broadcast("panel-resized", {panel: "notes", collapsed: this.panelController.isCollapsed()}) + } } } this.loadPreferences(); - this.onPanelResize = function(newWidth) { + this.onPanelResize = function(newWidth, lastLeft, isAtMaxWidth, isCollapsed) { authManager.setUserPrefValue("notesPanelWidth", newWidth); authManager.syncUserPreferences(); + $rootScope.$broadcast("panel-resized", {panel: "notes", collapsed: isCollapsed}) } angular.element(document).ready(() => { @@ -203,19 +208,31 @@ angular.module('app') } } - this.selectNote = function(note, viaClick = false) { + this.selectNote = async function(note, viaClick = false) { if(!note) { this.createNewNote(); return; } - this.selectedNote = note; - note.conflict_of = null; // clear conflict - this.selectionMade()(note); - this.selectedIndex = Math.max(this.visibleNotes().indexOf(note), 0); + let run = () => { + $timeout(() => { + this.selectedNote = note; + note.conflict_of = null; // clear conflict + this.selectionMade()(note); + this.selectedIndex = Math.max(this.visibleNotes().indexOf(note), 0); - if(viaClick && this.isFiltering()) { - desktopManager.searchText(this.noteFilter.text); + if(viaClick && this.isFiltering()) { + desktopManager.searchText(this.noteFilter.text); + } + }) + } + + if(note.content.protected && await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionViewProtectedNotes)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionViewProtectedNotes, () => { + run(); + }); + } else { + run(); } } @@ -298,17 +315,21 @@ angular.module('app') this.selectedSortByCreated = function() { this.setSortBy("created_at"); - this.sortDescending = true; } this.selectedSortByUpdated = function() { this.setSortBy("client_updated_at"); - this.sortDescending = true; } this.selectedSortByTitle = function() { this.setSortBy("title"); - this.sortDescending = false; + } + + this.toggleReverseSort = function() { + this.selectedMenuItem(); + this.sortReverse = !this.sortReverse; + authManager.setUserPrefValue("sortReverse", this.sortReverse); + authManager.syncUserPreferences(); } this.setSortBy = function(type) { diff --git a/app/assets/javascripts/app/controllers/tags.js b/app/assets/javascripts/app/controllers/tags.js index 52d15de84..4d6daa3a7 100644 --- a/app/assets/javascripts/app/controllers/tags.js +++ b/app/assets/javascripts/app/controllers/tags.js @@ -47,13 +47,17 @@ angular.module('app') let width = authManager.getUserPrefValue("tagsPanelWidth"); if(width) { this.panelController.setWidth(width); + if(this.panelController.isCollapsed()) { + $rootScope.$broadcast("panel-resized", {panel: "tags", collapsed: this.panelController.isCollapsed()}) + } } } this.loadPreferences(); - this.onPanelResize = function(newWidth) { + this.onPanelResize = function(newWidth, lastLeft, isAtMaxWidth, isCollapsed) { authManager.setUserPrefValue("tagsPanelWidth", newWidth, true); + $rootScope.$broadcast("panel-resized", {panel: "tags", collapsed: isCollapsed}) } this.componentManager = componentManager; diff --git a/app/assets/javascripts/app/directives/functional/elemReady.js b/app/assets/javascripts/app/directives/functional/elemReady.js new file mode 100644 index 000000000..7eef56fa7 --- /dev/null +++ b/app/assets/javascripts/app/directives/functional/elemReady.js @@ -0,0 +1,15 @@ +angular +.module('app') +.directive( 'elemReady', function( $parse ) { + return { + restrict: 'A', + link: function( $scope, elem, attrs ) { + elem.ready(function(){ + $scope.$apply(function(){ + var func = $parse(attrs.elemReady); + func($scope); + }) + }) + } + } +}) diff --git a/app/assets/javascripts/app/directives/functional/infiniteScroll.js b/app/assets/javascripts/app/directives/functional/infiniteScroll.js index 3e1e633ef..21bacd325 100644 --- a/app/assets/javascripts/app/directives/functional/infiniteScroll.js +++ b/app/assets/javascripts/app/directives/functional/infiniteScroll.js @@ -2,9 +2,6 @@ angular.module('app').directive('infiniteScroll', [ '$rootScope', '$window', '$timeout', function($rootScope, $window, $timeout) { return { link: function(scope, elem, attrs) { - // elem.css('overflow-x', 'hidden'); - // elem.css('height', 'inherit'); - var offset = parseInt(attrs.threshold) || 0; var e = elem[0] diff --git a/app/assets/javascripts/app/directives/functional/snEnter.js b/app/assets/javascripts/app/directives/functional/snEnter.js new file mode 100644 index 000000000..fe12e0983 --- /dev/null +++ b/app/assets/javascripts/app/directives/functional/snEnter.js @@ -0,0 +1,15 @@ +angular +.module('app') +.directive('snEnter', function() { + return function(scope, element, attrs) { + element.bind("keydown keypress", function(event) { + if(event.which === 13) { + scope.$apply(function(){ + scope.$eval(attrs.snEnter, {'event': event}); + }); + + event.preventDefault(); + } + }); + }; +}); diff --git a/app/assets/javascripts/app/directives/views/accountMenu.js b/app/assets/javascripts/app/directives/views/accountMenu.js index d24684515..6407cc2f3 100644 --- a/app/assets/javascripts/app/directives/views/accountMenu.js +++ b/app/assets/javascripts/app/directives/views/accountMenu.js @@ -10,10 +10,11 @@ class AccountMenu { } controller($scope, $rootScope, authManager, modelManager, syncManager, storageManager, dbManager, passcodeManager, - $timeout, $compile, archiveManager) { + $timeout, $compile, archiveManager, privilegesManager) { 'ngInject'; $scope.formData = {mergeLocal: true, ephemeral: false}; + $scope.user = authManager.user; syncManager.getServerURL().then((url) => { @@ -38,7 +39,6 @@ class AccountMenu { } $scope.canAddPasscode = !authManager.isEphemeralSession(); - $scope.syncStatus = syncManager.syncStatus; $scope.submitMfaForm = function() { @@ -167,10 +167,27 @@ class AccountMenu { $scope.openPasswordWizard = function(type) { // Close the account menu $scope.close(); - authManager.presentPasswordWizard(type); } + $scope.openPrivilegesModal = async function() { + $scope.close(); + + let run = () => { + $timeout(() => { + privilegesManager.presentPrivilegesManagementModal(); + }) + } + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePrivileges)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePrivileges, () => { + run(); + }); + } else { + run(); + } + } + // Allows indexeddb unencrypted logs to be deleted // clearAllModels will remove data from backing store, but not from working memory // See: https://github.com/standardnotes/desktop/issues/131 @@ -229,36 +246,49 @@ class AccountMenu { }) } - $scope.importFileSelected = function(files) { - $scope.importData = {}; + $scope.importFileSelected = async function(files) { - var file = files[0]; - var reader = new FileReader(); - reader.onload = function(e) { - try { - var data = JSON.parse(e.target.result); - $timeout(function(){ - if(data.auth_params) { - // request password - $scope.importData.requestPassword = true; - $scope.importData.data = data; + let run = () => { + $timeout(() => { + $scope.importData = {}; - $timeout(() => { - var element = document.getElementById("import-password-request"); - if(element) { - element.scrollIntoView(false); + var file = files[0]; + var reader = new FileReader(); + reader.onload = function(e) { + try { + var data = JSON.parse(e.target.result); + $timeout(function(){ + if(data.auth_params) { + // request password + $scope.importData.requestPassword = true; + $scope.importData.data = data; + + $timeout(() => { + var element = document.getElementById("import-password-request"); + if(element) { + element.scrollIntoView(false); + } + }) + } else { + $scope.performImport(data, null); } }) - } else { - $scope.performImport(data, null); + } catch (e) { + alert("Unable to open file. Ensure it is a proper JSON file and try again."); } - }) - } catch (e) { - alert("Unable to open file. Ensure it is a proper JSON file and try again."); - } + } + + reader.readAsText(file); + }) } - reader.readAsText(file); + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageBackups)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageBackups, () => { + run(); + }); + } else { + run(); + } } $scope.importJSONData = function(data, password, callback) { @@ -316,7 +346,7 @@ class AccountMenu { Export */ - $scope.downloadDataArchive = function() { + $scope.downloadDataArchive = async function() { archiveManager.downloadBackup($scope.archiveFormData.encrypted); } @@ -362,6 +392,35 @@ class AccountMenu { Passcode Lock */ + $scope.passcodeAutoLockOptions = passcodeManager.getAutoLockIntervalOptions(); + + $scope.reloadAutoLockInterval = function() { + passcodeManager.getAutoLockInterval().then((interval) => { + $timeout(() => { + $scope.selectedAutoLockInterval = interval; + }) + }) + } + + $scope.reloadAutoLockInterval(); + + $scope.selectAutoLockInterval = async function(interval) { + let run = async () => { + await passcodeManager.setAutoLockInterval(interval); + $timeout(() => { + $scope.reloadAutoLockInterval(); + }); + } + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => { + run(); + }); + } else { + run(); + } + } + $scope.hasPasscode = function() { return passcodeManager.hasPasscode(); } @@ -377,10 +436,12 @@ class AccountMenu { return; } - let fn = $scope.formData.changingPasscode ? passcodeManager.changePasscode : passcodeManager.setPasscode; + let fn = $scope.formData.changingPasscode ? passcodeManager.changePasscode.bind(passcodeManager) : passcodeManager.setPasscode.bind(passcodeManager); fn(passcode, () => { - $timeout(function(){ + $timeout(() => { + $scope.formData.passcode = null; + $scope.formData.confirmPasscode = null; $scope.formData.showPasscodeForm = false; var offline = authManager.offline(); @@ -393,27 +454,50 @@ class AccountMenu { }) } - $scope.changePasscodePressed = function() { - $scope.formData.changingPasscode = true; - $scope.addPasscodeClicked(); - $scope.formData.changingPasscode = false; + $scope.changePasscodePressed = async function() { + let run = () => { + $timeout(() => { + $scope.formData.changingPasscode = true; + $scope.addPasscodeClicked(); + }) + } + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => { + run(); + }); + } else { + run(); + } } - $scope.removePasscodePressed = function() { - var signedIn = !authManager.offline(); - var message = "Are you sure you want to remove your local passcode?"; - if(!signedIn) { - message += " This will remove encryption from your local data."; - } - if(confirm(message)) { - passcodeManager.clearPasscode(); + $scope.removePasscodePressed = async function() { + let run = () => { + $timeout(() => { + var signedIn = !authManager.offline(); + var message = "Are you sure you want to remove your local passcode?"; + if(!signedIn) { + message += " This will remove encryption from your local data."; + } + if(confirm(message)) { + passcodeManager.clearPasscode(); - if(authManager.offline()) { - syncManager.markAllItemsDirtyAndSaveOffline(); - // Don't create backup here, as if the user is temporarily removing the passcode to change it, - // we don't want to write unencrypted data to disk. - // $rootScope.$broadcast("major-data-change"); - } + if(authManager.offline()) { + syncManager.markAllItemsDirtyAndSaveOffline(); + // Don't create backup here, as if the user is temporarily removing the passcode to change it, + // we don't want to write unencrypted data to disk. + // $rootScope.$broadcast("major-data-change"); + } + } + }) + } + + if(await privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManagePasscode)) { + privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManagePasscode, () => { + run(); + }); + } else { + run(); } } diff --git a/app/assets/javascripts/app/directives/views/componentView.js b/app/assets/javascripts/app/directives/views/componentView.js index a68ea4be5..03a06b6e9 100644 --- a/app/assets/javascripts/app/directives/views/componentView.js +++ b/app/assets/javascripts/app/directives/views/componentView.js @@ -30,6 +30,16 @@ class ComponentView { controller($scope, $rootScope, $timeout, componentManager, desktopManager, themeManager) { 'ngInject'; + $scope.onVisibilityChange = function() { + if(document.visibilityState == "hidden") { + return; + } + + if($scope.issueLoading) { + $scope.reloadComponent(); + } + } + $scope.themeHandlerIdentifier = "component-view-" + Math.random(); componentManager.registerHandler({identifier: $scope.themeHandlerIdentifier, areas: ["themes"], activationHandler: (component) => { $scope.reloadThemeStatus(); @@ -45,34 +55,58 @@ class ComponentView { return; } - // activationHandlers may be called multiple times, design below to be idempotent - if(component.active) { - $scope.loading = true; - let iframe = componentManager.iframeForComponent(component); - if(iframe) { - // begin loading error handler. If onload isn't called in x seconds, display an error - if($scope.loadTimeout) { $timeout.cancel($scope.loadTimeout);} - $scope.loadTimeout = $timeout(() => { - if($scope.loading) { - $scope.issueLoading = true; - } - }, 3500); - iframe.onload = function(event) { - // console.log("iframe loaded for component", component.name, "cancelling load timeout", $scope.loadTimeout); - $timeout.cancel($scope.loadTimeout); - $scope.loading = false; - $scope.issueLoading = false; - componentManager.registerComponentWindow(component, iframe.contentWindow); - }.bind(this); - } - } - }, + $timeout(() => { + $scope.handleActivation(); + }) + }, actionHandler: (component, action, data) => { if(action == "set-size") { componentManager.handleSetSizeEvent(component, data); } - }} - ); + } + }); + + $scope.handleActivation = function() { + // activationHandlers may be called multiple times, design below to be idempotent + let component = $scope.component; + if(!component.active) { + return; + } + + $scope.loading = true; + + let iframe = componentManager.iframeForComponent(component); + if(iframe) { + // begin loading error handler. If onload isn't called in x seconds, display an error + if($scope.loadTimeout) { $timeout.cancel($scope.loadTimeout);} + $scope.loadTimeout = $timeout(() => { + if($scope.loading) { + $scope.loading = false; + $scope.issueLoading = true; + + if(!$scope.didAttemptReload) { + $scope.didAttemptReload = true; + $scope.reloadComponent(); + } else { + // We'll attempt to reload when the tab gains focus + document.addEventListener("visibilitychange", $scope.onVisibilityChange); + } + } + }, 3500); + iframe.onload = (event) => { + $timeout.cancel($scope.loadTimeout); + componentManager.registerComponentWindow(component, iframe.contentWindow); + + // Add small timeout to, as $scope.loading controls loading overlay, + // which is used to avoid flicker when enabling extensions while having an enabled theme + // we don't use ng-show because it causes problems with rendering iframes after timeout, for some reason. + $timeout(() => { + $scope.loading = false; + $scope.issueLoading = false; + }, 7) + }; + } + } /* @@ -106,7 +140,11 @@ class ComponentView { $scope.reloadComponent = function() { console.log("Reloading component", $scope.component); - componentManager.reloadComponent($scope.component); + // force iFrame to deinit, allows new one to be created + $scope.componentValid = false; + componentManager.reloadComponent($scope.component).then(() => { + $scope.reloadStatus(); + }); } $scope.reloadStatus = function(doManualReload = true) { @@ -114,7 +152,7 @@ class ComponentView { $scope.reloading = true; let previouslyValid = $scope.componentValid; - var expired, offlineRestricted, urlError; + var offlineRestricted, urlError; offlineRestricted = component.offlineOnly && !isDesktopApplication(); @@ -123,13 +161,23 @@ class ComponentView { || (isDesktopApplication() && (!component.local_url && !component.hasValidHostedUrl())) - expired = component.valid_until && component.valid_until <= new Date(); + $scope.expired = component.valid_until && component.valid_until <= new Date(); - $scope.componentValid = !offlineRestricted && !urlError && !expired; + // Here we choose our own readonly state based on custom logic. However, if a parent + // wants to implement their own readonly logic, they can lock it. + if(!component.lockReadonly) { + component.readonly = $scope.expired; + } + + $scope.componentValid = !offlineRestricted && !urlError; + + if(!$scope.componentValid) { + // required to disable overlay + $scope.loading = false; + } if(offlineRestricted) $scope.error = 'offline-restricted'; else if(urlError) $scope.error = 'url-missing'; - else if(expired) $scope.error = 'expired'; else $scope.error = null; if($scope.componentValid !== previouslyValid) { @@ -139,7 +187,7 @@ class ComponentView { } } - if(expired && doManualReload) { + if($scope.expired && doManualReload) { // Try reloading, handled by footer, which will open Extensions window momentarily to pull in latest data // Upon completion, this method, reloadStatus, will be called, upon where doManualReload will be false to prevent recursion. $rootScope.$broadcast("reload-ext-data"); @@ -189,10 +237,10 @@ class ComponentView { } desktopManager.deregisterUpdateObserver($scope.updateObserver); + document.removeEventListener("visibilitychange", $scope.onVisibilityChange); } $scope.$on("$destroy", function() { - // console.log("Deregistering handler", $scope.identifier, $scope.component.name); $scope.destroy(); }); } diff --git a/app/assets/javascripts/app/directives/views/editorMenu.js b/app/assets/javascripts/app/directives/views/editorMenu.js index 8736f484b..47bde5dd2 100644 --- a/app/assets/javascripts/app/directives/views/editorMenu.js +++ b/app/assets/javascripts/app/directives/views/editorMenu.js @@ -19,10 +19,6 @@ class EditorMenu { return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; }); - $scope.stack = componentManager.componentsForArea("editor-stack").sort((a, b) => { - return a.name.toLowerCase() < b.name.toLowerCase() ? -1 : 1; - }); - $scope.isDesktop = isDesktopApplication(); $scope.defaultEditor = $scope.editors.filter((e) => {return e.isDefaultEditor()})[0]; @@ -77,17 +73,10 @@ class EditorMenu { if(component == $scope.selectedEditor) { return true; - } else if(component.area == "editor-stack") { - return $scope.stackComponentEnabled(component); } else { return false; } } - - $scope.stackComponentEnabled = function(component) { - return component.active && !component.isExplicitlyDisabledForItem($scope.currentItem); - } - } } diff --git a/app/assets/javascripts/app/directives/views/menuRow.js b/app/assets/javascripts/app/directives/views/menuRow.js index 999e64f9f..49fbb5e0a 100644 --- a/app/assets/javascripts/app/directives/views/menuRow.js +++ b/app/assets/javascripts/app/directives/views/menuRow.js @@ -7,6 +7,7 @@ class MenuRow { this.scope = { action: "&", circle: "=", + circleAlign: "=", label: "=", subtitle: "=", hasButton: "=", diff --git a/app/assets/javascripts/app/directives/views/panelResizer.js b/app/assets/javascripts/app/directives/views/panelResizer.js index fc31c0ca6..0be60fffa 100644 --- a/app/assets/javascripts/app/directives/views/panelResizer.js +++ b/app/assets/javascripts/app/directives/views/panelResizer.js @@ -32,6 +32,10 @@ class PanelResizer { scope.control.flash = function() { scope.flash(); } + + scope.control.isCollapsed = function() { + return scope.isCollapsed(); + } } controller($scope, $element, modelManager, actionsManager, $timeout, $compile) { @@ -52,16 +56,19 @@ class PanelResizer { // Handle Double Click Event var widthBeforeLastDblClick = 0; resizerColumn.ondblclick = () => { - var collapsed = $scope.isCollapsed(); $timeout(() => { - if(collapsed) { + var preClickCollapseState = $scope.isCollapsed(); + if(preClickCollapseState) { $scope.setWidth(widthBeforeLastDblClick || $scope.defaultWidth); } else { widthBeforeLastDblClick = lastWidth; $scope.setWidth(minWidth); } + $scope.finishSettingWidth(); - $scope.onResizeFinish()(lastWidth, lastLeft, $scope.isAtMaxWidth()); + + var newCollapseState = !preClickCollapseState; + $scope.onResizeFinish()(lastWidth, lastLeft, $scope.isAtMaxWidth(), newCollapseState); }) } @@ -274,7 +281,7 @@ class PanelResizer { let isMaxWidth = $scope.isAtMaxWidth(); if($scope.onResizeFinish) { - $scope.onResizeFinish()(lastWidth, lastLeft, isMaxWidth); + $scope.onResizeFinish()(lastWidth, lastLeft, isMaxWidth, $scope.isCollapsed()); } $scope.finishSettingWidth(); diff --git a/app/assets/javascripts/app/directives/views/passwordWizard.js b/app/assets/javascripts/app/directives/views/passwordWizard.js index f93bed6d5..7c78e2cbb 100644 --- a/app/assets/javascripts/app/directives/views/passwordWizard.js +++ b/app/assets/javascripts/app/directives/views/passwordWizard.js @@ -102,6 +102,9 @@ class PasswordWizard { if(preprocessor) { preprocessor(() => { next(); + }, () => { + // on fail + $scope.isContinuing = false; }) } else { next(); @@ -114,7 +117,7 @@ class PasswordWizard { $scope.preprocessorForStep = function(step) { if(step == PasswordStep) { - return (callback) => { + return (onSuccess, onFail) => { $scope.showSpinner = true; $scope.continueTitle = "Generating Keys..."; $timeout(() => { @@ -122,7 +125,9 @@ class PasswordWizard { $scope.showSpinner = false; $scope.continueTitle = DefaultContinueTitle; if(success) { - callback(); + onSuccess(); + } else { + onFail && onFail(); } }); }) diff --git a/app/assets/javascripts/app/directives/views/privilegesAuthModal.js b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js new file mode 100644 index 000000000..8440fd849 --- /dev/null +++ b/app/assets/javascripts/app/directives/views/privilegesAuthModal.js @@ -0,0 +1,92 @@ +class PrivilegesAuthModal { + + constructor() { + this.restrict = "E"; + this.templateUrl = "directives/privileges-auth-modal.html"; + this.scope = { + action: "=", + onSuccess: "=", + onCancel: "=", + }; + } + + link($scope, el, attrs) { + $scope.dismiss = function() { + el.remove(); + } + } + + controller($scope, privilegesManager, passcodeManager, authManager, $timeout) { + 'ngInject'; + + $scope.authenticationParameters = {}; + $scope.sessionLengthOptions = privilegesManager.getSessionLengthOptions(); + + privilegesManager.getSelectedSessionLength().then((length) => { + $timeout(() => { + $scope.selectedSessionLength = length; + }) + }) + + $scope.selectSessionLength = function(length) { + $scope.selectedSessionLength = length; + } + + privilegesManager.netCredentialsForAction($scope.action).then((credentials) => { + $timeout(() => { + $scope.requiredCredentials = credentials.sort(); + }); + }); + + $scope.promptForCredential = function(credential) { + return privilegesManager.displayInfoForCredential(credential).prompt; + } + + $scope.cancel = function() { + $scope.dismiss(); + $scope.onCancel && $scope.onCancel(); + } + + $scope.isCredentialInFailureState = function(credential) { + if(!$scope.failedCredentials) { + return false; + } + return $scope.failedCredentials.find((candidate) => { + return candidate == credential; + }) != null; + } + + $scope.validate = function() { + var failed = []; + for(var cred of $scope.requiredCredentials) { + var value = $scope.authenticationParameters[cred]; + if(!value || value.length == 0) { + failed.push(cred); + } + } + + $scope.failedCredentials = failed; + return failed.length == 0; + } + + $scope.submit = function() { + if(!$scope.validate()) { + return; + } + privilegesManager.authenticateAction($scope.action, $scope.authenticationParameters).then((result) => { + $timeout(() => { + if(result.success) { + privilegesManager.setSessionLength($scope.selectedSessionLength); + $scope.onSuccess(); + $scope.dismiss(); + } else { + $scope.failedCredentials = result.failedCredentials; + } + }) + }) + } + + } +} + +angular.module('app').directive('privilegesAuthModal', () => new PrivilegesAuthModal); diff --git a/app/assets/javascripts/app/directives/views/privilegesManagementModal.js b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js new file mode 100644 index 000000000..bec8691d4 --- /dev/null +++ b/app/assets/javascripts/app/directives/views/privilegesManagementModal.js @@ -0,0 +1,88 @@ +class PrivilegesManagementModal { + + constructor() { + this.restrict = "E"; + this.templateUrl = "directives/privileges-management-modal.html"; + this.scope = { + + }; + } + + link($scope, el, attrs) { + $scope.dismiss = function() { + el.remove(); + } + } + + controller($scope, privilegesManager, passcodeManager, authManager, $timeout) { + 'ngInject'; + + $scope.dummy = {}; + + $scope.hasPasscode = passcodeManager.hasPasscode(); + $scope.hasAccount = !authManager.offline(); + + $scope.displayInfoForCredential = function(credential) { + let info = privilegesManager.displayInfoForCredential(credential); + if(credential == PrivilegesManager.CredentialLocalPasscode) { + info["availability"] = $scope.hasPasscode; + } else if(credential == PrivilegesManager.CredentialAccountPassword) { + info["availability"] = $scope.hasAccount; + } else { + info["availability"] = true; + } + + return info; + } + + $scope.displayInfoForAction = function(action) { + return privilegesManager.displayInfoForAction(action).label; + } + + $scope.isCredentialRequiredForAction = function(action, credential) { + if(!$scope.privileges) { + return false; + } + return $scope.privileges.isCredentialRequiredForAction(action, credential); + } + + $scope.clearSession = function() { + privilegesManager.clearSession().then(() => { + $scope.reloadPrivileges(); + }) + } + + $scope.reloadPrivileges = async function() { + $scope.availableActions = privilegesManager.getAvailableActions(); + $scope.availableCredentials = privilegesManager.getAvailableCredentials(); + let sessionEndDate = await privilegesManager.getSessionExpirey(); + $scope.sessionExpirey = sessionEndDate.toLocaleString(); + $scope.sessionExpired = new Date() >= sessionEndDate; + + $scope.credentialDisplayInfo = {}; + for(let cred of $scope.availableCredentials) { + $scope.credentialDisplayInfo[cred] = $scope.displayInfoForCredential(cred); + } + + privilegesManager.getPrivileges().then((privs) => { + $timeout(() => { + $scope.privileges = privs; + }) + }) + } + + $scope.checkboxValueChanged = function(action, credential) { + $scope.privileges.toggleCredentialForAction(action, credential); + privilegesManager.savePrivileges(); + } + + $scope.reloadPrivileges(); + + $scope.cancel = function() { + $scope.dismiss(); + $scope.onCancel && $scope.onCancel(); + } + } +} + +angular.module('app').directive('privilegesManagementModal', () => new PrivilegesManagementModal); diff --git a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js index d5d6313d3..70891f354 100644 --- a/app/assets/javascripts/app/directives/views/revisionPreviewModal.js +++ b/app/assets/javascripts/app/directives/views/revisionPreviewModal.js @@ -10,15 +10,56 @@ class RevisionPreviewModal { } link($scope, el, attrs) { - - $scope.dismiss = function() { - el.remove(); - } + $scope.el = el; } - controller($scope, modelManager, syncManager) { + controller($scope, modelManager, syncManager, componentManager, $timeout) { 'ngInject'; + $scope.dismiss = function() { + $scope.el.remove(); + $scope.$destroy(); + } + + $scope.$on("$destroy", function() { + if($scope.identifier) { + componentManager.deregisterHandler($scope.identifier); + } + }); + + $scope.note = new SFItem({content: $scope.content, content_type: "Note"}); + // Set UUID to editoForNote can find proper editor, + // but then generate new uuid for note as not to save changes to original, if editor makes changes. + $scope.note.uuid = $scope.uuid; + let editorForNote = componentManager.editorForNote($scope.note); + $scope.note.uuid = SFJS.crypto.generateUUIDSync(); + + if(editorForNote) { + // Create temporary copy, as a lot of componentManager is uuid based, + // so might interfere with active editor. Be sure to copy only the content, as the + // top level editor object has non-copyable properties like .window, which cannot be transfered + let editorCopy = new SNComponent({content: editorForNote.content}); + editorCopy.readonly = true; + editorCopy.lockReadonly = true; + $scope.identifier = editorCopy.uuid; + + componentManager.registerHandler({identifier: $scope.identifier, areas: ["editor-editor"], + contextRequestHandler: (component) => { + if(component == $scope.editor) { + return $scope.note; + } + }, + componentForSessionKeyHandler: (key) => { + if(key == $scope.editor.sessionKey) { + return $scope.editor; + } + } + }); + + $scope.editor = editorCopy; + } + + $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; diff --git a/app/assets/javascripts/app/filters/sortBy.js b/app/assets/javascripts/app/filters/sortBy.js index e182b19a5..c1fa496a8 100644 --- a/app/assets/javascripts/app/filters/sortBy.js +++ b/app/assets/javascripts/app/filters/sortBy.js @@ -1,6 +1,6 @@ angular.module('app') .filter('sortBy', function ($filter) { - return function(items, sortBy) { + return function(items, sortBy, reverse) { let sortValueFn = (a, b, pinCheck = false) => { if(!pinCheck) { if(a.pinned && b.pinned) { @@ -14,6 +14,11 @@ angular.module('app') var bValue = b[sortBy] || ""; let vector = 1; + + if(reverse) { + vector *= -1; + } + if(sortBy == "title") { aValue = aValue.toLowerCase(); bValue = bValue.toLowerCase(); @@ -21,11 +26,11 @@ angular.module('app') if(aValue.length == 0 && bValue.length == 0) { return 0; } else if(aValue.length == 0 && bValue.length != 0) { - return 1; + return 1 * vector; } else if(aValue.length != 0 && bValue.length == 0) { - return -1; + return -1 * vector; } else { - vector = -1; + vector *= -1; } } diff --git a/app/assets/javascripts/app/models/privileges.js b/app/assets/javascripts/app/models/privileges.js new file mode 100644 index 000000000..3fb5f96fa --- /dev/null +++ b/app/assets/javascripts/app/models/privileges.js @@ -0,0 +1,34 @@ +class SNPrivileges extends SFItem { + + setCredentialsForAction(action, credentials) { + this.content.desktopPrivileges[action] = credentials; + } + + getCredentialsForAction(action) { + return this.content.desktopPrivileges[action] || []; + } + + toggleCredentialForAction(action, credential) { + if(this.isCredentialRequiredForAction(action, credential)) { + this.removeCredentialForAction(action, credential); + } else { + this.addCredentialForAction(action, credential); + } + } + + removeCredentialForAction(action, credential) { + _.pull(this.content.desktopPrivileges[action], credential); + } + + addCredentialForAction(action, credential) { + var credentials = this.getCredentialsForAction(action); + credentials.push(credential); + this.setCredentialsForAction(action, credentials); + } + + isCredentialRequiredForAction(action, credential) { + var credentialsRequired = this.getCredentialsForAction(action); + return credentialsRequired.includes(credential); + } + +} diff --git a/app/assets/javascripts/app/services/actionsManager.js b/app/assets/javascripts/app/services/actionsManager.js index 1953907c3..f23dfd379 100644 --- a/app/assets/javascripts/app/services/actionsManager.js +++ b/app/assets/javascripts/app/services/actionsManager.js @@ -202,7 +202,7 @@ class ActionsManager { var scope = this.$rootScope.$new(true); scope.uuid = uuid; scope.content = content; - var el = this.$compile( "" )(scope); + var el = this.$compile( "" )(scope); angular.element(document.body).append(el); } diff --git a/app/assets/javascripts/app/services/archiveManager.js b/app/assets/javascripts/app/services/archiveManager.js index 4c60c6b13..6517cf204 100644 --- a/app/assets/javascripts/app/services/archiveManager.js +++ b/app/assets/javascripts/app/services/archiveManager.js @@ -1,9 +1,10 @@ class ArchiveManager { - constructor(passcodeManager, authManager, modelManager) { + constructor(passcodeManager, authManager, modelManager, privilegesManager) { this.passcodeManager = passcodeManager; this.authManager = authManager; this.modelManager = modelManager; + this.privilegesManager = privilegesManager; } /* @@ -15,26 +16,36 @@ class ArchiveManager { } async downloadBackupOfItems(items, encrypted) { - // download in Standard File format - var keys, authParams; - if(encrypted) { - if(this.authManager.offline() && this.passcodeManager.hasPasscode()) { - keys = this.passcodeManager.keys(); - authParams = this.passcodeManager.passcodeAuthParams(); - } else { - keys = await this.authManager.keys(); - authParams = await this.authManager.getAuthParams(); + let run = async () => { + // download in Standard File format + var keys, authParams; + if(encrypted) { + if(this.authManager.offline() && this.passcodeManager.hasPasscode()) { + keys = this.passcodeManager.keys(); + authParams = this.passcodeManager.passcodeAuthParams(); + } else { + keys = await this.authManager.keys(); + authParams = await this.authManager.getAuthParams(); + } } - } - this.__itemsData(items, keys, authParams).then((data) => { - let modifier = encrypted ? "Encrypted" : "Decrypted"; - this.__downloadData(data, `Standard Notes ${modifier} Backup - ${this.__formattedDate()}.txt`); + this.__itemsData(items, keys, authParams).then((data) => { + let modifier = encrypted ? "Encrypted" : "Decrypted"; + this.__downloadData(data, `Standard Notes ${modifier} Backup - ${this.__formattedDate()}.txt`); - // download as zipped plain text files - if(!keys) { - this.__downloadZippedItems(items); - } - }) + // download as zipped plain text files + if(!keys) { + this.__downloadZippedItems(items); + } + }) + } + + if(await this.privilegesManager.actionRequiresPrivilege(PrivilegesManager.ActionManageBackups)) { + this.privilegesManager.presentPrivilegesModal(PrivilegesManager.ActionManageBackups, () => { + run(); + }); + } else { + run(); + } } /* diff --git a/app/assets/javascripts/app/services/authManager.js b/app/assets/javascripts/app/services/authManager.js index 6787d3709..379617ca1 100644 --- a/app/assets/javascripts/app/services/authManager.js +++ b/app/assets/javascripts/app/services/authManager.js @@ -44,7 +44,7 @@ class AuthManager extends SFAuthManager { this.storageManager.setItemsMode(StorageManager.Ephemeral); } else { this.storageManager.setModelStorageMode(StorageManager.Fixed); - this.storageManager.setItemsMode(this.storageManager.hasPasscode() ? StorageManager.FixedEncrypted : StorageManager.Fixed); + this.storageManager.setItemsMode(this.storageManager.bestStorageMode()); this.storageManager.setItem("ephemeral", JSON.stringify(false), StorageManager.Fixed); } } @@ -92,6 +92,13 @@ class AuthManager extends SFAuthManager { } } + async verifyAccountPassword(password) { + let authParams = await this.getAuthParams(); + let keys = await SFJS.crypto.computeEncryptionKeysForUser(password, authParams); + let success = keys.mk === (await this.keys()).mk; + return success; + } + async checkForSecurityUpdate() { if(this.offline()) { return false; diff --git a/app/assets/javascripts/app/services/componentManager.js b/app/assets/javascripts/app/services/componentManager.js index 5d8fb15aa..045ceb93a 100644 --- a/app/assets/javascripts/app/services/componentManager.js +++ b/app/assets/javascripts/app/services/componentManager.js @@ -33,7 +33,7 @@ class ComponentManager { desktopManager.registerUpdateObserver((component) => { // Reload theme if active if(component.active && component.isTheme()) { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } }) @@ -147,14 +147,15 @@ class ComponentManager { }); } - postActiveThemeToAllComponents() { + postActiveThemesToAllComponents() { for(var component of this.components) { // Skip over components that are themes themselves, // or components that are not active, or components that don't have a window if(component.isTheme() || !component.active || !component.window) { continue; } - this.postActiveThemeToComponent(component); + + this.postActiveThemesToComponent(component); } } @@ -162,14 +163,16 @@ class ComponentManager { return this.componentsForArea("themes").filter((theme) => {return theme.active}); } - postActiveThemeToComponent(component) { - var themes = this.getActiveThemes(); - var urls = themes.map((theme) => { + urlsForActiveThemes() { + let themes = this.getActiveThemes(); + return themes.map((theme) => { return this.urlForComponent(theme); }) - var data = { - themes: urls - } + } + + postActiveThemesToComponent(component) { + let urls = this.urlsForActiveThemes(); + let data = { themes: urls } this.sendMessageToComponent(component, {action: "themes", data: data}) } @@ -291,7 +294,18 @@ class ComponentManager { } componentForSessionKey(key) { - return _.find(this.components, {sessionKey: key}); + let component = _.find(this.components, {sessionKey: key}); + if(!component) { + for(let handler of this.handlers) { + if(handler.componentForSessionKeyHandler) { + component = handler.componentForSessionKeyHandler(key); + if(component) { + break; + } + } + } + } + return component; } handleMessage(component, message) { @@ -302,6 +316,24 @@ class ComponentManager { return; } + // Actions that won't succeeed with readonly mode + let readwriteActions = [ + "save-items", + "associate-item", + "deassociate-item", + "create-item", + "create-items", + "delete-items", + "set-component-data" + ]; + + if(component.readonly && readwriteActions.includes(message.action)) { + // A component can be marked readonly if changes should not be saved. + // Particullary used for revision preview windows where the notes should not be savable. + alert(`The extension ${component.name} is trying to save, but it is in a locked state and cannot accept changes.`); + return; + } + /** Possible Messages: set-size @@ -343,11 +375,13 @@ class ComponentManager { this.handleInstallLocalComponentMessage(component, message); } else if(message.action === "present-conflict-resolution") { this.handlePresentConflictResolutionMessage(component, message); + } else if(message.action === "duplicate-item") { + this.handleDuplicateItemMessage(component, message); } // Notify observers for(let handler of this.handlers) { - if(handler.areas.includes(component.area) || handler.areas.includes("*")) { + if(handler.actionHandler && (handler.areas.includes(component.area) || handler.areas.includes("*"))) { this.timeout(function(){ handler.actionHandler(component, message.action, message.data); }) @@ -539,6 +573,24 @@ class ComponentManager { }); } + handleDuplicateItemMessage(component, message) { + var itemParams = message.data.item; + var item = this.modelManager.findItem(itemParams.uuid); + var requiredPermissions = [ + { + name: "stream-items", + content_types: [item.content_type] + } + ]; + + this.runWithPermissions(component, requiredPermissions, () => { + var duplicate = this.modelManager.duplicateItem(item); + this.syncManager.sync(); + + this.replyToMessage(component, message, {item: this.jsonForItem(duplicate, component)}); + }); + } + handleCreateItemsMessage(component, message) { var responseItems = message.data.item ? [message.data.item] : message.data.items; let uniqueContentTypes = _.uniq(responseItems.map((item) => {return item.content_type})); @@ -629,22 +681,35 @@ class ComponentManager { } handleToggleComponentMessage(sourceComponent, targetComponent, message) { - if(targetComponent.area == "modal") { - this.openModalComponent(targetComponent); + this.toggleComponent(targetComponent); + } + + toggleComponent(component) { + if(component.area == "modal") { + this.openModalComponent(component); } else { - if(targetComponent.active) { - this.deactivateComponent(targetComponent); + if(component.active) { + this.deactivateComponent(component); } else { - if(targetComponent.content_type == "SN|Theme" && !targetComponent.isLayerable()) { + if(component.content_type == "SN|Theme") { // Deactive currently active theme if new theme is not layerable var activeThemes = this.getActiveThemes(); - for(var theme of activeThemes) { - if(theme && !theme.isLayerable()) { - this.deactivateComponent(theme); - } + + // Activate current before deactivating others, so as not to flicker + this.activateComponent(component); + + if(!component.isLayerable()) { + setTimeout(() => { + for(var theme of activeThemes) { + if(theme && !theme.isLayerable()) { + this.deactivateComponent(theme); + } + } + }, 10); } + } else { + this.activateComponent(component); } - this.activateComponent(targetComponent); } } } @@ -765,14 +830,14 @@ class ComponentManager { var permissions = dialog.permissions; var component = dialog.component; var callback = dialog.callback; - var el = this.$compile( "" )(dialog); + var el = this.$compile( "" )(dialog); angular.element(document.body).append(el); } openModalComponent(component) { var scope = this.$rootScope.$new(true); scope.component = component; - var el = this.$compile( "" )(scope); + var el = this.$compile( "" )(scope); angular.element(document.body).append(el); } @@ -782,6 +847,10 @@ class ComponentManager { deregisterHandler(identifier) { var handler = _.find(this.handlers, {identifier: identifier}); + if(!handler) { + console.log("Attempting to deregister non-existing handler"); + return; + } this.handlers.splice(this.handlers.indexOf(handler), 1); } @@ -805,34 +874,39 @@ class ComponentManager { data: { uuid: component.uuid, environment: isDesktopApplication() ? "desktop" : "web", - platform: getPlatformString() + platform: getPlatformString(), + activeThemeUrls: this.urlsForActiveThemes() } }); - this.postActiveThemeToComponent(component); + this.postActiveThemesToComponent(component); this.desktopManager.notifyComponentActivation(component); } /* Performs func in timeout, but syncronously, if used `await waitTimeout` */ - async waitTimeout(func) { - return new Promise((resolve, reject) => { - this.timeout(() => { - func(); - resolve(); - }); - }) - } + // No longer used. See comment in activateComponent. + // async waitTimeout(func) { + // return new Promise((resolve, reject) => { + // this.timeout(() => { + // func(); + // resolve(); + // }); + // }) + // } async activateComponent(component, dontSync = false) { var didChange = component.active != true; component.active = true; - for(var handler of this.handlers) { + for(let handler of this.handlers) { if(handler.areas.includes(component.area) || handler.areas.includes("*")) { // We want to run the handler in a $timeout so the UI updates, but we also don't want it to run asyncronously // so that the steps below this one are run before the handler. So we run in a waitTimeout. - await this.waitTimeout(() => { + // Update 12/18: We were using this.waitTimeout previously, however, that caused the iframe.onload callback to never be called + // for some reason for iframes on desktop inside the revision-preview-modal. So we'll use safeApply instead. I'm not quite sure + // where the original "so the UI updates" comment applies to, but we'll have to keep an eye out to see if this causes problems somewhere else. + this.$rootScope.safeApply(() => { handler.activationHandler && handler.activationHandler(component); }) } @@ -848,7 +922,7 @@ class ComponentManager { } if(component.area == "themes") { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } } @@ -859,7 +933,8 @@ class ComponentManager { for(let handler of this.handlers) { if(handler.areas.includes(component.area) || handler.areas.includes("*")) { - await this.waitTimeout(() => { + // See comment in activateComponent regarding safeApply and awaitTimeout + this.$rootScope.safeApply(() => { handler.activationHandler && handler.activationHandler(component); }) } @@ -881,7 +956,7 @@ class ComponentManager { }) if(component.area == "themes") { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } } @@ -893,7 +968,8 @@ class ComponentManager { for(let handler of this.handlers) { if(handler.areas.includes(component.area) || handler.areas.includes("*")) { - await this.waitTimeout(() => { + // See comment in activateComponent regarding safeApply and awaitTimeout + this.$rootScope.safeApply(() => { handler.activationHandler && handler.activationHandler(component); }) } @@ -908,7 +984,7 @@ class ComponentManager { }) if(component.area == "themes") { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } // @@ -919,7 +995,8 @@ class ComponentManager { component.active = true; for(var handler of this.handlers) { if(handler.areas.includes(component.area) || handler.areas.includes("*")) { - await this.waitTimeout(() => { + // See comment in activateComponent regarding safeApply and awaitTimeout + this.$rootScope.safeApply(() => { handler.activationHandler && handler.activationHandler(component); }) } @@ -930,7 +1007,7 @@ class ComponentManager { } if(component.area == "themes") { - this.postActiveThemeToAllComponents(); + this.postActiveThemesToAllComponents(); } }) } @@ -981,10 +1058,7 @@ class ComponentManager { if(!iframe) { return; } - var width = data.width; - var height = data.height; - iframe.width = width; - iframe.height = height; + setSize(iframe, data); // On Firefox, resizing a component iframe does not seem to have an effect with editor-stack extensions. @@ -1007,6 +1081,20 @@ class ComponentManager { } } + editorForNote(note) { + let editors = this.componentsForArea("editor-editor"); + for(var editor of editors) { + if(editor.isExplicitlyEnabledForItem(note)) { + return editor; + } + } + + // No editor found for note. Use default editor, if note does not prefer system editor + if(!note.getAppDataItem("prefersPlainEditor")) { + return editors.filter((e) => {return e.isDefaultEditor()})[0]; + } + } + } diff --git a/app/assets/javascripts/app/services/desktopManager.js b/app/assets/javascripts/app/services/desktopManager.js index d437fa296..58ce492d9 100644 --- a/app/assets/javascripts/app/services/desktopManager.js +++ b/app/assets/javascripts/app/services/desktopManager.js @@ -79,6 +79,14 @@ class DesktopManager { this.searchHandler = handler; } + desktop_windowGainedFocus() { + this.$rootScope.$broadcast("window-gained-focus"); + } + + desktop_windowLostFocus() { + this.$rootScope.$broadcast("window-lost-focus"); + } + desktop_onComponentInstallationComplete(componentData, error) { console.log("Web|Component Installation/Update Complete", componentData, error); diff --git a/app/assets/javascripts/app/services/httpManager.js b/app/assets/javascripts/app/services/httpManager.js index 637db6041..a3415b4b5 100644 --- a/app/assets/javascripts/app/services/httpManager.js +++ b/app/assets/javascripts/app/services/httpManager.js @@ -5,7 +5,7 @@ class HttpManager extends SFHttpManager { super($timeout); this.setJWTRequestHandler(async () => { - return storageManager.getItem("jwt");; + return storageManager.getItem("jwt"); }) } } diff --git a/app/assets/javascripts/app/services/modelManager.js b/app/assets/javascripts/app/services/modelManager.js index c3f30c207..9af2df562 100644 --- a/app/assets/javascripts/app/services/modelManager.js +++ b/app/assets/javascripts/app/services/modelManager.js @@ -7,7 +7,8 @@ SFModelManager.ContentTypeClassMapping = { "SN|Theme" : SNTheme, "SN|Component" : SNComponent, "SF|Extension" : SNServerExtension, - "SF|MFA" : SNMfa + "SF|MFA" : SNMfa, + "SN|Privileges" : SNPrivileges }; SFItem.AppDomain = "org.standardnotes.sn"; diff --git a/app/assets/javascripts/app/services/passcodeManager.js b/app/assets/javascripts/app/services/passcodeManager.js index 47c9e763b..79ed39f02 100644 --- a/app/assets/javascripts/app/services/passcodeManager.js +++ b/app/assets/javascripts/app/services/passcodeManager.js @@ -1,100 +1,247 @@ -angular.module('app') - .provider('passcodeManager', function () { +const MillisecondsPerSecond = 1000; - this.$get = function($rootScope, $timeout, modelManager, dbManager, authManager, storageManager) { - return new PasscodeManager($rootScope, $timeout, modelManager, dbManager, authManager, storageManager); - } +class PasscodeManager { - function PasscodeManager($rootScope, $timeout, modelManager, dbManager, authManager, storageManager) { + constructor($rootScope, authManager, storageManager, syncManager) { + this.authManager = authManager; + this.storageManager = storageManager; + this.syncManager = syncManager; + this.$rootScope = $rootScope; - this._hasPasscode = storageManager.getItemSync("offlineParams", StorageManager.Fixed) != null; + this._hasPasscode = this.storageManager.getItemSync("offlineParams", StorageManager.Fixed) != null; this._locked = this._hasPasscode; - this.isLocked = function() { - return this._locked; - } + this.passcodeChangeObservers = []; - this.hasPasscode = function() { - return this._hasPasscode; - } + this.configureAutoLock(); + } - this.keys = function() { - return this._keys; - } + addPasscodeChangeObserver(callback) { + this.passcodeChangeObservers.push(callback); + } - this.passcodeAuthParams = function() { - var authParams = JSON.parse(storageManager.getItemSync("offlineParams", StorageManager.Fixed)); - if(authParams && !authParams.version) { - var keys = this.keys(); - if(keys && keys.ak) { - // If there's no version stored, and there's an ak, it has to be 002. Newer versions would have thier version stored in authParams. - authParams.version = "002"; - } else { - authParams.version = "001"; - } - } - return authParams; - } + lockApplication() { + window.location.reload(); + this.cancelAutoLockTimer(); + } - this.unlock = function(passcode, callback) { - var params = this.passcodeAuthParams(); - SFJS.crypto.computeEncryptionKeysForUser(passcode, params).then((keys) => { - if(keys.pw !== params.hash) { - callback(false); - return; - } + isLocked() { + return this._locked; + } - this._keys = keys; - this._authParams = params; - this.decryptLocalStorage(keys, params).then(() => { - this._locked = false; - callback(true); - }) - }); - } + hasPasscode() { + return this._hasPasscode; + } - this.setPasscode = (passcode, callback) => { - var uuid = SFJS.crypto.generateUUIDSync(); + keys() { + return this._keys; + } - SFJS.crypto.generateInitialKeysAndAuthParamsForUser(uuid, passcode).then((results) => { - let keys = results.keys; - let authParams = results.authParams; + async setAutoLockInterval(interval) { + return this.storageManager.setItem(PasscodeManager.AutoLockIntervalKey, JSON.stringify(interval), StorageManager.FixedEncrypted); + } - authParams.hash = keys.pw; - this._keys = keys; - this._hasPasscode = true; - this._authParams = authParams; - - // Encrypting will initially clear localStorage - this.encryptLocalStorage(keys, authParams); - - // After it's cleared, it's safe to write to it - storageManager.setItem("offlineParams", JSON.stringify(authParams), StorageManager.Fixed); - callback(true); - }); - } - - this.changePasscode = (newPasscode, callback) => { - this.setPasscode(newPasscode, callback); - } - - this.clearPasscode = function() { - storageManager.setItemsMode(authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.Fixed); // Transfer from Ephemeral - storageManager.removeItem("offlineParams", StorageManager.Fixed); - this._keys = null; - this._hasPasscode = false; - } - - this.encryptLocalStorage = function(keys, authParams) { - storageManager.setKeys(keys, authParams); - // Switch to Ephemeral storage, wiping Fixed storage - // Last argument is `force`, which we set to true because in the case of changing passcode - storageManager.setItemsMode(authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.FixedEncrypted, true); - } - - this.decryptLocalStorage = async function(keys, authParams) { - storageManager.setKeys(keys, authParams); - return storageManager.decryptStorage(); + async getAutoLockInterval() { + let interval = await this.storageManager.getItem(PasscodeManager.AutoLockIntervalKey, StorageManager.FixedEncrypted); + if(interval) { + return JSON.parse(interval); + } else { + return PasscodeManager.AutoLockIntervalNone; } } -}); + + passcodeAuthParams() { + var authParams = JSON.parse(this.storageManager.getItemSync("offlineParams", StorageManager.Fixed)); + if(authParams && !authParams.version) { + var keys = this.keys(); + if(keys && keys.ak) { + // If there's no version stored, and there's an ak, it has to be 002. Newer versions would have their version stored in authParams. + authParams.version = "002"; + } else { + authParams.version = "001"; + } + } + return authParams; + } + + async verifyPasscode(passcode) { + return new Promise(async (resolve, reject) => { + var params = this.passcodeAuthParams(); + let keys = await SFJS.crypto.computeEncryptionKeysForUser(passcode, params); + if(keys.pw !== params.hash) { + resolve(false); + } else { + resolve(true); + } + }) + } + + unlock(passcode, callback) { + var params = this.passcodeAuthParams(); + SFJS.crypto.computeEncryptionKeysForUser(passcode, params).then((keys) => { + if(keys.pw !== params.hash) { + callback(false); + return; + } + + this._keys = keys; + this._authParams = params; + this.decryptLocalStorage(keys, params).then(() => { + this._locked = false; + callback(true); + }) + }); + } + + setPasscode(passcode, callback) { + var uuid = SFJS.crypto.generateUUIDSync(); + + SFJS.crypto.generateInitialKeysAndAuthParamsForUser(uuid, passcode).then((results) => { + let keys = results.keys; + let authParams = results.authParams; + + authParams.hash = keys.pw; + this._keys = keys; + this._hasPasscode = true; + this._authParams = authParams; + + // Encrypting will initially clear localStorage + this.encryptLocalStorage(keys, authParams); + + // After it's cleared, it's safe to write to it + this.storageManager.setItem("offlineParams", JSON.stringify(authParams), StorageManager.Fixed); + callback(true); + + this.notifyObserversOfPasscodeChange(); + }); + } + + changePasscode(newPasscode, callback) { + this.setPasscode(newPasscode, callback); + } + + clearPasscode() { + this.storageManager.setItemsMode(this.authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.Fixed); // Transfer from Ephemeral + this.storageManager.removeItem("offlineParams", StorageManager.Fixed); + this._keys = null; + this._hasPasscode = false; + + this.notifyObserversOfPasscodeChange(); + } + + notifyObserversOfPasscodeChange() { + for(var observer of this.passcodeChangeObservers) { + observer(); + } + } + + encryptLocalStorage(keys, authParams) { + this.storageManager.setKeys(keys, authParams); + // Switch to Ephemeral storage, wiping Fixed storage + // Last argument is `force`, which we set to true because in the case of changing passcode + this.storageManager.setItemsMode(this.authManager.isEphemeralSession() ? StorageManager.Ephemeral : StorageManager.FixedEncrypted, true); + } + + async decryptLocalStorage(keys, authParams) { + this.storageManager.setKeys(keys, authParams); + return this.storageManager.decryptStorage(); + } + + configureAutoLock() { + if(isDesktopApplication()) { + // desktop only + this.$rootScope.$on("window-lost-focus", () => { + this.documentVisibilityChanged(false); + }) + this.$rootScope.$on("window-gained-focus", () => { + this.documentVisibilityChanged(true); + }) + } else { + // tab visibility listender, web only + document.addEventListener('visibilitychange', (e) => { + let visible = document.visibilityState == "visible"; + this.documentVisibilityChanged(visible); + }); + } + + PasscodeManager.AutoLockIntervalNone = 0; + PasscodeManager.AutoLockIntervalImmediate = 1; + PasscodeManager.AutoLockIntervalOneMinute = 60 * MillisecondsPerSecond; + PasscodeManager.AutoLockIntervalFiveMinutes = 300 * MillisecondsPerSecond; + PasscodeManager.AutoLockIntervalOneHour = 3600 * MillisecondsPerSecond; + + PasscodeManager.AutoLockIntervalKey = "AutoLockIntervalKey"; + } + + getAutoLockIntervalOptions() { + return [ + { + value: PasscodeManager.AutoLockIntervalNone, + label: "Off" + }, + { + value: PasscodeManager.AutoLockIntervalImmediate, + label: "Immediately" + }, + { + value: PasscodeManager.AutoLockIntervalOneMinute, + label: "1m" + }, + { + value: PasscodeManager.AutoLockIntervalFiveMinutes, + label: "5m" + }, + { + value: PasscodeManager.AutoLockIntervalOneHour, + label: "1h" + } + ] + } + + documentVisibilityChanged(visible) { + if(visible) { + // check to see if lockAfterDate is not null, and if the application isn't locked. + // if that's the case, it needs to be locked immediately. + if(this.lockAfterDate && new Date() > this.lockAfterDate && !this.isLocked()) { + this.lockApplication(); + } else { + if(!this.isLocked()) { + this.syncManager.sync(); + } + } + this.cancelAutoLockTimer(); + } else { + this.beginAutoLockTimer(); + } + } + + async beginAutoLockTimer() { + var interval = await this.getAutoLockInterval(); + if(interval == PasscodeManager.AutoLockIntervalNone) { + return; + } + + // Use a timeout if possible, but if the computer is put to sleep, timeouts won't work. + // Need to set a date as backup. this.lockAfterDate does not need to be persisted, as + // living in memory seems sufficient. If memory is cleared, then the application will lock anyway. + let addToNow = (seconds) => { + let date = new Date(); + date.setSeconds(date.getSeconds() + seconds); + return date; + } + + this.lockAfterDate = addToNow(interval / MillisecondsPerSecond); + this.lockTimeout = setTimeout(() => { + this.lockApplication(); + // We don't need to look at this anymore since we've succeeded with timeout lock + this.lockAfterDate = null; + }, interval); + } + + cancelAutoLockTimer() { + clearTimeout(this.lockTimeout); + this.lockAfterDate = null; + } +} + +angular.module('app').service('passcodeManager', PasscodeManager); diff --git a/app/assets/javascripts/app/services/privilegesManager.js b/app/assets/javascripts/app/services/privilegesManager.js new file mode 100644 index 000000000..a1c83f077 --- /dev/null +++ b/app/assets/javascripts/app/services/privilegesManager.js @@ -0,0 +1,309 @@ +class PrivilegesManager { + + constructor(passcodeManager, authManager, singletonManager, modelManager, storageManager, $rootScope, $compile) { + this.passcodeManager = passcodeManager; + this.authManager = authManager; + this.singletonManager = singletonManager; + this.modelManager = modelManager; + this.storageManager = storageManager; + this.$rootScope = $rootScope; + this.$compile = $compile; + + this.loadPrivileges(); + + PrivilegesManager.CredentialAccountPassword = "CredentialAccountPassword"; + PrivilegesManager.CredentialLocalPasscode = "CredentialLocalPasscode"; + + PrivilegesManager.ActionManageExtensions = "ActionManageExtensions"; + PrivilegesManager.ActionManageBackups = "ActionManageBackups"; + PrivilegesManager.ActionViewProtectedNotes = "ActionViewProtectedNotes"; + PrivilegesManager.ActionManagePrivileges = "ActionManagePrivileges"; + PrivilegesManager.ActionManagePasscode = "ActionManagePasscode"; + PrivilegesManager.ActionDeleteNote = "ActionDeleteNote"; + + PrivilegesManager.SessionExpiresAtKey = "SessionExpiresAtKey"; + PrivilegesManager.SessionLengthKey = "SessionLengthKey"; + + PrivilegesManager.SessionLengthNone = 0; + PrivilegesManager.SessionLengthFiveMinutes = 300; + PrivilegesManager.SessionLengthOneHour = 3600; + PrivilegesManager.SessionLengthOneWeek = 604800; + + this.availableActions = [ + PrivilegesManager.ActionViewProtectedNotes, + PrivilegesManager.ActionDeleteNote, + PrivilegesManager.ActionManagePasscode, + PrivilegesManager.ActionManageBackups, + PrivilegesManager.ActionManageExtensions, + PrivilegesManager.ActionManagePrivileges, + ] + + this.availableCredentials = [ + PrivilegesManager.CredentialAccountPassword, + PrivilegesManager.CredentialLocalPasscode + ]; + + this.sessionLengths = [ + PrivilegesManager.SessionLengthNone, + PrivilegesManager.SessionLengthFiveMinutes, + PrivilegesManager.SessionLengthOneHour, + PrivilegesManager.SessionLengthOneWeek, + PrivilegesManager.SessionLengthIndefinite + ] + } + + getAvailableActions() { + return this.availableActions; + } + + getAvailableCredentials() { + return this.availableCredentials; + } + + presentPrivilegesModal(action, onSuccess, onCancel) { + if(this.authenticationInProgress()) { + onCancel && onCancel(); + return; + } + + let customSuccess = () => { + onSuccess && onSuccess(); + this.currentAuthenticationElement = null; + } + + let customCancel = () => { + onCancel && onCancel(); + this.currentAuthenticationElement = null; + } + + var scope = this.$rootScope.$new(true); + scope.action = action; + scope.onSuccess = customSuccess; + scope.onCancel = customCancel; + var el = this.$compile( "" )(scope); + angular.element(document.body).append(el); + + this.currentAuthenticationElement = el; + } + + async netCredentialsForAction(action) { + let credentials = (await this.getPrivileges()).getCredentialsForAction(action); + let netCredentials = []; + + for(var cred of credentials) { + if(cred == PrivilegesManager.CredentialAccountPassword) { + if(!this.authManager.offline()) { + netCredentials.push(cred); + } + } else if(cred == PrivilegesManager.CredentialLocalPasscode) { + if(this.passcodeManager.hasPasscode()) { + netCredentials.push(cred); + } + } + } + + return netCredentials; + } + + presentPrivilegesManagementModal() { + var scope = this.$rootScope.$new(true); + var el = this.$compile( "")(scope); + angular.element(document.body).append(el); + } + + authenticationInProgress() { + return this.currentAuthenticationElement != null; + } + + async loadPrivileges() { + return new Promise((resolve, reject) => { + let prefsContentType = "SN|Privileges"; + let contentTypePredicate = new SFPredicate("content_type", "=", prefsContentType); + this.singletonManager.registerSingleton([contentTypePredicate], (resolvedSingleton) => { + this.privileges = resolvedSingleton; + if(!this.privileges.content.desktopPrivileges) { + this.privileges.content.desktopPrivileges = {}; + } + resolve(resolvedSingleton); + }, (valueCallback) => { + // Safe to create. Create and return object. + var privs = new SNPrivileges({content_type: prefsContentType}); + this.modelManager.addItem(privs); + privs.setDirty(true); + this.$rootScope.sync(); + valueCallback(privs); + resolve(privs); + }); + }); + } + + async getPrivileges() { + if(this.privileges) { + return this.privileges; + } else { + return this.loadPrivileges(); + } + } + + displayInfoForCredential(credential) { + let metadata = {} + + metadata[PrivilegesManager.CredentialAccountPassword] = { + label: "Account Password", + prompt: "Please enter your account password." + } + + metadata[PrivilegesManager.CredentialLocalPasscode] = { + label: "Local Passcode", + prompt: "Please enter your local passcode." + } + + return metadata[credential]; + } + + displayInfoForAction(action) { + let metadata = {}; + + metadata[PrivilegesManager.ActionManageExtensions] = { + label: "Manage Extensions" + }; + + metadata[PrivilegesManager.ActionManageBackups] = { + label: "Download/Import Backups" + }; + + metadata[PrivilegesManager.ActionViewProtectedNotes] = { + label: "View Protected Notes" + }; + + metadata[PrivilegesManager.ActionManagePrivileges] = { + label: "Manage Privileges" + }; + + metadata[PrivilegesManager.ActionManagePasscode] = { + label: "Manage Passcode" + } + + metadata[PrivilegesManager.ActionDeleteNote] = { + label: "Delete Notes" + } + + return metadata[action]; + } + + getSessionLengthOptions() { + return [ + { + value: PrivilegesManager.SessionLengthNone, + label: "Don't Remember" + }, + { + value: PrivilegesManager.SessionLengthFiveMinutes, + label: "5 Minutes" + }, + { + value: PrivilegesManager.SessionLengthOneHour, + label: "1 Hour" + }, + { + value: PrivilegesManager.SessionLengthOneWeek, + label: "1 Week" + } + ] + } + + async setSessionLength(length) { + let addToNow = (seconds) => { + let date = new Date(); + date.setSeconds(date.getSeconds() + seconds); + return date; + } + + let expiresAt = addToNow(length); + + return Promise.all([ + this.storageManager.setItem(PrivilegesManager.SessionExpiresAtKey, JSON.stringify(expiresAt), this.storageManager.bestStorageMode()), + this.storageManager.setItem(PrivilegesManager.SessionLengthKey, JSON.stringify(length), this.storageManager.bestStorageMode()), + ]) + } + + async clearSession() { + return this.setSessionLength(PrivilegesManager.SessionLengthNone); + } + + async getSelectedSessionLength() { + let length = await this.storageManager.getItem(PrivilegesManager.SessionLengthKey, this.storageManager.bestStorageMode()); + if(length) { + return JSON.parse(length); + } else { + return PrivilegesManager.SessionLengthNone; + } + } + + async getSessionExpirey() { + let expiresAt = await this.storageManager.getItem(PrivilegesManager.SessionExpiresAtKey, this.storageManager.bestStorageMode()); + if(expiresAt) { + return new Date(JSON.parse(expiresAt)); + } else { + return new Date(); + } + } + + async actionHasPrivilegesConfigured(action) { + return (await this.netCredentialsForAction(action)).length > 0; + } + + async actionRequiresPrivilege(action) { + let expiresAt = await this.getSessionExpirey(); + if(expiresAt > new Date()) { + return false; + } + return (await this.netCredentialsForAction(action)).length > 0; + } + + async savePrivileges() { + let privs = await this.getPrivileges(); + privs.setDirty(true); + this.$rootScope.sync(); + } + + async authenticateAction(action, credentialAuthMapping) { + var requiredCredentials = (await this.netCredentialsForAction(action)); + var successfulCredentials = [], failedCredentials = []; + + for(let requiredCredential of requiredCredentials) { + var passesAuth = await this._verifyAuthenticationParameters(requiredCredential, credentialAuthMapping[requiredCredential]); + if(passesAuth) { + successfulCredentials.push(requiredCredential); + } else { + failedCredentials.push(requiredCredential); + } + } + + return { + success: failedCredentials.length == 0, + successfulCredentials: successfulCredentials, + failedCredentials: failedCredentials + } + } + + async _verifyAuthenticationParameters(credential, value) { + + let verifyAccountPassword = async (password) => { + return this.authManager.verifyAccountPassword(password); + } + + let verifyLocalPasscode = async (passcode) => { + return this.passcodeManager.verifyPasscode(passcode); + } + + if(credential == PrivilegesManager.CredentialAccountPassword) { + return verifyAccountPassword(value); + } else if(credential == PrivilegesManager.CredentialLocalPasscode) { + return verifyLocalPasscode(value); + } + } + +} + +angular.module('app').service('privilegesManager', PrivilegesManager); diff --git a/app/assets/javascripts/app/services/sessionHistory.js b/app/assets/javascripts/app/services/sessionHistory.js index d64dec37f..7b5ac9f04 100644 --- a/app/assets/javascripts/app/services/sessionHistory.js +++ b/app/assets/javascripts/app/services/sessionHistory.js @@ -6,10 +6,17 @@ class SessionHistory extends SFSessionHistoryManager { "Note" : NoteHistoryEntry } + // Session History can be encrypted with passcode keys. If it changes, we need to resave session + // history with the new keys. + passcodeManager.addPasscodeChangeObserver(() => { + this.saveToDisk(); + }) + var keyRequestHandler = async () => { let offline = authManager.offline(); let auth_params = offline ? passcodeManager.passcodeAuthParams() : await authManager.getAuthParams(); let keys = offline ? passcodeManager.keys() : await authManager.keys(); + return { keys: keys, offline: offline, diff --git a/app/assets/javascripts/app/services/singletonManager.js b/app/assets/javascripts/app/services/singletonManager.js index 8638cf36f..4d7969eb7 100644 --- a/app/assets/javascripts/app/services/singletonManager.js +++ b/app/assets/javascripts/app/services/singletonManager.js @@ -24,9 +24,29 @@ class SingletonManager { $rootScope.$on("initial-data-loaded", (event, data) => { this.resolveSingletons(modelManager.allItems, null, true); + this.initialDataLoaded = true; + }) + + /* + If an item alternates its uuid on registration, singletonHandlers might need to update + their local reference to the object, since the object reference will change on uuid alternation + */ + modelManager.addModelUuidChangeObserver("singleton-manager", (oldModel, newModel) => { + for(var handler of this.singletonHandlers) { + if(handler.singleton && SFPredicate.ItemSatisfiesPredicates(newModel, handler.predicates)) { + // Reference is now invalid, calling resolveSingleton should update it + handler.singleton = null; + this.resolveSingletons([newModel]); + } + } }) $rootScope.$on("sync:completed", (event, data) => { + // Wait for initial data load before handling any sync. If we don't want for initial data load, + // then the singleton resolver won't have the proper items to work with to determine whether to resolve or create. + if(!this.initialDataLoaded) { + return; + } // The reason we also need to consider savedItems in consolidating singletons is in case of sync conflicts, // a new item can be created, but is never processed through "retrievedItems" since it is only created locally then saved. @@ -108,7 +128,6 @@ class SingletonManager { var singleton = allExtantItemsMatchingPredicate[0]; singletonHandler.singleton = singleton; singletonHandler.resolutionCallback(singleton); - } } } else { diff --git a/app/assets/javascripts/app/services/storageManager.js b/app/assets/javascripts/app/services/storageManager.js index 908490747..87b46eb56 100644 --- a/app/assets/javascripts/app/services/storageManager.js +++ b/app/assets/javascripts/app/services/storageManager.js @@ -174,6 +174,10 @@ class StorageManager extends SFStorageManager { return this.getItemSync("encryptedStorage", StorageManager.Fixed) !== null; } + bestStorageMode() { + return this.hasPasscode() ? StorageManager.FixedEncrypted : StorageManager.Fixed; + } + /* Model Storage diff --git a/app/assets/javascripts/app/services/syncManager.js b/app/assets/javascripts/app/services/syncManager.js index 291eaf50c..02596cf7f 100644 --- a/app/assets/javascripts/app/services/syncManager.js +++ b/app/assets/javascripts/app/services/syncManager.js @@ -11,7 +11,7 @@ class SyncManager extends SFSyncManager { scope.item1 = items[0]; scope.item2 = items[1]; scope.callback = callback; - var el = this.$compile( "" )(scope); + var el = this.$compile( "" )(scope); angular.element(document.body).append(el); } diff --git a/app/assets/javascripts/app/services/themeManager.js b/app/assets/javascripts/app/services/themeManager.js index d5bec58e3..84921e12e 100644 --- a/app/assets/javascripts/app/services/themeManager.js +++ b/app/assets/javascripts/app/services/themeManager.js @@ -1,9 +1,39 @@ class ThemeManager { - constructor(componentManager, desktopManager) { + constructor(componentManager, desktopManager, storageManager, passcodeManager) { this.componentManager = componentManager; + this.storageManager = storageManager; + this.desktopManager = desktopManager; + this.activeThemes = []; - desktopManager.registerUpdateObserver((component) => { + ThemeManager.CachedThemesKey = "cachedThemes"; + + this.registerObservers(); + + // When a passcode is added, all local storage will be encrypted (it doesn't know what was + // originally saved as Fixed or FixedEncrypted). We want to rewrite cached themes here to Fixed + // so that it's readable without authentication. + passcodeManager.addPasscodeChangeObserver(() => { + this.cacheThemes(); + }) + + // The desktop application won't have its applicationDataPath until the angular document is ready, + // so it wont be able to resolve local theme urls until thats ready + angular.element(document).ready(() => { + this.activateCachedThemes(); + }); + } + + activateCachedThemes() { + let cachedThemes = this.getCachedThemes(); + let writeToCache = false; + for(var theme of cachedThemes) { + this.activateTheme(theme, writeToCache); + } + } + + registerObservers() { + this.desktopManager.registerUpdateObserver((component) => { // Reload theme if active if(component.active && component.isTheme()) { this.deactivateTheme(component); @@ -13,7 +43,7 @@ class ThemeManager { } }) - componentManager.registerHandler({identifier: "themeManager", areas: ["themes"], activationHandler: (component) => { + this.componentManager.registerHandler({identifier: "themeManager", areas: ["themes"], activationHandler: (component) => { if(component.active) { this.activateTheme(component); } else { @@ -33,9 +63,17 @@ class ThemeManager { this.componentManager.deactivateComponent(theme); } } + + this.decacheThemes(); } - activateTheme(theme) { + activateTheme(theme, writeToCache = true) { + if(_.find(this.activeThemes, {uuid: theme.uuid})) { + return; + } + + this.activeThemes.push(theme); + var url = this.componentManager.urlForComponent(theme); var link = document.createElement("link"); link.href = url; @@ -44,6 +82,10 @@ class ThemeManager { link.media = "screen,print"; link.id = theme.uuid; document.getElementsByTagName("head")[0].appendChild(link); + + if(writeToCache) { + this.cacheThemes(); + } } deactivateTheme(theme) { @@ -52,6 +94,36 @@ class ThemeManager { element.disabled = true; element.parentNode.removeChild(element); } + + _.remove(this.activeThemes, {uuid: theme.uuid}); + + this.cacheThemes(); + } + + async cacheThemes() { + let mapped = await Promise.all(this.activeThemes.map(async (theme) => { + let transformer = new SFItemParams(theme); + let params = await transformer.paramsForLocalStorage(); + return params; + })); + let data = JSON.stringify(mapped); + return this.storageManager.setItem(ThemeManager.CachedThemesKey, data, StorageManager.Fixed); + } + + async decacheThemes() { + return this.storageManager.removeItem(ThemeManager.CachedThemesKey, StorageManager.Fixed); + } + + getCachedThemes() { + let cachedThemes = this.storageManager.getItemSync(ThemeManager.CachedThemesKey, StorageManager.Fixed); + if(cachedThemes) { + let parsed = JSON.parse(cachedThemes); + return parsed.map((theme) => { + return new SNTheme(theme); + }); + } else { + return []; + } } } diff --git a/app/assets/stylesheets/app/_editor.scss b/app/assets/stylesheets/app/_editor.scss index 0d4f3b225..47d3f2c66 100644 --- a/app/assets/stylesheets/app/_editor.scss +++ b/app/assets/stylesheets/app/_editor.scss @@ -1,14 +1,17 @@ $heading-height: 75px; + +#editor-column { + .locked { + opacity: 0.8; + } +} + .editor { flex: 1 50%; display: flex; flex-direction: column; overflow-y: hidden; - background-color: white; -} - -.locked { - opacity: 0.8; + background-color: var(--sn-stylekit-background-color); } #editor-title-bar { @@ -19,7 +22,6 @@ $heading-height: 75px; padding-bottom: 10px; padding-right: 10px; - background-color: white; border-bottom: none; z-index: $z-index-editor-title-bar; @@ -27,7 +29,7 @@ $heading-height: 75px; overflow: visible; > .title { - font-size: 18px; + font-size: var(--sn-stylekit-font-size-h1); font-weight: bold; padding-top: 0px; width: 100%; @@ -41,9 +43,10 @@ $heading-height: 75px; border: none; outline: none; background-color: transparent; + color: var(--sn-stylekit-foreground-color); &:disabled { - color: black; + color: var(--sn-stylekit-foreground-color); } } @@ -55,22 +58,21 @@ $heading-height: 75px; position: absolute; right: 20px; - font-size: 12px; + font-size: calc(var(--sn-stylekit-base-font-size) - 2px); text-transform: none; font-weight: normal; margin-top: 4px; text-align: right; - color: rgba(black, 0.23); - &.error, .error { - color: #f6a200; + .desc, .message:not(.warning):not(.danger) { + // color: var(--sn-stylekit-editor-foreground-color); + opacity: 0.35; } } .editor-tags { clear: left; width: 100%; - // height: 25px; overflow: visible; position: relative; @@ -78,6 +80,11 @@ $heading-height: 75px; height: 50px; overflow: auto; // Required for expired sub to not overflow + .component-view { + // see comment under main .component-view css defintion + position: inherit; + } + iframe { height: 50px; width: 100%; @@ -88,6 +95,7 @@ $heading-height: 75px; .tags-input { background-color: transparent; + color: var(--sn-stylekit-foreground-color); width: 100%; border: none; } @@ -100,7 +108,7 @@ $heading-height: 75px; overflow-y: hidden; height: 100%; display: flex; - background-color: white; + background-color: var(--sn-stylekit-background-color); position: relative; @@ -113,12 +121,14 @@ $heading-height: 75px; font-family: monospace; overflow-y: scroll; width: 100%; + background-color: var(--sn-stylekit-background-color); + color: var(--sn-stylekit-foreground-color); border: none; outline: none; padding: 15px; padding-top: 11px; - font-size: 17px; + font-size: var(--sn-stylekit-font-size-editor); resize: none; } } @@ -126,12 +136,25 @@ $heading-height: 75px; #editor-pane-component-stack { width: 100%; + // When two component stack items are expired and eat up full screen, this is required to scroll them. + // overflow: auto; + // When expired components, without this, requires scroll + overflow: visible; + + #component-stack-menu-bar { + border-bottom: none; + } + .component-stack-item { width: 100%; position: relative; - border-top: 1px solid $bg-color; + iframe { width: 100%; + background-color: var(--sn-stylekit-background-color); + // we moved the border top from the .component-stack-item to the .iframe, as on parent, + // it increases its height and caused unneccessary scrollbars on windows. + border-top: 1px solid var(--sn-stylekit-border-color); } } } diff --git a/app/assets/stylesheets/app/_footer.scss b/app/assets/stylesheets/app/_footer.scss index d2d1519ce..e5d46fe1f 100644 --- a/app/assets/stylesheets/app/_footer.scss +++ b/app/assets/stylesheets/app/_footer.scss @@ -6,12 +6,12 @@ z-index: $z-index-footer-bar; } -#footer-bar .item { +#footer-bar .sk-app-bar-item { z-index: $z-index-footer-bar-item; position: relative; user-select: none; - .panel { + .sk-panel { max-height: 85vh; position: absolute; right: 0px; @@ -20,16 +20,28 @@ min-width: 300px; z-index: $z-index-footer-bar-item-panel; margin-top: 15px; - background-color: white; } + &.dock-shortcut:hover .sk-app-bar-item-column { + border-bottom: 2px solid var(--sn-stylekit-info-color); + } + + svg { + width: 12px; + height: 12px; + fill: var(--sn-stylekit-foreground-color); + + &:hover { + fill: var(--sn-stylekit-info-color); + } + } } #account-panel { width: 400px; } -.panel { +.sk-panel { cursor: default; } @@ -43,6 +55,5 @@ a.disabled { #footer-lock-icon { margin-left: 5px; - padding-left: 8px; - border-left: 1px solid gray; + padding-left: 5px; } diff --git a/app/assets/stylesheets/app/_ionicons.scss b/app/assets/stylesheets/app/_ionicons.scss index 884e1f781..6390e6f48 100644 --- a/app/assets/stylesheets/app/_ionicons.scss +++ b/app/assets/stylesheets/app/_ionicons.scss @@ -11,14 +11,34 @@ Modified icons to fit ionicon’s grid from original. */ @font-face { font-family: "Ionicons"; src: url("../assets/ionicons.eot?v=2.0.0"); src: url("../assets/ionicons.eot?v=2.0.1#iefix") format("embedded-opentype"), url("../assets/ionicons.ttf?v=2.0.1") format("truetype"), url("../assets/ionicons.woff?v=2.0.1") format("woff"), url("../assets/ionicons.svg?v=2.0.1#Ionicons") format("svg"); font-weight: normal; font-style: normal; } -.ion, .ionicons, .ion-ios-box:before, .ion-bookmark:before, .ion-locked:before { display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } + +.ion, .ionicons, +.ion-ios-box:before, +.ion-bookmark:before, +.ion-locked:before, +.ion-arrow-return-left:before, +.ion-arrow-return-right:before, +.ion-key:before, +.ion-lock-combination:before, +.ion-eye-disabled:before +{ + display: inline-block; font-family: "Ionicons"; speak: none; font-style: normal; font-weight: normal; font-variant: normal; text-transform: none; text-rendering: auto; line-height: 1; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; +} .ion-ios-box:before { content: "\f3ec"; } .ion-locked:before { content: "\f200"; } -.ion-bookmark:before { - content: "\f26b"; -} +.ion-bookmark:before { content: "\f26b"; } + +.ion-arrow-return-left:before { content: "\f265"; } + +.ion-arrow-return-right:before { content: "\f266"; } + +.ion-key:before { content: "\f296"; } + +.ion-lock-combination:before { content: "\f4d4"; } + +.ion-eye-disabled:before { content: "\f306"; } /*# sourceMappingURL=ionicons.css.map */ diff --git a/app/assets/stylesheets/app/_lock-screen.scss b/app/assets/stylesheets/app/_lock-screen.scss index 7dad8285a..89ce4dfb4 100644 --- a/app/assets/stylesheets/app/_lock-screen.scss +++ b/app/assets/stylesheets/app/_lock-screen.scss @@ -12,33 +12,24 @@ bottom: 0; z-index: $z-index-lock-screen; - background-color: rgba(white, 0.5); - color: black; - font-size: 16px; + background-color: var(--sn-stylekit-background-color); + color: var(--sn-stylekit-foreground-color); display: flex; + flex-direction: column; align-items: center; justify-content: center; - .background { - position: absolute; - z-index: -1; - width: 100%; - height: 100%; - } - - .panel { + .sk-panel { width: 315px; flex-grow: 0; + // border-radius: 0; - .header { + .sk-panel-header { justify-content: center; } } #passcode-reset { - margin-top: 18px; text-align: center; - width: 100%; - font-size: 13px; } } diff --git a/app/assets/stylesheets/app/_main.scss b/app/assets/stylesheets/app/_main.scss index c4f412b3b..a63f25de2 100644 --- a/app/assets/stylesheets/app/_main.scss +++ b/app/assets/stylesheets/app/_main.scss @@ -1,11 +1,3 @@ -$main-text-color: black; -$secondary-text-color: rgba($main-text-color, 0.8); -$bg-color: #e3e3e3; -$light-bg-color: #e9e9e9; -$selection-color: $bg-color; -$selected-text-color: black; -$blue-color: #086dd6; - $z-index-editor-content: 10; $z-index-editor-title-bar: 100; @@ -27,13 +19,13 @@ body { "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif; - color: $main-text-color; -webkit-font-smoothing: antialiased; min-height: 100%; height: 100%; - font-size: 14px; + font-size: var(--sn-stylekit-base-font-size); margin: 0; - background-color: $bg-color; + color: var(--sn-stylekit-foreground-color); + background-color: var(--sn-stylekit-background-color); } * { @@ -41,11 +33,11 @@ body { } .tinted { - color: $blue-color; + color: var(--sn-stylekit-info-color); } .tinted-selected { - color: white; + color: var(--sn-stylekit-info-contrast-color); } *:focus {outline:0;} @@ -61,7 +53,6 @@ input, button, select, textarea { } a { - color: $blue-color; text-decoration: none; &.no-decoration { @@ -77,6 +68,16 @@ a { } } +::selection { + background: var(--sn-stylekit-info-color) !important; /* WebKit/Blink Browsers */ + color: var(--sn-stylekit-info-contrast-color); +} + +::-moz-selection { + background: var(--sn-stylekit-info-color) !important; + color: var(--sn-stylekit-info-contrast-color); +} + p { overflow: auto; } @@ -85,7 +86,7 @@ p { min-height: 100vh; height: 100vh; overflow: auto; - background-color: $bg-color; + background-color: var(--sn-stylekit-background-color); } $footer-height: 32px; @@ -115,7 +116,8 @@ $footer-height: 32px; height: 100%; position: absolute; cursor: col-resize; - background-color: rgba(black, 0.1); + // needs to be a color that works on main bg and contrast bg + background-color: var(--sn-stylekit-secondary-contrast-background-color); opacity: 0; border-top: none; border-bottom: none; @@ -145,7 +147,8 @@ $footer-height: 32px; &.collapsed { opacity: 1; - background-color: #DDDDDD; + // so it blends in with editor a bit more + background-color: var(--sn-stylekit-editor-background-color); } &.dragging { @@ -169,7 +172,6 @@ $footer-height: 32px; padding-bottom: 0px; height: 100%; max-height: calc(100vh - #{$footer-height}); - font-size: 17px; position: relative; overflow: hidden; @@ -181,13 +183,12 @@ $footer-height: 32px; > .content { height: 100%; max-height: 100%; - background-color: white; + background-color: var(--sn-stylekit-background-color); position: relative; } .section-title-bar { font-weight: bold; - font-size: 14px; .padded { padding: 0 14px; @@ -197,7 +198,8 @@ $footer-height: 32px; display: flex; justify-content: space-between; align-items: center; - overflow: hidden; + // This was causing problems with tags + button cutting off on right when the panel is a certain size + // overflow: hidden; > .title { white-space: nowrap; @@ -205,24 +207,6 @@ $footer-height: 32px; width: 80%; overflow: hidden; } - - > .add-button { - $button-bg: #e9e9e9; - color: lighten($main-text-color, 40%); - font-size: 18px; - width: 45px; - height: 24px; - cursor: pointer; - background-color: $button-bg; - border-radius: 4px; - font-weight: normal; - text-align: center; - - &:hover { - background-color: darken($button-bg, 5%); - color: lighten($main-text-color, 40%); - } - } } } } diff --git a/app/assets/stylesheets/app/_menus.scss b/app/assets/stylesheets/app/_menus.scss index 77de3a5ff..e8f62bc0c 100644 --- a/app/assets/stylesheets/app/_menus.scss +++ b/app/assets/stylesheets/app/_menus.scss @@ -1,5 +1,5 @@ -.app-bar { - .item { +.sk-app-bar { + .sk-app-bar-item { position: relative; } } @@ -15,6 +15,4 @@ margin-top: 5px; width: 280px; max-height: calc(85vh - 90px); - background-color: white; - color: $selected-text-color; } diff --git a/app/assets/stylesheets/app/_modals.scss b/app/assets/stylesheets/app/_modals.scss index ca1dac561..e277f2dcc 100644 --- a/app/assets/stylesheets/app/_modals.scss +++ b/app/assets/stylesheets/app/_modals.scss @@ -1,23 +1,58 @@ #permissions-modal { width: 350px; - .panel { + .sk-panel { border-radius: 0; - background-color: white; } - .content { + .sk-panel-content { padding-top: 1.1rem; } - .footer { + .sk-panel-footer { padding-bottom: 1.4rem; } } +#privileges-modal { + width: 700px; + + table { + margin-bottom: 12px; + width: 100%; + overflow: auto; + border-collapse: collapse; + border-spacing: 0px; + border-color: var(--sn-stylekit-contrast-border-color); + background-color: var(--sn-stylekit-background-color); + color: var(--sn-stylekit-contrast-foreground-color); + + th, td { + padding: 6px 13px; + border: 1px solid var(--sn-stylekit-contrast-border-color); + } + + tr:nth-child(2n) { + background-color: var(--sn-stylekit-contrast-background-color); + } + } + + th { + text-align: center; + font-weight: normal; + } + + .priv-header { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } +} + #password-wizard { font-size: 16px; } #item-preview-modal { - > .content { + > .sk-modal-content { width: 800px; height: 500px; } @@ -37,21 +72,17 @@ .border { height: 100%; - background-color: rgba(black, 0.1); + background-color: var(--sn-stylekit-border-color); width: 1px; margin: 0 15px; } } -.panel { - background-color: white; -} - .header .subtitle { font-size: 1.1rem; } -.modal { +.sk-modal { position: fixed; margin-left: auto; margin-right: auto; @@ -62,54 +93,57 @@ z-index: $z-index-modal; width: 100vw; height: 100vh; - background-color: rgba(gray, 0.3); - color: black; + + background-color: transparent; + color: var(--sn-stylekit-contrast-foreground-color); display: flex; align-items: center; justify-content: center; .sn-component { height: 100%; - .panel { + .sk-panel { height: 100%; } } &.auto-height { - > .content { + > .sk-modal-content { height: auto !important; } } &.large { - > .content { + > .sk-modal-content { width: 900px; height: 600px; } } &.medium { - > .content { + > .sk-modal-content { width: 700px; height: 500px; } } &.small { - > .content { + > .sk-modal-content { width: 700px; height: 344px; } } - .background { + .sk-modal-background { position: absolute; z-index: -1; width: 100%; height: 100%; + background-color: var(--sn-stylekit-contrast-background-color); + opacity: 0.7; } - > .content { + > .sk-modal-content { overflow-y: auto; width: auto; padding: 0; @@ -135,6 +169,10 @@ display: flex; flex-direction: column; + // required so that .loading-overlay absolute works properly wrt to modal components. However, seems to break #note-tags-component-container. + // I couldn't find any solution to this other than to customize .component-view position back to inherit for note-tags-component-container. + position: relative; + // not sure why we need this. Removed because it creates unncessary scroll bars. Tested on folders extension, creates horizontal scrollbar at bottom on windows // overflow: auto; // Update: we needed that because when we display the expired Extended view, it allows it to scroll vertically. @@ -144,8 +182,24 @@ min-width: 100%; } - iframe { - flex: 1; + .loading-overlay { + position: absolute; + background-color: var(--sn-stylekit-editor-background-color); width: 100%; + height: 100%; + left: 0; + top: 0; + } + + iframe { + // We're disabling flex: 1; because on Firefox, it causes weird sizing issues with component stack items. + // Not sure yet if totally required. + // Update: The extensions manager doesn't display correctly without it + // flex-grow: 1 should fix that. + + flex-grow: 1; + width: 100%; + height: 100%; + background-color: transparent; } } diff --git a/app/assets/stylesheets/app/_notes.scss b/app/assets/stylesheets/app/_notes.scss index e3c4a4647..5e6a549cc 100644 --- a/app/assets/stylesheets/app/_notes.scss +++ b/app/assets/stylesheets/app/_notes.scss @@ -1,6 +1,8 @@ #notes-column, .notes { - border-left: 1px solid #dddddd; - border-right: 1px solid #dddddd; + border-left: 1px solid var(--sn-stylekit-border-color); + border-right: 1px solid var(--sn-stylekit-border-color); + + font-size: var(--sn-stylekit-font-size-h2); width: 350px; flex-grow: 0; @@ -21,15 +23,11 @@ font-size: 18px; .section-title-bar-header .title { - color: rgba(black, 0.40); + color: var(--sn-stylekit-neutral-color); width: calc(90% - 45px); } } - #notes-add-button { - - } - #notes-menu-bar { position: relative; margin-top: 14px; @@ -42,7 +40,7 @@ position: relative; .filter-bar { - background-color: $light-bg-color; + background-color: var(--sn-stylekit-contrast-background-color); border-radius: 4px; height: 100%; color: #909090; @@ -60,9 +58,9 @@ border-radius: 50%; width: 17px; height: 17px; - color: white; cursor: default; - background-color: gray; + background-color: var(--sn-stylekit-neutral-color); + color: var(--sn-stylekit-neutral-contrast-color); font-size: 10px; line-height: 17px; text-align: center; @@ -73,7 +71,7 @@ transition: background-color 0.15s linear; &:hover { - background-color: $blue-color; + background-color: var(--sn-stylekit-info-color); } } } @@ -102,9 +100,8 @@ .note { width: 100%; padding: 15px; - border-bottom: 1px solid $bg-color; + border-bottom: 1px solid var(--sn-stylekit-border-color); cursor: pointer; - background-color: white; > .name { font-weight: 600; @@ -137,11 +134,11 @@ overflow: hidden; text-overflow: ellipsis; - $line-height: 18px; .default-preview, .plain-preview { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1; /* number of lines to show */ + $line-height: 18px; line-height: $line-height; /* fallback */ max-height: calc(#{$line-height} * 1); /* fallback */ } @@ -158,14 +155,53 @@ opacity: 0.6; } - &.selected { - background-color: $blue-color; - color: white; + .note-flag { + color: var(--sn-stylekit-info-color); + } - .pinned { - color: white; + .note-flags { + display: flex; + flex-direction: row; + align-items: center; + + .note-flag { + margin-right: 10px; } } + progress { + background-color: var(--sn-stylekit-contrast-background-color); + color: var(--sn-stylekit-info-color); + } + + progress::-webkit-progress-bar { + background-color: var(--sn-stylekit-contrast-background-color); + } + + progress::-webkit-progress-value { + background-color: var(--sn-stylekit-info-color); + } + + &.selected { + background-color: var(--sn-stylekit-info-color); + color: var(--sn-stylekit-info-contrast-color); + + .note-flag { + color: var(--sn-stylekit-info-contrast-color); + } + + progress { + background-color: var(--sn-stylekit-secondary-foreground-color); + color: var(--sn-stylekit-secondary-background-color); + } + + progress::-webkit-progress-bar { + background-color: var(--sn-stylekit-secondary-foreground-color); + } + + progress::-webkit-progress-value { + background-color: var(--sn-stylekit-secondary-background-color); + } + } } } diff --git a/app/assets/stylesheets/app/_scrollbars.scss b/app/assets/stylesheets/app/_scrollbars.scss deleted file mode 100644 index 415aa0ac9..000000000 --- a/app/assets/stylesheets/app/_scrollbars.scss +++ /dev/null @@ -1,31 +0,0 @@ -.windows-web, .windows-desktop, .linux-web, .linux-desktop { - - $thumb-color: #dfdfdf; - $track-border-color: #E7E7E7; - $thumb-width: 4px; - - ::-webkit-scrollbar { - width: 17px; - height: 18px; - border-left: 0.5px solid $track-border-color; - } - - ::-webkit-scrollbar-thumb { - height: 6px; - border: $thumb-width solid rgba(0, 0, 0, 0); - background-clip: padding-box; - -webkit-border-radius: 10px; - background-color: $thumb-color; - -webkit-box-shadow: inset -1px -1px 0px rgba(0, 0, 0, 0.05), inset 1px 1px 0px rgba(0, 0, 0, 0.05); - } - - ::-webkit-scrollbar-button { - width: 0; - height: 0; - display: none; - } - - ::-webkit-scrollbar-corner { - background-color: transparent; - } -} diff --git a/app/assets/stylesheets/app/_stylekit-sub.scss b/app/assets/stylesheets/app/_stylekit-sub.scss index b0a9285e1..3405cedaa 100644 --- a/app/assets/stylesheets/app/_stylekit-sub.scss +++ b/app/assets/stylesheets/app/_stylekit-sub.scss @@ -1,6 +1,6 @@ .sn-component { - .notification { + .sk-notification { &.unpadded { padding: 0; padding-bottom: 0 !important; @@ -12,13 +12,13 @@ } .bordered-row { - border-bottom: 1px solid rgba(black, 0.1); - border-top: 1px solid rgba(black, 0.1); + border-bottom: 1px solid var(--sn-stylekit-border-color); + border-top: 1px solid var(--sn-stylekit-border-color); } } - .app-bar { + .sk-app-bar { &.no-top-edge { border-top: 0; } @@ -26,10 +26,8 @@ } -.panel { - color: black; - - .header { +.sk-panel { + .sk-panel-header { .close-button { &:hover { text-decoration: none; @@ -37,25 +35,20 @@ } } - input { - min-height: 39px; - } - - - .button-group.stretch { - .button:not(.featured) { + .sk-button-group.stretch { + .sk-button:not(.featured) { // Default buttons that are not featured and stretched should have larger vertical padding padding: 9px; } } - - a { - color: $blue-color; - } } #session-history-menu { - .menu-panel .row .sublabel.opaque { + .sk-menu-panel .sk-menu-panel-row .sk-sublabel.opaque { opacity: 1.0 } } + +button.sk-button { + border: none; +} diff --git a/app/assets/stylesheets/app/_tags.scss b/app/assets/stylesheets/app/_tags.scss index 45a849be6..8049e4b88 100644 --- a/app/assets/stylesheets/app/_tags.scss +++ b/app/assets/stylesheets/app/_tags.scss @@ -6,27 +6,18 @@ -webkit-user-select: none; &, #tags-content { - background-color: #f6f6f6; + background-color: var(--sn-stylekit-secondary-background-color); display: flex; flex-direction: column; } #tags-title-bar { - color: black; - padding-top: 14px; - padding-bottom: 16px; + color: var(--sn-stylekit-secondary-foreground-color); + padding-top: 15px; + padding-bottom: 8px; padding-left: 12px; padding-right: 12px; font-size: 12px; - color: rgba(black, 0.8); - } - - #tag-add-button { - background-color: #d7d7d7; - - &:hover { - background-color: rgba(#d7d7d7, 0.8); - } } .scrollable { @@ -52,7 +43,6 @@ cursor: pointer; transition: height .1s ease-in-out; position: relative; - font-size: 14px; > .info { height: 20px; @@ -62,7 +52,7 @@ background-color: transparent; font-weight: 600; float: left; - color: $main-text-color; + color: var(--sn-stylekit-secondary-foreground-color); border: none; cursor: pointer; text-overflow: ellipsis; @@ -76,6 +66,7 @@ right: 17px; padding-top: 1px; font-weight: bold; + color: var(--sn-stylekit-neutral-color); } } @@ -97,32 +88,17 @@ } } - $tags-selected-color: #dbdbdb; - &.selected { - background-color: $tags-selected-color; - color: $selected-text-color; > .title { - color: $selected-text-color; cursor: text; } } - /* When a note is dragged over tag */ - &.over { - background-color: $tags-selected-color; - color: $selected-text-color; - border: 2px dashed white; + &:hover:not(.selected), &.selected { + background-color: var(--sn-stylekit-secondary-contrast-background-color); + color: var(--sn-stylekit-secondary-contrast-foreground-color); > .title { - color: $selected-text-color; - } - } - - &:hover:not(.selected) { - background-color: $tags-selected-color; - color: $selected-text-color; - > .title { - color: $selected-text-color; + color: var(--sn-stylekit-secondary-contrast-foreground-color); } } } diff --git a/app/assets/stylesheets/main.css.scss b/app/assets/stylesheets/main.css.scss index d59551f78..9e28dc002 100644 --- a/app/assets/stylesheets/main.css.scss +++ b/app/assets/stylesheets/main.css.scss @@ -1,6 +1,5 @@ @import "app/main"; @import "app/ui"; -@import "app/scrollbars"; @import "app/footer"; @import "app/tags"; @import "app/notes"; diff --git a/app/assets/templates/directives/account-menu.html.haml b/app/assets/templates/directives/account-menu.html.haml index f0fb6736c..60d0d357c 100644 --- a/app/assets/templates/directives/account-menu.html.haml +++ b/app/assets/templates/directives/account-menu.html.haml @@ -1,139 +1,169 @@ .sn-component - .panel#account-panel - .header - %h1.title Account - %a.close-button{"ng-click" => "close()"} Close - .content - - .panel-section.hero{"ng-if" => "!user && !formData.showLogin && !formData.showRegister && !formData.mfa"} - %h1.title Sign in or register to enable sync and end-to-end encryption. - .panel-row - .panel-row - .button-group.stretch - .button.info.featured{"ng-click" => "formData.showLogin = true"} - .label Sign In - .button.info.featured{"ng-click" => "formData.showRegister = true"} - .label Register - %p + .sk-panel#account-panel + .sk-panel-header + .sk-panel-header-title Account + %a.sk-a.info.close-button{"ng-click" => "close()"} Close + .sk-panel-content + .sk-panel-section.sk-panel-hero{"ng-if" => "!user && !formData.showLogin && !formData.showRegister && !formData.mfa"} + .sk-panel-row + .sk-h1 Sign in or register to enable sync and end-to-end encryption. + .sk-panel-row + .sk-button-group.stretch + .sk-button.info.featured{"ng-click" => "formData.showLogin = true"} + .sk-label Sign In + .sk-button.info.featured{"ng-click" => "formData.showRegister = true"} + .sk-label Register + .sk-panel-row.sk-p Standard Notes is free on every platform, and comes standard with sync and encryption. - .panel-section{"ng-if" => "formData.showLogin || formData.showRegister"} - %h3.title.panel-row + .sk-panel-section{"ng-if" => "formData.showLogin || formData.showRegister"} + .sk-panel-section-title {{formData.showLogin ? "Sign In" : "Register"}} - %form.panel-form{"ng-submit" => "submitAuthForm()"} - %input{:placeholder => 'Email', "sn-autofocus" => 'true', "should-focus" => "true", :name => 'email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} - %input{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password'} - %input{:placeholder => 'Confirm Password', "ng-if" => "formData.showRegister", :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.password_conf'} + %form.sk-panel-form{"ng-submit" => "submitAuthForm()"} + .sk-panel-section + %input.sk-input.contrast{:placeholder => 'Email', "sn-autofocus" => 'true', "should-focus" => "true", :name => 'email', :required => true, :type => 'email', 'ng-model' => 'formData.email'} + %input.sk-input.contrast{:placeholder => 'Password', :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.user_password', 'sn-enter' => 'submitAuthForm()'} + %input.sk-input.contrast{:placeholder => 'Confirm Password', "ng-if" => "formData.showRegister", :name => 'password', :required => true, :type => 'password', 'ng-model' => 'formData.password_conf', 'sn-enter' => 'submitAuthForm()'} + .sk-panel-row + %a.sk-panel-row.sk-bold{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} + Advanced Options - %a.panel-row{"ng-click" => "formData.showAdvanced = !formData.showAdvanced"} - Advanced Options - .notification.info{"ng-if" => "formData.showRegister"} - %h2.title No Password Reset. - .text Because your notes are encrypted using your password, Standard Notes does not have a password reset option. You cannot forget your password. - - .notification.unpadded.default.advanced-options.panel-row{"ng-if" => "formData.showAdvanced"} - .panel-column.stretch - %h4.title.panel-row.padded-row Advanced Options + .sk-notification.unpadded.contrast.advanced-options.sk-panel-row{"ng-if" => "formData.showAdvanced"} + .sk-panel-column.stretch + .sk-notification-title.sk-panel-row.padded-row Advanced Options %div.bordered-row.padded-row - %label Sync Server Domain - %input.form-control.mt-5{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'formData.url'} - %label.padded-row{"ng-if" => "formData.showLogin"} - %input{"type" => "checkbox", "ng-model" => "formData.strictSignin"} + %label.sk-label Sync Server Domain + %input.sk-input.mt-5.sk-base{:name => 'server', :placeholder => 'Server URL', :required => true, :type => 'text', 'ng-model' => 'formData.url'} + %label.sk-label.padded-row{"ng-if" => "formData.showLogin"} + %input.sk-input{"type" => "checkbox", "ng-model" => "formData.strictSignin"} Use strict sign in %span %a{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} (Learn more) - .button-group.stretch.panel-row.form-submit - %button.button.info.featured{"type" => "submit", "ng-disabled" => "formData.authenticating"} - .label {{formData.showLogin ? "Sign In" : "Register"}} + .sk-panel-section.form-submit{"ng-if" => "!formData.authenticating"} + .sk-button-group.stretch + .sk-button.info.featured{'ng-click' => 'submitAuthForm()', "ng-disabled" => "formData.authenticating"} + .sk-label {{formData.showLogin ? "Sign In" : "Register"}} - %label - %input{"type" => "checkbox", "ng-model" => "formData.ephemeral", "ng-true-value" => "false", "ng-false-value" => "true"} - Stay signed in - %label{"ng-if" => "notesAndTagsCount() > 0"} - %input{"type" => "checkbox", "ng-model" => "formData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} - Merge local data ({{notesAndTagsCount()}} notes and tags) + .sk-notification.neutral{"ng-if" => "formData.showRegister"} + .sk-notification-title No Password Reset. + .sk-notification-text Because your notes are encrypted using your password, Standard Notes does not have a password reset option. You cannot forget your password. - %em.block.center-align.mt-10{"ng-if" => "formData.status", "style" => "font-size: 14px;"} - {{formData.status}} + .sk-panel-section.no-bottom-pad{"ng-if" => "formData.status"} + .sk-horizontal-group + .sk-spinner.small.neutral + .sk-label {{formData.status}} - .panel-section{"ng-if" => "formData.mfa"} - %form{"ng-submit" => "submitMfaForm()"} - %p {{formData.mfa.message}} - %input.form-control.mt-10{:placeholder => "Enter Code", "sn-autofocus" => "true", "should-focus" => "true", :autofocus => "true", :name => 'mfa', :required => true, 'ng-model' => 'formData.userMfaCode'} - .button-group.stretch.panel-row.form-submit - %button.button.info.featured{"type" => "submit"} - .label Sign In + .sk-panel-section.no-bottom-pad{"ng-if" => "!formData.authenticating"} + %label.sk-panel-row.justify-left + .sk-horizontal-group + %input{"type" => "checkbox", "ng-model" => "formData.ephemeral", "ng-true-value" => "false", "ng-false-value" => "true"} + Stay signed in + %label.sk-panel-row.justify-left{"ng-if" => "notesAndTagsCount() > 0"} + .sk-panel-row + %input{"type" => "checkbox", "ng-model" => "formData.mergeLocal", "ng-bind" => "true", "ng-change" => "mergeLocalChanged()"} + Merge local data ({{notesAndTagsCount()}} notes and tags) + + .sk-panel-section{"ng-if" => "formData.mfa"} + %form.sk-panel-form{"ng-submit" => "submitMfaForm()"} + .sk-p.sk-panel-row {{formData.mfa.message}} + .sk-panel-row + %input.sk-input.contrast{:placeholder => "Enter Code", "sn-autofocus" => "true", "should-focus" => "true", :autofocus => "true", :name => 'mfa', :required => true, 'ng-model' => 'formData.userMfaCode'} + .sk-button-group.stretch.sk-panel-row.form-submit{"ng-if" => "!formData.status"} + %button.sk-button.info.featured{"type" => "submit"} + .sk-label Sign In + .sk-panel-section.no-bottom-pad{"ng-if" => "formData.status"} + .sk-panel-row + .sk-panel-row + .sk-horizontal-group + .sk-spinner.small.neutral + .sk-label {{formData.status}} %div{"ng-if" => "!formData.showLogin && !formData.showRegister && !formData.mfa"} - .panel-section{"ng-if" => "user"} - .notification.danger{"ng-if" => "syncStatus.error"} - %h2.title Sync Unreachable - .text Hmm...we can't seem to sync your account. The reason: {{syncStatus.error.message}} - %p - %a{"href" => "https://standardnotes.org/help", "target" => "_blank"} Need help? - .panel-row - %h2.title.wrap {{user.email}} - .horizontal-group{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} - .spinner.small.info - .sublabel + .sk-panel-section{"ng-if" => "user"} + .sk-notification.danger{"ng-if" => "syncStatus.error"} + .sk-notification-title Sync Unreachable + .sk-notification-text Hmm...we can't seem to sync your account. The reason: {{syncStatus.error.message}} + %a.sk-a.info-contrast.sk-bold.sk-panel-row{"href" => "https://standardnotes.org/help", "target" => "_blank"} Need help? + + .sk-panel-row + .sk-panel-column + .sk-h1.sk-bold.wrap {{user.email}} + .sk-subtitle.subtle.normal {{server}} + .sk-horizontal-group{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} + .sk-spinner.small.info + .sk-sublabel {{"Syncing" + (syncStatus.total > 0 ? ":" : "")}} %span{"ng-if" => "syncStatus.total > 0"} {{syncStatus.current}}/{{syncStatus.total}} - .subtitle.subtle.normal {{server}} - .panel-row + .sk-panel-row - %a.panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} Change Password - %a.panel-row.justify-left.condensed.success{"ng-if" => "securityUpdateAvailable", "ng-click" => "openPasswordWizard('upgrade-security')"} - .inline.circle.small.success.mr-8 + %a.sk-a.info.sk-panel-row.condensed{"ng-click" => "openPasswordWizard('change-pw')"} + Change Password + %a.sk-a.info.sk-panel-row.condensed{"ng-show" => "user", "ng-click" => "openPrivilegesModal('')"} + Manage Privileges + %a.sk-panel-row.justify-left.condensed.success{"ng-if" => "securityUpdateAvailable", "ng-click" => "openPasswordWizard('upgrade-security')"} + .inline.sk-circle.small.success.mr-8 .inline Security Update Available - .panel-section - %h3.title.panel-row Encryption - %h5.subtitle.info.panel-row{"ng-if" => "encryptionEnabled()"} + .sk-panel-section + .sk-panel-section-title Encryption + .sk-panel-section-subtitle.info{"ng-if" => "encryptionEnabled()"} {{encryptionStatusForNotes()}} - %p + %p.sk-p {{encryptionStatusString()}} - .panel-section - %h3.title.panel-row Passcode Lock + .sk-panel-section + .sk-panel-section-title Passcode Lock %div{"ng-if" => "!hasPasscode()"} %div{"ng-if" => "canAddPasscode"} - .panel-row{"ng-if" => "!formData.showPasscodeForm"} - .button.info{"ng-click" => "addPasscodeClicked(); $event.stopPropagation();"} - .label Add Passcode + .sk-panel-row{"ng-if" => "!formData.showPasscodeForm"} + .sk-button.info{"ng-click" => "addPasscodeClicked(); $event.stopPropagation();"} + .sk-label Add Passcode - %p Add an app passcode to lock the app and encrypt on-device key storage. + %p.sk-p Add an app passcode to lock the app and encrypt on-device key storage. %div{"ng-if" => "!canAddPasscode"} - %p Adding a passcode is not supported in temporary sessions. Please sign out, then sign back in with the "Stay signed in" option checked. + %p.sk-p Adding a passcode is not supported in temporary sessions. Please sign out, then sign back in with the "Stay signed in" option checked. - %form{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"} - %input.form-control{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} - %input.form-control{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} - .button-group.stretch.panel-row.form-submit - %button.button.info{"type" => "submit"} - .label Set Passcode - %a.panel-row{"ng-click" => "formData.showPasscodeForm = false"} Cancel + %form.sk-panel-form{"ng-if" => "formData.showPasscodeForm", "ng-submit" => "submitPasscodeForm()"} + .sk-panel-row + %input.sk-input.contrast{:type => 'password', "ng-model" => "formData.passcode", "placeholder" => "Passcode", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input.contrast{:type => 'password', "ng-model" => "formData.confirmPasscode", "placeholder" => "Confirm Passcode"} + .sk-button-group.stretch.sk-panel-row.form-submit + %button.sk-button.info{"type" => "submit"} + .sk-label Set Passcode + %a.neutral.sk-a.sk-panel-row{"ng-click" => "formData.showPasscodeForm = false"} Cancel %div{"ng-if" => "hasPasscode() && !formData.showPasscodeForm"} - .panel-row - %p - Passcode lock is enabled. - %span{"ng-if" => "isDesktopApplication()"} Your passcode will be required on new sessions after app quit. - .panel-row.justify-left - .horizontal-group - %a.info{"ng-click" => "changePasscodePressed()"} Change Passcode - %a.danger{"ng-click" => "removePasscodePressed()"} Remove Passcode + .sk-p + Passcode lock is enabled. + .sk-notification.contrast + .sk-notification-title Options + .sk-notification-text + .sk-panel-row + .sk-horizontal-group + .sk-h4.sk-bold Autolock + %a.sk-a.info{"ng-repeat" => "option in passcodeAutoLockOptions", "ng-click" => "selectAutoLockInterval(option.value)", + "ng-class" => "{'boxed' : option.value == selectedAutoLockInterval}"} + {{option.label}} + .sk-p The autolock timer begins when the window or tab loses focus. + .sk-panel-row + %a.sk-a.info.sk-panel-row.condensed{"ng-show" => "!user", "ng-click" => "openPrivilegesModal('')"} Manage Privileges + %a.sk-a.info.sk-panel-row.condensed{"ng-click" => "changePasscodePressed()"} Change Passcode + %a.sk-a.danger.sk-panel-row.condensed{"ng-click" => "removePasscodePressed()"} Remove Passcode - .panel-section{"ng-if" => "!importData.loading"} - %h3.title Data Backups - %form.panel-form{"ng-if" => "encryptedBackupsAvailable()"} - .input-group + .sk-panel-section{"ng-if" => "!importData.loading"} + .sk-panel-section-title Data Backups + .sk-p + Download a backup of all your data. + .sk-panel-row + %form.sk-panel-form.sk-panel-row{"ng-if" => "encryptedBackupsAvailable()"} + .sk-input-group %label %input{"type" => "radio", "ng-model" => "archiveFormData.encrypted", "ng-value" => "true", "ng-change" => "archiveFormData.encrypted = true"} Encrypted @@ -141,30 +171,30 @@ %input{"type" => "radio", "ng-model" => "archiveFormData.encrypted", "ng-value" => "false", "ng-change" => "archiveFormData.encrypted = false"} Decrypted - .button-group - .button.info{"ng-click" => "downloadDataArchive()"} - .label Download Backup + .sk-button-group.sk-panel-row.justify-left + .sk-button.info{"ng-click" => "downloadDataArchive()"} + .sk-label Download Backup - %label.button.info + %label.sk-button.info %input{"type" => "file", "style" => "display: none;", "file-change" => "->", "handler" => "importFileSelected(files)"} - .label Import From Backup + .sk-label Import Backup %span{"ng-if" => "isDesktopApplication()"} Backups are automatically created on desktop and can be managed via the "Backups" top-level menu. #import-password-request{"ng-if" => "importData.requestPassword"} - %form.panel-form.stretch{"ng-submit" => "submitImportPassword()"} + %form.sk-panel-form.stretch{"ng-submit" => "submitImportPassword()"} %p Enter the account password associated with the import file. - %input.form-control.mt-5{:type => 'password', "placeholder" => "Enter File Account Password", "ng-model" => "importData.password", "autofocus" => "true"} - .button-group.stretch.panel-row.form-submit - %button.button.info{"type" => "submit"} - .label Decrypt & Import + %input.sk-input.mt-5{:type => 'password', "placeholder" => "Enter File Account Password", "ng-model" => "importData.password", "autofocus" => "true"} + .sk-button-group.stretch.sk-panel-row.form-submit + %button.sk-button.info{"type" => "submit"} + .sk-label Decrypt & Import %p Importing from backup will not overwrite existing data, but instead create a duplicate of any differing data. %p If you'd like to import only a selection of items instead of the whole file, please use the Batch Manager extension. - .panel-row - .spinner.small.info{"ng-if" => "importData.loading"} - .footer - %a.right{"ng-if" => "formData.showLogin || formData.showRegister", "ng-click" => "formData.showLogin = false; formData.showRegister = false;"} + .sk-panel-row + .sk-spinner.small.info{"ng-if" => "importData.loading"} + .sk-panel-footer + %a.sk-a.right{"ng-if" => "formData.showLogin || formData.showRegister", "ng-click" => "formData.showLogin = false; formData.showRegister = false;"} Cancel - %a.right{"ng-if" => "!formData.showLogin && !formData.showRegister", "ng-click" => "destroyLocalData()"} + %a.sk-a.right.danger{"ng-if" => "!formData.showLogin && !formData.showRegister", "ng-click" => "destroyLocalData()"} {{ user ? "Sign out and clear local data" : "Clear all local data" }} diff --git a/app/assets/templates/directives/actions-menu.html.haml b/app/assets/templates/directives/actions-menu.html.haml index cf0b7fffe..47ce2b5d6 100644 --- a/app/assets/templates/directives/actions-menu.html.haml +++ b/app/assets/templates/directives/actions-menu.html.haml @@ -1,20 +1,20 @@ .sn-component - .menu-panel.dropdown-menu + .sk-menu-panel.dropdown-menu %a.no-decoration{"ng-if" => "extensions.length == 0", "href" => "https://standardnotes.org/extensions", "target" => "blank"} %menu-row{"label" => "'Download Actions'"} %div{"ng-repeat" => "extension in extensions"} - .header{"ng-click" => "extension.hide = !extension.hide; $event.stopPropagation();"} - .column - %h4.title {{extension.name}} - .spinner.small.loading{"ng-if" => "extension.loading"} + .sk-menu-panel-header{"ng-click" => "extension.hide = !extension.hide; $event.stopPropagation();"} + .sk-menu-panel-column + .sk-menu-panel-header-title {{extension.name}} + .sk-spinner.small.loading{"ng-if" => "extension.loading"} %div{"ng-if" => "extension.hide"} … %menu-row{"ng-if" => "!extension.hide", "ng-repeat" => "action in extension.actionsWithContextForItem(item)", "action" => "executeAction(action, extension);", "label" => "action.label", "subtitle" => "action.desc", "spinner-class" => "action.running ? 'info' : null", "sub-rows" => "action.subrows"} - .sublabel{"ng-if" => "action.access_type"} + .sk-sublabel{"ng-if" => "action.access_type"} Uses %strong {{action.access_type}} access to this note. diff --git a/app/assets/templates/directives/component-modal.html.haml b/app/assets/templates/directives/component-modal.html.haml index 6692df4d6..4501b11aa 100644 --- a/app/assets/templates/directives/component-modal.html.haml +++ b/app/assets/templates/directives/component-modal.html.haml @@ -1,10 +1,10 @@ -.background{"ng-click" => "dismiss()"} +.sk-modal-background{"ng-click" => "dismiss()"} -.content{"ng-attr-id" => "component-content-outer-{{component.uuid}}"} +.sk-modal-content{"ng-attr-id" => "component-content-outer-{{component.uuid}}"} .sn-component - .panel{"ng-attr-id" => "component-content-inner-{{component.uuid}}"} - .header - %h1.title + .sk-panel{"ng-attr-id" => "component-content-inner-{{component.uuid}}"} + .sk-panel-header + .sk-panel-header-title {{component.name}} - %a.close-button.info{"ng-click" => "dismiss()"} Close + %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close %component-view.component-view{"component" => "component"} diff --git a/app/assets/templates/directives/component-view.html.haml b/app/assets/templates/directives/component-view.html.haml index 70b6be9d8..e68436225 100644 --- a/app/assets/templates/directives/component-view.html.haml +++ b/app/assets/templates/directives/component-view.html.haml @@ -1,103 +1,61 @@ .sn-component{"ng-if" => "issueLoading"} - .app-bar.no-edges.no-top-edge + .sk-app-bar.no-edges.no-top-edge .left - .item - .label.warning There was an issue loading {{component.name}}. + .sk-app-bar-item + .sk-label.warning There was an issue loading {{component.name}}. .right - .item{"ng-click" => "reloadComponent()"} - .label Reload + .sk-app-bar-item{"ng-click" => "reloadComponent()"} + .sk-label Reload .sn-component{"ng-if" => "showNoThemesMessage"} - .app-bar.no-edges.no-top-edge + .sk-app-bar.no-edges.no-top-edge .left - .item - .label.warning This extension does not support themes. + .sk-app-bar-item + .sk-label.warning This extension does not support themes. .right - .item{"ng-click" => "noThemesMessageDismiss()"} - .label Dismiss - .item{"ng-click" => "disableActiveTheme()"} - .label Disable Active Theme + .sk-app-bar-item{"ng-click" => "noThemesMessageDismiss()"} + .sk-label Dismiss + .sk-app-bar-item{"ng-click" => "disableActiveTheme()"} + .sk-label Disable Active Theme -.sn-component{"ng-if" => "error == 'expired'"} - .panel.static - .content - .panel-section.stretch - %h2.title Unable to load Standard Notes Extended - %p Your Extended subscription expired on {{component.dateToLocalizedString(component.valid_until)}}. - %p - Please visit - %a{"href" => "https://dashboard.standardnotes.org", "target" => "_blank"} dashboard.standardnotes.org - to renew your subscription. - .panel-row - .panel-column - %p - %strong To reload your account status: - %p - %ol - %li - Open the - %strong Extensions - menu located in the lower left corner of the app to refresh your account status. - %li Click Reload below. - - .panel-row - .button.info{"ng-if" => "!reloading", "ng-click" => "reloadStatus()"} - .label Reload - .spinner.info.small{"ng-if" => "reloading"} - - .panel-row - .panel-section - %p{"ng-if" => "component.isEditor()"} - Otherwise, please follow the steps below to disable any external editors, - so you can edit your note using the plain text editor instead. - - %p To temporarily disable this extension: - - .panel-row - .button.info{"ng-click" => "destroy()"} - .label Disable Extension - .spinner.info.small{"ng-if" => "reloading"} - - .panel-row - - %div{"ng-if" => "component.isEditor()"} - %p To disassociate this note from this editor: - - %ol - %li Click the "Editor" menu item above (under the note title). - %li Select "Plain Editor". - %li Repeat this for every note you'd like to access. You can also delete the editor completely to disable it for all notes. To do so, click "Extensions" in the lower left corner of the app, then, for every editor, click "Uninstall". - - %p - Need help? Please email us at - %a{"href" => "mailto:hello@standardnotes.org", "target" => "_blank"} hello@standardnotes.org - or check out the - %a{"href" => "https://standardnotes.org/help", "target" => "_blank"} Help - page. +.sn-component{"ng-if" => "expired"} + .sk-app-bar + .left + .sk-app-bar-item + .sk-app-bar-item-column + .sk-circle.danger.small + .sk-app-bar-item-column + %a.sk-label.sk-base{"href" => "https://dashboard.standardnotes.org", "target" => "_blank"} + Your Extended subscription expired on {{component.dateToLocalizedString(component.valid_until)}}. + Extensions are in a read-only state. + .right + .sk-app-bar-item + .sk-app-bar-item-column + %a.sk-label{"href" => "https://standardnotes.org/help", "target" => "_blank"} Help .sn-component{"ng-if" => "error == 'offline-restricted'"} - .panel.static - .content - .panel-section.stretch - %h2.title You have restricted this extension to be used offline only. + .sk-panel.static + .sk-panel-content + .sk-panel-section.stretch + .sk-panel-section-title You have restricted this extension to be used offline only. %p Offline extensions are not available in the Web app. - .panel-row - .panel-column + .sk-panel-row + .sk-panel-column %p You can either: %p %ul %li Enable the Hosted option for this extension by opening the 'Extensions' menu and toggling 'Use hosted when local is unavailable' under this extension's options. Then press Reload below. %li Use the Desktop application. - .panel-row - .button.info{"ng-if" => "!reloading", "ng-click" => "reloadStatus()"} - .label Reload - .spinner.info.small{"ng-if" => "reloading"} + .sk-panel-row + .sk-button.info{"ng-if" => "!reloading", "ng-click" => "reloadStatus()"} + .sk-label Reload + .sk-spinner.info.small{"ng-if" => "reloading"} .sn-component{"ng-if" => "error == 'url-missing'"} - .panel.static - .content - .panel-section.stretch - %h2.title This extension is not installed correctly. + .sk-panel.static + .sk-panel-content + .sk-panel-section.stretch + .sk-panel-section-title This extension is not installed correctly. %p Please uninstall {{component.name}}, then re-install it. %p @@ -111,3 +69,5 @@ "sandbox" => "allow-scripts allow-top-navigation-by-user-activation allow-popups allow-popups-to-escape-sandbox allow-same-origin allow-modals allow-forms", "data-component-id" => "{{component.uuid}}"} Loading + +.loading-overlay{"ng-if" => "loading"} diff --git a/app/assets/templates/directives/conflict-resolution-modal.html.haml b/app/assets/templates/directives/conflict-resolution-modal.html.haml index 87bb97e28..c59b7ea03 100644 --- a/app/assets/templates/directives/conflict-resolution-modal.html.haml +++ b/app/assets/templates/directives/conflict-resolution-modal.html.haml @@ -1,26 +1,27 @@ -.modal.large#conflict-resolution-modal - .content - .sn-component - .panel - .header - %h1.title Conflicted items — choose which version to keep - .horizontal-group - %a.close-button.info{"ng-click" => "keepItem1()"} Keep left - %a.close-button.info{"ng-click" => "keepItem2()"} Keep right - %a.close-button.info{"ng-click" => "keepBoth()"} Keep both - %a.close-button.info{"ng-click" => "export()"} Export - %a.close-button.info{"ng-click" => "dismiss(); $event.stopPropagation()"} Close - .content.selectable - .panel-section +.sn-component + .sk-modal.large#conflict-resolution-modal + .sk-modal-background + .sk-modal-content + .sk-panel + .sk-panel-header + %h1.sk-panel-header-title Conflicted items — choose which version to keep + .sk-horizontal-group + %a.sk-a.info.close-button{"ng-click" => "keepItem1()"} Keep left + %a.sk-a.info.close-button{"ng-click" => "keepItem2()"} Keep right + %a.sk-a.info.close-button{"ng-click" => "keepBoth()"} Keep both + %a.sk-a.info.close-button{"ng-click" => "export()"} Export + %a.sk-a.info.close-button{"ng-click" => "dismiss(); $event.stopPropagation()"} Close + .sk-panel-content.selectable + .sk-panel-section %h3 %strong Content type: {{contentType}} %p You may wish to look at the "created_at" and "updated_at" fields of the items to gain better context in deciding which to keep. #items - .panel.static#item1.item.border-color + .sk-panel.static#item1.item %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{item1Content}} .border - .panel.static#item2.item + .sk-panel.static#item2.item %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{item2Content}} diff --git a/app/assets/templates/directives/editor-menu.html.haml b/app/assets/templates/directives/editor-menu.html.haml index 9d6ce6df9..cc0ff2dcd 100644 --- a/app/assets/templates/directives/editor-menu.html.haml +++ b/app/assets/templates/directives/editor-menu.html.haml @@ -1,26 +1,17 @@ .sn-component - .menu-panel.dropdown-menu - .section - .header - %h4.title Note Editor + .sk-menu-panel.dropdown-menu + .sk-menu-panel-section + .sk-menu-panel-header + .sk-menu-panel-header-title Note Editor %menu-row{"label" => "'Plain Editor'", "circle" => "selectedEditor == null && 'success'", "action" => "selectComponent(null)"} %menu-row{"ng-repeat" => "editor in editors", "action" => "selectComponent(editor)", "label" => "editor.name", "circle" => "selectedEditor === editor && 'success'", "has-button" => "selectedEditor == editor || defaultEditor == editor", "button-text" => "defaultEditor == editor ? 'Undefault' : 'Set Default'", "button-action" => "toggleDefaultForEditor(editor)", "button-class" => "defaultEditor == editor ? 'warning' : 'info'"} - .column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(editor)"} - %strong.red.medium-text{"ng-if" => "editor.conflict_of"} Conflicted copy - .sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(editor)"} Running Locally + .sk-menu-panel-column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(editor)"} + %strong.danger.medium-text{"ng-if" => "editor.conflict_of"} Conflicted copy + .sk-sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(editor)"} Running Locally %a.no-decoration{"ng-if" => "editors.length == 0", "href" => "https://standardnotes.org/extensions", "target" => "blank"} %menu-row{"label" => "'Download More Editors'"} - - .section{"ng-if" => "stack.length > 0"} - .header - %h4.title Editor Stack - %menu-row{"ng-repeat" => "component in stack", "action" => "selectComponent(component)", "label" => "component.name", - "circle" => "stackComponentEnabled(component) ? 'success' : 'danger'"} - .column{"ng-if" => "component.conflict_of || shouldDisplayRunningLocallyLabel(component)"} - %strong.red.medium-text{"ng-if" => "component.conflict_of"} Conflicted copy - .sublabel{"ng-if" => "shouldDisplayRunningLocallyLabel(component)"} Running Locally diff --git a/app/assets/templates/directives/input-modal.html.haml b/app/assets/templates/directives/input-modal.html.haml index 706e6ac97..66d36f10e 100644 --- a/app/assets/templates/directives/input-modal.html.haml +++ b/app/assets/templates/directives/input-modal.html.haml @@ -1,18 +1,20 @@ -.modal.small.auto-height - .content - .sn-component - .panel - .header - %h1.title {{title}} - %a.close-button{"ng-click" => "dismiss()"} Close - .content - .panel-section - %p.panel-row {{message}} - .panel-row - .panel-column.stretch - %form{"ng-submit" => "submit()"} - %input.form-control{:type => '{{type}}', "ng-model" => "formData.input", "placeholder" => "{{placeholder}}", "sn-autofocus" => "true", "should-focus" => "true"} +.sn-component + .sk-modal.small.auto-height + .sk-modal-background + .sk-modal-content + .sn-component + .sk-panel + .sk-panel-header + .sk-h1.sk-panel-header-title {{title}} + %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close + .sk-panel-content + .sk-panel-section + .sk-p.sk-panel-row {{message}} + .sk-panel-row + .sk-panel-column.stretch + %form{"ng-submit" => "submit()"} + %input.sk-input.contrast{:type => '{{type}}', "ng-model" => "formData.input", "placeholder" => "{{placeholder}}", "sn-autofocus" => "true", "should-focus" => "true"} - .footer - %a.right{"ng-click" => "submit()"} - Submit + .sk-panel-footer + %a.sk-a.info.right{"ng-click" => "submit()"} + Submit diff --git a/app/assets/templates/directives/menu-row.html.haml b/app/assets/templates/directives/menu-row.html.haml index 0cb3cf604..ca3ffc399 100644 --- a/app/assets/templates/directives/menu-row.html.haml +++ b/app/assets/templates/directives/menu-row.html.haml @@ -1,21 +1,24 @@ -.row{"ng-attr-title" => "{{desc}}", "ng-click" => "onClick($event)"} - .column +.sk-menu-panel-row.row{"ng-attr-title" => "{{desc}}", "ng-click" => "onClick($event)"} + .sk-menu-panel-column .left - .column{"ng-if" => "circle"} - .circle.small{"ng-class" => "circle"} - .column{"ng-class" => "{'faded' : faded || disabled}"} - .label + .sk-menu-panel-column{"ng-if" => "circle && (!circleAlign || circleAlign == 'left')"} + .sk-circle.small{"ng-class" => "circle"} + .sk-menu-panel-column{"ng-class" => "{'faded' : faded || disabled}"} + .sk-label {{label}} - .sublabel{"ng-if" => "subtitle"} + .sk-sublabel{"ng-if" => "subtitle"} {{subtitle}} %ng-transclude - .subrows{"ng-if" => "subRows && subRows.length > 0"} + .sk-menu-panel-subrows{"ng-if" => "subRows && subRows.length > 0"} %menu-row{"ng-repeat" => "row in subRows", "action" => "row.onClick()", "label" => "row.label", "subtitle" => "row.subtitle", "spinner-class" => "row.spinnerClass"} - .column{"ng-if" => "hasButton"} - .button.info{"ng-click" => "clickButton($event)", "ng-class" => "buttonClass"} - {{buttonText}} + .sk-menu-panel-column{"ng-if" => "circle && circleAlign == 'right'"} + .sk-circle.small{"ng-class" => "circle"} - .column{"ng-if" => "spinnerClass"} - .spinner.small{"ng-class" => "spinnerClass"} + .sk-menu-panel-column{"ng-if" => "hasButton"} + .sk-button{"ng-click" => "clickButton($event)", "ng-class" => "buttonClass"} + .sk-label {{buttonText}} + + .sk-menu-panel-column{"ng-if" => "spinnerClass"} + .sk-spinner.small{"ng-class" => "spinnerClass"} diff --git a/app/assets/templates/directives/password-wizard.html.haml b/app/assets/templates/directives/password-wizard.html.haml index cbcdf6f54..b51f3cff3 100644 --- a/app/assets/templates/directives/password-wizard.html.haml +++ b/app/assets/templates/directives/password-wizard.html.haml @@ -1,108 +1,104 @@ -#password-wizard.modal.small.auto-height - .content - .sn-component - .panel - .header - %h1.title {{title}} - %a.close-button{"ng-click" => "dismiss()"} Close - .content +.sn-component + #password-wizard.sk-modal.small.auto-height + .sk-modal-background + .sk-modal-content + .sn-component + .sk-panel + .sk-panel-header + .sk-panel-header-title {{title}} + %a.sk-a.info.close-button{"ng-click" => "dismiss()"} Close + .sk-panel-content - %div{"ng-if" => "step == 0"} - %div{"ng-if" => "changePassword"} - %h2.title.panel-row Change your password - %p - Changing your password involves changing your encryption key, which requires your data to be re-encrypted and synced. - If you have many items, syncing your data can take several minutes. - %p.panel-row - %strong You must keep the application window open during this process. - %div{"ng-if" => "securityUpdate"} - %h2.title.panel-row Perform security update - %p - A new update is available for your account. Updates address improvements and enhancements to our security specification. - This process will guide you through the update, and perform the steps necessary with your supervision. - %p - For more information about security updates, please visit - %a{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} standardnotes.org/help/security. - - %p.panel-row - .info Press Continue to proceed. - - .panel-row - .panel-row - - .panel-section{"ng-if" => "step > 0"} - - %h3.title.panel-row Step {{step}} — {{titleForStep(step)}} - - %div{"ng-if" => "step == 1"} - %p.panel-row - As a result of this process, the entirety of your data will be re-encrypted and synced to your account. This is a generally safe process, - but unforeseen factors like poor network connectivity or a sudden shutdown of your computer may cause this process to fail. - It's best to be on the safe side before large operations such as this one. - .panel-row - .panel-row - .button-group - .button.info{"ng-click" => "downloadBackup(true)"} - .label Download Encrypted Backup - .button.info{"ng-click" => "downloadBackup(false)"} - .label Download Decrypted Backup - - %div{"ng-if" => "step == 2"} - %p.panel-row - As a result of this process, your encryption keys will change. - Any device on which you use Standard Notes will need to end its session. After this process completes, you will be asked to sign back in. - - %p.bold.panel-row.info-i Please sign out of all applications (excluding this one), including: - %ul - %li Desktop - %li Web (Chrome, Firefox, Safari) - %li Mobile (iOS and Android) - %p.panel-row - If you do not currently have access to a device you're signed in on, you may proceed, - but must make signing out and back in the first step upon gaining access to that device. - %p.panel-row Press Continue only when you have completed signing out of all your devices. - - - %div{"ng-if" => "step == 3"} + %div{"ng-if" => "step == 0"} %div{"ng-if" => "changePassword"} + %p.sk-p.sk-panel-row + Changing your password involves changing your encryption key, which requires your data to be re-encrypted and synced. + If you have many items, syncing your data can take several minutes. + %p.sk-p.sk-panel-row You must keep the application window open during this process. %div{"ng-if" => "securityUpdate"} - %p.panel-row Enter your current password. We'll run this through our encryption scheme to generate strong new encryption keys. - .panel-row - .panel-row - .panel-column.stretch - %form - %input.form-control{:type => 'password', "ng-model" => "formData.currentPassword", "placeholder" => "Current Password", "sn-autofocus" => "true", "should-focus" => "true"} - %input.form-control{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPassword", "placeholder" => "New Password"} - %input.form-control{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPasswordConfirmation", "placeholder" => "Confirm New Password"} + %p.sk-p.sk-panel-row + A new update is available for your account. Updates address improvements and enhancements to our security specification. + This process will guide you through the update, and perform the steps necessary with your supervision. + %p.sk-p.sk-panel-row + For more information about security updates, please visit + %a.sk-a.info{"href" => "https://standardnotes.org/help/security", "target" => "_blank"} standardnotes.org/help/security. - %div{"ng-if" => "step == 4"} - %p.panel-row - Your data is being re-encrypted with your new keys and synced to your account. - %p.panel-row.danger - Do not close this window until this process completes. + %p.sk-panel-row.sk-p + .info Press Continue to proceed. - .panel-row - .panel-column - .spinner.small.inline.info.mr-5{"ng-if" => "formData.processing"} - .inline.bold{"ng-class" => "{'info' : !formData.statusError, 'error' : formData.statusError}"} - {{formData.status}} - .panel-column{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} - %p.info - Syncing {{syncStatus.current}}/{{syncStatus.total}} + .sk-panel-section{"ng-if" => "step > 0"} - %div{"ng-if" => "step == 5"} - %div{"ng-if" => "changePassword"} - %p.panel-row Your password has been successfully changed. - %div{"ng-if" => "securityUpdate"} - %p.panel-row - The security update has been successfully applied to your account. - %p.panel-row - %strong Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility. + .sk-panel-section-title Step {{step}} — {{titleForStep(step)}} - %p.panel-row You may now sign back in on all your devices and close this window. + %div{"ng-if" => "step == 1"} + %p.sk-panel-row.sk-p + As a result of this process, the entirety of your data will be re-encrypted and synced to your account. This is a generally safe process, + but unforeseen factors like poor network connectivity or a sudden shutdown of your computer may cause this process to fail. + It's best to be on the safe side before large operations such as this one. + .sk-panel-row + .sk-panel-row + .sk-button-group + .sk-button.info{"ng-click" => "downloadBackup(true)"} + .sk-label Download Encrypted Backup + .sk-button.info{"ng-click" => "downloadBackup(false)"} + .sk-label Download Decrypted Backup - .footer - .empty - %a.right{"ng-click" => "continue()", "ng-disabled" => "lockContinue", "ng-class" => "{'disabled' : lockContinue}"} - .spinner.small.inline.info.mr-5{"ng-if" => "showSpinner"} - {{continueTitle}} + %div{"ng-if" => "step == 2"} + %p.sk-p.sk-panel-row + As a result of this process, your encryption keys will change. + Any device on which you use Standard Notes will need to end its session. After this process completes, you will be asked to sign back in. + + %p.sk-p.bold.sk-panel-row.info-i Please sign out of all applications (excluding this one), including: + %ul + %li.sk-p Desktop + %li.sk-p Web (Chrome, Firefox, Safari) + %li.sk-p Mobile (iOS and Android) + %p.sk-p.sk-panel-row + If you do not currently have access to a device you're signed in on, you may proceed, + but must make signing out and back in the first step upon gaining access to that device. + %p.sk-p.sk-panel-row Press Continue only when you have completed signing out of all your devices. + + + %div{"ng-if" => "step == 3"} + %div{"ng-if" => "changePassword"} + %div{"ng-if" => "securityUpdate"} + %p.sk-panel-row Enter your current password. We'll run this through our encryption scheme to generate strong new encryption keys. + .sk-panel-row + .sk-panel-row + .sk-panel-column.stretch + %form.sk-panel-form + %input.sk-input.contrast{:type => 'password', "ng-model" => "formData.currentPassword", "placeholder" => "Current Password", "sn-autofocus" => "true", "should-focus" => "true"} + %input.sk-input.contrast{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPassword", "placeholder" => "New Password"} + %input.sk-input.contrast{"ng-if" => "changePassword", :type => 'password', "ng-model" => "formData.newPasswordConfirmation", "placeholder" => "Confirm New Password"} + + %div{"ng-if" => "step == 4"} + %p.sk-panel-row + Your data is being re-encrypted with your new keys and synced to your account. + %p.sk-panel-row.danger{"ng-if" => "lockContinue"} + Do not close this window until this process completes. + + .sk-panel-row + .sk-panel-column + .sk-spinner.small.inline.info.mr-5{"ng-if" => "formData.processing"} + .inline.bold{"ng-class" => "{'info' : !formData.statusError, 'error' : formData.statusError}"} + {{formData.status}} + .sk-panel-column{"delay-hide" => "true", "show" => "syncStatus.syncOpInProgress || syncStatus.needsMoreSync", "delay" => "1000"} + %p.info + Syncing {{syncStatus.current}}/{{syncStatus.total}} + + %div{"ng-if" => "step == 5"} + %div{"ng-if" => "changePassword"} + %p.sk-p.sk-panel-row.info-i Your password has been successfully changed. + %div{"ng-if" => "securityUpdate"} + %p.sk-p.sk-panel-row.info-i + The security update has been successfully applied to your account. + %p.sk-p.sk-panel-row + Please ensure you are running the latest version of Standard Notes on all platforms to ensure maximum compatibility. + + %p.sk-p.sk-panel-row You may now sign back in on all your devices and close this window. + + .sk-panel-footer + .empty + %a.sk-a.info.right{"ng-click" => "continue()", "ng-disabled" => "lockContinue", "ng-class" => "{'disabled' : lockContinue}"} + .sk-spinner.small.inline.info.mr-5{"ng-if" => "showSpinner"} + {{continueTitle}} diff --git a/app/assets/templates/directives/permissions-modal.html.haml b/app/assets/templates/directives/permissions-modal.html.haml index 63a5dc38f..9628eb9ad 100644 --- a/app/assets/templates/directives/permissions-modal.html.haml +++ b/app/assets/templates/directives/permissions-modal.html.haml @@ -1,22 +1,23 @@ -.background{"ng-click" => "deny()"} +.sk-modal-background{"ng-click" => "deny()"} -.content#permissions-modal +.sk-modal-content#permissions-modal .sn-component - .panel - .header - %h1.title Activate Extension - %a.close-button.info{"ng-click" => "deny()"} Cancel - .content - .panel-section - .panel-row - %h3 + .sk-panel + .sk-panel-header + .sk-panel-header-title Activate Extension + %a.sk-a.info.close-button{"ng-click" => "deny()"} Cancel + .sk-panel-content + .sk-panel-section + .sk-panel-row + .sk-h2 %strong {{component.name}} would like to interact with your {{permissionsString()}} - .panel-row - %p + .sk-panel-row + %p.sk-p Extensions use an offline messaging system to communicate. Learn more at - %a{"href" => "https://standardnotes.org/permissions", "target" => "_blank"} https://standardnotes.org/permissions. - .footer - .button.info.big.block.bold{"ng-click" => "accept()"} Continue + %a.sk-a.info{"href" => "https://standardnotes.org/permissions", "target" => "_blank"} https://standardnotes.org/permissions. + .sk-panel-footer + .sk-button.info.big.block.bold{"ng-click" => "accept()"} + .sk-label Continue diff --git a/app/assets/templates/directives/privileges-auth-modal.html.haml b/app/assets/templates/directives/privileges-auth-modal.html.haml new file mode 100644 index 000000000..95d41c9a5 --- /dev/null +++ b/app/assets/templates/directives/privileges-auth-modal.html.haml @@ -0,0 +1,29 @@ +.sk-modal-background{"ng-click" => "cancel()"} + +.sk-modal-content#privileges-modal + .sn-component + .sk-panel + .sk-panel-header + .sk-panel-header-title Authentication Required + %a.close-button.info{"ng-click" => "cancel()"} Cancel + .sk-panel-content + .sk-panel-section + %div{"ng-repeat" => "credential in requiredCredentials"} + .sk-p.sk-bold.sk-panel-row + %strong {{promptForCredential(credential)}} + .sk-panel-row + %input.sk-input.contrast{"type" => "password", "ng-model" => "authenticationParameters[credential]", + "sn-autofocus" => "true", "should-focus" => "$index == 0", "sn-enter" => "submit()"} + .sk-panel-row + %label.sk-label.danger{"ng-if" => "isCredentialInFailureState(credential)"} Invalid authentication. Please try again. + .sk-panel-row + .sk-panel-row + .sk-horizontal-group + .sk-p.sk-bold Remember For + %a.sk-a.info{"ng-repeat" => "option in sessionLengthOptions", "ng-click" => "selectSessionLength(option.value)", + "ng-class" => "{'boxed' : option.value == selectedSessionLength}"} + {{option.label}} + + .sk-panel-footer.extra-padding + .sk-button.info.big.block.bold{"ng-click" => "submit()"} + .sk-label Submit diff --git a/app/assets/templates/directives/privileges-management-modal.html.haml b/app/assets/templates/directives/privileges-management-modal.html.haml new file mode 100644 index 000000000..fb9654a05 --- /dev/null +++ b/app/assets/templates/directives/privileges-management-modal.html.haml @@ -0,0 +1,41 @@ +.sk-modal-background{"ng-click" => "cancel()"} + +.sk-modal-content#privileges-modal + .sn-component + .sk-panel + .sk-panel-header + .sk-panel-header-title Manage Privileges + %a.sk-a.close-button.info{"ng-click" => "cancel()"} Done + .sk-panel-content + .sk-panel-section + %table.sk-table + %thead + %tr + %th + %th{"ng-repeat" => "cred in availableCredentials"} + .priv-header + %strong {{credentialDisplayInfo[cred].label}} + .sk-p.font-small{"style" => "margin-top: 2px", "ng-show" => "!credentialDisplayInfo[cred].availability"} Not Configured + %tbody + %tr{"ng-repeat" => "action in availableActions"} + %td + .sk-p {{displayInfoForAction(action)}} + %th{"ng-repeat" => "credential in availableCredentials"} + %input{"type" => "checkbox", "ng-disabled" => "!credentialDisplayInfo[credential].availability", "ng-checked" => "isCredentialRequiredForAction(action, credential)", "ng-click" => "checkboxValueChanged(action, credential)"} + + .sk-panel-section{"ng-if" => "sessionExpirey && !sessionExpired"} + .sk-p.sk-panel-row You will not be asked to authenticate until {{sessionExpirey}}. + %a.sk-a.sk-panel-row.info{"ng-click" => "clearSession()"} Clear Session + .sk-panel-footer + .sk-h2.sk-bold About Privileges + .sk-panel-section.no-bottom-pad + .sk-panel-row + .text-content + .sk-p + Privileges represent interface level authentication for accessing certain items and features. + Note that when your application is unlocked, your data exists in temporary memory in an unencrypted state. + Privileges are meant to protect against unwanted access in the event of an unlocked application, but do not affect data encryption state. + %p.sk-p + Privileges sync across your other devices (not including mobile); however, note that if you require + a "Local Passcode" privilege, and another device does not have a local passcode set up, the local passcode + requirement will be ignored on that device. diff --git a/app/assets/templates/directives/revision-preview-modal.html.haml b/app/assets/templates/directives/revision-preview-modal.html.haml index df37fb182..bd0a5158a 100644 --- a/app/assets/templates/directives/revision-preview-modal.html.haml +++ b/app/assets/templates/directives/revision-preview-modal.html.haml @@ -1,13 +1,17 @@ -.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 {{content.title}} - %p.normal{"style" => "white-space: pre-wrap; font-size: 16px;"} {{content.text}} +.sn-component + .sk-modal.medium#item-preview-modal + .sk-modal-background + .sk-modal-content + .sn-component + .sk-panel + .sk-panel-header + .sk-panel-header-title Preview + .sk-horizontal-group + %a.sk-a.info.close-button{"ng-click" => "restore(false)"} Restore + %a.sk-a.info.close-button{"ng-click" => "restore(true)"} Restore as copy + %a.sk-a.info.close-button{"ng-click" => "dismiss(); $event.stopPropagation()"} Close + .sk-panel-content.selectable{"ng-if" => "!editor"} + .sk-h2 {{content.title}} + %p.normal.sk-p{"style" => "white-space: pre-wrap; font-size: 16px;"} {{content.text}} + + %component-view.component-view{"ng-if" => "editor", "component" => "editor"} diff --git a/app/assets/templates/directives/session-history-menu.html.haml b/app/assets/templates/directives/session-history-menu.html.haml index fd994a9a6..72f87e640 100644 --- a/app/assets/templates/directives/session-history-menu.html.haml +++ b/app/assets/templates/directives/session-history-menu.html.haml @@ -1,23 +1,23 @@ .sn-component#session-history-menu - .menu-panel.dropdown-menu - .header - .column - %h4.title {{history.entries.length || 'No'}} revisions - %h4{"ng-click" => "showOptions = !showOptions; $event.stopPropagation();"} - %a Options + .sk-menu-panel.dropdown-menu + .sk-menu-panel-header + .sk-menu-panel-column + .sk-menu-panel-header-title {{history.entries.length || 'No'}} revisions + .sk-menu-panel-column{"ng-click" => "showOptions = !showOptions; $event.stopPropagation();"} + %a.sk-a.info.sk-menu-panel-header-title Options %div{"ng-if" => "showOptions"} %menu-row{"label" => "'Clear note local history'", "action" => "clearItemHistory()"} %menu-row{"label" => "'Clear all local history'", "action" => "clearAllHistory()"} %menu-row{"label" => "(autoOptimize ? 'Disable' : 'Enable') + ' auto cleanup'", "action" => "toggleAutoOptimize()"} - .sublabel + .sk-sublabel Automatically cleans up small revisions to conserve space. %menu-row{"label" => "(diskEnabled ? 'Disable' : 'Enable') + ' saving history to disk'", "action" => "toggleDiskSaving()"} - .sublabel + .sk-sublabel Saving to disk may increase app loading time and memory footprint. %menu-row{"ng-repeat" => "revision in entries", "action" => "openRevision(revision);", "label" => "revision.previewTitle()"} - .sublabel.opaque{"ng-class" => "classForRevision(revision)"} + .sk-sublabel.opaque{"ng-class" => "classForRevision(revision)"} {{revision.previewSubTitle()}} diff --git a/app/assets/templates/editor.html.haml b/app/assets/templates/editor.html.haml index d78f5eca9..25386c77a 100644 --- a/app/assets/templates/editor.html.haml +++ b/app/assets/templates/editor.html.haml @@ -1,19 +1,21 @@ -.section.editor#editor-column{"aria-label" => "Note"} +.section.editor#editor-column.sn-component{"aria-label" => "Note"} .sn-component - .app-bar.no-edges{"ng-if" => "ctrl.note.locked", "ng-init" => "ctrl.lockText = 'Note Locked'", "ng-mouseover" => "ctrl.lockText = 'Unlock'", "ng-mouseleave" => "ctrl.lockText = 'Note Locked'"} + .sk-app-bar.no-edges{"ng-if" => "ctrl.note.locked", "ng-init" => "ctrl.lockText = 'Note Locked'", "ng-mouseover" => "ctrl.lockText = 'Unlock'", "ng-mouseleave" => "ctrl.lockText = 'Note Locked'"} .left - .item{"ng-click" => "ctrl.toggleLockNote()"} - .label.warning + .sk-app-bar-item{"ng-click" => "ctrl.toggleLockNote()"} + .sk-label.warning %i.icon.ion-locked {{ctrl.lockText}} #editor-title-bar.section-title-bar{"ng-show" => "ctrl.note && !ctrl.note.errorDecrypting", "ng-class" => "{'locked' : ctrl.note.locked }"} .title %input.input#note-title-editor{"ng-model" => "ctrl.note.title", "ng-keyup" => "$event.keyCode == 13 && ctrl.saveTitle($event)", - "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", "ng-blur" => "ctrl.onNameBlur()", - "select-on-click" => "true", "ng-disabled" => "ctrl.note.locked"} + "ng-change" => "ctrl.nameChanged()", "ng-focus" => "ctrl.onNameFocus()", "ng-blur" => "ctrl.onNameBlur()", + "select-on-click" => "true", "ng-disabled" => "ctrl.note.locked"} - #save-status{"ng-class" => "{'error bold': ctrl.syncTakingTooLong}", "ng-bind-html" => "ctrl.noteStatus"} + #save-status + .message{"ng-class" => "{'warning sk-bold': ctrl.syncTakingTooLong, 'danger sk-bold': ctrl.saveError}"} {{ctrl.noteStatus.message}} + .desc{"ng-show" => "ctrl.noteStatus.desc"} {{ctrl.noteStatus.desc}} .editor-tags #note-tags-component-container{"ng-if" => "ctrl.tagsComponent"} @@ -23,43 +25,44 @@ "spellcheck" => "false", "ng-disabled" => "ctrl.note.locked"} .sn-component{"ng-if" => "ctrl.note"} - .app-bar.no-edges + .sk-app-bar.no-edges#editor-menu-bar .left - .item{"ng-click" => "ctrl.showMenu = !ctrl.showMenu; ctrl.showExtensions = false; ctrl.showEditorMenu = false;", "ng-class" => "{'selected' : ctrl.showMenu}", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} - .label Options - .menu-panel.dropdown-menu{"ng-if" => "ctrl.showMenu"} - .section - .header - %h4.title Note Options + .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showMenu')", "ng-class" => "{'selected' : ctrl.showMenu}", "click-outside" => "ctrl.showMenu = false;", "is-open" => "ctrl.showMenu"} + .sk-label Options + .sk-menu-panel.dropdown-menu{"ng-if" => "ctrl.showMenu"} + .sk-menu-panel-section + .sk-menu-panel-header + .sk-menu-panel-header-title Note Options %menu-row{"label" => "ctrl.note.pinned ? 'Unpin' : 'Pin'", "action" => "ctrl.selectedMenuItem(true); ctrl.togglePin()", "desc" => "'Pin or unpin a note from the top of your list'"} %menu-row{"label" => "ctrl.note.archived ? 'Unarchive' : 'Archive'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleArchiveNote()", "desc" => "'Archive or unarchive a note from your Archived system tag'"} %menu-row{"label" => "ctrl.note.locked ? 'Unlock' : 'Lock'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleLockNote()", "desc" => "'Locking notes prevents unintentional editing'"} - %menu-row{"label" => "ctrl.note.content.hidePreview ? 'Unhide Preview' : 'Hide Preview'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleNotePreview()", "desc" => "'Hide or unhide the note preview from the list of notes'"} + %menu-row{"label" => "ctrl.note.content.protected ? 'Unprotect' : 'Protect'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleProtectNote()", "desc" => "'Protecting a note will require credentials to view it (Manage Privileges via Account menu)'"} + %menu-row{"label" => "'Preview'", "circle" => "ctrl.note.content.hidePreview ? 'danger' : 'success'", "circle-align" => "'right'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleNotePreview()", "desc" => "'Hide or unhide the note preview from the list of notes'"} %menu-row{"label" => "'Delete'", "action" => "ctrl.selectedMenuItem(); ctrl.deleteNote()", "desc" => "'Delete this note permanently from all your devices'"} - .section - .header - %h4.title Global Display + .sk-menu-panel-section + .sk-menu-panel-header + .sk-menu-panel-header-title Global Display - %menu-row{"label" => "'Monospace Font'", "circle" => "ctrl.monospaceFont ? 'success' : 'default'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('monospaceFont')", + %menu-row{"label" => "'Monospace Font'", "circle" => "ctrl.monospaceFont ? 'success' : 'neutral'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('monospaceFont')", "desc" => "'Toggles the font style for the default editor'", "subtitle" => "ctrl.selectedEditor ? 'Not available with editor extensions' : null", "disabled" => "ctrl.selectedEditor"} - %menu-row{"label" => "'Spellcheck'", "circle" => "ctrl.spellcheck ? 'success' : 'default'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('spellcheck')", + %menu-row{"label" => "'Spellcheck'", "circle" => "ctrl.spellcheck ? 'success' : 'neutral'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('spellcheck')", "desc" => "'Toggles spellcheck for the default editor'", "subtitle" => "ctrl.selectedEditor ? 'Not available with editor extensions' : null", "disabled" => "ctrl.selectedEditor"} - %menu-row{"label" => "'Margin Resizers'", "circle" => "ctrl.marginResizersEnabled ? 'success' : 'default'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('marginResizersEnabled')", + %menu-row{"label" => "'Margin Resizers'", "circle" => "ctrl.marginResizersEnabled ? 'success' : 'neutral'", "action" => "ctrl.selectedMenuItem(true); ctrl.toggleKey('marginResizersEnabled')", "desc" => "'Allows for editor left and right margins to be resized'", "faded" => "!ctrl.marginResizersEnabled"} - .item{"ng-click" => "ctrl.onEditorMenuClick()", "ng-class" => "{'selected' : ctrl.showEditorMenu}", "click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} - .label Editor + .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showEditorMenu')", "ng-class" => "{'selected' : ctrl.showEditorMenu}", "click-outside" => "ctrl.showEditorMenu = false;", "is-open" => "ctrl.showEditorMenu"} + .sk-label Editor %editor-menu{"ng-if" => "ctrl.showEditorMenu", "callback" => "ctrl.editorMenuOnSelect", "selected-editor" => "ctrl.selectedEditor", "current-item" => "ctrl.note"} - .item{"ng-click" => "ctrl.showExtensions = !ctrl.showExtensions; ctrl.showMenu = false; ctrl.showEditorMenu = false;", "ng-class" => "{'selected' : ctrl.showExtensions}", "click-outside" => "ctrl.showExtensions = false;", "is-open" => "ctrl.showExtensions"} - .label Actions + .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showExtensions')", "ng-class" => "{'selected' : ctrl.showExtensions}", "click-outside" => "ctrl.showExtensions = false;", "is-open" => "ctrl.showExtensions"} + .sk-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 + .sk-app-bar-item{"ng-click" => "ctrl.toggleMenu('showSessionHistory')", "click-outside" => "ctrl.showSessionHistory = false;", "is-open" => "ctrl.showSessionHistory"} + .sk-label Session History %session-history-menu{"ng-if" => "ctrl.showSessionHistory", "item" => "ctrl.note"} .editor-content#editor-content{"ng-if" => "ctrl.noteReady && !ctrl.note.errorDecrypting"} @@ -78,7 +81,15 @@ .section{"ng-if" => "ctrl.note.errorDecrypting"} %p.medium-padding{"style" => "padding-top: 0 !important;"} There was an error decrypting this item. Ensure you are running the latest version of this app, then sign out and sign back in to try again. - #editor-pane-component-stack + #editor-pane-component-stack{"ng-show" => "ctrl.note"} + #component-stack-menu-bar.sk-app-bar.no-edges{"ng-if" => "ctrl.componentStack.length"} + .left + .sk-app-bar-item{"ng-repeat" => "component in ctrl.componentStack", "ng-click" => "ctrl.toggleStackComponentForCurrentItem(component)"} + .sk-app-bar-item-column + .sk-circle.small{"ng-class" => "{'info' : !component.hidden && component.active, 'neutral' : component.hidden || !component.active}"} + .sk-app-bar-item-column + .sk-label {{component.name}} + .sn-component - %component-view.component-view.component-stack-item.border-color{"ng-repeat" => "component in ctrl.componentStack", + %component-view.component-view.component-stack-item{"ng-repeat" => "component in ctrl.componentStack", "ng-if" => "component.active", "ng-show" => "!component.hidden", "manual-dealloc" => "true", "component" => "component"} diff --git a/app/assets/templates/footer.html.haml b/app/assets/templates/footer.html.haml index c4dfd0171..31192f7eb 100644 --- a/app/assets/templates/footer.html.haml +++ b/app/assets/templates/footer.html.haml @@ -1,44 +1,55 @@ .sn-component - #footer-bar.app-bar.no-edges + #footer-bar.sk-app-bar.no-edges .left - .item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.showAccountMenu = false;", "is-open" => "ctrl.showAccountMenu"} - .column - .circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'default')"} - .column - .label.title{"ng-class" => "{red: ctrl.error}"} Account + + .sk-app-bar-item{"ng-click" => "ctrl.accountMenuPressed()", "click-outside" => "ctrl.clickOutsideAccountMenu()", "is-open" => "ctrl.showAccountMenu"} + .sk-app-bar-item-column + .sk-circle.small{"ng-class" => "ctrl.error ? 'danger' : (ctrl.getUser() ? 'info' : 'neutral')"} + .sk-app-bar-item-column + .sk-label.title{"ng-class" => "{red: ctrl.error}"} Account %account-menu{"ng-click" => "$event.stopPropagation()", "ng-if" => "ctrl.showAccountMenu", "on-successful-auth" => "ctrl.onAuthSuccess", "close-function" => "ctrl.closeAccountMenu"} - .item - %a.no-decoration.label.title{"href" => "https://standardnotes.org/help", "target" => "_blank"} + .sk-app-bar-item + %a.no-decoration.sk-label.title{"href" => "https://standardnotes.org/help", "target" => "_blank"} Help - .item.border + .sk-app-bar-item.border - .item{"ng-repeat" => "room in ctrl.rooms track by room.uuid"} - .column{"ng-click" => "ctrl.selectRoom(room)"} - .label {{room.name}} + .sk-app-bar-item{"ng-repeat" => "room in ctrl.rooms track by room.uuid"} + .sk-app-bar-item-column{"ng-click" => "ctrl.selectRoom(room)"} + .sk-label {{room.name}} %component-modal{"ng-if" => "room.showRoom", "component" => "room", "on-dismiss" => "ctrl.onRoomDismiss"} .right - .item{"ng-if" => "ctrl.securityUpdateAvailable", "ng-click" => "ctrl.openSecurityUpdate()"} - %span.success.label Security update available. + .sk-app-bar-item{"ng-if" => "ctrl.securityUpdateAvailable", "ng-click" => "ctrl.openSecurityUpdate()"} + %span.success.sk-label Security update available. - .item{"ng-if" => "ctrl.newUpdateAvailable == true", "ng-click" => "ctrl.clickedNewUpdateAnnouncement()"} - %span.info.label New update available. + .sk-app-bar-item{"ng-if" => "ctrl.newUpdateAvailable == true", "ng-click" => "ctrl.clickedNewUpdateAnnouncement()"} + %span.info.sk-label New update available. - .item.no-pointer{"ng-if" => "ctrl.lastSyncDate && !ctrl.isRefreshing"} - .label.subtle + .sk-app-bar-item.no-pointer{"ng-if" => "ctrl.lastSyncDate && !ctrl.isRefreshing"} + .sk-label.subtle Last refreshed {{ctrl.lastSyncDate | appDateTime}} - .item{"ng-if" => "ctrl.lastSyncDate && ctrl.isRefreshing"} - .spinner.small + .sk-app-bar-item{"ng-if" => "ctrl.lastSyncDate && ctrl.isRefreshing"} + .sk-spinner.small - .item{"ng-if" => "ctrl.offline"} - .label Offline - .item{"ng-if" => "!ctrl.offline", "ng-click" => "ctrl.refreshData()"} - .label Refresh + .sk-app-bar-item{"ng-if" => "ctrl.offline"} + .sk-label Offline + .sk-app-bar-item{"ng-if" => "!ctrl.offline", "ng-click" => "ctrl.refreshData()"} + .sk-label Refresh - .item#lock-item{"ng-if" => "ctrl.hasPasscode()"} - .label + .sk-app-bar-item.border{"ng-if" => "ctrl.dockShortcuts.length > 0"} + + .sk-app-bar-item.dock-shortcut{"ng-repeat" => "shortcut in ctrl.dockShortcuts"} + .sk-app-bar-item-column{"ng-click" => "ctrl.selectShortcut(shortcut)", "ng-class" => "{'underline': shortcut.component.active}"} + .div{"ng-if" => "shortcut.icon.type == 'circle'"} + .sk-circle.small{"ng-style" => "{'background-color': shortcut.icon.background_color, 'border-color': shortcut.icon.border_color}"} + .div{"ng-if" => "shortcut.icon.type == 'svg'"} + .svg-item{"ng-attr-id" => "dock-svg-{{shortcut.component.uuid}}", "elem-ready" => "ctrl.initSvgForShortcut(shortcut)"} + + .sk-app-bar-item.border{"ng-if" => "ctrl.hasPasscode()"} + .sk-app-bar-item#lock-item{"ng-if" => "ctrl.hasPasscode()", "title" => "Locks application and wipes unencrypted data from memory."} + .sk-label %i.icon.ion-locked#footer-lock-icon{"ng-if" => "ctrl.hasPasscode()", "ng-click" => "ctrl.lockApp()"} diff --git a/app/assets/templates/home.html.haml b/app/assets/templates/home.html.haml index b8d03b4d3..4ca4c5695 100644 --- a/app/assets/templates/home.html.haml +++ b/app/assets/templates/home.html.haml @@ -1,11 +1,11 @@ .main-ui-view{"ng-class" => "platform"} + %lock-screen{"ng-if" => "needsUnlock", "on-success" => "onSuccessfulUnlock"} - .app#app{"ng-if" => "!needsUnlock"} + + .app#app{"ng-if" => "!needsUnlock", "ng-class" => "appClass"} %tags-section{"save" => "tagsSave", "add-new" => "tagsAddNew", "selection-made" => "tagsSelectionMade", "all-tag" => "allTag", "archive-tag" => "archiveTag", "tags" => "tags", "remove-tag" => "removeTag"} - %notes-section{"add-new" => "notesAddNew", "selection-made" => "notesSelectionMade", "tag" => "selectedTag"} - %editor-section{"note" => "selectedNote", "remove" => "deleteNote", "update-tags" => "updateTagsForNote"} %footer{"ng-if" => "!needsUnlock"} diff --git a/app/assets/templates/lock-screen.html.haml b/app/assets/templates/lock-screen.html.haml index e79559517..72ebdd7d7 100644 --- a/app/assets/templates/lock-screen.html.haml +++ b/app/assets/templates/lock-screen.html.haml @@ -1,23 +1,25 @@ #lock-screen.sn-component - .panel - .header - %h1.title Passcode Required - .content - .panel-section - %form.panel-form.panel-row{"ng-submit" => "submitPasscodeForm()"} - .panel-column.stretch - %input.panel-row{:type => 'password', + .sk-panel + .sk-panel-header + .sk-panel-header-title Passcode Required + .sk-panel-content + .sk-panel-section + %form.sk-panel-form.sk-panel-row{"ng-submit" => "submitPasscodeForm()"} + .sk-panel-column.stretch + %input.center-text.sk-input.contrast{:type => 'password', "ng-model" => "formData.passcode", "autofocus" => "true", "sn-autofocus" => "true", "should-focus" => "true", "placeholder" => "Enter Passcode", "autocomplete" => "new-password"} - .button-group.stretch.panel-row.form-submit - %button.button.info{"type" => "submit"} - .label Unlock + .sk-button-group.stretch.sk-panel-row.form-submit + %button.sk-button.info{"type" => "submit"} + .sk-label Unlock - #passcode-reset - %a.default{"ng-if" => "!formData.showRecovery", "ng-click" => "forgotPasscode()"} Forgot Passcode? + .sk-panel-footer + #passcode-reset + %a.sk-a.neutral{"ng-if" => "!formData.showRecovery", "ng-click" => "forgotPasscode()"} Forgot? - %div{"ng-if" => "formData.showRecovery"} - %p - If you forgot your local passcode, your only option is to clear all your local data from this device - and sign back in to your account. - %a.danger{"ng-click" => "beginDeleteData()"} Delete Local Data + %div{"ng-if" => "formData.showRecovery"} + .sk-p + If you forgot your local passcode, your only option is to clear your local data from this device + and sign back in to your account. + .sk-panel-row + %a.sk-a.danger.center-text{"ng-click" => "beginDeleteData()"} Delete Local Data diff --git a/app/assets/templates/notes.html.haml b/app/assets/templates/notes.html.haml index a1e48dd1b..475d35711 100644 --- a/app/assets/templates/notes.html.haml +++ b/app/assets/templates/notes.html.haml @@ -1,38 +1,40 @@ -.section.notes#notes-column{"aria-label" => "Notes"} +.sn-component.section.notes#notes-column{"aria-label" => "Notes"} .content .section-title-bar#notes-title-bar .padded .section-title-bar-header .title {{ctrl.panelTitle()}} - .add-button#notes-add-button{"ng-click" => "ctrl.createNewNote()", "title" => "Create a new note in the selected tag"} + + .sk-button.contrast.wide{"ng-click" => "ctrl.createNewNote()", "title" => "Create a new note in the selected tag"} + .sk-label + .filter-section{"role" => "search"} %input.filter-bar#search-bar.mousetrap{"select-on-click" => "true", "ng-model" => "ctrl.noteFilter.text", "placeholder" => "Search", "ng-change" => "ctrl.filterTextChanged()", "lowercase" => "true", "ng-blur" => "ctrl.onFilterEnter()", "ng-keyup" => "$event.keyCode == 13 && ctrl.onFilterEnter();", "title" => "Searches notes in the currently selected tag"} #search-clear-button{"ng-if" => "ctrl.noteFilter.text", "ng-click" => "ctrl.clearFilterText();"} ✕ .sn-component#notes-menu-bar - .app-bar.no-edges + .sk-app-bar.no-edges .left - .item{"ng-click" => "ctrl.showMenu = !ctrl.showMenu", "ng-class" => "{'selected' : ctrl.showMenu}"} - .column - .label + .sk-app-bar-item{"ng-click" => "ctrl.showMenu = !ctrl.showMenu", "ng-class" => "{'selected' : ctrl.showMenu}"} + .sk-app-bar-item-column + .sk-label Options - .column - .sublabel {{ctrl.optionsSubtitle()}} + .sk-app-bar-item-column + .sk-sublabel {{ctrl.optionsSubtitle()}} - .sn-component{"ng-if" => "ctrl.showMenu"} - .menu-panel.dropdown-menu - .section - .header - %h4.title Sort By + .sk-menu-panel.dropdown-menu{"ng-if" => "ctrl.showMenu"} + .sk-menu-panel-header + .sk-menu-panel-header-title Sort By + .sk-button.sk-secondary-contrast{"ng-click" => "ctrl.toggleReverseSort()"} + .sk-label + %i.icon{"ng-class" => "{'ion-arrow-return-left' : ctrl.sortReverse == false, 'ion-arrow-return-right' : ctrl.sortReverse == true }"} - %menu-row{"label" => "'Date Added'", "circle" => "ctrl.sortBy == 'created_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByCreated()", "desc" => "'Sort notes by newest first'"} - %menu-row{"label" => "'Date Modified'", "circle" => "ctrl.sortBy == 'client_updated_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByUpdated()", "desc" => "'Sort notes with the most recently updated first'"} - %menu-row{"label" => "'Title'", "circle" => "ctrl.sortBy == 'title' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByTitle()", "desc" => "'Sort notes alphabetically by their title'"} + %menu-row{"label" => "'Date Added'", "circle" => "ctrl.sortBy == 'created_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByCreated()", "desc" => "'Sort notes by newest first'"} + %menu-row{"label" => "'Date Modified'", "circle" => "ctrl.sortBy == 'client_updated_at' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByUpdated()", "desc" => "'Sort notes with the most recently updated first'"} + %menu-row{"label" => "'Title'", "circle" => "ctrl.sortBy == 'title' && 'success'", "action" => "ctrl.selectedMenuItem(); ctrl.selectedSortByTitle()", "desc" => "'Sort notes alphabetically by their title'"} - .section{"ng-if" => "!ctrl.tag.isSmartTag()"} - .header - %h4.title Display + .sk-menu-panel-section{"ng-if" => "!ctrl.tag.isSmartTag()"} + .sk-menu-panel-header + .sk-menu-panel-header-title Display %menu-row{"label" => "'Archived Notes'", "circle" => "ctrl.showArchived ? 'success' : 'danger'", "faded" => "!ctrl.showArchived", "action" => "ctrl.selectedMenuItem(); ctrl.toggleKey('showArchived')", "desc" => "'Archived notes are usually hidden. You can explicitly show them with this option.'"} %menu-row{"label" => "'Pinned Notes'", "circle" => "ctrl.hidePinned ? 'danger' : 'success'", "faded" => "ctrl.hidePinned", "action" => "ctrl.selectedMenuItem(); ctrl.toggleKey('hidePinned')", "desc" => "'Pinned notes always appear on top. You can hide them temporarily with this option so you can focus on other notes in the list.'"} @@ -42,26 +44,31 @@ .scrollable .infinite-scroll#notes-scrollable{"infinite-scroll" => "ctrl.paginate()", "can-load" => "true", "threshold" => "200"} - .note{"ng-repeat" => "note in (ctrl.sortedNotes = (ctrl.tag.notes | filter: ctrl.filterNotes | sortBy: ctrl.sortBy | limitTo:ctrl.notesToDisplay)) track by note.uuid", + .note{"ng-repeat" => "note in (ctrl.sortedNotes = (ctrl.tag.notes | filter: ctrl.filterNotes | sortBy: ctrl.sortBy:ctrl.sortReverse | limitTo:ctrl.notesToDisplay)) track by note.uuid", "ng-click" => "ctrl.selectNote(note, true)", "ng-class" => "{'selected' : ctrl.selectedNote == note}"} %strong.red.medium-text{"ng-if" => "note.conflict_of"} Conflicted copy %strong.red.medium-text{"ng-if" => "note.errorDecrypting"} Unable to Decrypt - .pinned.tinted{"ng-if" => "note.pinned", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"} - %i.icon.ion-bookmark - %strong.medium-text Pinned + .note-flags + .pinned.note-flag{"ng-if" => "note.pinned"} + %i.icon.ion-bookmark + %strong.medium-text Pinned - .archived.tinted{"ng-if" => "note.archived && !ctrl.tag.isSmartTag()", "ng-class" => "{'tinted-selected' : ctrl.selectedNote == note}"} - %i.icon.ion-ios-box - %strong.medium-text Archived + .archived.note-flag{"ng-if" => "note.archived && !ctrl.tag.isSmartTag()"} + %i.icon.ion-ios-box + %strong.medium-text Archived .tags-string{"ng-if" => "ctrl.shouldShowTags(note)"} .faded {{note.savedTagsString || note.tagsString()}} .name{"ng-if" => "note.title"} + %span.note-flag{"ng-show" => "note.locked"} + %i.icon.ion-locked.medium-text + %span.note-flag{"ng-show" => "note.content.protected"} + %i.icon.ion-eye-disabled {{note.title}} - .note-preview{"ng-if" => "!ctrl.hideNotePreview && !note.content.hidePreview"} + .note-preview{"ng-if" => "!ctrl.hideNotePreview && !note.content.hidePreview && !note.content.protected"} .html-preview{"ng-if" => "note.content.preview_html", "ng-bind-html" => "note.content.preview_html"} .plain-preview{"ng-if" => "!note.content.preview_html && note.content.preview_plain"} {{note.content.preview_plain}} .default-preview{"ng-if" => "!note.content.preview_html && !note.content.preview_plain"} {{note.text}} diff --git a/app/assets/templates/tags.html.haml b/app/assets/templates/tags.html.haml index 66c401a33..0af5c93b6 100644 --- a/app/assets/templates/tags.html.haml +++ b/app/assets/templates/tags.html.haml @@ -1,4 +1,4 @@ -.section.tags#tags-column{"aria-label" => "Tags"} +.sn-component.section.tags#tags-column{"aria-label" => "Tags"} .component-view-container{"ng-if" => "ctrl.component.active"} %component-view.component-view{"component" => "ctrl.component"} @@ -6,8 +6,10 @@ #tags-content.content{"ng-if" => "!(ctrl.component && ctrl.component.active)"} #tags-title-bar.section-title-bar .section-title-bar-header - .title Tags - .add-button#tag-add-button{"ng-click" => "ctrl.clickedAddNewTag()", "title" => "Create a new tag"} + + .sk-h3.title + %span.sk-bold Tags + .sk-button.sk-secondary-contrast.wide{"ng-click" => "ctrl.clickedAddNewTag()", "title" => "Create a new tag"} + .sk-label + .scrollable .infinite-scroll diff --git a/dist/assets/ionicons.eot b/dist/assets/ionicons.eot index 9edec3907..b2e176a7b 100644 Binary files a/dist/assets/ionicons.eot and b/dist/assets/ionicons.eot differ diff --git a/dist/assets/ionicons.svg b/dist/assets/ionicons.svg old mode 100644 new mode 100755 index 5188c5687..41ab5a832 --- a/dist/assets/ionicons.svg +++ b/dist/assets/ionicons.svg @@ -1,16 +1,16 @@ -Created by FontForge 20170925 at Fri Jan 19 12:18:20 2018 +Created by FontForge 20170925 at Thu Dec 13 12:46:07 2018 By mo Copyright (c) 2018, mo - + - - + + + + + + diff --git a/dist/assets/ionicons.ttf b/dist/assets/ionicons.ttf old mode 100644 new mode 100755 index 01db5bbde..8f31abd2f Binary files a/dist/assets/ionicons.ttf and b/dist/assets/ionicons.ttf differ diff --git a/dist/assets/ionicons.woff b/dist/assets/ionicons.woff old mode 100644 new mode 100755 index 20532652f..86767230e Binary files a/dist/assets/ionicons.woff and b/dist/assets/ionicons.woff differ diff --git a/package-lock.json b/package-lock.json index 712f36497..a97eed879 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.3.16", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -10,8 +10,8 @@ "integrity": "sha512-3Sp6WZZ/lXl+nTDoGpGWHEpTnnC6X5fnkolYZR6nwIfzbxxvA8utPWe1gCt7i0m9uVGsSz2IS8K8mJ7HmlduMg==", "dev": true, "requires": { - "jsonparse": "^1.2.0", - "through": ">=2.2.7 <3" + "jsonparse": "1.3.1", + "through": "2.3.8" } }, "abbrev": { @@ -32,8 +32,8 @@ "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", "dev": true, "requires": { - "acorn": "^5.4.1", - "xtend": "^4.0.1" + "acorn": "5.6.2", + "xtend": "4.0.1" }, "dependencies": { "acorn": { @@ -63,7 +63,7 @@ "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", "dev": true, "requires": { - "es6-promisify": "^5.0.0" + "es6-promisify": "5.0.0" } }, "ajv": { @@ -72,10 +72,10 @@ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "co": "4.6.0", + "fast-deep-equal": "1.1.0", + "fast-json-stable-stringify": "2.0.0", + "json-schema-traverse": "0.3.1" } }, "align-text": { @@ -84,9 +84,9 @@ "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", "dev": true, "requires": { - "kind-of": "^3.0.2", - "longest": "^1.0.1", - "repeat-string": "^1.5.2" + "kind-of": "3.2.2", + "longest": "1.0.1", + "repeat-string": "1.6.1" } }, "alter": { @@ -95,7 +95,7 @@ "integrity": "sha1-x1iICGF1cgNKrmJICvJrHU0cs80=", "dev": true, "requires": { - "stable": "~0.1.3" + "stable": "0.1.8" } }, "amdefine": { @@ -111,11 +111,11 @@ "dev": true, "optional": true, "requires": { - "bitsyntax": "~0.0.4", - "bluebird": "^3.4.6", + "bitsyntax": "0.0.4", + "bluebird": "3.5.1", "buffer-more-ints": "0.0.2", - "readable-stream": "1.x >=1.1.9", - "safe-buffer": "^5.0.1" + "readable-stream": "1.1.14", + "safe-buffer": "5.1.2" }, "dependencies": { "isarray": { @@ -132,10 +132,10 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -177,8 +177,8 @@ "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", "dev": true, "requires": { - "micromatch": "^2.1.5", - "normalize-path": "^2.0.0" + "micromatch": "2.3.11", + "normalize-path": "2.1.1" } }, "argparse": { @@ -187,7 +187,7 @@ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, "requires": { - "sprintf-js": "~1.0.2" + "sprintf-js": "1.0.3" }, "dependencies": { "sprintf-js": { @@ -204,7 +204,7 @@ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", "dev": true, "requires": { - "arr-flatten": "^1.0.1" + "arr-flatten": "1.1.0" } }, "arr-flatten": { @@ -267,9 +267,9 @@ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "bn.js": "4.11.8", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "assert": { @@ -329,7 +329,7 @@ "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", "dev": true, "requires": { - "acorn": "^4.0.3" + "acorn": "4.0.13" } }, "async": { @@ -391,7 +391,7 @@ "dev": true, "optional": true, "requires": { - "debug": "^2.2.0" + "debug": "2.6.9" } } } @@ -402,21 +402,21 @@ "integrity": "sha1-UCq1SHTX24itALiHoGODzgPQAvE=", "dev": true, "requires": { - "babel-core": "^6.26.0", - "babel-polyfill": "^6.26.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "chokidar": "^1.6.1", - "commander": "^2.11.0", - "convert-source-map": "^1.5.0", - "fs-readdir-recursive": "^1.0.0", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "output-file-sync": "^1.1.2", - "path-is-absolute": "^1.0.1", - "slash": "^1.0.0", - "source-map": "^0.5.6", - "v8flags": "^2.1.1" + "babel-core": "6.26.3", + "babel-polyfill": "6.26.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "chokidar": "1.7.0", + "commander": "2.15.1", + "convert-source-map": "1.5.1", + "fs-readdir-recursive": "1.1.0", + "glob": "7.1.2", + "lodash": "4.17.10", + "output-file-sync": "1.1.2", + "path-is-absolute": "1.0.1", + "slash": "1.0.0", + "source-map": "0.5.7", + "v8flags": "2.1.1" } }, "babel-code-frame": { @@ -425,9 +425,9 @@ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", "dev": true, "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" + "chalk": "1.1.3", + "esutils": "2.0.2", + "js-tokens": "3.0.2" } }, "babel-core": { @@ -436,25 +436,25 @@ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" + "babel-code-frame": "6.26.0", + "babel-generator": "6.26.1", + "babel-helpers": "6.24.1", + "babel-messages": "6.23.0", + "babel-register": "6.26.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "convert-source-map": "1.5.1", + "debug": "2.6.9", + "json5": "0.5.1", + "lodash": "4.17.10", + "minimatch": "3.0.4", + "path-is-absolute": "1.0.1", + "private": "0.1.8", + "slash": "1.0.0", + "source-map": "0.5.7" } }, "babel-generator": { @@ -463,14 +463,14 @@ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", "dev": true, "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" + "babel-messages": "6.23.0", + "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" } }, "babel-helper-builder-binary-assignment-operator-visitor": { @@ -479,9 +479,9 @@ "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", "dev": true, "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-explode-assignable-expression": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-call-delegate": { @@ -490,10 +490,10 @@ "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-define-map": { @@ -502,10 +502,10 @@ "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-helper-explode-assignable-expression": { @@ -514,9 +514,9 @@ "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-function-name": { @@ -525,11 +525,11 @@ "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", "dev": true, "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-get-function-arity": { @@ -538,8 +538,8 @@ "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-hoist-variables": { @@ -548,8 +548,8 @@ "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-optimise-call-expression": { @@ -558,8 +558,8 @@ "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-regex": { @@ -568,9 +568,9 @@ "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-helper-remap-async-to-generator": { @@ -579,11 +579,11 @@ "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helper-replace-supers": { @@ -592,12 +592,12 @@ "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", "dev": true, "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-optimise-call-expression": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-helpers": { @@ -606,8 +606,8 @@ "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-messages": { @@ -616,7 +616,7 @@ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-angularjs-annotate": { @@ -625,9 +625,9 @@ "integrity": "sha512-erYvZAJgnrgeyEZqIJOAiK6vUK44HsVb0+Tid4zTBcsvdQuas0Z5Teh0w/hcINKW3G0xweqA5LGfg2ZWlp3nMA==", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-types": "^6.26.0", - "simple-is": "~0.2.0" + "babel-code-frame": "6.26.0", + "babel-types": "6.26.0", + "simple-is": "0.2.0" } }, "babel-plugin-check-es2015-constants": { @@ -636,7 +636,7 @@ "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-syntax-async-functions": { @@ -663,9 +663,9 @@ "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", "dev": true, "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" + "babel-helper-remap-async-to-generator": "6.24.1", + "babel-plugin-syntax-async-functions": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-arrow-functions": { @@ -674,7 +674,7 @@ "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoped-functions": { @@ -683,7 +683,7 @@ "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-block-scoping": { @@ -692,11 +692,11 @@ "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "lodash": "4.17.10" } }, "babel-plugin-transform-es2015-classes": { @@ -705,15 +705,15 @@ "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", "dev": true, "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-define-map": "6.26.0", + "babel-helper-function-name": "6.24.1", + "babel-helper-optimise-call-expression": "6.24.1", + "babel-helper-replace-supers": "6.24.1", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-computed-properties": { @@ -722,8 +722,8 @@ "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-destructuring": { @@ -732,7 +732,7 @@ "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-duplicate-keys": { @@ -741,8 +741,8 @@ "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-for-of": { @@ -751,7 +751,7 @@ "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-function-name": { @@ -760,9 +760,9 @@ "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", "dev": true, "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-function-name": "6.24.1", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-literals": { @@ -771,7 +771,7 @@ "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-modules-amd": { @@ -780,9 +780,9 @@ "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-commonjs": { @@ -791,10 +791,10 @@ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", "dev": true, "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" + "babel-plugin-transform-strict-mode": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-modules-systemjs": { @@ -803,9 +803,9 @@ "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", "dev": true, "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-helper-hoist-variables": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-modules-umd": { @@ -814,9 +814,9 @@ "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", "dev": true, "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0" } }, "babel-plugin-transform-es2015-object-super": { @@ -825,8 +825,8 @@ "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", "dev": true, "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" + "babel-helper-replace-supers": "6.24.1", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-parameters": { @@ -835,12 +835,12 @@ "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", "dev": true, "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" + "babel-helper-call-delegate": "6.24.1", + "babel-helper-get-function-arity": "6.24.1", + "babel-runtime": "6.26.0", + "babel-template": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-shorthand-properties": { @@ -849,8 +849,8 @@ "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-spread": { @@ -859,7 +859,7 @@ "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-sticky-regex": { @@ -868,9 +868,9 @@ "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-plugin-transform-es2015-template-literals": { @@ -879,7 +879,7 @@ "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-typeof-symbol": { @@ -888,7 +888,7 @@ "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-es2015-unicode-regex": { @@ -897,9 +897,9 @@ "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", "dev": true, "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" + "babel-helper-regex": "6.26.0", + "babel-runtime": "6.26.0", + "regexpu-core": "2.0.0" } }, "babel-plugin-transform-exponentiation-operator": { @@ -908,9 +908,9 @@ "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", "dev": true, "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" + "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", + "babel-plugin-syntax-exponentiation-operator": "6.13.0", + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-regenerator": { @@ -919,7 +919,7 @@ "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", "dev": true, "requires": { - "regenerator-transform": "^0.10.0" + "regenerator-transform": "0.10.1" } }, "babel-plugin-transform-runtime": { @@ -928,7 +928,7 @@ "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", "dev": true, "requires": { - "babel-runtime": "^6.22.0" + "babel-runtime": "6.26.0" } }, "babel-plugin-transform-strict-mode": { @@ -937,8 +937,8 @@ "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", "dev": true, "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0" } }, "babel-polyfill": { @@ -947,9 +947,9 @@ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "regenerator-runtime": "^0.10.5" + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "regenerator-runtime": "0.10.5" }, "dependencies": { "regenerator-runtime": { @@ -966,36 +966,36 @@ "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-syntax-trailing-function-commas": "6.22.0", + "babel-plugin-transform-async-to-generator": "6.24.1", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-exponentiation-operator": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0", + "browserslist": "3.2.8", + "invariant": "2.2.4", + "semver": "5.5.0" } }, "babel-preset-es2015": { @@ -1004,30 +1004,30 @@ "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", "dev": true, "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.24.1", - "babel-plugin-transform-es2015-classes": "^6.24.1", - "babel-plugin-transform-es2015-computed-properties": "^6.24.1", - "babel-plugin-transform-es2015-destructuring": "^6.22.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", - "babel-plugin-transform-es2015-for-of": "^6.22.0", - "babel-plugin-transform-es2015-function-name": "^6.24.1", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", - "babel-plugin-transform-es2015-modules-umd": "^6.24.1", - "babel-plugin-transform-es2015-object-super": "^6.24.1", - "babel-plugin-transform-es2015-parameters": "^6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", - "babel-plugin-transform-regenerator": "^6.24.1" + "babel-plugin-check-es2015-constants": "6.22.0", + "babel-plugin-transform-es2015-arrow-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", + "babel-plugin-transform-es2015-block-scoping": "6.26.0", + "babel-plugin-transform-es2015-classes": "6.24.1", + "babel-plugin-transform-es2015-computed-properties": "6.24.1", + "babel-plugin-transform-es2015-destructuring": "6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", + "babel-plugin-transform-es2015-for-of": "6.23.0", + "babel-plugin-transform-es2015-function-name": "6.24.1", + "babel-plugin-transform-es2015-literals": "6.22.0", + "babel-plugin-transform-es2015-modules-amd": "6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "6.26.2", + "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", + "babel-plugin-transform-es2015-modules-umd": "6.24.1", + "babel-plugin-transform-es2015-object-super": "6.24.1", + "babel-plugin-transform-es2015-parameters": "6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", + "babel-plugin-transform-es2015-spread": "6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "6.24.1", + "babel-plugin-transform-es2015-template-literals": "6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", + "babel-plugin-transform-es2015-unicode-regex": "6.24.1", + "babel-plugin-transform-regenerator": "6.26.0" } }, "babel-preset-es2016": { @@ -1036,7 +1036,7 @@ "integrity": "sha1-+QC/k+LrwNJ235uKtZck6/2Vn4s=", "dev": true, "requires": { - "babel-plugin-transform-exponentiation-operator": "^6.24.1" + "babel-plugin-transform-exponentiation-operator": "6.24.1" } }, "babel-register": { @@ -1045,13 +1045,13 @@ "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", "dev": true, "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" + "babel-core": "6.26.3", + "babel-runtime": "6.26.0", + "core-js": "2.5.7", + "home-or-tmp": "2.0.0", + "lodash": "4.17.10", + "mkdirp": "0.5.1", + "source-map-support": "0.4.18" } }, "babel-runtime": { @@ -1060,8 +1060,8 @@ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", "dev": true, "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" + "core-js": "2.5.7", + "regenerator-runtime": "0.11.1" } }, "babel-template": { @@ -1070,11 +1070,11 @@ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" + "babel-runtime": "6.26.0", + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "lodash": "4.17.10" } }, "babel-traverse": { @@ -1083,15 +1083,15 @@ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", "dev": true, "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" + "babel-code-frame": "6.26.0", + "babel-messages": "6.23.0", + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0", + "debug": "2.6.9", + "globals": "9.18.0", + "invariant": "2.2.4", + "lodash": "4.17.10" } }, "babel-types": { @@ -1100,10 +1100,10 @@ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", "dev": true, "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" + "babel-runtime": "6.26.0", + "esutils": "2.0.2", + "lodash": "4.17.10", + "to-fast-properties": "1.0.3" } }, "babylon": { @@ -1130,13 +1130,13 @@ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", "dev": true, "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" + "cache-base": "1.0.1", + "class-utils": "0.3.6", + "component-emitter": "1.2.1", + "define-property": "1.0.0", + "isobject": "3.0.1", + "mixin-deep": "1.3.1", + "pascalcase": "0.1.1" }, "dependencies": { "component-emitter": { @@ -1151,7 +1151,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "is-accessor-descriptor": { @@ -1160,7 +1160,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -1169,7 +1169,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -1178,9 +1178,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -1222,7 +1222,7 @@ "dev": true, "optional": true, "requires": { - "tweetnacl": "^0.14.3" + "tweetnacl": "0.14.5" } }, "better-assert": { @@ -1257,7 +1257,7 @@ "dev": true, "optional": true, "requires": { - "readable-stream": "~2.0.5" + "readable-stream": "2.0.6" }, "dependencies": { "process-nextick-args": { @@ -1274,12 +1274,12 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "1.0.7", + "string_decoder": "0.10.31", + "util-deprecate": "1.0.2" } }, "string_decoder": { @@ -1315,10 +1315,10 @@ "integrity": "sha1-5LoM5BCkaTYyM2dgnstOZVMSUGk=", "dev": true, "requires": { - "continuable-cache": "^0.3.1", - "error": "^7.0.0", - "raw-body": "~1.1.0", - "safe-json-parse": "~1.0.1" + "continuable-cache": "0.3.1", + "error": "7.0.2", + "raw-body": "1.1.7", + "safe-json-parse": "1.0.1" } }, "body-parser": { @@ -1328,15 +1328,15 @@ "dev": true, "requires": { "bytes": "3.0.0", - "content-type": "~1.0.4", + "content-type": "1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "~1.6.3", + "depd": "1.1.2", + "http-errors": "1.6.3", "iconv-lite": "0.4.23", - "on-finished": "~2.3.0", + "on-finished": "2.3.0", "qs": "6.5.2", "raw-body": "2.3.3", - "type-is": "~1.6.16" + "type-is": "1.6.16" }, "dependencies": { "bytes": { @@ -1365,7 +1365,7 @@ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", "dev": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "bower": { @@ -1380,7 +1380,7 @@ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, @@ -1390,9 +1390,9 @@ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", "dev": true, "requires": { - "expand-range": "^1.8.1", - "preserve": "^0.2.0", - "repeat-element": "^1.1.2" + "expand-range": "1.8.2", + "preserve": "0.2.0", + "repeat-element": "1.1.2" } }, "brorand": { @@ -1407,12 +1407,12 @@ "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "combine-source-map": "~0.8.0", - "defined": "^1.0.0", - "safe-buffer": "^5.1.1", - "through2": "^2.0.0", - "umd": "^3.0.0" + "JSONStream": "1.3.3", + "combine-source-map": "0.8.0", + "defined": "1.0.0", + "safe-buffer": "5.1.2", + "through2": "2.0.3", + "umd": "3.0.3" } }, "browser-resolve": { @@ -1436,54 +1436,54 @@ "integrity": "sha512-fMES05wq1Oukts6ksGUU2TMVHHp06LyQt0SIwbXIHm7waSrQmNBZePsU0iM/4f94zbvb/wHma+D1YrdzWYnF/A==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "assert": "^1.4.0", - "browser-pack": "^6.0.1", - "browser-resolve": "^1.11.0", - "browserify-zlib": "~0.2.0", - "buffer": "^5.0.2", - "cached-path-relative": "^1.0.0", - "concat-stream": "^1.6.0", - "console-browserify": "^1.1.0", - "constants-browserify": "~1.0.0", - "crypto-browserify": "^3.0.0", - "defined": "^1.0.0", - "deps-sort": "^2.0.0", - "domain-browser": "^1.2.0", - "duplexer2": "~0.1.2", - "events": "^2.0.0", - "glob": "^7.1.0", - "has": "^1.0.0", - "htmlescape": "^1.1.0", - "https-browserify": "^1.0.0", - "inherits": "~2.0.1", - "insert-module-globals": "^7.0.0", - "labeled-stream-splicer": "^2.0.0", - "mkdirp": "^0.5.0", - "module-deps": "^6.0.0", - "os-browserify": "~0.3.0", - "parents": "^1.0.1", - "path-browserify": "~0.0.0", - "process": "~0.11.0", - "punycode": "^1.3.2", - "querystring-es3": "~0.2.0", - "read-only-stream": "^2.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.1.4", - "shasum": "^1.0.0", - "shell-quote": "^1.6.1", - "stream-browserify": "^2.0.0", - "stream-http": "^2.0.0", - "string_decoder": "^1.1.1", - "subarg": "^1.0.0", - "syntax-error": "^1.1.1", - "through2": "^2.0.0", - "timers-browserify": "^1.0.1", + "JSONStream": "1.3.3", + "assert": "1.4.1", + "browser-pack": "6.1.0", + "browser-resolve": "1.11.2", + "browserify-zlib": "0.2.0", + "buffer": "5.1.0", + "cached-path-relative": "1.0.1", + "concat-stream": "1.6.2", + "console-browserify": "1.1.0", + "constants-browserify": "1.0.0", + "crypto-browserify": "3.12.0", + "defined": "1.0.0", + "deps-sort": "2.0.0", + "domain-browser": "1.2.0", + "duplexer2": "0.1.4", + "events": "2.1.0", + "glob": "7.1.2", + "has": "1.0.3", + "htmlescape": "1.1.1", + "https-browserify": "1.0.0", + "inherits": "2.0.3", + "insert-module-globals": "7.1.0", + "labeled-stream-splicer": "2.0.1", + "mkdirp": "0.5.1", + "module-deps": "6.1.0", + "os-browserify": "0.3.0", + "parents": "1.0.1", + "path-browserify": "0.0.0", + "process": "0.11.10", + "punycode": "1.4.1", + "querystring-es3": "0.2.1", + "read-only-stream": "2.0.0", + "readable-stream": "2.3.6", + "resolve": "1.1.7", + "shasum": "1.0.2", + "shell-quote": "1.6.1", + "stream-browserify": "2.0.1", + "stream-http": "2.8.3", + "string_decoder": "1.1.1", + "subarg": "1.0.0", + "syntax-error": "1.4.0", + "through2": "2.0.3", + "timers-browserify": "1.4.2", "tty-browserify": "0.0.1", - "url": "~0.11.0", - "util": "~0.10.1", - "vm-browserify": "^1.0.0", - "xtend": "^4.0.0" + "url": "0.11.0", + "util": "0.10.4", + "vm-browserify": "1.0.1", + "xtend": "4.0.1" } }, "browserify-aes": { @@ -1492,12 +1492,12 @@ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "buffer-xor": "1.0.3", + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "browserify-cache-api": { @@ -1506,9 +1506,9 @@ "integrity": "sha1-liR+hT8Gj9bg1FzHPwuyzZd47wI=", "dev": true, "requires": { - "async": "^1.5.2", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "async": "1.5.2", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "browserify-cipher": { @@ -1517,9 +1517,9 @@ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" + "browserify-aes": "1.2.0", + "browserify-des": "1.0.1", + "evp_bytestokey": "1.0.3" } }, "browserify-des": { @@ -1528,9 +1528,9 @@ "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1" + "cipher-base": "1.0.4", + "des.js": "1.0.0", + "inherits": "2.0.3" } }, "browserify-incremental": { @@ -1539,10 +1539,10 @@ "integrity": "sha1-BxPLdYckemMqnwjPG9FpuHi2Koo=", "dev": true, "requires": { - "JSONStream": "^0.10.0", - "browserify-cache-api": "^3.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "0.10.0", + "browserify-cache-api": "3.0.1", + "through2": "2.0.3", + "xtend": "4.0.1" }, "dependencies": { "JSONStream": { @@ -1552,7 +1552,7 @@ "dev": true, "requires": { "jsonparse": "0.0.5", - "through": ">=2.2.7 <3" + "through": "2.3.8" } }, "jsonparse": { @@ -1569,8 +1569,8 @@ "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" + "bn.js": "4.11.8", + "randombytes": "2.0.6" } }, "browserify-sign": { @@ -1579,13 +1579,13 @@ "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "elliptic": "6.4.0", + "inherits": "2.0.3", + "parse-asn1": "5.1.1" } }, "browserify-zlib": { @@ -1594,7 +1594,7 @@ "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", "dev": true, "requires": { - "pako": "~1.0.5" + "pako": "1.0.6" } }, "browserslist": { @@ -1603,8 +1603,8 @@ "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" + "caniuse-lite": "1.0.30000849", + "electron-to-chromium": "1.3.48" } }, "buffer": { @@ -1613,8 +1613,8 @@ "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", "dev": true, "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "base64-js": "1.3.0", + "ieee754": "1.1.11" } }, "buffer-from": { @@ -1675,15 +1675,15 @@ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", "dev": true, "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" + "collection-visit": "1.0.0", + "component-emitter": "1.2.1", + "get-value": "2.0.6", + "has-value": "1.0.0", + "isobject": "3.0.1", + "set-value": "2.0.0", + "to-object-path": "0.3.0", + "union-value": "1.0.0", + "unset-value": "1.0.0" }, "dependencies": { "component-emitter": { @@ -1718,8 +1718,8 @@ "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "camelcase": { @@ -1734,8 +1734,8 @@ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { - "camelcase": "^2.0.0", - "map-obj": "^1.0.0" + "camelcase": "2.1.1", + "map-obj": "1.0.1" } }, "caniuse-lite": { @@ -1756,8 +1756,8 @@ "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", "dev": true, "requires": { - "align-text": "^0.1.3", - "lazy-cache": "^1.0.3" + "align-text": "0.1.4", + "lazy-cache": "1.0.4" } }, "chai": { @@ -1766,12 +1766,12 @@ "integrity": "sha1-D2RYS6ZC8PKs4oBiefTwbKI61zw=", "dev": true, "requires": { - "assertion-error": "^1.0.1", - "check-error": "^1.0.1", - "deep-eql": "^3.0.0", - "get-func-name": "^2.0.0", - "pathval": "^1.0.0", - "type-detect": "^4.0.0" + "assertion-error": "1.1.0", + "check-error": "1.0.2", + "deep-eql": "3.0.1", + "get-func-name": "2.0.0", + "pathval": "1.1.0", + "type-detect": "4.0.8" } }, "chalk": { @@ -1780,11 +1780,11 @@ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" + "ansi-styles": "2.2.1", + "escape-string-regexp": "1.0.5", + "has-ansi": "2.0.0", + "strip-ansi": "3.0.1", + "supports-color": "2.0.0" } }, "change-case": { @@ -1793,24 +1793,24 @@ "integrity": "sha512-Mww+SLF6MZ0U6kdg11algyKd5BARbyM4TbFBepwowYSR5ClfQGCGtxNXgykpN0uF/bstWeaGDT4JWaDh8zWAHA==", "dev": true, "requires": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" + "camel-case": "3.0.0", + "constant-case": "2.0.0", + "dot-case": "2.1.1", + "header-case": "1.0.1", + "is-lower-case": "1.1.3", + "is-upper-case": "1.1.2", + "lower-case": "1.1.4", + "lower-case-first": "1.0.2", + "no-case": "2.3.2", + "param-case": "2.1.1", + "pascal-case": "2.0.1", + "path-case": "2.1.1", + "sentence-case": "2.1.1", + "snake-case": "2.1.0", + "swap-case": "1.1.2", + "title-case": "2.1.1", + "upper-case": "1.1.3", + "upper-case-first": "1.1.2" } }, "check-error": { @@ -1825,15 +1825,15 @@ "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", "dev": true, "requires": { - "anymatch": "^1.3.0", - "async-each": "^1.0.0", - "fsevents": "^1.0.0", - "glob-parent": "^2.0.0", - "inherits": "^2.0.1", - "is-binary-path": "^1.0.0", - "is-glob": "^2.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0" + "anymatch": "1.3.2", + "async-each": "1.0.1", + "fsevents": "1.2.4", + "glob-parent": "2.0.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "2.0.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0" } }, "cipher-base": { @@ -1842,8 +1842,8 @@ "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "circular-json": { @@ -1858,10 +1858,10 @@ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", "dev": true, "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" + "arr-union": "3.1.0", + "define-property": "0.2.5", + "isobject": "3.0.1", + "static-extend": "0.1.2" }, "dependencies": { "define-property": { @@ -1870,7 +1870,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "isobject": { @@ -1887,8 +1887,8 @@ "integrity": "sha1-vxlF6C/ICPVWlebd6uwBQA79A/8=", "dev": true, "requires": { - "commander": "2.8.x", - "source-map": "0.4.x" + "commander": "2.8.1", + "source-map": "0.4.4" }, "dependencies": { "commander": { @@ -1897,7 +1897,7 @@ "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, "requires": { - "graceful-readlink": ">= 1.0.0" + "graceful-readlink": "1.0.1" } }, "source-map": { @@ -1906,7 +1906,7 @@ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", "dev": true, "requires": { - "amdefine": ">=0.0.4" + "amdefine": "1.0.1" } } } @@ -1917,8 +1917,8 @@ "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", "dev": true, "requires": { - "center-align": "^0.1.1", - "right-align": "^0.1.1", + "center-align": "0.1.3", + "right-align": "0.1.3", "wordwrap": "0.0.2" } }, @@ -1940,8 +1940,8 @@ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", "dev": true, "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" + "map-visit": "1.0.0", + "object-visit": "1.0.1" } }, "color-convert": { @@ -1950,7 +1950,7 @@ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", "dev": true, "requires": { - "color-name": "^1.1.1" + "color-name": "1.1.3" } }, "color-name": { @@ -1971,7 +1971,7 @@ "integrity": "sha1-RYwH4J4NkA/Ci3Cj/sLazR0st/Y=", "dev": true, "requires": { - "lodash": "^4.5.0" + "lodash": "4.17.10" } }, "combine-source-map": { @@ -1980,10 +1980,10 @@ "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", "dev": true, "requires": { - "convert-source-map": "~1.1.0", - "inline-source-map": "~0.6.0", - "lodash.memoize": "~3.0.3", - "source-map": "~0.5.3" + "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": { @@ -2000,7 +2000,7 @@ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", "dev": true, "requires": { - "delayed-stream": "~1.0.0" + "delayed-stream": "1.0.0" } }, "commander": { @@ -2033,10 +2033,10 @@ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" + "buffer-from": "1.1.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "typedarray": "0.0.6" } }, "connect": { @@ -2047,7 +2047,7 @@ "requires": { "debug": "2.6.9", "finalhandler": "1.1.0", - "parseurl": "~1.3.2", + "parseurl": "1.3.2", "utils-merge": "1.0.1" } }, @@ -2057,7 +2057,7 @@ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", "dev": true, "requires": { - "date-now": "^0.1.4" + "date-now": "0.1.4" } }, "constant-case": { @@ -2066,8 +2066,8 @@ "integrity": "sha1-QXV2TTidP6nI7NKRhu1gBSQ7akY=", "dev": true, "requires": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" + "snake-case": "2.1.0", + "upper-case": "1.1.3" } }, "constants-browserify": { @@ -2124,8 +2124,8 @@ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" + "bn.js": "4.11.8", + "elliptic": "6.4.0" } }, "create-hash": { @@ -2134,11 +2134,11 @@ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" + "cipher-base": "1.0.4", + "inherits": "2.0.3", + "md5.js": "1.3.4", + "ripemd160": "2.0.2", + "sha.js": "2.4.11" } }, "create-hmac": { @@ -2147,12 +2147,12 @@ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "cipher-base": "1.0.4", + "create-hash": "1.2.0", + "inherits": "2.0.3", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" } }, "cross-spawn": { @@ -2161,7 +2161,7 @@ "integrity": "sha1-vWf5bAfvtjA7f+lMHpefiEeOCjk=", "dev": true, "requires": { - "lru-cache": "^2.5.0" + "lru-cache": "2.7.3" } }, "cryptiles": { @@ -2171,7 +2171,7 @@ "dev": true, "optional": true, "requires": { - "boom": "2.x.x" + "boom": "2.10.1" } }, "crypto-browserify": { @@ -2180,17 +2180,17 @@ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" + "browserify-cipher": "1.0.1", + "browserify-sign": "4.0.4", + "create-ecdh": "4.0.3", + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "diffie-hellman": "5.0.3", + "inherits": "2.0.3", + "pbkdf2": "3.0.16", + "public-encrypt": "4.0.2", + "randombytes": "2.0.6", + "randomfill": "1.0.4" } }, "currently-unhandled": { @@ -2199,7 +2199,7 @@ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", "dev": true, "requires": { - "array-find-index": "^1.0.1" + "array-find-index": "1.0.2" } }, "custom-event": { @@ -2214,7 +2214,7 @@ "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "dashdash": { @@ -2223,7 +2223,7 @@ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "data-uri-to-buffer": { @@ -2251,8 +2251,8 @@ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=", "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.3.0" + "get-stdin": "4.0.1", + "meow": "3.7.0" } }, "debug": { @@ -2282,7 +2282,7 @@ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", "dev": true, "requires": { - "type-detect": "^4.0.0" + "type-detect": "4.0.8" } }, "deep-is": { @@ -2298,8 +2298,8 @@ "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", "dev": true, "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" + "foreach": "2.0.5", + "object-keys": "1.0.11" } }, "define-property": { @@ -2308,8 +2308,8 @@ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", "dev": true, "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "is-descriptor": "1.0.2", + "isobject": "3.0.1" }, "dependencies": { "is-accessor-descriptor": { @@ -2318,7 +2318,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -2327,7 +2327,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -2336,9 +2336,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -2368,9 +2368,9 @@ "dev": true, "optional": true, "requires": { - "ast-types": "0.x.x", - "escodegen": "1.x.x", - "esprima": "3.x.x" + "ast-types": "0.11.5", + "escodegen": "1.11.0", + "esprima": "3.1.3" }, "dependencies": { "esprima": { @@ -2400,10 +2400,10 @@ "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "shasum": "^1.0.0", - "subarg": "^1.0.0", - "through2": "^2.0.0" + "JSONStream": "1.3.3", + "shasum": "1.0.2", + "subarg": "1.0.0", + "through2": "2.0.3" } }, "des.js": { @@ -2412,8 +2412,8 @@ "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true, "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "destroy": { @@ -2428,7 +2428,7 @@ "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "detective": { @@ -2437,9 +2437,9 @@ "integrity": "sha512-TFHMqfOvxlgrfVzTEkNBSh9SvSNX/HfF4OFI2QFGCyPm02EsyILqnUeb5P6q7JZ3SFNTBL5t2sePRgrN4epUWQ==", "dev": true, "requires": { - "acorn-node": "^1.3.0", - "defined": "^1.0.0", - "minimist": "^1.1.1" + "acorn-node": "1.3.0", + "defined": "1.0.0", + "minimist": "1.2.0" }, "dependencies": { "minimist": { @@ -2468,9 +2468,9 @@ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" + "bn.js": "4.11.8", + "miller-rabin": "4.0.1", + "randombytes": "2.0.6" } }, "dom-serialize": { @@ -2479,10 +2479,10 @@ "integrity": "sha1-ViromZ9Evl6jB29UGdzVnrQ6yVs=", "dev": true, "requires": { - "custom-event": "~1.0.0", - "ent": "~2.2.0", - "extend": "^3.0.0", - "void-elements": "^2.0.0" + "custom-event": "1.0.1", + "ent": "2.2.0", + "extend": "3.0.1", + "void-elements": "2.0.1" } }, "domain-browser": { @@ -2497,7 +2497,7 @@ "integrity": "sha1-NNzzf1Co6TwrO8qLt/uRVcfaO+4=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "double-ended-queue": { @@ -2513,7 +2513,7 @@ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", "dev": true, "requires": { - "readable-stream": "^2.0.2" + "readable-stream": "2.3.6" } }, "ecc-jsbn": { @@ -2523,7 +2523,7 @@ "dev": true, "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "0.1.1" } }, "ee-first": { @@ -2544,13 +2544,13 @@ "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", "dev": true, "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" + "bn.js": "4.11.8", + "brorand": "1.1.0", + "hash.js": "1.1.3", + "hmac-drbg": "1.0.1", + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" } }, "encodeurl": { @@ -2571,8 +2571,8 @@ "integrity": "sha1-pfdf/02ZJhJt2sDqXcOOaJFTywI=", "dev": true, "requires": { - "string-template": "~0.2.1", - "xtend": "~4.0.0" + "string-template": "0.2.1", + "xtend": "4.0.1" } }, "error-ex": { @@ -2581,7 +2581,7 @@ "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", "dev": true, "requires": { - "is-arrayish": "^0.2.1" + "is-arrayish": "0.2.1" } }, "es6-promise": { @@ -2596,7 +2596,7 @@ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { - "es6-promise": "^4.0.3" + "es6-promise": "4.2.4" } }, "escape-html": { @@ -2618,11 +2618,11 @@ "dev": true, "optional": true, "requires": { - "esprima": "^3.1.3", - "estraverse": "^4.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" + "esprima": "3.1.3", + "estraverse": "4.2.0", + "esutils": "2.0.2", + "optionator": "0.8.2", + "source-map": "0.6.1" }, "dependencies": { "esprima": { @@ -2690,8 +2690,8 @@ "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", "dev": true, "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" + "md5.js": "1.3.4", + "safe-buffer": "5.1.2" } }, "exit": { @@ -2706,9 +2706,9 @@ "integrity": "sha1-SIsdHSRRyz06axks/AMPRMWFX+o=", "dev": true, "requires": { - "array-slice": "^0.2.3", - "array-unique": "^0.2.1", - "braces": "^0.1.2" + "array-slice": "0.2.3", + "array-unique": "0.2.1", + "braces": "0.1.5" }, "dependencies": { "braces": { @@ -2717,7 +2717,7 @@ "integrity": "sha1-wIVxEIUpHYt1/ddOqw+FlygHEeY=", "dev": true, "requires": { - "expand-range": "^0.1.0" + "expand-range": "0.1.1" } }, "expand-range": { @@ -2726,8 +2726,8 @@ "integrity": "sha1-TLjtoJk8pW+k9B/ELzy7TMrf8EQ=", "dev": true, "requires": { - "is-number": "^0.1.1", - "repeat-string": "^0.2.2" + "is-number": "0.1.1", + "repeat-string": "0.2.2" } }, "is-number": { @@ -2750,7 +2750,7 @@ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", "dev": true, "requires": { - "is-posix-bracket": "^0.1.0" + "is-posix-bracket": "0.1.1" } }, "expand-range": { @@ -2759,7 +2759,7 @@ "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", "dev": true, "requires": { - "fill-range": "^2.1.0" + "fill-range": "2.2.4" } }, "extend": { @@ -2774,8 +2774,8 @@ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" + "assign-symbols": "1.0.0", + "is-extendable": "1.0.1" }, "dependencies": { "is-extendable": { @@ -2784,7 +2784,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "^2.0.4" + "is-plain-object": "2.0.4" } } } @@ -2795,7 +2795,7 @@ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "extract-zip": { @@ -2841,7 +2841,7 @@ "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", "dev": true, "requires": { - "websocket-driver": ">=0.5.1" + "websocket-driver": "0.7.0" } }, "fd-slicer": { @@ -2850,7 +2850,7 @@ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", "dev": true, "requires": { - "pend": "~1.2.0" + "pend": "1.2.0" } }, "figures": { @@ -2859,8 +2859,8 @@ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "1.0.5", + "object-assign": "4.1.1" } }, "file-sync-cmp": { @@ -2888,11 +2888,11 @@ "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", "dev": true, "requires": { - "is-number": "^2.1.0", - "isobject": "^2.0.0", - "randomatic": "^3.0.0", - "repeat-element": "^1.1.2", - "repeat-string": "^1.5.2" + "is-number": "2.1.0", + "isobject": "2.1.0", + "randomatic": "3.0.0", + "repeat-element": "1.1.2", + "repeat-string": "1.6.1" } }, "finalhandler": { @@ -2902,12 +2902,12 @@ "dev": true, "requires": { "debug": "2.6.9", - "encodeurl": "~1.0.1", - "escape-html": "~1.0.3", - "on-finished": "~2.3.0", - "parseurl": "~1.3.2", - "statuses": "~1.3.1", - "unpipe": "~1.0.0" + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "on-finished": "2.3.0", + "parseurl": "1.3.2", + "statuses": "1.3.1", + "unpipe": "1.0.0" }, "dependencies": { "statuses": { @@ -2924,8 +2924,8 @@ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", "dev": true, "requires": { - "path-exists": "^2.0.0", - "pinkie-promise": "^2.0.0" + "path-exists": "2.1.0", + "pinkie-promise": "2.0.1" } }, "findup-sync": { @@ -2934,7 +2934,7 @@ "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", "dev": true, "requires": { - "glob": "~5.0.0" + "glob": "5.0.15" }, "dependencies": { "glob": { @@ -2943,11 +2943,11 @@ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", "dev": true, "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^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" } } } @@ -2958,7 +2958,7 @@ "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", "dev": true, "requires": { - "debug": "^3.1.0" + "debug": "3.1.0" }, "dependencies": { "debug": { @@ -2984,7 +2984,7 @@ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", "dev": true, "requires": { - "for-in": "^1.0.1" + "for-in": "1.0.2" } }, "foreach": { @@ -3005,9 +3005,9 @@ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", "dev": true, "requires": { - "asynckit": "^0.4.0", + "asynckit": "0.4.0", "combined-stream": "1.0.6", - "mime-types": "^2.1.12" + "mime-types": "2.1.18" } }, "fragment-cache": { @@ -3016,7 +3016,7 @@ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", "dev": true, "requires": { - "map-cache": "^0.2.2" + "map-cache": "0.2.2" } }, "fresh": { @@ -3031,9 +3031,9 @@ "integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0" + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0", + "klaw": "1.3.1" } }, "fs-readdir-recursive": { @@ -3055,81 +3055,93 @@ "dev": true, "optional": true, "requires": { - "nan": "^2.9.2", - "node-pre-gyp": "^0.10.0" + "nan": "2.11.0", + "node-pre-gyp": "0.10.0" }, "dependencies": { "abbrev": { "version": "1.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true, "optional": true }, "ansi-regex": { "version": "2.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", "dev": true }, "aproba": { "version": "1.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", "dev": true, "optional": true }, "are-we-there-yet": { "version": "1.1.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz", + "integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=", "dev": true, "optional": true, "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "delegates": "1.0.0", + "readable-stream": "2.3.6" } }, "balanced-match": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", "dev": true }, "brace-expansion": { "version": "1.1.11", - "bundled": true, + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, "requires": { - "balanced-match": "^1.0.0", + "balanced-match": "1.0.0", "concat-map": "0.0.1" } }, "chownr": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", "dev": true, "optional": true }, "code-point-at": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", "dev": true }, "concat-map": { "version": "0.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, "console-control-strings": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, "core-util-is": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", "dev": true, "optional": true }, "debug": { "version": "2.6.9", - "bundled": true, + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "optional": true, "requires": { @@ -3138,160 +3150,180 @@ }, "deep-extend": { "version": "0.5.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz", + "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w==", "dev": true, "optional": true }, "delegates": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", "dev": true, "optional": true }, "detect-libc": { "version": "1.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", "dev": true, "optional": true }, "fs-minipass": { "version": "1.2.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "2.2.4" } }, "fs.realpath": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true, "optional": true }, "gauge": { "version": "2.7.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", "dev": true, "optional": true, "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" + "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, + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "dev": true, "optional": 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" + "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, + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", "dev": true, "optional": true }, "iconv-lite": { "version": "0.4.21", - "bundled": true, + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.21.tgz", + "integrity": "sha512-En5V9za5mBt2oUA03WGD3TwDv0MKAruqsuxstbMUZaj9W9k/m1CV/9py3l0L5kw9Bln8fdHQmzHSYtvpvTLpKw==", "dev": true, "optional": true, "requires": { - "safer-buffer": "^2.1.0" + "safer-buffer": "2.1.2" } }, "ignore-walk": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", "dev": true, "optional": true, "requires": { - "minimatch": "^3.0.4" + "minimatch": "3.0.4" } }, "inflight": { "version": "1.0.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "optional": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { "version": "2.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, "ini": { "version": "1.3.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", "dev": true, "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "isarray": { "version": "1.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", "dev": true, "optional": true }, "minimatch": { "version": "3.0.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { "version": "0.0.8", - "bundled": true, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", "dev": true }, "minipass": { "version": "2.2.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.2.4.tgz", + "integrity": "sha512-hzXIWWet/BzWhYs2b+u7dRHlruXhwdgvlTMDKC6Cb1U7ps6Ac6yQlR39xsbjWJE377YTCtKwIXIpJ5oP+j5y8g==", "dev": true, "requires": { - "safe-buffer": "^5.1.1", - "yallist": "^3.0.0" + "safe-buffer": "5.1.1", + "yallist": "3.0.2" } }, "minizlib": { "version": "1.1.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", + "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", "dev": true, "optional": true, "requires": { - "minipass": "^2.2.1" + "minipass": "2.2.4" } }, "mkdirp": { "version": "0.5.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "dev": true, "requires": { "minimist": "0.0.8" @@ -3299,145 +3331,162 @@ }, "ms": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", "dev": true, "optional": true }, "needle": { "version": "2.2.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/needle/-/needle-2.2.0.tgz", + "integrity": "sha512-eFagy6c+TYayorXw/qtAdSvaUpEbBsDwDyxYFgLZ0lTojfH7K+OdBqAF7TAFwDokJaGpubpSGG0wO3iC0XPi8w==", "dev": true, "optional": true, "requires": { - "debug": "^2.1.2", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" + "debug": "2.6.9", + "iconv-lite": "0.4.21", + "sax": "1.2.4" } }, "node-pre-gyp": { "version": "0.10.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.10.0.tgz", + "integrity": "sha512-G7kEonQLRbcA/mOoFoxvlMrw6Q6dPf92+t/l0DFSMuSlDoWaI9JWIyPwK0jyE1bph//CUEL65/Fz1m2vJbmjQQ==", "dev": true, "optional": true, "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.1.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" + "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, + "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.1.tgz", + "integrity": "sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=", "dev": true, "optional": true, "requires": { - "abbrev": "1", - "osenv": "^0.1.4" + "abbrev": "1.1.1", + "osenv": "0.1.5" } }, "npm-bundled": { "version": "1.0.3", - "bundled": true, + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.3.tgz", + "integrity": "sha512-ByQ3oJ/5ETLyglU2+8dBObvhfWXX8dtPZDMePCahptliFX2iIuhyEszyFk401PZUNQH20vvdW5MLjJxkwU80Ow==", "dev": true, "optional": true }, "npm-packlist": { "version": "1.1.10", - "bundled": true, + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.1.10.tgz", + "integrity": "sha512-AQC0Dyhzn4EiYEfIUjCdMl0JJ61I2ER9ukf/sLxJUcZHfo+VyEfz2rMJgLZSS1v30OxPQe1cN0LZA1xbcaVfWA==", "dev": true, "optional": true, "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" + "ignore-walk": "3.0.1", + "npm-bundled": "1.0.3" } }, "npmlog": { "version": "4.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", "dev": true, "optional": true, "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" + "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, + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", "dev": true }, "object-assign": { "version": "4.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", "dev": true, "optional": true }, "once": { "version": "1.4.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "os-homedir": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true, "optional": true }, "os-tmpdir": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true, "optional": true }, "osenv": { "version": "0.1.5", - "bundled": true, + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", "dev": true, "optional": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "path-is-absolute": { "version": "1.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true, "optional": true }, "process-nextick-args": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", "dev": true, "optional": true }, "rc": { "version": "1.2.7", - "bundled": true, + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz", + "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==", "dev": true, "optional": true, "requires": { - "deep-extend": "^0.5.1", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" + "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, + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true, "optional": true } @@ -3445,134 +3494,151 @@ }, "readable-stream": { "version": "2.3.6", - "bundled": true, + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "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.1" + "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, + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "optional": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "safe-buffer": { "version": "5.1.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", "dev": true }, "safer-buffer": { "version": "2.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true, "optional": true }, "sax": { "version": "1.2.4", - "bundled": true, + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", "dev": true, "optional": true }, "semver": { "version": "5.5.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", "dev": true, "optional": true }, "set-blocking": { "version": "2.0.0", - "bundled": true, + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true, "optional": true }, "signal-exit": { "version": "3.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true, "optional": true }, "string-width": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "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, + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "optional": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.1" } }, "strip-ansi": { "version": "3.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-json-comments": { "version": "2.0.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", "dev": true, "optional": true }, "tar": { "version": "4.4.1", - "bundled": true, + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.1.tgz", + "integrity": "sha512-O+v1r9yN4tOsvl90p5HAP4AEqbYhx4036AGMm075fH9F8Qwi3oJ+v4u50FkT/KkvywNGtwkk0zRI+8eYm1X/xg==", "dev": true, "optional": true, "requires": { - "chownr": "^1.0.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.2.4", - "minizlib": "^1.1.0", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.1", - "yallist": "^3.0.2" + "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, + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", "dev": true, "optional": true }, "wide-align": { "version": "1.1.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "dev": true, "optional": true, "requires": { - "string-width": "^1.0.2" + "string-width": "1.0.2" } }, "wrappy": { "version": "1.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, "yallist": { "version": "3.0.2", - "bundled": true, + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.2.tgz", + "integrity": "sha1-hFK0u36Dx8GI2AQcGoN8dz1ti7k=", "dev": true } } @@ -3584,7 +3650,7 @@ "dev": true, "optional": true, "requires": { - "readable-stream": "1.1.x", + "readable-stream": "1.1.14", "xregexp": "2.0.0" }, "dependencies": { @@ -3602,10 +3668,10 @@ "dev": true, "optional": true, "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", + "core-util-is": "1.0.2", + "inherits": "2.0.3", "isarray": "0.0.1", - "string_decoder": "~0.10.x" + "string_decoder": "0.10.31" } }, "string_decoder": { @@ -3629,7 +3695,7 @@ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==", "dev": true, "requires": { - "globule": "^1.0.0" + "globule": "1.2.1" } }, "generate-function": { @@ -3639,7 +3705,7 @@ "dev": true, "optional": true, "requires": { - "is-property": "^1.0.2" + "is-property": "1.0.2" } }, "generate-object-property": { @@ -3649,7 +3715,7 @@ "dev": true, "optional": true, "requires": { - "is-property": "^1.0.0" + "is-property": "1.0.2" } }, "get-func-name": { @@ -3671,12 +3737,12 @@ "dev": true, "optional": true, "requires": { - "data-uri-to-buffer": "1", - "debug": "2", - "extend": "3", - "file-uri-to-path": "1", - "ftp": "~0.3.10", - "readable-stream": "2" + "data-uri-to-buffer": "1.2.0", + "debug": "2.6.9", + "extend": "3.0.1", + "file-uri-to-path": "1.0.0", + "ftp": "0.3.10", + "readable-stream": "2.3.6" } }, "get-value": { @@ -3697,7 +3763,7 @@ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", "dev": true, "requires": { - "assert-plus": "^1.0.0" + "assert-plus": "1.0.0" } }, "glob": { @@ -3706,12 +3772,12 @@ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "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" + "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" } }, "glob-base": { @@ -3720,8 +3786,8 @@ "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", "dev": true, "requires": { - "glob-parent": "^2.0.0", - "is-glob": "^2.0.0" + "glob-parent": "2.0.0", + "is-glob": "2.0.1" } }, "glob-parent": { @@ -3730,7 +3796,7 @@ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", "dev": true, "requires": { - "is-glob": "^2.0.0" + "is-glob": "2.0.1" } }, "globals": { @@ -3745,9 +3811,9 @@ "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==", "dev": true, "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" + "glob": "7.1.2", + "lodash": "4.17.10", + "minimatch": "3.0.4" } }, "graceful-fs": { @@ -3774,23 +3840,23 @@ "integrity": "sha512-/JzmZNPfKorlCrrmxWqQO4JVodO+DVd5XX4DkocL/1WlLlKVLE9+SdEIempOAxDhWPysLle6afvn/hg7Ck2k9g==", "dev": true, "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", - "eventemitter2": "~0.4.13", - "exit": "~0.1.1", - "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", - "iconv-lite": "~0.4.13", - "js-yaml": "~3.5.2", - "minimatch": "~3.0.2", - "mkdirp": "~0.5.1", - "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" + "coffeescript": "1.10.0", + "dateformat": "1.0.12", + "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": "2.0.0", + "grunt-legacy-util": "1.1.1", + "iconv-lite": "0.4.23", + "js-yaml": "3.5.5", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "nopt": "3.0.6", + "path-is-absolute": "1.0.1", + "rimraf": "2.6.2" }, "dependencies": { "glob": { @@ -3799,12 +3865,12 @@ "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.2", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" + "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": { @@ -3813,10 +3879,10 @@ "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", "dev": true, "requires": { - "findup-sync": "~0.3.0", - "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" + "findup-sync": "0.3.0", + "grunt-known-options": "1.1.0", + "nopt": "3.0.6", + "resolve": "1.1.7" } } } @@ -3827,7 +3893,7 @@ "integrity": "sha1-EJYDorlf8BAZtxjHA0EmjwnYvhk=", "dev": true, "requires": { - "html-minifier": "~2.1.2" + "html-minifier": "2.1.7" } }, "grunt-babel": { @@ -3836,7 +3902,7 @@ "integrity": "sha1-N4GJtIfeEWjExKn8iN1gBbNd+WA=", "dev": true, "requires": { - "babel-core": "^6.0.12" + "babel-core": "6.26.3" } }, "grunt-browserify": { @@ -3845,13 +3911,13 @@ "integrity": "sha1-R/2M+LrFj+LeaDr9xX9/OoDKeS0=", "dev": true, "requires": { - "async": "^2.5.0", - "browserify": "^16.0.0", - "browserify-incremental": "^3.1.1", - "glob": "^7.1.2", - "lodash": "^4.17.4", - "resolve": "^1.1.6", - "watchify": "^3.6.1" + "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": { @@ -3860,7 +3926,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } } } @@ -3871,8 +3937,8 @@ "integrity": "sha1-YVCYYwhOhx1+ht5IwBUlntl3Rb0=", "dev": true, "requires": { - "chalk": "^1.0.0", - "source-map": "^0.5.3" + "chalk": "1.1.3", + "source-map": "0.5.7" } }, "grunt-contrib-copy": { @@ -3881,8 +3947,8 @@ "integrity": "sha1-cGDGWB6QS4qw0A8HbgqPbj58NXM=", "dev": true, "requires": { - "chalk": "^1.1.1", - "file-sync-cmp": "^0.1.0" + "chalk": "1.1.3", + "file-sync-cmp": "0.1.1" } }, "grunt-contrib-cssmin": { @@ -3891,9 +3957,9 @@ "integrity": "sha1-FzTL09hMpzZHWLflj/GOUqpgu3Y=", "dev": true, "requires": { - "chalk": "^1.0.0", - "clean-css": "~3.4.2", - "maxmin": "^1.1.0" + "chalk": "1.1.3", + "clean-css": "3.4.28", + "maxmin": "1.1.0" } }, "grunt-contrib-sass": { @@ -3902,11 +3968,11 @@ "integrity": "sha1-gGg4JRy8DhqU1k1RXN00z2dNcBs=", "dev": true, "requires": { - "async": "^0.9.0", - "chalk": "^1.0.0", - "cross-spawn": "^0.2.3", - "dargs": "^4.0.0", - "which": "^1.0.5" + "async": "0.9.2", + "chalk": "1.1.3", + "cross-spawn": "0.2.9", + "dargs": "4.1.0", + "which": "1.3.1" }, "dependencies": { "async": { @@ -3923,11 +3989,11 @@ "integrity": "sha1-s9AmDr3WzvoS/y+Onh4ln33kIW8=", "dev": true, "requires": { - "chalk": "^1.0.0", - "maxmin": "^1.1.0", - "object.assign": "^4.0.4", - "uglify-js": "~2.8.21", - "uri-path": "^1.0.0" + "chalk": "1.1.3", + "maxmin": "1.1.0", + "object.assign": "4.1.0", + "uglify-js": "2.8.29", + "uri-path": "1.0.0" }, "dependencies": { "uglify-js": { @@ -3936,9 +4002,9 @@ "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", "dev": true, "requires": { - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" } } } @@ -3949,10 +4015,10 @@ "integrity": "sha512-yGweN+0DW5yM+oo58fRu/XIRrPcn3r4tQx+nL7eMRwjpvk+rQY6R8o94BPK0i2UhTg9FN21hS+m8vR8v9vXfeg==", "dev": true, "requires": { - "async": "^2.6.0", - "gaze": "^1.1.0", - "lodash": "^4.17.10", - "tiny-lr": "^1.1.1" + "async": "2.6.1", + "gaze": "1.1.3", + "lodash": "4.17.10", + "tiny-lr": "1.1.1" }, "dependencies": { "async": { @@ -3961,7 +4027,7 @@ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", "dev": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } } } @@ -3972,7 +4038,7 @@ "integrity": "sha1-b7W9R+JQ3Q9VzS76kj7kMQFEFCM=", "dev": true, "requires": { - "dargs": "~0.1.0" + "dargs": "0.1.0" }, "dependencies": { "dargs": { @@ -3995,10 +4061,10 @@ "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", "dev": true, "requires": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.5" + "colors": "1.1.2", + "grunt-legacy-log-utils": "2.0.1", + "hooker": "0.2.3", + "lodash": "4.17.10" } }, "grunt-legacy-log-utils": { @@ -4007,8 +4073,8 @@ "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", "dev": true, "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" + "chalk": "2.4.1", + "lodash": "4.17.10" }, "dependencies": { "ansi-styles": { @@ -4017,7 +4083,7 @@ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, "requires": { - "color-convert": "^1.9.0" + "color-convert": "1.9.1" } }, "chalk": { @@ -4026,9 +4092,9 @@ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", "dev": true, "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "ansi-styles": "3.2.1", + "escape-string-regexp": "1.0.5", + "supports-color": "5.4.0" } }, "supports-color": { @@ -4037,7 +4103,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -4048,13 +4114,13 @@ "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", "dev": true, "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" + "async": "1.5.2", + "exit": "0.1.2", + "getobject": "0.1.0", + "hooker": "0.2.3", + "lodash": "4.17.10", + "underscore.string": "3.3.4", + "which": "1.3.1" } }, "grunt-newer": { @@ -4063,8 +4129,8 @@ "integrity": "sha1-g8y3od2ny9irI7BZAk6+YUrS80I=", "dev": true, "requires": { - "async": "^1.5.2", - "rimraf": "^2.5.2" + "async": "1.5.2", + "rimraf": "2.6.2" } }, "grunt-ng-annotate": { @@ -4073,8 +4139,18 @@ "integrity": "sha1-dqKiGha6Y+Vve+G3XuXErZMCeTk=", "dev": true, "requires": { - "lodash.clonedeep": "^4.5.0", - "ng-annotate": "^1.2.1" + "lodash.clonedeep": "4.5.0", + "ng-annotate": "1.2.2" + } + }, + "grunt-shell": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/grunt-shell/-/grunt-shell-2.1.0.tgz", + "integrity": "sha1-Q595FZ7RHmSmUaacyKPQK+v17MI=", + "dev": true, + "requires": { + "chalk": "1.1.3", + "npm-run-path": "2.0.2" } }, "gzip-size": { @@ -4083,8 +4159,8 @@ "integrity": "sha1-Zs+LEBBHInuVus5uodoMF37Vwi8=", "dev": true, "requires": { - "browserify-zlib": "^0.1.4", - "concat-stream": "^1.4.1" + "browserify-zlib": "0.1.4", + "concat-stream": "1.6.2" }, "dependencies": { "browserify-zlib": { @@ -4093,7 +4169,7 @@ "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", "dev": true, "requires": { - "pako": "~0.2.0" + "pako": "0.2.9" } }, "pako": { @@ -4116,8 +4192,8 @@ "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", "dev": true, "requires": { - "ajv": "^5.1.0", - "har-schema": "^2.0.0" + "ajv": "5.5.2", + "har-schema": "2.0.0" } }, "has": { @@ -4126,7 +4202,7 @@ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", "dev": true, "requires": { - "function-bind": "^1.1.1" + "function-bind": "1.1.1" } }, "has-ansi": { @@ -4135,7 +4211,7 @@ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "has-binary2": { @@ -4179,9 +4255,9 @@ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", "dev": true, "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" + "get-value": "2.0.6", + "has-values": "1.0.0", + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -4198,8 +4274,8 @@ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", "dev": true, "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" + "is-number": "3.0.0", + "kind-of": "4.0.0" }, "dependencies": { "is-number": { @@ -4208,7 +4284,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -4217,7 +4293,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -4228,7 +4304,7 @@ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -4239,8 +4315,8 @@ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "hash.js": { @@ -4249,8 +4325,8 @@ "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", "dev": true, "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "inherits": "2.0.3", + "minimalistic-assert": "1.0.1" } }, "hasha": { @@ -4259,8 +4335,8 @@ "integrity": "sha1-eNfL/B5tZjA/55g3NlmEUXsvbuE=", "dev": true, "requires": { - "is-stream": "^1.0.1", - "pinkie-promise": "^2.0.0" + "is-stream": "1.1.0", + "pinkie-promise": "2.0.1" } }, "hawk": { @@ -4270,10 +4346,10 @@ "dev": true, "optional": true, "requires": { - "boom": "2.x.x", - "cryptiles": "2.x.x", - "hoek": "2.x.x", - "sntp": "1.x.x" + "boom": "2.10.1", + "cryptiles": "2.0.5", + "hoek": "2.16.3", + "sntp": "1.0.9" } }, "he": { @@ -4288,8 +4364,8 @@ "integrity": "sha1-lTWXMZfBRLCWE81l0xfvGZY70C0=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "hipchat-notifier": { @@ -4299,8 +4375,8 @@ "dev": true, "optional": true, "requires": { - "lodash": "^4.0.0", - "request": "^2.0.0" + "lodash": "4.17.10", + "request": "2.87.0" } }, "hmac-drbg": { @@ -4309,9 +4385,9 @@ "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", "dev": true, "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" + "hash.js": "1.1.3", + "minimalistic-assert": "1.0.1", + "minimalistic-crypto-utils": "1.0.1" } }, "hoek": { @@ -4326,8 +4402,8 @@ "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", "dev": true, "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" + "os-homedir": "1.0.2", + "os-tmpdir": "1.0.2" } }, "hooker": { @@ -4348,13 +4424,13 @@ "integrity": "sha1-kFHW/LvPIU7TB+GtdPQyu5rWVcw=", "dev": true, "requires": { - "change-case": "3.0.x", - "clean-css": "3.4.x", - "commander": "2.9.x", - "he": "1.1.x", - "ncname": "1.0.x", - "relateurl": "0.2.x", - "uglify-js": "2.6.x" + "change-case": "3.0.2", + "clean-css": "3.4.28", + "commander": "2.9.0", + "he": "1.1.1", + "ncname": "1.0.0", + "relateurl": "0.2.7", + "uglify-js": "2.6.4" }, "dependencies": { "commander": { @@ -4363,7 +4439,7 @@ "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, "requires": { - "graceful-readlink": ">= 1.0.0" + "graceful-readlink": "1.0.1" } } } @@ -4380,10 +4456,10 @@ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { - "depd": "~1.1.2", + "depd": "1.1.2", "inherits": "2.0.3", "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" + "statuses": "1.5.0" } }, "http-parser-js": { @@ -4398,9 +4474,9 @@ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", "dev": true, "requires": { - "eventemitter3": "^3.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" + "eventemitter3": "3.1.0", + "follow-redirects": "1.5.0", + "requires-port": "1.0.0" } }, "http-proxy-agent": { @@ -4409,7 +4485,7 @@ "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", "dev": true, "requires": { - "agent-base": "4", + "agent-base": "4.2.1", "debug": "3.1.0" }, "dependencies": { @@ -4430,9 +4506,9 @@ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", "dev": true, "requires": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "1.0.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" } }, "httpntlm": { @@ -4441,8 +4517,8 @@ "integrity": "sha1-rQFScUOi6Hc8+uapb1hla7UqNLI=", "dev": true, "requires": { - "httpreq": ">=0.4.22", - "underscore": "~1.7.0" + "httpreq": "0.4.24", + "underscore": "1.7.0" } }, "httpreq": { @@ -4463,8 +4539,8 @@ "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", "dev": true, "requires": { - "agent-base": "^4.1.0", - "debug": "^3.1.0" + "agent-base": "4.2.1", + "debug": "3.1.0" }, "dependencies": { "debug": { @@ -4484,7 +4560,7 @@ "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", "dev": true, "requires": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": "2.1.2" } }, "ieee754": { @@ -4499,7 +4575,7 @@ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", "dev": true, "requires": { - "repeating": "^2.0.0" + "repeating": "2.0.1" } }, "indexof": { @@ -4521,8 +4597,8 @@ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", "dev": true, "requires": { - "once": "^1.3.0", - "wrappy": "1" + "once": "1.4.0", + "wrappy": "1.0.2" } }, "inherits": { @@ -4537,7 +4613,7 @@ "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", "dev": true, "requires": { - "source-map": "~0.5.3" + "source-map": "0.5.7" } }, "insert-module-globals": { @@ -4546,15 +4622,15 @@ "integrity": "sha512-LbYZdybvKjbbcKLp03lB323Cgc8f0iL0Rjh8U6JZ7K1gZSf7MxQH191iCNUcLX4qIQ6/yWe4Q4ZsQ+opcReNFg==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "combine-source-map": "^0.8.0", - "concat-stream": "^1.6.1", - "is-buffer": "^1.1.0", - "lexical-scope": "^1.2.0", - "path-is-absolute": "^1.0.1", - "process": "~0.11.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "1.3.3", + "combine-source-map": "0.8.0", + "concat-stream": "1.6.2", + "is-buffer": "1.1.6", + "lexical-scope": "1.2.0", + "path-is-absolute": "1.0.1", + "process": "0.11.10", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "invariant": { @@ -4563,7 +4639,7 @@ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", "dev": true, "requires": { - "loose-envify": "^1.0.0" + "loose-envify": "1.3.1" } }, "ip": { @@ -4578,7 +4654,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-arrayish": { @@ -4593,7 +4669,7 @@ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", "dev": true, "requires": { - "binary-extensions": "^1.0.0" + "binary-extensions": "1.11.0" } }, "is-buffer": { @@ -4608,7 +4684,7 @@ "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { - "builtin-modules": "^1.0.0" + "builtin-modules": "1.1.1" } }, "is-data-descriptor": { @@ -4617,7 +4693,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-descriptor": { @@ -4626,9 +4702,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" }, "dependencies": { "kind-of": { @@ -4651,7 +4727,7 @@ "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", "dev": true, "requires": { - "is-primitive": "^2.0.0" + "is-primitive": "2.0.0" } }, "is-extendable": { @@ -4672,7 +4748,7 @@ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "number-is-nan": "1.0.1" } }, "is-glob": { @@ -4681,7 +4757,7 @@ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", "dev": true, "requires": { - "is-extglob": "^1.0.0" + "is-extglob": "1.0.0" } }, "is-lower-case": { @@ -4690,7 +4766,7 @@ "integrity": "sha1-fhR75HaNxGbbO/shzGCzHmrWk5M=", "dev": true, "requires": { - "lower-case": "^1.1.0" + "lower-case": "1.1.4" } }, "is-my-ip-valid": { @@ -4707,11 +4783,11 @@ "dev": true, "optional": true, "requires": { - "generate-function": "^2.0.0", - "generate-object-property": "^1.1.0", - "is-my-ip-valid": "^1.0.0", - "jsonpointer": "^4.0.0", - "xtend": "^4.0.0" + "generate-function": "2.3.1", + "generate-object-property": "1.2.0", + "is-my-ip-valid": "1.0.0", + "jsonpointer": "4.0.1", + "xtend": "4.0.1" } }, "is-number": { @@ -4720,7 +4796,7 @@ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "is-plain-object": { @@ -4729,7 +4805,7 @@ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", "dev": true, "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -4776,7 +4852,7 @@ "integrity": "sha1-jQsfp+eTOh5YSDYA7H2WYcuvdW8=", "dev": true, "requires": { - "upper-case": "^1.1.0" + "upper-case": "1.1.3" } }, "is-utf8": { @@ -4830,9 +4906,9 @@ "integrity": "sha1-jKctEC5jm4Z8ZImFbg4YqceqQrc=", "dev": true, "requires": { - "exit": "^0.1.2", - "glob": "^7.0.6", - "jasmine-core": "~2.99.0" + "exit": "0.1.2", + "glob": "7.1.2", + "jasmine-core": "2.99.1" } }, "jasmine-core": { @@ -4853,8 +4929,8 @@ "integrity": "sha1-A3fDgBfKvHMisNH7zSWkkWQfL74=", "dev": true, "requires": { - "argparse": "^1.0.2", - "esprima": "^2.6.0" + "argparse": "1.0.10", + "esprima": "2.7.3" } }, "jsbn": { @@ -4888,7 +4964,7 @@ "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", "dev": true, "requires": { - "jsonify": "~0.0.0" + "jsonify": "0.0.0" } }, "json-stringify-safe": { @@ -4909,7 +4985,7 @@ "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { - "graceful-fs": "^4.1.6" + "graceful-fs": "4.1.11" } }, "jsonify": { @@ -4949,31 +5025,31 @@ "integrity": "sha512-rECezBeY7mjzGUWhFlB7CvPHgkHJLXyUmWg+6vHCEsdWNUTnmiS6jRrIMcJEWgU2DUGZzGWG0bTRVky8fsDTOA==", "dev": true, "requires": { - "bluebird": "^3.3.0", - "body-parser": "^1.16.1", - "chokidar": "^2.0.3", - "colors": "^1.1.0", - "combine-lists": "^1.0.0", - "connect": "^3.6.0", - "core-js": "^2.2.0", - "di": "^0.0.1", - "dom-serialize": "^2.2.0", - "expand-braces": "^0.1.1", - "glob": "^7.1.1", - "graceful-fs": "^4.1.2", - "http-proxy": "^1.13.0", - "isbinaryfile": "^3.0.0", - "lodash": "^4.17.4", - "log4js": "^2.5.3", - "mime": "^1.3.4", - "minimatch": "^3.0.2", - "optimist": "^0.6.1", - "qjobs": "^1.1.4", - "range-parser": "^1.2.0", - "rimraf": "^2.6.0", - "safe-buffer": "^5.0.1", + "bluebird": "3.5.1", + "body-parser": "1.18.3", + "chokidar": "2.0.4", + "colors": "1.1.2", + "combine-lists": "1.0.1", + "connect": "3.6.6", + "core-js": "2.5.7", + "di": "0.0.1", + "dom-serialize": "2.2.1", + "expand-braces": "0.1.2", + "glob": "7.1.2", + "graceful-fs": "4.1.11", + "http-proxy": "1.17.0", + "isbinaryfile": "3.0.2", + "lodash": "4.17.10", + "log4js": "2.11.0", + "mime": "1.6.0", + "minimatch": "3.0.4", + "optimist": "0.6.1", + "qjobs": "1.2.0", + "range-parser": "1.2.0", + "rimraf": "2.6.2", + "safe-buffer": "5.1.2", "socket.io": "2.0.4", - "source-map": "^0.6.1", + "source-map": "0.6.1", "tmp": "0.0.33", "useragent": "2.2.1" }, @@ -4984,7 +5060,7 @@ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=", "dev": true, "requires": { - "mime-types": "~2.1.18", + "mime-types": "2.1.18", "negotiator": "0.6.1" } }, @@ -4994,8 +5070,8 @@ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" + "micromatch": "3.1.10", + "normalize-path": "2.1.1" } }, "arr-diff": { @@ -5022,16 +5098,16 @@ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" + "arr-flatten": "1.1.0", + "array-unique": "0.3.2", + "extend-shallow": "2.0.1", + "fill-range": "4.0.0", + "isobject": "3.0.1", + "repeat-element": "1.1.2", + "snapdragon": "0.8.2", + "snapdragon-node": "2.1.1", + "split-string": "3.1.0", + "to-regex": "3.0.2" }, "dependencies": { "extend-shallow": { @@ -5040,7 +5116,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5051,19 +5127,19 @@ "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", "dev": true, "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.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": "^4.0.0", - "lodash.debounce": "^4.0.8", - "normalize-path": "^2.1.1", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.0.0", - "upath": "^1.0.5" + "anymatch": "2.0.0", + "async-each": "1.0.1", + "braces": "2.3.2", + "fsevents": "1.2.4", + "glob-parent": "3.1.0", + "inherits": "2.0.3", + "is-binary-path": "1.0.1", + "is-glob": "4.0.0", + "lodash.debounce": "4.0.8", + "normalize-path": "2.1.1", + "path-is-absolute": "1.0.1", + "readdirp": "2.1.0", + "upath": "1.1.0" } }, "component-emitter": { @@ -5078,13 +5154,13 @@ "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", "dev": true, "requires": { - "accepts": "~1.3.4", + "accepts": "1.3.5", "base64id": "1.0.0", "cookie": "0.3.1", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.0", - "uws": "~9.14.0", - "ws": "~3.3.1" + "debug": "3.1.0", + "engine.io-parser": "2.1.2", + "uws": "9.14.0", + "ws": "3.3.3" }, "dependencies": { "debug": { @@ -5106,14 +5182,14 @@ "requires": { "component-emitter": "1.2.1", "component-inherit": "0.0.3", - "debug": "~3.1.0", - "engine.io-parser": "~2.1.1", + "debug": "3.1.0", + "engine.io-parser": "2.1.2", "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", + "ws": "3.3.3", + "xmlhttprequest-ssl": "1.5.5", "yeast": "0.1.2" }, "dependencies": { @@ -5135,10 +5211,10 @@ "dev": true, "requires": { "after": "0.8.2", - "arraybuffer.slice": "~0.0.7", + "arraybuffer.slice": "0.0.7", "base64-arraybuffer": "0.1.5", "blob": "0.0.4", - "has-binary2": "~1.0.2" + "has-binary2": "1.0.3" } }, "expand-brackets": { @@ -5147,13 +5223,13 @@ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", "dev": true, "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "posix-character-classes": "0.1.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -5162,7 +5238,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "extend-shallow": { @@ -5171,7 +5247,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "is-accessor-descriptor": { @@ -5180,7 +5256,7 @@ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5189,7 +5265,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5200,7 +5276,7 @@ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5209,7 +5285,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5220,9 +5296,9 @@ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", "dev": true, "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" + "is-accessor-descriptor": "0.1.6", + "is-data-descriptor": "0.1.4", + "kind-of": "5.1.0" } }, "kind-of": { @@ -5239,14 +5315,14 @@ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", "dev": true, "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "array-unique": "0.3.2", + "define-property": "1.0.0", + "expand-brackets": "2.1.4", + "extend-shallow": "2.0.1", + "fragment-cache": "0.2.1", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "define-property": { @@ -5255,7 +5331,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "extend-shallow": { @@ -5264,7 +5340,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5275,10 +5351,10 @@ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "extend-shallow": "2.0.1", + "is-number": "3.0.0", + "repeat-string": "1.6.1", + "to-regex-range": "2.1.1" }, "dependencies": { "extend-shallow": { @@ -5287,7 +5363,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -5298,8 +5374,8 @@ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" + "is-glob": "3.1.0", + "path-dirname": "1.0.2" }, "dependencies": { "is-glob": { @@ -5308,7 +5384,7 @@ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, "requires": { - "is-extglob": "^2.1.0" + "is-extglob": "2.1.1" } } } @@ -5319,7 +5395,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -5328,7 +5404,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -5337,9 +5413,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "is-extglob": { @@ -5354,7 +5430,7 @@ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", "dev": true, "requires": { - "is-extglob": "^2.1.1" + "is-extglob": "2.1.1" } }, "is-number": { @@ -5363,7 +5439,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" }, "dependencies": { "kind-of": { @@ -5372,7 +5448,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } } } @@ -5401,18 +5477,18 @@ "integrity": "sha512-z1XdwyGFg8/WGkOyF6DPJjivCWNLKrklGdViywdYnSKOvgtEBo2UyEMZS5sD2mZrQlU3TvO8wDWLc8mzE1ncBQ==", "dev": true, "requires": { - "amqplib": "^0.5.2", - "axios": "^0.15.3", - "circular-json": "^0.5.4", - "date-format": "^1.2.0", - "debug": "^3.1.0", - "hipchat-notifier": "^1.1.0", - "loggly": "^1.1.0", - "mailgun-js": "^0.18.0", - "nodemailer": "^2.5.0", - "redis": "^2.7.1", - "semver": "^5.5.0", - "slack-node": "~0.2.0", + "amqplib": "0.5.2", + "axios": "0.15.3", + "circular-json": "0.5.5", + "date-format": "1.2.0", + "debug": "3.1.0", + "hipchat-notifier": "1.1.0", + "loggly": "1.1.1", + "mailgun-js": "0.18.1", + "nodemailer": "2.7.2", + "redis": "2.8.0", + "semver": "5.5.0", + "slack-node": "0.2.0", "streamroller": "0.7.0" }, "dependencies": { @@ -5439,19 +5515,19 @@ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "braces": "2.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "extglob": "2.0.4", + "fragment-cache": "0.2.1", + "kind-of": "6.0.2", + "nanomatch": "1.2.13", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" } }, "socket.io": { @@ -5460,11 +5536,11 @@ "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=", "dev": true, "requires": { - "debug": "~2.6.6", - "engine.io": "~3.1.0", - "socket.io-adapter": "~1.1.0", + "debug": "2.6.9", + "engine.io": "3.1.5", + "socket.io-adapter": "1.1.1", "socket.io-client": "2.0.4", - "socket.io-parser": "~3.1.1" + "socket.io-parser": "3.1.3" } }, "socket.io-adapter": { @@ -5483,14 +5559,14 @@ "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": "2.6.9", + "engine.io-client": "3.1.6", "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.1.3", "to-array": "0.1.4" } }, @@ -5501,8 +5577,8 @@ "dev": true, "requires": { "component-emitter": "1.2.1", - "debug": "~3.1.0", - "has-binary2": "~1.0.2", + "debug": "3.1.0", + "has-binary2": "1.0.3", "isarray": "2.0.1" }, "dependencies": { @@ -5529,7 +5605,7 @@ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", "dev": true, "requires": { - "os-tmpdir": "~1.0.2" + "os-tmpdir": "1.0.2" } }, "ultron": { @@ -5544,8 +5620,8 @@ "integrity": "sha1-z1k+9PLRdYdei7ZY6pLhik/QbY4=", "dev": true, "requires": { - "lru-cache": "2.2.x", - "tmp": "0.0.x" + "lru-cache": "2.2.4", + "tmp": "0.0.33" } }, "ws": { @@ -5554,9 +5630,9 @@ "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", "dev": true, "requires": { - "async-limiter": "~1.0.0", - "safe-buffer": "~5.1.0", - "ultron": "~1.1.0" + "async-limiter": "1.0.0", + "safe-buffer": "5.1.2", + "ultron": "1.1.1" } }, "xmlhttprequest-ssl": { @@ -5573,7 +5649,7 @@ "integrity": "sha1-rmw8WKMTodALRRZMRVubhs4X+WA=", "dev": true, "requires": { - "resolve": "^1.1.6" + "resolve": "1.1.7" } }, "karma-jasmine": { @@ -5588,8 +5664,8 @@ "integrity": "sha1-0jyjSAG9qYY60xjju0vUBisTrNI=", "dev": true, "requires": { - "lodash": "^4.0.1", - "phantomjs-prebuilt": "^2.1.7" + "lodash": "4.17.10", + "phantomjs-prebuilt": "2.1.16" } }, "kew": { @@ -5604,7 +5680,7 @@ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, "requires": { - "is-buffer": "^1.1.5" + "is-buffer": "1.1.6" } }, "klaw": { @@ -5613,7 +5689,7 @@ "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", "dev": true, "requires": { - "graceful-fs": "^4.1.9" + "graceful-fs": "4.1.11" } }, "labeled-stream-splicer": { @@ -5622,9 +5698,9 @@ "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", "dev": true, "requires": { - "inherits": "^2.0.1", - "isarray": "^2.0.4", - "stream-splicer": "^2.0.0" + "inherits": "2.0.3", + "isarray": "2.0.4", + "stream-splicer": "2.0.0" }, "dependencies": { "isarray": { @@ -5648,8 +5724,8 @@ "dev": true, "optional": true, "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "prelude-ls": "1.1.2", + "type-check": "0.3.2" } }, "lexical-scope": { @@ -5658,7 +5734,7 @@ "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", "dev": true, "requires": { - "astw": "^2.0.0" + "astw": "2.2.0" } }, "libbase64": { @@ -5704,11 +5780,11 @@ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0", - "strip-bom": "^2.0.0" + "graceful-fs": "4.1.11", + "parse-json": "2.2.0", + "pify": "2.3.0", + "pinkie-promise": "2.0.1", + "strip-bom": "2.0.0" } }, "lodash": { @@ -5742,9 +5818,9 @@ "dev": true, "optional": true, "requires": { - "json-stringify-safe": "5.0.x", - "request": "2.75.x", - "timespan": "2.3.x" + "json-stringify-safe": "5.0.1", + "request": "2.75.0", + "timespan": "2.3.0" }, "dependencies": { "assert-plus": { @@ -5775,9 +5851,9 @@ "dev": true, "optional": true, "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.5", - "mime-types": "^2.1.11" + "asynckit": "0.4.0", + "combined-stream": "1.0.6", + "mime-types": "2.1.18" } }, "har-validator": { @@ -5787,10 +5863,10 @@ "dev": true, "optional": true, "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "is-my-json-valid": "^2.12.4", - "pinkie-promise": "^2.0.0" + "chalk": "1.1.3", + "commander": "2.15.1", + "is-my-json-valid": "2.19.0", + "pinkie-promise": "2.0.1" } }, "http-signature": { @@ -5800,9 +5876,9 @@ "dev": true, "optional": true, "requires": { - "assert-plus": "^0.2.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" + "assert-plus": "0.2.0", + "jsprim": "1.4.1", + "sshpk": "1.14.1" } }, "qs": { @@ -5819,27 +5895,27 @@ "dev": true, "optional": true, "requires": { - "aws-sign2": "~0.6.0", - "aws4": "^1.2.1", - "bl": "~1.1.2", - "caseless": "~0.11.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.0", - "forever-agent": "~0.6.1", - "form-data": "~2.0.0", - "har-validator": "~2.0.6", - "hawk": "~3.1.3", - "http-signature": "~1.1.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.7", - "node-uuid": "~1.4.7", - "oauth-sign": "~0.8.1", - "qs": "~6.2.0", - "stringstream": "~0.0.4", - "tough-cookie": "~2.3.0", - "tunnel-agent": "~0.4.1" + "aws-sign2": "0.6.0", + "aws4": "1.7.0", + "bl": "1.1.2", + "caseless": "0.11.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.0.0", + "har-validator": "2.0.6", + "hawk": "3.1.3", + "http-signature": "1.1.1", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "node-uuid": "1.4.8", + "oauth-sign": "0.8.2", + "qs": "6.2.3", + "stringstream": "0.0.6", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.4.3" } }, "tunnel-agent": { @@ -5863,7 +5939,7 @@ "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", "dev": true, "requires": { - "js-tokens": "^3.0.0" + "js-tokens": "3.0.2" } }, "loud-rejection": { @@ -5872,8 +5948,8 @@ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", "dev": true, "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" + "currently-unhandled": "0.4.1", + "signal-exit": "3.0.2" } }, "lower-case": { @@ -5888,7 +5964,7 @@ "integrity": "sha1-5dp8JvKacHO+AtUrrJmA5ZIq36E=", "dev": true, "requires": { - "lower-case": "^1.1.2" + "lower-case": "1.1.4" } }, "lru-cache": { @@ -5915,15 +5991,15 @@ "dev": true, "optional": true, "requires": { - "async": "~2.6.0", - "debug": "~3.1.0", - "form-data": "~2.3.0", - "inflection": "~1.12.0", - "is-stream": "^1.1.0", - "path-proxy": "~1.0.0", - "promisify-call": "^2.0.2", - "proxy-agent": "~3.0.0", - "tsscmp": "~1.0.0" + "async": "2.6.1", + "debug": "3.1.0", + "form-data": "2.3.2", + "inflection": "1.12.0", + "is-stream": "1.1.0", + "path-proxy": "1.0.0", + "promisify-call": "2.0.4", + "proxy-agent": "3.0.1", + "tsscmp": "1.0.6" }, "dependencies": { "async": { @@ -5933,7 +6009,7 @@ "dev": true, "optional": true, "requires": { - "lodash": "^4.17.10" + "lodash": "4.17.10" } }, "debug": { @@ -5966,7 +6042,7 @@ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", "dev": true, "requires": { - "object-visit": "^1.0.0" + "object-visit": "1.0.1" } }, "math-random": { @@ -5981,10 +6057,10 @@ "integrity": "sha1-cTZehKmd2Piz99X94vANHn9zvmE=", "dev": true, "requires": { - "chalk": "^1.0.0", - "figures": "^1.0.1", - "gzip-size": "^1.0.0", - "pretty-bytes": "^1.0.0" + "chalk": "1.1.3", + "figures": "1.7.0", + "gzip-size": "1.0.0", + "pretty-bytes": "1.0.4" } }, "md5.js": { @@ -5993,8 +6069,8 @@ "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hash-base": "3.0.4", + "inherits": "2.0.3" } }, "media-typer": { @@ -6009,16 +6085,16 @@ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { - "camelcase-keys": "^2.0.0", - "decamelize": "^1.1.2", - "loud-rejection": "^1.0.0", - "map-obj": "^1.0.1", - "minimist": "^1.1.3", - "normalize-package-data": "^2.3.4", - "object-assign": "^4.0.1", - "read-pkg-up": "^1.0.1", - "redent": "^1.0.0", - "trim-newlines": "^1.0.0" + "camelcase-keys": "2.1.0", + "decamelize": "1.2.0", + "loud-rejection": "1.6.0", + "map-obj": "1.0.1", + "minimist": "1.2.0", + "normalize-package-data": "2.4.0", + "object-assign": "4.1.1", + "read-pkg-up": "1.0.1", + "redent": "1.0.0", + "trim-newlines": "1.0.0" }, "dependencies": { "minimist": { @@ -6035,19 +6111,19 @@ "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" + "arr-diff": "2.0.0", + "array-unique": "0.2.1", + "braces": "1.8.5", + "expand-brackets": "0.1.5", + "extglob": "0.3.2", + "filename-regex": "2.0.1", + "is-extglob": "1.0.0", + "is-glob": "2.0.1", + "kind-of": "3.2.2", + "normalize-path": "2.1.1", + "object.omit": "2.0.1", + "parse-glob": "3.0.4", + "regex-cache": "0.4.4" } }, "miller-rabin": { @@ -6056,8 +6132,8 @@ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" + "bn.js": "4.11.8", + "brorand": "1.1.0" } }, "mime": { @@ -6078,7 +6154,7 @@ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", "dev": true, "requires": { - "mime-db": "~1.33.0" + "mime-db": "1.33.0" } }, "minimalistic-assert": { @@ -6099,7 +6175,7 @@ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "dev": true, "requires": { - "brace-expansion": "^1.1.7" + "brace-expansion": "1.1.11" } }, "minimist": { @@ -6114,8 +6190,8 @@ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", "dev": true, "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" + "for-in": "1.0.2", + "is-extendable": "1.0.1" }, "dependencies": { "is-extendable": { @@ -6124,7 +6200,7 @@ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, "requires": { - "is-plain-object": "^2.0.4" + "is-plain-object": "2.0.4" } } } @@ -6172,7 +6248,7 @@ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", "dev": true, "requires": { - "has-flag": "^3.0.0" + "has-flag": "3.0.0" } } } @@ -6183,21 +6259,21 @@ "integrity": "sha512-NPs5N511VD1rrVJihSso/LiBShRbJALYBKzDW91uZYy7BpjnO4bGnZL3HjZ9yKcFdZUWwaYjDz9zxbuP7vKMuQ==", "dev": true, "requires": { - "JSONStream": "^1.0.3", - "browser-resolve": "^1.7.0", - "cached-path-relative": "^1.0.0", - "concat-stream": "~1.6.0", - "defined": "^1.0.0", - "detective": "^5.0.2", - "duplexer2": "^0.1.2", - "inherits": "^2.0.1", - "parents": "^1.0.0", - "readable-stream": "^2.0.2", - "resolve": "^1.4.0", - "stream-combiner2": "^1.1.1", - "subarg": "^1.0.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "JSONStream": "1.3.3", + "browser-resolve": "1.11.2", + "cached-path-relative": "1.0.1", + "concat-stream": "1.6.2", + "defined": "1.0.0", + "detective": "5.1.0", + "duplexer2": "0.1.4", + "inherits": "2.0.3", + "parents": "1.0.1", + "readable-stream": "2.3.6", + "resolve": "1.7.1", + "stream-combiner2": "1.1.1", + "subarg": "1.0.0", + "through2": "2.0.3", + "xtend": "4.0.1" }, "dependencies": { "resolve": { @@ -6206,7 +6282,7 @@ "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "dev": true, "requires": { - "path-parse": "^1.0.5" + "path-parse": "1.0.5" } } } @@ -6230,17 +6306,17 @@ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", "dev": true, "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" + "arr-diff": "4.0.0", + "array-unique": "0.3.2", + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "fragment-cache": "0.2.1", + "is-windows": "1.0.2", + "kind-of": "6.0.2", + "object.pick": "1.3.0", + "regex-not": "1.0.2", + "snapdragon": "0.8.2", + "to-regex": "3.0.2" }, "dependencies": { "arr-diff": { @@ -6269,7 +6345,7 @@ "integrity": "sha1-W1etGLHKCShk72Kwse2BlPODtxw=", "dev": true, "requires": { - "xml-char-classes": "^1.0.0" + "xml-char-classes": "1.0.0" } }, "negotiator": { @@ -6291,18 +6367,18 @@ "integrity": "sha1-3D/FG6Cy+LOF2+BH9NoG9YCh/WE=", "dev": true, "requires": { - "acorn": "~2.6.4", - "alter": "~0.2.0", - "convert-source-map": "~1.1.2", - "optimist": "~0.6.1", - "ordered-ast-traverse": "~1.1.1", - "simple-fmt": "~0.1.0", - "simple-is": "~0.2.0", - "source-map": "~0.5.3", - "stable": "~0.1.5", - "stringmap": "~0.2.2", - "stringset": "~0.2.1", - "tryor": "~0.1.2" + "acorn": "2.6.4", + "alter": "0.2.0", + "convert-source-map": "1.1.3", + "optimist": "0.6.1", + "ordered-ast-traverse": "1.1.1", + "simple-fmt": "0.1.0", + "simple-is": "0.2.0", + "source-map": "0.5.7", + "stable": "0.1.8", + "stringmap": "0.2.2", + "stringset": "0.2.1", + "tryor": "0.1.2" }, "dependencies": { "acorn": { @@ -6325,7 +6401,7 @@ "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", "dev": true, "requires": { - "lower-case": "^1.1.1" + "lower-case": "1.1.4" } }, "node-uuid": { @@ -6358,8 +6434,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.2", - "smart-buffer": "^1.0.4" + "ip": "1.1.5", + "smart-buffer": "1.1.15" } } } @@ -6426,7 +6502,7 @@ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", "dev": true, "requires": { - "abbrev": "1" + "abbrev": "1.1.1" } }, "normalize-package-data": { @@ -6435,10 +6511,10 @@ "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", "dev": true, "requires": { - "hosted-git-info": "^2.1.4", - "is-builtin-module": "^1.0.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" + "hosted-git-info": "2.6.0", + "is-builtin-module": "1.0.0", + "semver": "5.5.0", + "validate-npm-package-license": "3.0.3" } }, "normalize-path": { @@ -6447,7 +6523,16 @@ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, "requires": { - "remove-trailing-separator": "^1.0.1" + "remove-trailing-separator": "1.1.0" + } + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "2.0.1" } }, "number-is-nan": { @@ -6480,9 +6565,9 @@ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", "dev": true, "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" + "copy-descriptor": "0.1.1", + "define-property": "0.2.5", + "kind-of": "3.2.2" }, "dependencies": { "define-property": { @@ -6491,7 +6576,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } } } @@ -6508,7 +6593,7 @@ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", "dev": true, "requires": { - "isobject": "^3.0.0" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -6525,10 +6610,10 @@ "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" + "define-properties": "1.1.2", + "function-bind": "1.1.1", + "has-symbols": "1.0.0", + "object-keys": "1.0.11" } }, "object.omit": { @@ -6537,8 +6622,8 @@ "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", "dev": true, "requires": { - "for-own": "^0.1.4", - "is-extendable": "^0.1.1" + "for-own": "0.1.5", + "is-extendable": "0.1.1" } }, "object.pick": { @@ -6547,7 +6632,7 @@ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", "dev": true, "requires": { - "isobject": "^3.0.1" + "isobject": "3.0.1" }, "dependencies": { "isobject": { @@ -6573,7 +6658,7 @@ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", "dev": true, "requires": { - "wrappy": "1" + "wrappy": "1.0.2" } }, "optimist": { @@ -6582,8 +6667,8 @@ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", "dev": true, "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" + "minimist": "0.0.8", + "wordwrap": "0.0.2" } }, "optionator": { @@ -6593,12 +6678,12 @@ "dev": true, "optional": 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" + "deep-is": "0.1.3", + "fast-levenshtein": "2.0.6", + "levn": "0.3.0", + "prelude-ls": "1.1.2", + "type-check": "0.3.2", + "wordwrap": "1.0.0" }, "dependencies": { "wordwrap": { @@ -6616,7 +6701,7 @@ "integrity": "sha1-aEOhcLwO7otSDMjdwd3TqjD6BXw=", "dev": true, "requires": { - "ordered-esprima-props": "~1.1.0" + "ordered-esprima-props": "1.1.0" } }, "ordered-esprima-props": { @@ -6649,7 +6734,7 @@ "integrity": "sha1-UM+GFjZeh+Ax4ppeyTOaPaRyX6I=", "dev": true, "requires": { - "shell-quote": "^1.4.2" + "shell-quote": "1.6.1" } }, "output-file-sync": { @@ -6658,9 +6743,9 @@ "integrity": "sha1-0KM+7+YaIF+suQCS6CZZjVJFznY=", "dev": true, "requires": { - "graceful-fs": "^4.1.4", - "mkdirp": "^0.5.1", - "object-assign": "^4.1.0" + "graceful-fs": "4.1.11", + "mkdirp": "0.5.1", + "object-assign": "4.1.1" } }, "pac-proxy-agent": { @@ -6670,14 +6755,14 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "get-uri": "^2.0.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "pac-resolver": "^3.0.0", - "raw-body": "^2.2.0", - "socks-proxy-agent": "^3.0.0" + "agent-base": "4.2.1", + "debug": "3.1.0", + "get-uri": "2.0.2", + "http-proxy-agent": "2.1.0", + "https-proxy-agent": "2.2.1", + "pac-resolver": "3.0.0", + "raw-body": "2.3.3", + "socks-proxy-agent": "3.0.1" }, "dependencies": { "bytes": { @@ -6717,8 +6802,8 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.1.0", - "socks": "^1.1.10" + "agent-base": "4.2.1", + "socks": "1.1.10" } } } @@ -6730,11 +6815,11 @@ "dev": true, "optional": true, "requires": { - "co": "^4.6.0", - "degenerator": "^1.0.4", - "ip": "^1.1.5", - "netmask": "^1.0.6", - "thunkify": "^2.1.2" + "co": "4.6.0", + "degenerator": "1.0.4", + "ip": "1.1.5", + "netmask": "1.0.6", + "thunkify": "2.1.2" } }, "pako": { @@ -6749,7 +6834,7 @@ "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "parents": { @@ -6758,7 +6843,7 @@ "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", "dev": true, "requires": { - "path-platform": "~0.11.15" + "path-platform": "0.11.15" } }, "parse-asn1": { @@ -6767,11 +6852,11 @@ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3" + "asn1.js": "4.10.1", + "browserify-aes": "1.2.0", + "create-hash": "1.2.0", + "evp_bytestokey": "1.0.3", + "pbkdf2": "3.0.16" } }, "parse-glob": { @@ -6780,10 +6865,10 @@ "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", "dev": true, "requires": { - "glob-base": "^0.3.0", - "is-dotfile": "^1.0.0", - "is-extglob": "^1.0.0", - "is-glob": "^2.0.0" + "glob-base": "0.3.0", + "is-dotfile": "1.0.3", + "is-extglob": "1.0.0", + "is-glob": "2.0.1" } }, "parse-json": { @@ -6792,7 +6877,7 @@ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", "dev": true, "requires": { - "error-ex": "^1.2.0" + "error-ex": "1.3.1" } }, "parseqs": { @@ -6801,7 +6886,7 @@ "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseuri": { @@ -6810,7 +6895,7 @@ "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", "dev": true, "requires": { - "better-assert": "~1.0.0" + "better-assert": "1.0.2" } }, "parseurl": { @@ -6825,8 +6910,8 @@ "integrity": "sha1-LVeNNFX2YNpl7KGO+VtODekSdh4=", "dev": true, "requires": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" + "camel-case": "3.0.0", + "upper-case-first": "1.1.2" } }, "pascalcase": { @@ -6847,7 +6932,7 @@ "integrity": "sha1-lLgDfDctP+KQbkZbtF4l0ibo7qU=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "path-dirname": { @@ -6862,7 +6947,7 @@ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", "dev": true, "requires": { - "pinkie-promise": "^2.0.0" + "pinkie-promise": "2.0.1" } }, "path-is-absolute": { @@ -6871,6 +6956,12 @@ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, "path-parse": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", @@ -6890,7 +6981,7 @@ "dev": true, "optional": true, "requires": { - "inflection": "~1.3.0" + "inflection": "1.3.8" }, "dependencies": { "inflection": { @@ -6908,9 +6999,9 @@ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "pify": "^2.0.0", - "pinkie-promise": "^2.0.0" + "graceful-fs": "4.1.11", + "pify": "2.3.0", + "pinkie-promise": "2.0.1" } }, "pathval": { @@ -6925,11 +7016,11 @@ "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", "dev": true, "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" + "create-hash": "1.2.0", + "create-hmac": "1.1.7", + "ripemd160": "2.0.2", + "safe-buffer": "5.1.2", + "sha.js": "2.4.11" } }, "pend": { @@ -6950,15 +7041,15 @@ "integrity": "sha1-79ISpKOWbTZHaE6ouniFSb4q7+8=", "dev": true, "requires": { - "es6-promise": "^4.0.3", - "extract-zip": "^1.6.5", - "fs-extra": "^1.0.0", - "hasha": "^2.2.0", - "kew": "^0.7.0", - "progress": "^1.1.8", - "request": "^2.81.0", - "request-progress": "^2.0.1", - "which": "^1.2.10" + "es6-promise": "4.2.4", + "extract-zip": "1.6.7", + "fs-extra": "1.0.0", + "hasha": "2.2.0", + "kew": "0.7.0", + "progress": "1.1.8", + "request": "2.87.0", + "request-progress": "2.0.1", + "which": "1.3.1" } }, "pify": { @@ -6979,7 +7070,7 @@ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", "dev": true, "requires": { - "pinkie": "^2.0.0" + "pinkie": "2.0.4" } }, "posix-character-classes": { @@ -7006,8 +7097,8 @@ "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=", "dev": true, "requires": { - "get-stdin": "^4.0.1", - "meow": "^3.1.0" + "get-stdin": "4.0.1", + "meow": "3.7.0" } }, "private": { @@ -7041,7 +7132,7 @@ "dev": true, "optional": true, "requires": { - "with-callback": "^1.0.2" + "with-callback": "1.0.2" } }, "proxy-agent": { @@ -7051,14 +7142,14 @@ "dev": true, "optional": true, "requires": { - "agent-base": "^4.2.0", - "debug": "^3.1.0", - "http-proxy-agent": "^2.1.0", - "https-proxy-agent": "^2.2.1", - "lru-cache": "^4.1.2", - "pac-proxy-agent": "^2.0.1", - "proxy-from-env": "^1.0.0", - "socks-proxy-agent": "^4.0.1" + "agent-base": "4.2.1", + "debug": "3.1.0", + "http-proxy-agent": "2.1.0", + "https-proxy-agent": "2.2.1", + "lru-cache": "4.1.3", + "pac-proxy-agent": "2.0.2", + "proxy-from-env": "1.0.0", + "socks-proxy-agent": "4.0.1" }, "dependencies": { "debug": { @@ -7078,8 +7169,8 @@ "dev": true, "optional": true, "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" + "pseudomap": "1.0.2", + "yallist": "2.1.2" } } } @@ -7104,11 +7195,11 @@ "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", "dev": true, "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1" + "bn.js": "4.11.8", + "browserify-rsa": "4.0.1", + "create-hash": "1.2.0", + "parse-asn1": "5.1.1", + "randombytes": "2.0.6" } }, "punycode": { @@ -7147,9 +7238,9 @@ "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", "dev": true, "requires": { - "is-number": "^4.0.0", - "kind-of": "^6.0.0", - "math-random": "^1.0.1" + "is-number": "4.0.0", + "kind-of": "6.0.2", + "math-random": "1.0.1" }, "dependencies": { "is-number": { @@ -7172,7 +7263,7 @@ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", "dev": true, "requires": { - "safe-buffer": "^5.1.0" + "safe-buffer": "5.1.2" } }, "randomfill": { @@ -7181,8 +7272,8 @@ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" + "randombytes": "2.0.6", + "safe-buffer": "5.1.2" } }, "range-parser": { @@ -7197,8 +7288,8 @@ "integrity": "sha1-HQJ8K/oRasxmI7yo8AAWVyqH1CU=", "dev": true, "requires": { - "bytes": "1", - "string_decoder": "0.10" + "bytes": "1.0.0", + "string_decoder": "0.10.31" }, "dependencies": { "string_decoder": { @@ -7215,7 +7306,7 @@ "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", "dev": true, "requires": { - "readable-stream": "^2.0.2" + "readable-stream": "2.3.6" } }, "read-pkg": { @@ -7224,9 +7315,9 @@ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", "dev": true, "requires": { - "load-json-file": "^1.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^1.0.0" + "load-json-file": "1.1.0", + "normalize-package-data": "2.4.0", + "path-type": "1.1.0" } }, "read-pkg-up": { @@ -7235,8 +7326,8 @@ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", "dev": true, "requires": { - "find-up": "^1.0.0", - "read-pkg": "^1.0.0" + "find-up": "1.1.2", + "read-pkg": "1.1.0" } }, "readable-stream": { @@ -7245,13 +7336,13 @@ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { - "core-util-is": "~1.0.0", - "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.1" + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "1.0.0", + "process-nextick-args": "2.0.0", + "safe-buffer": "5.1.2", + "string_decoder": "1.1.1", + "util-deprecate": "1.0.2" } }, "readdirp": { @@ -7260,10 +7351,10 @@ "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", "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", + "minimatch": "3.0.4", + "readable-stream": "2.3.6", + "set-immediate-shim": "1.0.1" } }, "redent": { @@ -7272,8 +7363,8 @@ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", "dev": true, "requires": { - "indent-string": "^2.1.0", - "strip-indent": "^1.0.1" + "indent-string": "2.1.0", + "strip-indent": "1.0.1" } }, "redis": { @@ -7283,9 +7374,9 @@ "dev": true, "optional": true, "requires": { - "double-ended-queue": "^2.1.0-0", - "redis-commands": "^1.2.0", - "redis-parser": "^2.6.0" + "double-ended-queue": "2.1.0-0", + "redis-commands": "1.3.5", + "redis-parser": "2.6.0" } }, "redis-commands": { @@ -7320,9 +7411,9 @@ "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", "dev": true, "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" + "babel-runtime": "6.26.0", + "babel-types": "6.26.0", + "private": "0.1.8" } }, "regex-cache": { @@ -7331,7 +7422,7 @@ "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", "dev": true, "requires": { - "is-equal-shallow": "^0.1.3" + "is-equal-shallow": "0.1.3" } }, "regex-not": { @@ -7340,8 +7431,8 @@ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", "dev": true, "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" + "extend-shallow": "3.0.2", + "safe-regex": "1.1.0" } }, "regexpu-core": { @@ -7350,9 +7441,9 @@ "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", "dev": true, "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" + "regenerate": "1.4.0", + "regjsgen": "0.2.0", + "regjsparser": "0.1.5" } }, "regjsgen": { @@ -7367,7 +7458,7 @@ "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", "dev": true, "requires": { - "jsesc": "~0.5.0" + "jsesc": "0.5.0" }, "dependencies": { "jsesc": { @@ -7408,7 +7499,7 @@ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", "dev": true, "requires": { - "is-finite": "^1.0.0" + "is-finite": "1.0.2" } }, "request": { @@ -7417,26 +7508,26 @@ "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", "dev": true, "requires": { - "aws-sign2": "~0.7.0", - "aws4": "^1.6.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", - "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.17", - "oauth-sign": "~0.8.2", - "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", - "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" + "aws-sign2": "0.7.0", + "aws4": "1.7.0", + "caseless": "0.12.0", + "combined-stream": "1.0.6", + "extend": "3.0.1", + "forever-agent": "0.6.1", + "form-data": "2.3.2", + "har-validator": "5.0.3", + "http-signature": "1.2.0", + "is-typedarray": "1.0.0", + "isstream": "0.1.2", + "json-stringify-safe": "5.0.1", + "mime-types": "2.1.18", + "oauth-sign": "0.8.2", + "performance-now": "2.1.0", + "qs": "6.5.2", + "safe-buffer": "5.1.2", + "tough-cookie": "2.3.4", + "tunnel-agent": "0.6.0", + "uuid": "3.2.1" } }, "request-progress": { @@ -7445,7 +7536,7 @@ "integrity": "sha1-XTa7V5YcZzqlt4jbyBQf3yO0Tgg=", "dev": true, "requires": { - "throttleit": "^1.0.0" + "throttleit": "1.0.0" } }, "requestretry": { @@ -7455,10 +7546,10 @@ "dev": true, "optional": true, "requires": { - "extend": "^3.0.0", - "lodash": "^4.15.0", - "request": "^2.74.0", - "when": "^3.7.7" + "extend": "3.0.1", + "lodash": "4.17.10", + "request": "2.87.0", + "when": "3.7.8" } }, "requires-port": { @@ -7491,7 +7582,7 @@ "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", "dev": true, "requires": { - "align-text": "^0.1.1" + "align-text": "0.1.4" } }, "rimraf": { @@ -7500,7 +7591,7 @@ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "dev": true, "requires": { - "glob": "^7.0.5" + "glob": "7.1.2" } }, "ripemd160": { @@ -7509,8 +7600,8 @@ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", "dev": true, "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "hash-base": "3.0.4", + "inherits": "2.0.3" } }, "safe-buffer": { @@ -7531,7 +7622,7 @@ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { - "ret": "~0.1.10" + "ret": "0.1.15" } }, "safer-buffer": { @@ -7553,18 +7644,18 @@ "dev": true, "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", + "depd": "1.1.2", + "destroy": "1.0.4", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "etag": "1.8.1", "fresh": "0.5.2", - "http-errors": "~1.6.2", + "http-errors": "1.6.3", "mime": "1.4.1", "ms": "2.0.0", - "on-finished": "~2.3.0", - "range-parser": "~1.2.0", - "statuses": "~1.4.0" + "on-finished": "2.3.0", + "range-parser": "1.2.0", + "statuses": "1.4.0" }, "dependencies": { "mime": { @@ -7587,8 +7678,8 @@ "integrity": "sha1-H24t2jnBaL+S0T+G1KkYkz9mftQ=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" + "no-case": "2.3.2", + "upper-case-first": "1.1.2" } }, "serve-static": { @@ -7597,9 +7688,9 @@ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==", "dev": true, "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.2", + "encodeurl": "1.0.2", + "escape-html": "1.0.3", + "parseurl": "1.3.2", "send": "0.16.2" } }, @@ -7615,10 +7706,10 @@ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "split-string": "3.1.0" }, "dependencies": { "extend-shallow": { @@ -7627,7 +7718,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -7644,8 +7735,8 @@ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" + "inherits": "2.0.3", + "safe-buffer": "5.1.2" } }, "shasum": { @@ -7654,8 +7745,8 @@ "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "dev": true, "requires": { - "json-stable-stringify": "~0.0.0", - "sha.js": "~2.4.4" + "json-stable-stringify": "0.0.1", + "sha.js": "2.4.11" } }, "shell-quote": { @@ -7664,10 +7755,10 @@ "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", "dev": true, "requires": { - "array-filter": "~0.0.0", - "array-map": "~0.0.0", - "array-reduce": "~0.0.0", - "jsonify": "~0.0.0" + "array-filter": "0.0.1", + "array-map": "0.0.0", + "array-reduce": "0.0.0", + "jsonify": "0.0.0" } }, "signal-exit": { @@ -7695,7 +7786,7 @@ "dev": true, "optional": true, "requires": { - "requestretry": "^1.2.2" + "requestretry": "1.13.0" } }, "slash": { @@ -7728,9 +7819,9 @@ "dev": true }, "sn-stylekit": { - "version": "1.0.15", - "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-1.0.15.tgz", - "integrity": "sha512-QeWlaCMHtF/VhFWWICzmx39ger92DEj1uLiCW4VVLX9LtU7nKQ5plqHgrpvnctO+wNh9LIYdPBLLWxTwgXm6Eg==", + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/sn-stylekit/-/sn-stylekit-2.0.13.tgz", + "integrity": "sha512-rGDc2cc0/r84lQn/HJOw6GvJz5VonSK2UVdLTS9TFo+wwbAtRnww8aj7VILgNneUAnqwdCKdY5O/Fk3rN0Hw7g==", "dev": true }, "snake-case": { @@ -7739,7 +7830,7 @@ "integrity": "sha1-Qb2xtz8w7GagTU4srRt2OH1NbZ8=", "dev": true, "requires": { - "no-case": "^2.2.0" + "no-case": "2.3.2" } }, "snapdragon": { @@ -7748,14 +7839,14 @@ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", "dev": true, "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" + "base": "0.11.2", + "debug": "2.6.9", + "define-property": "0.2.5", + "extend-shallow": "2.0.1", + "map-cache": "0.2.2", + "source-map": "0.5.7", + "source-map-resolve": "0.5.2", + "use": "3.1.1" }, "dependencies": { "define-property": { @@ -7764,7 +7855,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } }, "extend-shallow": { @@ -7773,7 +7864,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } } } @@ -7784,9 +7875,9 @@ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", "dev": true, "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" + "define-property": "1.0.0", + "isobject": "3.0.1", + "snapdragon-util": "3.0.1" }, "dependencies": { "define-property": { @@ -7795,7 +7886,7 @@ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", "dev": true, "requires": { - "is-descriptor": "^1.0.0" + "is-descriptor": "1.0.2" } }, "is-accessor-descriptor": { @@ -7804,7 +7895,7 @@ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-data-descriptor": { @@ -7813,7 +7904,7 @@ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", "dev": true, "requires": { - "kind-of": "^6.0.0" + "kind-of": "6.0.2" } }, "is-descriptor": { @@ -7822,9 +7913,9 @@ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", "dev": true, "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" + "is-accessor-descriptor": "1.0.0", + "is-data-descriptor": "1.0.0", + "kind-of": "6.0.2" } }, "isobject": { @@ -7847,7 +7938,7 @@ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", "dev": true, "requires": { - "kind-of": "^3.2.0" + "kind-of": "3.2.2" } }, "sntp": { @@ -7857,7 +7948,7 @@ "dev": true, "optional": true, "requires": { - "hoek": "2.x.x" + "hoek": "2.16.3" } }, "socks": { @@ -7867,8 +7958,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.4", - "smart-buffer": "^1.0.13" + "ip": "1.1.5", + "smart-buffer": "1.1.15" } }, "socks-proxy-agent": { @@ -7878,8 +7969,8 @@ "dev": true, "optional": true, "requires": { - "agent-base": "~4.2.0", - "socks": "~2.2.0" + "agent-base": "4.2.1", + "socks": "2.2.1" }, "dependencies": { "smart-buffer": { @@ -7896,8 +7987,8 @@ "dev": true, "optional": true, "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.0.1" + "ip": "1.1.5", + "smart-buffer": "4.0.1" } } } @@ -7914,11 +8005,11 @@ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", "dev": true, "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" + "atob": "2.1.2", + "decode-uri-component": "0.2.0", + "resolve-url": "0.2.1", + "source-map-url": "0.4.0", + "urix": "0.1.0" } }, "source-map-support": { @@ -7927,7 +8018,7 @@ "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", "dev": true, "requires": { - "source-map": "^0.5.6" + "source-map": "0.5.7" } }, "source-map-url": { @@ -7942,8 +8033,8 @@ "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", "dev": true, "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "spdx-expression-parse": "3.0.0", + "spdx-license-ids": "3.0.0" } }, "spdx-exceptions": { @@ -7958,8 +8049,8 @@ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", "dev": true, "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "spdx-exceptions": "2.1.0", + "spdx-license-ids": "3.0.0" } }, "spdx-license-ids": { @@ -7974,7 +8065,7 @@ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", "dev": true, "requires": { - "extend-shallow": "^3.0.0" + "extend-shallow": "3.0.2" } }, "sprintf-js": { @@ -7989,14 +8080,14 @@ "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", "dev": true, "requires": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "tweetnacl": "~0.14.0" + "asn1": "0.2.3", + "assert-plus": "1.0.0", + "bcrypt-pbkdf": "1.0.1", + "dashdash": "1.14.1", + "ecc-jsbn": "0.1.1", + "getpass": "0.1.7", + "jsbn": "0.1.1", + "tweetnacl": "0.14.5" } }, "stable": { @@ -8006,9 +8097,9 @@ "dev": true }, "standard-file-js": { - "version": "0.3.19", - "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.3.19.tgz", - "integrity": "sha512-H23VzukJescWRQp8WoSGm/arU7KzglC7bY7sGy8AwCcStxvAz278VqysGTnwQGpObxEHsp9hKucnV34RhASLtA==", + "version": "0.3.22", + "resolved": "https://registry.npmjs.org/standard-file-js/-/standard-file-js-0.3.22.tgz", + "integrity": "sha512-nezAUHLX0K0DVtdofrWv2wuznXD8xPJLC/F/usGqtxvtqWbpH+MG99WtHidOd3D38qlGY7PER1nRbFT0WbA92w==", "dev": true }, "static-extend": { @@ -8017,8 +8108,8 @@ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", "dev": true, "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" + "define-property": "0.2.5", + "object-copy": "0.1.0" }, "dependencies": { "define-property": { @@ -8027,7 +8118,7 @@ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", "dev": true, "requires": { - "is-descriptor": "^0.1.0" + "is-descriptor": "0.1.6" } } } @@ -8044,8 +8135,8 @@ "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", "dev": true, "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" + "inherits": "2.0.3", + "readable-stream": "2.3.6" } }, "stream-combiner2": { @@ -8054,8 +8145,8 @@ "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", "dev": true, "requires": { - "duplexer2": "~0.1.0", - "readable-stream": "^2.0.2" + "duplexer2": "0.1.4", + "readable-stream": "2.3.6" } }, "stream-http": { @@ -8064,11 +8155,11 @@ "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", "dev": true, "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" + "builtin-status-codes": "3.0.0", + "inherits": "2.0.3", + "readable-stream": "2.3.6", + "to-arraybuffer": "1.0.1", + "xtend": "4.0.1" } }, "stream-splicer": { @@ -8077,8 +8168,8 @@ "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", "dev": true, "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.2" + "inherits": "2.0.3", + "readable-stream": "2.3.6" } }, "streamroller": { @@ -8087,10 +8178,10 @@ "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", "dev": true, "requires": { - "date-format": "^1.2.0", - "debug": "^3.1.0", - "mkdirp": "^0.5.1", - "readable-stream": "^2.3.0" + "date-format": "1.2.0", + "debug": "3.1.0", + "mkdirp": "0.5.1", + "readable-stream": "2.3.6" }, "dependencies": { "debug": { @@ -8116,7 +8207,7 @@ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "safe-buffer": "5.1.2" } }, "stringmap": { @@ -8144,7 +8235,7 @@ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "2.1.1" } }, "strip-bom": { @@ -8153,7 +8244,7 @@ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", "dev": true, "requires": { - "is-utf8": "^0.2.0" + "is-utf8": "0.2.1" } }, "strip-indent": { @@ -8162,7 +8253,7 @@ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", "dev": true, "requires": { - "get-stdin": "^4.0.1" + "get-stdin": "4.0.1" } }, "subarg": { @@ -8171,7 +8262,7 @@ "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", "dev": true, "requires": { - "minimist": "^1.1.0" + "minimist": "1.2.0" }, "dependencies": { "minimist": { @@ -8194,8 +8285,8 @@ "integrity": "sha1-w5IDpFhzhfrTyFCgvRvK+ggZdOM=", "dev": true, "requires": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" + "lower-case": "1.1.4", + "upper-case": "1.1.3" } }, "syntax-error": { @@ -8204,7 +8295,7 @@ "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", "dev": true, "requires": { - "acorn-node": "^1.2.0" + "acorn-node": "1.3.0" } }, "throttleit": { @@ -8225,8 +8316,8 @@ "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "dev": true, "requires": { - "readable-stream": "^2.1.5", - "xtend": "~4.0.1" + "readable-stream": "2.3.6", + "xtend": "4.0.1" } }, "thunkify": { @@ -8242,7 +8333,7 @@ "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", "dev": true, "requires": { - "process": "~0.11.0" + "process": "0.11.10" } }, "timespan": { @@ -8258,12 +8349,12 @@ "integrity": "sha512-44yhA3tsaRoMOjQQ+5v5mVdqef+kH6Qze9jTpqtVufgYjYt08zyZAwNwwVBj3i1rJMnR52IxOW0LK0vBzgAkuA==", "dev": true, "requires": { - "body": "^5.1.0", - "debug": "^3.1.0", - "faye-websocket": "~0.10.0", - "livereload-js": "^2.3.0", - "object-assign": "^4.1.0", - "qs": "^6.4.0" + "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": { @@ -8283,8 +8374,8 @@ "integrity": "sha1-PhJyFtpY0rxb7PE3q5Ha46fNj6o=", "dev": true, "requires": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" + "no-case": "2.3.2", + "upper-case": "1.1.3" } }, "to-array": { @@ -8311,7 +8402,7 @@ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } }, "to-regex": { @@ -8320,10 +8411,10 @@ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", "dev": true, "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" + "define-property": "2.0.2", + "extend-shallow": "3.0.2", + "regex-not": "1.0.2", + "safe-regex": "1.1.0" } }, "to-regex-range": { @@ -8332,8 +8423,8 @@ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "3.0.0", + "repeat-string": "1.6.1" }, "dependencies": { "is-number": { @@ -8342,7 +8433,7 @@ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, "requires": { - "kind-of": "^3.0.2" + "kind-of": "3.2.2" } } } @@ -8353,7 +8444,7 @@ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==", "dev": true, "requires": { - "punycode": "^1.4.1" + "punycode": "1.4.1" } }, "trim-newlines": { @@ -8393,7 +8484,7 @@ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", "dev": true, "requires": { - "safe-buffer": "^5.0.1" + "safe-buffer": "5.1.2" } }, "tweetnacl": { @@ -8409,7 +8500,7 @@ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", "dev": true, "requires": { - "prelude-ls": "~1.1.2" + "prelude-ls": "1.1.2" } }, "type-detect": { @@ -8425,7 +8516,7 @@ "dev": true, "requires": { "media-typer": "0.3.0", - "mime-types": "~2.1.18" + "mime-types": "2.1.18" } }, "typedarray": { @@ -8440,10 +8531,10 @@ "integrity": "sha1-ZeovswWck5RpLxX+2HwrNsFrmt8=", "dev": true, "requires": { - "async": "~0.2.6", - "source-map": "~0.5.1", - "uglify-to-browserify": "~1.0.0", - "yargs": "~3.10.0" + "async": "0.2.10", + "source-map": "0.5.7", + "uglify-to-browserify": "1.0.2", + "yargs": "3.10.0" }, "dependencies": { "async": { @@ -8478,8 +8569,8 @@ "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=", "dev": true, "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" + "sprintf-js": "1.1.1", + "util-deprecate": "1.0.2" } }, "union-value": { @@ -8488,10 +8579,10 @@ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", "dev": true, "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^0.4.3" + "arr-union": "3.1.0", + "get-value": "2.0.6", + "is-extendable": "0.1.1", + "set-value": "0.4.3" }, "dependencies": { "extend-shallow": { @@ -8500,7 +8591,7 @@ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, "requires": { - "is-extendable": "^0.1.0" + "is-extendable": "0.1.1" } }, "set-value": { @@ -8509,10 +8600,10 @@ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", "dev": true, "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.1", - "to-object-path": "^0.3.0" + "extend-shallow": "2.0.1", + "is-extendable": "0.1.1", + "is-plain-object": "2.0.4", + "to-object-path": "0.3.0" } } } @@ -8529,8 +8620,8 @@ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" + "has-value": "0.3.1", + "isobject": "3.0.1" }, "dependencies": { "has-value": { @@ -8539,9 +8630,9 @@ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" + "get-value": "2.0.6", + "has-values": "0.1.4", + "isobject": "2.1.0" }, "dependencies": { "isobject": { @@ -8587,7 +8678,7 @@ "integrity": "sha1-XXm+3P8UQZUY/S7bCgUHybaFkRU=", "dev": true, "requires": { - "upper-case": "^1.1.1" + "upper-case": "1.1.3" } }, "uri-path": { @@ -8672,7 +8763,7 @@ "integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=", "dev": true, "requires": { - "user-home": "^1.1.1" + "user-home": "1.1.1" } }, "validate-npm-package-license": { @@ -8681,8 +8772,8 @@ "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", "dev": true, "requires": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "spdx-correct": "3.0.0", + "spdx-expression-parse": "3.0.0" } }, "verror": { @@ -8691,9 +8782,9 @@ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", "dev": true, "requires": { - "assert-plus": "^1.0.0", + "assert-plus": "1.0.0", "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" + "extsprintf": "1.3.0" } }, "vm-browserify": { @@ -8714,13 +8805,13 @@ "integrity": "sha512-7jWG0c3cKKm2hKScnSAMUEUjRJKXUShwMPk0ASVhICycQhwND3IMAdhJYmc1mxxKzBUJTSF5HZizfrKrS6BzkA==", "dev": true, "requires": { - "anymatch": "^1.3.0", - "browserify": "^16.1.0", - "chokidar": "^1.0.0", - "defined": "^1.0.0", - "outpipe": "^1.1.0", - "through2": "^2.0.0", - "xtend": "^4.0.0" + "anymatch": "1.3.2", + "browserify": "16.2.2", + "chokidar": "1.7.0", + "defined": "1.0.0", + "outpipe": "1.1.1", + "through2": "2.0.3", + "xtend": "4.0.1" } }, "websocket-driver": { @@ -8729,8 +8820,8 @@ "integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=", "dev": true, "requires": { - "http-parser-js": ">=0.4.0", - "websocket-extensions": ">=0.1.1" + "http-parser-js": "0.4.13", + "websocket-extensions": "0.1.3" } }, "websocket-extensions": { @@ -8752,7 +8843,7 @@ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, "requires": { - "isexe": "^2.0.0" + "isexe": "2.0.0" } }, "window-size": { @@ -8812,9 +8903,9 @@ "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { - "camelcase": "^1.0.2", - "cliui": "^2.1.0", - "decamelize": "^1.0.0", + "camelcase": "1.2.1", + "cliui": "2.1.0", + "decamelize": "1.2.0", "window-size": "0.1.0" }, "dependencies": { @@ -8832,7 +8923,7 @@ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", "dev": true, "requires": { - "fd-slicer": "~1.0.1" + "fd-slicer": "1.0.1" } }, "yeast": { diff --git a/package.json b/package.json index 7c64b522a..0614f8400 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "standard-notes-web", - "version": "2.3.18", + "version": "3.0.0", "license": "AGPL-3.0-or-later", "repository": { "type": "git", @@ -23,7 +23,7 @@ "bower": "^1.8.0", "chai": "^4.1.2", "connect": "^3.6.6", - "grunt": "^1.0.1", + "grunt": "^1.0.3", "grunt-angular-templates": "^1.1.0", "grunt-babel": "^6.0.0", "grunt-browserify": "^5.0.0", @@ -44,7 +44,8 @@ "mocha": "^5.2.0", "serve-static": "^1.13.2", "sn-models": "0.1.9", - "sn-stylekit": "1.0.15", - "standard-file-js": "0.3.19" + "sn-stylekit": "2.0.13", + "standard-file-js": "0.3.22", + "grunt-shell": "^2.1.0" } } diff --git a/public/extensions/batch-manager b/public/extensions/batch-manager index c05c78303..db7b790e3 160000 --- a/public/extensions/batch-manager +++ b/public/extensions/batch-manager @@ -1 +1 @@ -Subproject commit c05c78303875de567585330b3db2716b9e8103d0 +Subproject commit db7b790e3302f4c3ca37cd9502d842e4ae936500 diff --git a/public/extensions/extensions-manager b/public/extensions/extensions-manager index 68b78744c..aa7682717 160000 --- a/public/extensions/extensions-manager +++ b/public/extensions/extensions-manager @@ -1 +1 @@ -Subproject commit 68b78744cbcac3812f07dea59a407b670ab4c5e7 +Subproject commit aa76827177f5067ff5b115cb964900de0380c026