From 65849456d0e349643ecda5bda6aba73d13dc88f1 Mon Sep 17 00:00:00 2001 From: Eric Mc Sween Date: Tue, 16 Jul 2019 10:13:18 +0100 Subject: [PATCH] Merge pull request #1925 from overleaf/as-babel-plugin-angular-annotate Enable Angular "annotations" via Babel plugin GitOrigin-RevId: 343610025e3ba791fb284a0b696a1ea33e125a80 --- services/web/.babelrc | 3 +- services/web/Gruntfile.js | 3 - services/web/npm-shrinkwrap.json | 1817 +++++++---------- services/web/package.json | 1 + services/web/public/src/directives/equals.js | 26 +- .../public/src/directives/eventTracking.js | 121 +- .../controllers/BinaryFileController.js | 378 ++-- .../chat/controllers/ChatMessageController.js | 88 +- .../web/public/src/ide/directives/layout.js | 489 +++-- .../SavingNotificationController.js | 131 +- .../controllers/FileTreeController.js | 1139 +++++------ .../controllers/FileTreeEntityController.js | 204 +- .../FileTreeRootFolderController.js | 42 +- .../ide/file-tree/directives/fileEntity.js | 61 +- .../controllers/HistoryListController.js | 334 ++- .../HistoryV2AddLabelModalController.js | 71 +- .../HistoryV2DeleteLabelModalController.js | 61 +- .../HistoryV2FileTreeController.js | 12 +- .../controllers/HistoryV2ListController.js | 72 +- .../controllers/HistoryV2ToolbarController.js | 10 +- .../src/ide/pdf/controllers/PdfController.js | 366 ++-- .../src/ide/pdfng/directives/pdfHighlights.js | 66 +- .../public/src/ide/pdfng/directives/pdfJs.js | 268 ++- .../src/ide/pdfng/directives/pdfPage.js | 281 ++- .../src/ide/pdfng/directives/pdfRenderer.js | 879 ++++---- .../src/ide/pdfng/directives/pdfSpinner.js | 54 +- .../src/ide/pdfng/directives/pdfTextLayer.js | 110 +- .../src/ide/pdfng/directives/pdfViewer.js | 1560 +++++++------- services/web/public/src/ide/services/ide.js | 190 +- .../controllers/ProjectNameController.js | 123 +- .../controllers/SettingsController.js | 386 ++-- .../src/ide/settings/services/settings.js | 100 +- .../ide/share/controllers/ShareController.js | 112 +- .../src/ide/share/services/projectInvites.js | 74 +- .../src/ide/share/services/projectMembers.js | 56 +- .../web/public/src/main/account-settings.js | 231 +-- .../controllers/UserAffiliationsController.js | 439 ++-- .../factories/UserAffiliationsDataService.js | 270 ++- .../web/public/src/main/clear-sessions.js | 46 +- .../oauth/controllers/UserOauthController.js | 169 +- .../oauth/factories/UserOauthDataService.js | 29 +- .../project-list/services/project-list.js | 56 +- .../web/public/src/modules/errorCatcher.js | 50 +- 43 files changed, 5168 insertions(+), 5810 deletions(-) diff --git a/services/web/.babelrc b/services/web/.babelrc index 0a9b732ab0..60f6c97b52 100644 --- a/services/web/.babelrc +++ b/services/web/.babelrc @@ -2,5 +2,6 @@ "presets": [ "react", ["env", { "modules": false }] - ] + ], + "plugins": ["angularjs-annotate"] } \ No newline at end of file diff --git a/services/web/Gruntfile.js b/services/web/Gruntfile.js index 0104d5b536..17d910fef2 100644 --- a/services/web/Gruntfile.js +++ b/services/web/Gruntfile.js @@ -23,9 +23,6 @@ module.exports = function(grunt) { compile: { options: { optimize: 'uglify2', - uglify2: { - mangle: false - }, appDir: 'public/js', baseUrl: './', dir: 'public/minjs', diff --git a/services/web/npm-shrinkwrap.json b/services/web/npm-shrinkwrap.json index 08738aaeea..08e3c6133e 100644 --- a/services/web/npm-shrinkwrap.json +++ b/services/web/npm-shrinkwrap.json @@ -4,10 +4,73 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "@babel/runtime": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.3.1.tgz", - "integrity": "sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA==", + "integrity": "sha1-V0sD6OipiY6vSocqkuogt4Rvbyo=", "dev": true, "requires": { "regenerator-runtime": "^0.12.0" @@ -16,7 +79,7 @@ "regenerator-runtime": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "integrity": "sha1-+hpxVEdkwDb4xJsToIsllMn4oN4=", "dev": true } } @@ -24,7 +87,7 @@ "@babel/runtime-corejs2": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.3.1.tgz", - "integrity": "sha512-YpO13776h3e6Wy8dl2J8T9Qwlvopr+b4trCEhHE+yek6yIqV8sx6g3KozdHMbXeBpjosbPi+Ii5Z7X9oXFHUKA==", + "integrity": "sha1-DBEyQuIyj5Z01CcDqJvubr6+moI=", "requires": { "core-js": "^2.5.7", "regenerator-runtime": "^0.12.0" @@ -33,19 +96,44 @@ "core-js": { "version": "2.6.5", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", - "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" + "integrity": "sha1-RLyNJJ5/sv9dAOA0Gn/7lPv2eJU=" }, "regenerator-runtime": { "version": "0.12.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", - "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==" + "integrity": "sha1-+hpxVEdkwDb4xJsToIsllMn4oN4=" + } + } + }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + }, + "dependencies": { + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true } } }, "@contentful/axios": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/@contentful/axios/-/axios-0.18.0.tgz", - "integrity": "sha512-4r4Ww1IJlmRolKgovLTTmdS6CsdvXYVxgXRFwWSh1x36T/0Wg9kTwdaVaApZXcv1DfYyw9RSNdxIGSwTP2/Lag==", + "integrity": "sha1-V24OYEdBGmaXHoLUBoiox5XmLyc=", "requires": { "follow-redirects": "^1.2.5", "is-buffer": "^1.1.5" @@ -54,7 +142,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "requires": { "ms": "2.0.0" } @@ -62,7 +150,7 @@ "follow-redirects": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz", - "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==", + "integrity": "sha1-I09Jz3cLfzW0DnkPY2zroMOgq3c=", "requires": { "debug": "^3.1.0" } @@ -171,7 +259,7 @@ "@google-cloud/profiler": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/@google-cloud/profiler/-/profiler-0.2.3.tgz", - "integrity": "sha512-rNvtrFtIebIxZEJ/O0t8n7HciZGIXBo8DvHxWqAmsCaeLvkTtsaL6HmPkwxrNQ1IhbYWAxF+E/DwCiHyhKmgTg==", + "integrity": "sha1-Fj3738Mwuug1X+RuHlvgZTV7H1w=", "requires": { "@google-cloud/common": "^0.26.0", "@types/console-log-level": "^1.4.0", @@ -193,7 +281,7 @@ "@google-cloud/common": { "version": "0.26.2", "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-0.26.2.tgz", - "integrity": "sha512-xJ2M/q3MrUbnYZuFlpF01caAlEhAUoRn0NXp93Hn3pkFpfSOG8YfbKbpBAHvcKVbBOAKVIwPsleNtuyuabUwLQ==", + "integrity": "sha1-nFTiRxqEqgMelaJIJJduCA8lVkU=", "requires": { "@google-cloud/projectify": "^0.3.2", "@google-cloud/promisify": "^0.3.0", @@ -322,7 +410,7 @@ "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==" + "integrity": "sha1-SyzSXFDVmHNcUCkiJP2MbfQeMjE=" }, "readable-stream": { "version": "3.4.0", @@ -342,7 +430,7 @@ "string_decoder": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "integrity": "sha1-/obnOLGVRK/nBGkkOyoe6SQOro0=", "requires": { "safe-buffer": "~5.1.0" } @@ -1308,12 +1396,12 @@ "@protobufjs/base64": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==" + "integrity": "sha1-TIVzDlm5ofHzSQR9vyQpYDS7JzU=" }, "@protobufjs/codegen": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==" + "integrity": "sha1-fvN/DQEPsCitGtWXIuUG2SYoFcs=" }, "@protobufjs/eventemitter": { "version": "1.1.0", @@ -1357,7 +1445,7 @@ "@sheerun/mutationobserver-shim": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz", - "integrity": "sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==", + "integrity": "sha1-gBPyr1Sit9c19xVg/zYNOoF2qHs=", "dev": true }, "@sindresorhus/is": { @@ -1373,12 +1461,12 @@ "@types/console-log-level": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/@types/console-log-level/-/console-log-level-1.4.0.tgz", - "integrity": "sha512-x+OscEQwcx5Biair4enH7ov9W+clcqUWaZRaxn5IkT4yNWWjRr2oiYDkY/x1uXSTVZOQ2xlbFQySaQGB+VdXGQ==" + "integrity": "sha1-7/ccQa689RyLpa2LBdfVQkviuPM=" }, "@types/duplexify": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/@types/duplexify/-/duplexify-3.6.0.tgz", - "integrity": "sha512-5zOA53RUlzN74bvrSGwjudssD9F3a797sDZQkiYpUOxW+WHaXTCPz4/d5Dgi6FKnOqZ2CpaTo0DhgIfsXAOE/A==", + "integrity": "sha1-38grZL06IWj1vSZESvFlvwI33Ng=", "requires": { "@types/node": "*" } @@ -1386,7 +1474,7 @@ "@types/form-data": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-2.2.1.tgz", - "integrity": "sha512-JAMFhOaHIciYVh8fb5/83nmuO/AHwmto+Hq7a9y8FzLDcC1KCU344XDOMEmahnrTFlHjgh4L0WJFczNIX2GxnQ==", + "integrity": "sha1-7is7jqoRwJOCiZU2BrdFtzjFSx4=", "requires": { "@types/node": "*" } @@ -1394,12 +1482,12 @@ "@types/geojson": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/@types/geojson/-/geojson-1.0.6.tgz", - "integrity": "sha512-Xqg/lIZMrUd0VRmSRbCAewtwGZiAk3mEUDvV4op1tGl+LvyPcb/MIOSxTl9z+9+J+R4/vpjiCAT4xeKzH9ji1w==" + "integrity": "sha1-PgKXJyjGkkjCrwjWCkjLuGgP/98=" }, "@types/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", - "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + "integrity": "sha1-cZVR0jUtMBrIuB23Mqy2vcKNve8=" }, "@types/node": { "version": "12.0.8", @@ -1409,7 +1497,7 @@ "@types/request": { "version": "2.48.1", "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.1.tgz", - "integrity": "sha512-ZgEZ1TiD+KGA9LiAAPPJL68Id2UWfeSO62ijSXZjFJArVV+2pKcsVHmrcu+1oiE3q6eDGiFiSolRc4JHoerBBg==", + "integrity": "sha1-5ALWkapmcPu/8ZV7FfEnAjCrQvo=", "requires": { "@types/caseless": "*", "@types/form-data": "*", @@ -1420,17 +1508,17 @@ "@types/semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + "integrity": "sha1-FGwqKe59O65L8vyydGNuJkyBPEU=" }, "@types/tough-cookie": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-2.3.5.tgz", - "integrity": "sha512-SCcK7mvGi3+ZNz833RRjFIxrn4gI1PPR3NtuIS+6vMkvmsGjosqTJwRt5bAEFLRz+wtJMWv8+uOnZf2hi2QXTg==" + "integrity": "sha1-naRO11VxmZtlw3tgybK4jbVMWF0=" }, "abbrev": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==" + "integrity": "sha1-+PLIh60Qv2f2NPAFtph/7TF5qsg=" }, "abort-controller": { "version": "3.0.0", @@ -1452,7 +1540,7 @@ "acorn": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.0.tgz", - "integrity": "sha512-MW/FjM+IvU9CgBzjO3UIPCE2pyEwUsoFl+VGdczOPEdxfGFjuKny/gN54mOuX7Qxmb9Rg9MCn2oKiSUeW+pjrw==" + "integrity": "sha1-sKO+MXUsl6D3ATxfSQO3GgXbaBg=" }, "acorn-dynamic-import": { "version": "2.0.2", @@ -1506,7 +1594,7 @@ "acorn-walk": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "integrity": "sha1-02O2b1+sXwGP+cOh57b44xDMORM=", "dev": true }, "after": { @@ -1518,7 +1606,7 @@ "agent-base": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", - "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", + "integrity": "sha1-mDi1wzkrliutAx5qTF4QJKvsRc4=", "requires": { "es6-promisify": "^5.0.0" } @@ -1558,7 +1646,7 @@ "amqplib": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/amqplib/-/amqplib-0.5.2.tgz", - "integrity": "sha512-l9mCs6LbydtHqRniRwYkKdqxVa6XMz3Vw1fh+2gJaaVgTM6Jk3o8RccAKWKtlhT1US5sWrFh+KKxsVUALURSIA==", + "integrity": "sha1-0tcxPH/6pNELzx5iUt5FkbbMe2M=", "dev": true, "optional": true, "requires": { @@ -1572,7 +1660,7 @@ "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=", "dev": true, "optional": true }, @@ -1615,7 +1703,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -1636,7 +1724,7 @@ "ansi-escapes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz", - "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw==", + "integrity": "sha1-9zIHu4EgfXX9bIPxJa8m7qN4yjA=", "dev": true }, "ansi-html": { @@ -1659,7 +1747,7 @@ "anymatch": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", + "integrity": "sha1-VT3Lj5HjyImEXf26NMd3IbkLnXo=", "dev": true, "requires": { "micromatch": "^2.1.5", @@ -1674,7 +1762,7 @@ "aproba": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==" + "integrity": "sha1-aALmJk79GMeQobDVF/DyYnvyyUo=" }, "archiver": { "version": "0.9.0", @@ -1777,7 +1865,7 @@ "commander": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "integrity": "sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So=", "dev": true } } @@ -1794,7 +1882,7 @@ "arr-flatten": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "integrity": "sha1-NgSLv/TntH4TZkQxbJlmnqWukfE=", "dev": true }, "arr-union": { @@ -1854,7 +1942,7 @@ "arraybuffer.slice": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz", - "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==", + "integrity": "sha1-O7xCdd1YTMGxCAm4nU6LY6aednU=", "dev": true }, "arrify": { @@ -1875,7 +1963,7 @@ "asn1.js": { "version": "4.10.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "integrity": "sha1-ucK/WAXx5kqt7tbfOiv6+1pz9aA=", "dev": true, "requires": { "bn.js": "^4.0.0", @@ -1900,7 +1988,7 @@ "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", - "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "integrity": "sha1-5gtrDo8wG9l+U3UhW9pAbIURjAs=", "dev": true }, "assign-symbols": { @@ -1912,7 +2000,7 @@ "ast-types": { "version": "0.11.3", "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz", - "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", + "integrity": "sha1-wgdX/nLucSeOoP89h+XCyjDZ7fg=", "dev": true, "optional": true }, @@ -1936,13 +2024,13 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "integrity": "sha1-ePrtjD0HSrgfIrTphdeehzj3IPg=", "dev": true }, "async-listener": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", + "integrity": "sha1-p8l6vlcLpgLXgic8DeYKUePhfLw=", "requires": { "semver": "^5.3.0", "shimmer": "^1.1.0" @@ -1992,7 +2080,7 @@ "uuid": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" + "integrity": "sha1-PdPT55Crwk17DToDT/q6vijrvAQ=" }, "xml2js": { "version": "0.4.17", @@ -2033,7 +2121,7 @@ "axobject-query": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", - "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "integrity": "sha1-6hh6vluQArN3+SXYv30cVhrfOPk=", "dev": true, "requires": { "ast-types-flow": "0.0.7" @@ -2065,13 +2153,13 @@ "commander": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "integrity": "sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So=", "dev": true }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -2085,7 +2173,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -2113,7 +2201,7 @@ "babel-core": { "version": "6.26.3", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", + "integrity": "sha1-suLwnjQtDwyI4vAuBneUEl51wgc=", "dev": true, "requires": { "babel-code-frame": "^6.26.0", @@ -2140,7 +2228,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -2149,7 +2237,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -2166,7 +2254,7 @@ "babel-generator": { "version": "6.26.1", "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", + "integrity": "sha1-GERAjTuPDTWkBOp6wYDwh6YBvZA=", "dev": true, "requires": { "babel-messages": "^6.23.0", @@ -2355,6 +2443,17 @@ "babel-runtime": "^6.22.0" } }, + "babel-plugin-angularjs-annotate": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/babel-plugin-angularjs-annotate/-/babel-plugin-angularjs-annotate-0.10.0.tgz", + "integrity": "sha512-NPE7FOAxcLPCUR/kNkrhHIjoScR3RyIlRH3yRn79j8EZWtpILVnCOdA9yKfsOmRh6BHnLHKl8ZAThc+YDd/QwQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/types": "^7.2.0", + "simple-is": "~0.2.0" + } + }, "babel-plugin-check-es2015-constants": { "version": "6.22.0", "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", @@ -2525,7 +2624,7 @@ "babel-plugin-transform-es2015-modules-commonjs": { "version": "6.26.2", "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", + "integrity": "sha1-WKeThjqefKhwvcWogRF/+sJ9tvM=", "dev": true, "requires": { "babel-plugin-transform-strict-mode": "^6.24.1", @@ -2741,7 +2840,7 @@ "babel-preset-env": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "integrity": "sha1-3qefpOvriDzTXasH4mDBycBN93o=", "dev": true, "requires": { "babel-plugin-check-es2015-constants": "^6.22.0", @@ -2779,7 +2878,7 @@ "browserslist": { "version": "3.2.7", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.7.tgz", - "integrity": "sha512-oYVLxFVqpX9uMhOIQBLtZL+CX4uY8ZpWcjNTaxyWl5rO8yA9SSNikFnAfvk8J3P/7z3BZwNmEqFKaJoYltj3MQ==", + "integrity": "sha1-qkiGNNMgtV6IurAlYYTbvMoebek=", "dev": true, "requires": { "caniuse-lite": "^1.0.30000835", @@ -2869,7 +2968,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -2892,7 +2991,7 @@ "babylon": { "version": "6.18.0", "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==", + "integrity": "sha1-ry87iPpvXB5MY00aD46sT1WzleM=", "dev": true }, "backbone": { @@ -2906,7 +3005,7 @@ "underscore": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.9.0.tgz", - "integrity": "sha512-4IV1DSSxC1QK48j9ONFK1MoIAKKkbE8i7u55w2R6IqBqbT7A/iG7aZBCR2Bi8piF0Uz+i/MG1aeqLwl/5vqF+A==" + "integrity": "sha1-MduzFM/MiPFpzTaS2RSdgaAKc+Q=" } } }, @@ -2932,7 +3031,7 @@ "base": { "version": "0.11.2", "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "integrity": "sha1-e95c7RRbbVUakNuH+DxVi060io8=", "dev": true, "requires": { "cache-base": "^1.0.1", @@ -2956,7 +3055,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -2965,7 +3064,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -2974,7 +3073,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -2991,7 +3090,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } @@ -3005,7 +3104,7 @@ "base64-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", - "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==" + "integrity": "sha1-qRlH2h9KUW6jjltOwOw3c2deCIY=" }, "base64-stream": { "version": "0.1.3", @@ -3023,7 +3122,7 @@ "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -3037,7 +3136,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "requires": { "safe-buffer": "~5.1.0" } @@ -3084,7 +3183,7 @@ "bcrypt": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/bcrypt/-/bcrypt-3.0.4.tgz", - "integrity": "sha512-XqmCym97kT6l+jFEKeFvGuNE9aVEFDGsLMv+tIBTXkJI1sHS0g8s7VQEPJagSMPwWiB5Vpr2kVzVKc/YfwWthA==", + "integrity": "sha1-HIgTed3yG8reVuMXJmnScVLZDVA=", "requires": { "nan": "2.12.1", "node-pre-gyp": "0.12.0" @@ -3328,7 +3427,7 @@ "nan": { "version": "2.12.1", "resolved": "https://registry.npmjs.org/nan/-/nan-2.12.1.tgz", - "integrity": "sha512-JY7V6lRkStKcKTvHO5NVSQRv+RV+FIL5pvDoLiAtSL9pKlC5x9PKQcZDsq7m4FO4d57mkhC6Z+QhAh3Jdk5JFw==" + "integrity": "sha1-exqhk+mqhgV+PHu9CsRI53CSVVI=" }, "needle": { "version": "2.2.4", @@ -3611,13 +3710,13 @@ "big.js": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", - "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "integrity": "sha1-pfwpi4G54Nyi5FiCR4S2XFK6WI4=", "dev": true }, "bignumber.js": { "version": "7.2.1", "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", - "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" + "integrity": "sha1-gMBIdZ2CaACAfEv9Uh5Q7bulel8=" }, "binary-extensions": { "version": "1.11.0", @@ -3670,7 +3769,7 @@ "bn.js": { "version": "4.11.8", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "integrity": "sha1-LN4J617jQfSEdGuwMJsyU7GxRC8=", "dev": true }, "body-parser": { @@ -3693,7 +3792,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "requires": { "ms": "2.0.0" } @@ -3701,7 +3800,7 @@ "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" } } }, @@ -3744,7 +3843,7 @@ "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", + "integrity": "sha1-VcbDmouljZxhrSLNh3Uy3rZlogs=", "dev": true, "requires": { "ansi-align": "^2.0.0", @@ -3765,7 +3864,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -3780,7 +3879,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -3803,7 +3902,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -3822,7 +3921,7 @@ "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -3864,7 +3963,7 @@ "browserify-aes": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "integrity": "sha1-Mmc0ZC9APavDADIJhTu3CtQo70g=", "dev": true, "requires": { "buffer-xor": "^1.0.3", @@ -3878,7 +3977,7 @@ "browserify-cipher": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "integrity": "sha1-jWR0wbhwv9q807z8wZNKEOlPFfA=", "dev": true, "requires": { "browserify-aes": "^1.0.4", @@ -3889,7 +3988,7 @@ "browserify-des": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", - "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", + "integrity": "sha1-M0MSTbbXrVPiaogmMYcSvchFD5w=", "dev": true, "requires": { "cipher-base": "^1.0.1", @@ -3925,7 +4024,7 @@ "browserify-zlib": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "integrity": "sha1-KGlFnZqjviRf6P4sofRuLn9U1z8=", "dev": true, "requires": { "pako": "~1.0.5" @@ -3976,12 +4075,12 @@ "buffer-from": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", - "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==" + "integrity": "sha1-TLiDLSNhJYmwQG6eKVbBfwb99TE=" }, "buffer-indexof": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", - "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "integrity": "sha1-Uvq8xqYG0aADAoAmSO9o9jnaJow=", "dev": true }, "buffer-more-ints": { @@ -4077,7 +4176,7 @@ "cache-base": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "integrity": "sha1-Cn9GQWgxyLZi7jb+TnxZ129marI=", "dev": true, "requires": { "collection-visit": "^1.0.0", @@ -4157,7 +4256,7 @@ "caniuse-lite": { "version": "1.0.30000840", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000840.tgz", - "integrity": "sha512-Lw6AaouV6lh7TgIdQtLiUFKKO2mtDnZFkzCq5/V6tqs4ZI0OGVSDCEt1uegZ3OOBEBUYuVw3Hhr9DQSbgVofFA==", + "integrity": "sha1-NEUT+PhDU2z5lpSWTAmBEnfu45U=", "dev": true }, "capture-stack-trace": { @@ -4183,7 +4282,7 @@ "chai": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", - "integrity": "sha512-eRYY0vPS2a9zt5w5Z0aCeWbrXTEyvk7u/Xf71EzNObrjSCPgMm1Nku/D/u2tiqHBX5j40wWhj54YJLtgn8g55A==", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", "dev": true, "requires": { "assertion-error": "^1.0.1", @@ -4194,7 +4293,7 @@ "chai-spies": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/chai-spies/-/chai-spies-1.0.0.tgz", - "integrity": "sha512-elF2ZUczBsFoP07qCfMO/zeggs8pqCf3fZGyK5+2X4AndS8jycZYID91ztD9oQ7d/0tnS963dPkd0frQEThDsg==", + "integrity": "sha1-0Ws5M2+zFtA6v4w3X+sjwMi7Fj0=", "dev": true }, "chalk": { @@ -4237,7 +4336,6 @@ "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", @@ -4255,7 +4353,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -4264,7 +4362,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -4297,7 +4395,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -4308,7 +4406,7 @@ "chownr": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==" + "integrity": "sha1-VHJri4//TfBTxCGH6AH7RBLfFJQ=" }, "ci-info": { "version": "1.1.3", @@ -4319,7 +4417,7 @@ "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", "dev": true, "requires": { "inherits": "^2.0.1", @@ -4329,13 +4427,13 @@ "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "integrity": "sha1-gVyZ6oT2gJUp0vRXkb34JxE1LWY=", "dev": true }, "class-utils": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "integrity": "sha1-+TNprouafOAv1B+q0MqDAzGQxGM=", "dev": true, "requires": { "arr-union": "^3.1.0", @@ -4391,7 +4489,7 @@ "clean-css-cli": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/clean-css-cli/-/clean-css-cli-4.2.1.tgz", - "integrity": "sha512-ST2yi9F2kAmLRs9phSpGRUm44SbRy29QGm1OuAKfTU0KCLilFMTcz+/Fxhbdi5GrsjIMhTBdFUQhc55CjM3Isw==", + "integrity": "sha1-CjZwd62Fy0RRFIrB8u206xmStO0=", "dev": true, "requires": { "clean-css": "^4.2.1", @@ -4402,7 +4500,7 @@ "clean-css": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz", - "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==", + "integrity": "sha1-LUEe92uFabbQyEBo2r6FsKpeXBc=", "dev": true, "requires": { "source-map": "~0.6.0" @@ -4411,7 +4509,7 @@ "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -4425,7 +4523,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -4434,7 +4532,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true } } @@ -4478,7 +4576,7 @@ "cluster-key-slot": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/cluster-key-slot/-/cluster-key-slot-1.0.12.tgz", - "integrity": "sha512-21O0kGmvED5OJ7ZTdqQ5lQQ+sjuez33R+d35jZKLwqUb5mqcPHUsxOSzj61+LHVtxGZd1kShbQM3MjB/gBJkVg==" + "integrity": "sha1-1d7/KlIHF7yYMTl5tocwmy02jik=" }, "co": { "version": "4.6.0", @@ -4507,7 +4605,7 @@ "codemirror": { "version": "5.33.0", "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.33.0.tgz", - "integrity": "sha512-HT6PKVqkwpzwB3jl5hXFoQteEWXbSWMzG3Z8RVYlx8hZwCOLCy4NU7vkSB3dYX3e6ORwRfGw4uFOXaw4rn/a9Q==" + "integrity": "sha1-RirZpv6NOLVBqVNqOZfh75O0DGo=" }, "coffee-script": { "version": "1.12.4", @@ -4528,7 +4626,7 @@ "color-convert": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz", - "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==", + "integrity": "sha1-wSYRB66y8pTr/+ye2eytUppgl+0=", "dev": true, "requires": { "color-name": "^1.1.1" @@ -4571,7 +4669,7 @@ "common-tags": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.8.0.tgz", - "integrity": "sha512-6P6g0uetGpW/sdyUy/iQQCbFF0kWVMSIVSyYz7Zgjcgh8mgw8PQzDNZeyZ5DQ2gM7LBoZPHmnjz8rUthkBG5tw==", + "integrity": "sha1-jjFT5ULUo56bEFVENK+q+YlWqTc=", "dev": true }, "commondir": { @@ -4643,7 +4741,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -4652,13 +4750,13 @@ "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "integrity": "sha1-o0kgUKXLm2NFBUHjnZeI0icng9s=", "dev": true }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "integrity": "sha1-bzI/YKg9ERRvgx/xH9ZuL+VQO7g=", "dev": true, "requires": { "mime-db": "~1.33.0" @@ -4686,7 +4784,7 @@ "concat-stream": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "integrity": "sha1-kEvfGUzTEi/Gdcd/xKw9T/D9GjQ=", "requires": { "buffer-from": "^1.0.0", "inherits": "^2.0.3", @@ -4702,7 +4800,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" }, "readable-stream": { "version": "2.3.6", @@ -4721,7 +4819,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "requires": { "safe-buffer": "~5.1.0" } @@ -4731,7 +4829,7 @@ "configstore": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz", - "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==", + "integrity": "sha1-xvJd767vJt8S3TNBSwAf6BpUP48=", "dev": true, "requires": { "dot-prop": "^4.1.0", @@ -4757,7 +4855,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -4807,7 +4905,7 @@ "connect-redis": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/connect-redis/-/connect-redis-3.3.3.tgz", - "integrity": "sha512-rpWsW2uk1uOe/ccY/JvW+RiLrhZm7auIx8z4yR+KXemFTIhJyD58jXiJbI0E/fZCnybawpdSqOZ+6/ah6aBeyg==", + "integrity": "sha1-D7jzcBkvYtp17HqVB4B1mfvhWzc=", "requires": { "debug": "^3.1.0", "redis": "^2.1.0" @@ -4816,7 +4914,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "requires": { "ms": "2.0.0" } @@ -4870,17 +4968,17 @@ "content-security-policy-builder": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.0.0.tgz", - "integrity": "sha512-j+Nhmj1yfZAikJLImCvPJFE29x/UuBi+/MWqggGGc515JKaZrjuei2RhULJmy0MsstW3E3htl002bwmBNMKr7w==" + "integrity": "sha1-h0mh1UL8voIjcoHqn3Fs5os5TdI=" }, "content-type": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" + "integrity": "sha1-4TjMdeBAxyexlm/l5fjJruJW/js=" }, "contentful": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/contentful/-/contentful-6.1.1.tgz", - "integrity": "sha512-Jirqr3aPzo5FhFl15NNCSvnVQosc2+f90qvxgH0vrwhJNka2H4Fdg2ioxNTME3HWkENsY541GJcN/9DwBv1btg==", + "integrity": "sha1-df2VEldyjZ3huaLQS50mim2NGg0=", "requires": { "@contentful/axios": "^0.18.0", "contentful-resolve-response": "^1.1.4", @@ -4892,14 +4990,14 @@ "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==" + "integrity": "sha1-G3eTz3JZ6jj7NmHU04syYK+K5Oc=" } } }, "contentful-resolve-response": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/contentful-resolve-response/-/contentful-resolve-response-1.1.4.tgz", - "integrity": "sha512-oFq6n6zjbiwD9/7mBa8YHPwvPM0B0D4uOgg1n/rVzpQPhCrzeIixNj6fbJAbDiJt05rZqxiY3K1Db7pPRhRaZw==", + "integrity": "sha1-nrZWh27sss0ARE8K3ya9kaXsGZI=", "requires": { "lodash": "^4.17.4" } @@ -4916,7 +5014,7 @@ "continuation-local-storage": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", + "integrity": "sha1-EfYT906RT+mzTJKtLSj+auHbf/s=", "requires": { "async-listener": "^0.6.0", "emitter-listener": "^1.1.1" @@ -4957,7 +5055,7 @@ "cookies": { "version": "0.7.3", "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.7.3.tgz", - "integrity": "sha512-+gixgxYSgQLTaTIilDHAdlNPZDENDQernEMiIcZpYYP14zgHsCt4Ce1FEjFtcp6GefhozebB6orvhAAWx/IS0A==", + "integrity": "sha1-eRLOIfvy6MLacM8cPzUa7PWdrfo=", "dev": true, "requires": { "depd": "~1.1.2", @@ -4973,7 +5071,7 @@ "core-js": { "version": "2.5.6", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz", - "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ==", + "integrity": "sha1-D+bUW/PKw6w2Sp1y3nV29OsiG50=", "dev": true }, "core-util-is": { @@ -4998,7 +5096,7 @@ "create-ecdh": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "integrity": "sha1-yREbbzMEXEaX8UR4f5JUzcd8Rf8=", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -5017,7 +5115,7 @@ "create-hash": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "integrity": "sha1-iJB4rxGmN1a8+1m9IhmWvjqe8ZY=", "dev": true, "requires": { "cipher-base": "^1.0.1", @@ -5030,7 +5128,7 @@ "create-hmac": { "version": "1.1.7", "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "integrity": "sha1-aRcMeLOrlXFHsriwRXLkfq0iQ/8=", "dev": true, "requires": { "cipher-base": "^1.0.3", @@ -5044,7 +5142,7 @@ "create-react-class": { "version": "15.6.3", "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz", - "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==", + "integrity": "sha1-LXMjf7P5cK5uvgEanmb0bbyoADY=", "requires": { "fbjs": "^0.8.9", "loose-envify": "^1.3.1", @@ -5065,7 +5163,7 @@ "lru-cache": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz", - "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==", + "integrity": "sha1-oRdc80lt/IQ2wVbDNLSVWZK85pw=", "dev": true, "requires": { "pseudomap": "^1.0.2", @@ -5075,7 +5173,7 @@ "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", "dev": true, "requires": { "isexe": "^2.0.0" @@ -5094,7 +5192,7 @@ "boom": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", + "integrity": "sha1-XdnabuOl8wIHdDYpDLcX0/SlTgI=", "requires": { "hoek": "4.x.x" } @@ -5104,7 +5202,7 @@ "crypto-browserify": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "integrity": "sha1-OWz58xN/A+S45TLFj2mCVOAPgOw=", "dev": true, "requires": { "browserify-cipher": "^1.0.0", @@ -5246,7 +5344,7 @@ "data-uri-to-buffer": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz", - "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ==", + "integrity": "sha1-dxY+qcINhkG0cH6PGKvfmnjzSDU=", "dev": true, "optional": true }, @@ -5343,7 +5441,7 @@ "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "integrity": "sha1-1Flono1lS6d+AqgX+HENcCyxbp0=", "dev": true, "requires": { "is-descriptor": "^1.0.2", @@ -5353,7 +5451,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -5362,7 +5460,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -5371,7 +5469,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -5388,7 +5486,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } @@ -5440,7 +5538,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -5454,7 +5552,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -5469,7 +5567,7 @@ "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "dev": true, "requires": { "glob": "^7.0.5" @@ -5568,7 +5666,7 @@ "diffie-hellman": { "version": "5.0.3", "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "integrity": "sha1-QOjumPVaIUlgcUaSHGPhrl89KHU=", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -5579,7 +5677,7 @@ "dlv": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/dlv/-/dlv-1.1.2.tgz", - "integrity": "sha512-xxD4VSH67GbRvSGUrckvha94RD7hjgOH7rqGxiytLpkaeMvixOHFZTGFK6EkIm3T761OVHT8ABHmGkq9gXgu6Q==", + "integrity": "sha1-Jw9nN7MNJbZlen6WLHhEA/hRN+U=", "dev": true }, "dns-equal": { @@ -5591,7 +5689,7 @@ "dns-packet": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", - "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "integrity": "sha1-EqpCaYEHW+UAuRDu3NC0fdfe2lo=", "dev": true, "requires": { "ip": "^1.1.0", @@ -5615,7 +5713,7 @@ "doctrine": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "integrity": "sha1-XNAfwQFiG0LEzX9dGmYkNxbT850=", "dev": true, "requires": { "esutils": "^2.0.2" @@ -5659,7 +5757,7 @@ "dom-testing-library": { "version": "3.16.5", "resolved": "https://registry.npmjs.org/dom-testing-library/-/dom-testing-library-3.16.5.tgz", - "integrity": "sha512-t3OaTcDdsAqtAZNeZ13KnOJmt+2HaDJqYWyf0iBRzbG6GwrNtpF0122Ygu/qkerIwcnHMX1ihwZVx/DhaLpmTw==", + "integrity": "sha1-jHHxJ8a07kgRVmB5gEApG1nfyJQ=", "dev": true, "requires": { "@babel/runtime": "^7.1.5", @@ -5671,13 +5769,13 @@ "ansi-regex": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", - "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "integrity": "sha1-cN55Ht8CFATD/WFaqJEYrgQy5ak=", "dev": true }, "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -5686,7 +5784,7 @@ "pretty-format": { "version": "24.0.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-24.0.0.tgz", - "integrity": "sha512-LszZaKG665djUcqg5ZQq+XzezHLKrxsA86ZABTozp+oNhkdqa+tG2dX4qa6ERl5c/sRDrAa3lHmwnvKoP+OG/g==", + "integrity": "sha1-y2WZ/XOsCI437WgvYSkeRnj0hZE=", "dev": true, "requires": { "ansi-regex": "^4.0.0", @@ -5698,19 +5796,19 @@ "domain-browser": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "integrity": "sha1-PTH1AZGmdJ3RN1p/Ui6CPULlTto=", "dev": true }, "domelementtype": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "integrity": "sha1-0EjESzew0Qp/Kj1f7j9DM9eQSB8=", "dev": true }, "domhandler": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "integrity": "sha1-iAUJfpM9ZehVRvcm1g9euItE+AM=", "dev": true, "requires": { "domelementtype": "1" @@ -5719,7 +5817,7 @@ "domutils": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "integrity": "sha1-Vuo0HoNOBuZ0ivehyyXaZ+qfjCo=", "dev": true, "requires": { "dom-serializer": "0", @@ -5734,7 +5832,7 @@ "dot-prop": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "integrity": "sha1-HxngwuGqDjJ5fEl5nyg3rGr2nFc=", "dev": true, "requires": { "is-obj": "^1.0.0" @@ -5886,7 +5984,7 @@ "emitter-listener": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", + "integrity": "sha1-VrFA6PaZI3Wz18ssqxzHQy2WMug=", "requires": { "shimmer": "^1.2.0" }, @@ -5894,14 +5992,14 @@ "shimmer": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==" + "integrity": "sha1-YQhZ994ye1h+/r9QH7QxF/mv8zc=" } } }, "emoji-regex": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-6.5.1.tgz", - "integrity": "sha512-PAHp6TxrCy7MGMFidro8uikr+zlJJKJ/Q6mm2ExZ7HwkyR9lSVFfE3kt36qcwa24BQL7y0G9axycGjK1A/0uNQ==", + "integrity": "sha1-m66pKbFVVlwR6kHGYm6qZc75ksI=", "dev": true }, "emojis-list": { @@ -5927,7 +6025,7 @@ "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" } } }, @@ -5942,7 +6040,7 @@ "engine.io": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.5.tgz", - "integrity": "sha512-D06ivJkYxyRrcEe0bTpNnBQNgP9d3xog+qZlLbui8EsMr/DouQpf5o9FzJnWYHEYE0YsFHllUv2R1dkgYZXHcA==", + "integrity": "sha1-Dn751pDrCzVZfx1K0Comyi26OEU=", "dev": true, "requires": { "accepts": "~1.3.4", @@ -5973,7 +6071,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -5982,13 +6080,13 @@ "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "integrity": "sha1-o0kgUKXLm2NFBUHjnZeI0icng9s=", "dev": true }, "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "integrity": "sha1-bzI/YKg9ERRvgx/xH9ZuL+VQO7g=", "dev": true, "requires": { "mime-db": "~1.33.0" @@ -6005,7 +6103,7 @@ "engine.io-client": { "version": "3.1.6", "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.6.tgz", - "integrity": "sha512-hnuHsFluXnsKOndS4Hv6SvUrgdYx1pk2NqfaDMW+GWdgfU3+/V25Cj7I8a0x92idSpa5PIhJRKxPvp9mnoLsfg==", + "integrity": "sha1-W96xMPi5SlCsXL63JYPnpKBj3f0=", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -6024,7 +6122,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -6035,7 +6133,7 @@ "engine.io-parser": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz", - "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==", + "integrity": "sha1-TA9M/3mq7su9z96maoI8YIVAkZY=", "dev": true, "requires": { "after": "0.8.2", @@ -6065,13 +6163,13 @@ "entities": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "integrity": "sha1-vfpzUplmTfr9NFKe1PhSKidf6lY=", "dev": true }, "errno": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "integrity": "sha1-RoTXF3mtOa8Xfj8AeZb3xnyFJhg=", "dev": true, "requires": { "prr": "~1.0.1" @@ -6089,7 +6187,7 @@ "es-abstract": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", - "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", + "integrity": "sha1-zOh9UY8Elok7GjDNhGGDVTVIBoE=", "dev": true, "requires": { "es-to-primitive": "^1.1.1", @@ -6113,7 +6211,7 @@ "es5-ext": { "version": "0.10.42", "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz", - "integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==", + "integrity": "sha1-jAfdM68E1dzRMQtc7xO+pjqJuo0=", "dev": true, "requires": { "es6-iterator": "~2.0.3", @@ -6149,7 +6247,7 @@ "es6-promise": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz", - "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==" + "integrity": "sha1-3EIhwrFlGHYL2MOaUtjzVvwA7Sk=" }, "es6-promisify": { "version": "5.0.0", @@ -6207,7 +6305,7 @@ "escodegen": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", - "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", + "integrity": "sha1-264X75bI5L7bE1b0UE+kzC98t+I=", "dev": true, "optional": true, "requires": { @@ -6228,7 +6326,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true, "optional": true } @@ -6249,7 +6347,7 @@ "eslint": { "version": "4.19.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz", - "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==", + "integrity": "sha1-MtHWU+HZBAiFS/spbwdux+GGowA=", "dev": true, "requires": { "ajv": "^5.3.0", @@ -6301,7 +6399,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -6310,7 +6408,7 @@ "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", "dev": true, "requires": { "sprintf-js": "~1.0.2" @@ -6319,7 +6417,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -6330,7 +6428,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -6339,13 +6437,13 @@ "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "integrity": "sha1-RJnt3NERDgshi6zy+n9/WfVcqAQ=", "dev": true }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -6359,7 +6457,7 @@ "globals": { "version": "11.5.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz", - "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ==", + "integrity": "sha1-a8hA3mdxFzsZHxPTqclNRB7pJkI=", "dev": true }, "has-flag": { @@ -6371,7 +6469,7 @@ "js-yaml": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz", - "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==", + "integrity": "sha1-WXwai9VxUvJtYizkEXhRpR9euu8=", "dev": true, "requires": { "argparse": "^1.0.7", @@ -6381,7 +6479,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -6399,7 +6497,7 @@ "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -6410,7 +6508,7 @@ "eslint-config-prettier": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-3.1.0.tgz", - "integrity": "sha512-QYGfmzuc4q4J6XIhlp8vRKdI/fI0tQfQPy1dME3UOLprE+v4ssH/3W9LM2Q7h5qBcy5m0ehCrBDU2YF8q6OY8w==", + "integrity": "sha1-LCbSzc+joF8GQs1+bk7zMWzav6I=", "dev": true, "requires": { "get-stdin": "^6.0.0" @@ -6419,7 +6517,7 @@ "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "integrity": "sha1-ngm/cSs2CrkiXoEgSPcf3pyJZXs=", "dev": true } } @@ -6427,19 +6525,19 @@ "eslint-config-standard": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-11.0.0.tgz", - "integrity": "sha512-oDdENzpViEe5fwuRCWla7AXQd++/oyIp8zP+iP9jiUPG6NBj3SHgdgtl/kTn00AjeN+1HNvavTKmYbMo+xMOlw==", + "integrity": "sha1-h+4NPJ2VOC3HYZWMuyPanuox4Lo=", "dev": true }, "eslint-config-standard-jsx": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-5.0.0.tgz", - "integrity": "sha512-rLToPAEqLMPBfWnYTu6xRhm2OWziS2n40QFqJ8jAM8NSVzeVKTa3nclhsU4DpPJQRY60F34Oo1wi/71PN/eITg==", + "integrity": "sha1-Sr+sVU84Zo4AeMZkVp57I4Tl0qo=", "dev": true }, "eslint-config-standard-react": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/eslint-config-standard-react/-/eslint-config-standard-react-6.0.0.tgz", - "integrity": "sha512-YWlqfvREbH1r6SaRTgFOq+VE3f8/ZQypkfnpDpSmZjztEjxnzznm4xeE2/mDQRx77Okhd/pKHXNZLMsSneJH8A==", + "integrity": "sha1-02bWw8CSQm/TrnlKTKCzyxMfKWQ=", "dev": true, "requires": { "eslint-config-standard-jsx": "^5.0.0" @@ -6448,7 +6546,7 @@ "eslint-import-resolver-node": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", - "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "integrity": "sha1-WPFfuDm40FdsqYBBNHaqskcttmo=", "dev": true, "requires": { "debug": "^2.6.9", @@ -6458,7 +6556,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -6479,7 +6577,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -6524,7 +6622,7 @@ "eslint-plugin-chai-friendly": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/eslint-plugin-chai-friendly/-/eslint-plugin-chai-friendly-0.4.1.tgz", - "integrity": "sha512-hkpLN7VVoGGsofZjUhcQ+sufC3FgqMJwD0DvAcRfxY1tVRyQyVsqpaKnToPHJQOrRo0FQ0fSEDwW2gr4rsNdGA==", + "integrity": "sha1-nusX+SJ3uoC7ZPDpRsaTajrnB7Q=", "dev": true }, "eslint-plugin-import": { @@ -6593,7 +6691,7 @@ "eslint-plugin-jsx-a11y": { "version": "6.1.2", "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.1.2.tgz", - "integrity": "sha512-7gSSmwb3A+fQwtw0arguwMdOdzmKUgnUcbSNlo+GjKLAQFuC2EZxWqG9XHRI8VscBJD5a8raz3RuxQNFW+XJbw==", + "integrity": "sha1-abykiQs23PD+Ft0hKdLYi5jzP4g=", "dev": true, "requires": { "aria-query": "^3.0.0", @@ -6609,7 +6707,7 @@ "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", "dev": true, "requires": { "function-bind": "^1.1.1" @@ -6620,7 +6718,7 @@ "eslint-plugin-mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-mocha/-/eslint-plugin-mocha-5.2.0.tgz", - "integrity": "sha512-4VTX/qIoxUFRnXLNm6bEhEJyfGnGagmQzV4TWXKzkZgIYyP2FSubEdCjEFTyS/dGwSVRWCWGX7jO7BK8R0kppg==", + "integrity": "sha1-2Hhtn/+MuLX25LYeQDldZWilxOI=", "dev": true, "requires": { "ramda": "^0.25.0" @@ -6629,7 +6727,7 @@ "eslint-plugin-node": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-6.0.1.tgz", - "integrity": "sha512-Q/Cc2sW1OAISDS+Ji6lZS2KV4b7ueA/WydVWd1BECTQwVvfQy5JAi3glhINoKzoMnfnuRgNP+ZWKrGAbp3QDxw==", + "integrity": "sha1-vxlkIpgGQ3kxXXpLKnWTc3b6BeQ=", "dev": true, "requires": { "ignore": "^3.3.6", @@ -6641,7 +6739,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -6650,7 +6748,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=", "dev": true } } @@ -6664,7 +6762,7 @@ "eslint-plugin-react": { "version": "7.11.1", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.11.1.tgz", - "integrity": "sha512-cVVyMadRyW7qsIUh3FHp3u6QHNhOgVrLQYdQEB1bPWBsgbNCHdFAeNMquBMCcZJu59eNthX053L70l7gRt4SCw==", + "integrity": "sha1-wBp69vF1GUV9YRaqlPxtLMrVRDw=", "dev": true, "requires": { "array-includes": "^3.0.3", @@ -6677,7 +6775,7 @@ "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", "dev": true, "requires": { "function-bind": "^1.1.1" @@ -6686,7 +6784,7 @@ "prop-types": { "version": "15.6.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.2.tgz", - "integrity": "sha512-3pboPvLiWD7dkI3qf3KbUe6hKFKa52w+AE0VCqECtf+QHAKgOL37tTaNCnuX1nAAQ4ZhyP+kYVKf8rLmJ/feDQ==", + "integrity": "sha1-BdXKd7RFPphdYPx/+MhZCUpJcQI=", "dev": true, "requires": { "loose-envify": "^1.3.1", @@ -6698,7 +6796,7 @@ "eslint-plugin-standard": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.1.0.tgz", - "integrity": "sha512-fVcdyuKRr0EZ4fjWl3c+gp1BANFJD1+RaWa2UPYfMZ6jCtp5RG00kSaXnK/dE5sYzt4kaWJ9qdxqUfc0d9kX0w==", + "integrity": "sha1-Kp4hJZukxHwC1TstDJE11LECLUc=", "dev": true }, "eslint-scope": { @@ -6714,13 +6812,13 @@ "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "integrity": "sha1-PzGA+y4pEBdxastMnW1bXDSmqB0=", "dev": true }, "espree": { "version": "3.5.4", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz", - "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==", + "integrity": "sha1-sPRHGHyKi+2US4FaZgvd9d610ac=", "dev": true, "requires": { "acorn": "^5.5.0", @@ -6730,7 +6828,7 @@ "acorn": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", + "integrity": "sha1-9HPdR+AnegjijpvsWu6wR1HwuMk=", "dev": true } } @@ -6744,7 +6842,7 @@ "esquery": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "integrity": "sha1-QGxRZYsfWZGl+bYrHcJbAOPlxwg=", "dev": true, "requires": { "estraverse": "^4.0.0" @@ -6753,7 +6851,7 @@ "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "integrity": "sha1-AHo7n9vCs7uH5IeeoZyS/b05Qs8=", "dev": true, "requires": { "estraverse": "^4.1.0" @@ -6819,7 +6917,7 @@ "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "integrity": "sha1-f8vbGY3HGVlDLv4ThCaE4FJaywI=", "dev": true, "requires": { "md5.js": "^1.3.4", @@ -6979,7 +7077,7 @@ "express-bearer-token": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/express-bearer-token/-/express-bearer-token-2.2.0.tgz", - "integrity": "sha512-w4A62k6modqSlE/CJzurj2YwisoVHWqrXiNs5P+CZD7MFORbcsOBbpjD3SGGKEW44R46Kps3QopaICE6p7dORw==" + "integrity": "sha1-ngG7uKKXkfHcMX4WhUOsrHa8mJ8=" }, "express-http-proxy": { "version": "1.1.0", @@ -6994,7 +7092,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "requires": { "ms": "2.0.0" } @@ -7004,7 +7102,7 @@ "express-session": { "version": "1.15.6", "resolved": "https://registry.npmjs.org/express-session/-/express-session-1.15.6.tgz", - "integrity": "sha512-r0nrHTCYtAMrFwZ0kBzZEXa1vtPVrw0dKvGSrKP4dahwBQ1BJpF2/y1Pp4sCD/0kvxV4zZeclyvfmw0B4RMJQA==", + "integrity": "sha1-R7QWDIj0KrcP6KUI4xy/92dXqwo=", "requires": { "cookie": "0.3.1", "cookie-signature": "1.0.6", @@ -7025,7 +7123,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "requires": { "ms": "2.0.0" } @@ -7033,7 +7131,7 @@ "uid-safe": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/uid-safe/-/uid-safe-2.1.5.tgz", - "integrity": "sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==", + "integrity": "sha1-Kz1cckDo/C5Y+Komnl7knAhXvTo=", "requires": { "random-bytes": "~1.0.0" } @@ -7063,7 +7161,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "requires": { "is-plain-object": "^2.0.4" @@ -7079,7 +7177,7 @@ "external-editor": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz", - "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==", + "integrity": "sha1-BFURz9jRM/OEZnPRBHwVTiFK09U=", "dev": true, "requires": { "chardet": "^0.4.0", @@ -7090,7 +7188,7 @@ "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", - "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==", + "integrity": "sha1-KXhx9jvlB63Pv8pxXQzQ7thOmmM=", "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" @@ -7136,7 +7234,7 @@ "fast-text-encoding": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fast-text-encoding/-/fast-text-encoding-1.0.0.tgz", - "integrity": "sha512-R9bHCvweUxxwkDwhjav5vxpFvdPGlVngtqmx4pIZfSUhM/Q4NiIUHB456BAf+Q1Nwu3HEZYONtu+Rya+af4jiQ==" + "integrity": "sha1-PlzoKTQJz6pxd6cbnKhOGx5vJe8=" }, "fastparse": { "version": "1.1.1", @@ -7175,7 +7273,7 @@ "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=", "requires": { "asap": "~2.0.3" } @@ -7212,7 +7310,7 @@ "file-uri-to-path": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==" + "integrity": "sha1-VTp7hEb/b2hDWcRF8eN6BdrMM90=" }, "file-utils": { "version": "0.1.5", @@ -7264,7 +7362,7 @@ "fill-range": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz", - "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==", + "integrity": "sha1-6x53OrsFbc2N8r/favWbizqTZWU=", "dev": true, "requires": { "is-number": "^2.1.0", @@ -7480,7 +7578,7 @@ "fs-extra": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz", - "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==", + "integrity": "sha1-DYUhIuW8W+tFP7Ao6cDJvzY0DJQ=", "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", @@ -7490,7 +7588,7 @@ "fs-minipass": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "integrity": "sha1-BsJ3IYRU7CiN93raVKA7hwKqy50=", "requires": { "minipass": "^2.2.1" } @@ -7498,7 +7596,7 @@ "fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", - "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "integrity": "sha1-4y/AMKLM7kSmtTcTCNpUvgs5fSc=", "dev": true }, "fs.realpath": { @@ -7506,542 +7604,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "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" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "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" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "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" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "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" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true - } - } - }, "ftp": { "version": "0.3.10", "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", @@ -8078,7 +7640,7 @@ "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=" }, "functional-red-black-tree": { "version": "1.0.1", @@ -8181,7 +7743,7 @@ "get-uri": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.1.tgz", - "integrity": "sha512-7aelVrYqCLuVjq2kEKRTH8fXPTC0xKTkM+G7UlFkEwCXY3sFbSxvY375JoFowOAYbkaU47SrBvOefUlLZZ+6QA==", + "integrity": "sha1-29ysrNjGCKODFoaTaBF2l6FjHFk=", "dev": true, "optional": true, "requires": { @@ -8196,7 +7758,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "optional": true, "requires": { @@ -8213,7 +7775,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true, "optional": true }, @@ -8236,7 +7798,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "optional": true, "requires": { @@ -8268,7 +7830,7 @@ "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -8281,7 +7843,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "requires": { "brace-expansion": "^1.1.7" } @@ -8319,7 +7881,7 @@ "globals": { "version": "9.18.0", "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", + "integrity": "sha1-qjiWs+abSH8X4x7SFD1pqOMMLYo=", "dev": true }, "globby": { @@ -8339,7 +7901,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -8353,7 +7915,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -8631,7 +8193,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -8878,7 +8440,7 @@ "handlebars-loader": { "version": "1.7.0", "resolved": "https://registry.npmjs.org/handlebars-loader/-/handlebars-loader-1.7.0.tgz", - "integrity": "sha512-tfS3n+PrDB2gnDnrx0/DGvdb4wF4JqV7CEiVof3RymOIWYrcmD+ZiaXTlZ/f7fZ7+aQPEv6JRG0HS7nTlyvGlQ==", + "integrity": "sha1-T3ULxiw1D7ki5S2FZNZniH6QlyM=", "dev": true, "requires": { "async": "~0.2.10", @@ -8945,7 +8507,7 @@ "has-binary2": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz", - "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==", + "integrity": "sha1-d3asYn8+p3JQz8My2rfd9eT10R0=", "dev": true, "requires": { "isarray": "2.0.1" @@ -9049,7 +8611,7 @@ "hash.js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "integrity": "sha1-NA3tvmKQGHFRweodd3o0SJNd+EY=", "dev": true, "requires": { "inherits": "^2.0.3", @@ -9059,7 +8621,7 @@ "hawk": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", - "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", + "integrity": "sha1-r02RTrBl+bXOTZ0RwcshJu7MMDg=", "requires": { "boom": "4.x.x", "cryptiles": "3.x.x", @@ -9080,7 +8642,7 @@ "helmet": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.10.0.tgz", - "integrity": "sha512-wVu5jSeImztLqNQPc4hqGr1DG0Ki2UJVmQ1KTugIrtl1f4Zw5SqVqh6QPyw5b6/Jo/iAnyTt+pcehB0RdEJsbw==", + "integrity": "sha1-lqKp/sU8JgCdPWJlxs/a2jjd+n8=", "requires": { "dns-prefetch-control": "0.1.0", "dont-sniff-mimetype": "1.0.0", @@ -9099,7 +8661,7 @@ "helmet-csp": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.7.0.tgz", - "integrity": "sha512-IGIAkWnxjRbgMXFA2/kmDqSIrIaSfZ6vhMHlSHw7jm7Gm9nVVXqwJ2B1YEpYrJsLrqY+w2Bbimk7snux9+sZAw==", + "integrity": "sha1-eTQJRhfR/re7LcQ7t9nogw93RxY=", "requires": { "camelize": "1.0.0", "content-security-policy-builder": "2.0.0", @@ -9111,7 +8673,7 @@ "hex2dec": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/hex2dec/-/hex2dec-1.1.2.tgz", - "integrity": "sha512-Yu+q/XWr2fFQ11tHxPq4p4EiNkb2y+lAacJNhAdRXVfRIcDH6gi7htWFnnlIzvqHMHoWeIsfXlNAjZInpAOJDA==" + "integrity": "sha1-jhzkvvNqdPfVcjw/swkMKGAHczg=" }, "hide-powered-by": { "version": "1.0.0", @@ -9143,7 +8705,7 @@ "hoek": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", - "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" + "integrity": "sha1-ctnQdU9/4lyi0BrY+PmpRJqJUm0=" }, "home-or-tmp": { "version": "2.0.0", @@ -9169,7 +8731,7 @@ "hosted-git-info": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", - "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", + "integrity": "sha1-IyNbKasjDFdqqw1PE/wEawsDgiI=", "dev": true }, "hpack.js": { @@ -9193,7 +8755,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -9214,7 +8776,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -9230,7 +8792,7 @@ "hsts": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.1.0.tgz", - "integrity": "sha512-zXhh/DqgrTXJ7erTN6Fh5k/xjMhDGXCqdYN3wvxUvGUQvnxcFfUd8E+6vLg/nk3ss1TYMb+DhRl25fYABioTvA==" + "integrity": "sha1-y9bJGKI4X+4d1WgL+ys6GUwBIcw=" }, "html-entities": { "version": "1.2.1", @@ -9241,7 +8803,7 @@ "htmlparser2": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.0.tgz", - "integrity": "sha512-J1nEUGv+MkXS0weHNWVKJJ+UrLfePxRWpN3C9bEi9fLxL2+ggW94DQvgYVXsaT30PGwYRIZKNZXuyMhp3Di4bQ==", + "integrity": "sha1-X15CLc9hGcDZg+02Jgzp3tC+5GQ=", "dev": true, "requires": { "domelementtype": "^1.3.0", @@ -9255,7 +8817,7 @@ "readable-stream": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", - "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "integrity": "sha1-7Wu8bFuliwkAOf8YzmcFFXla6wY=", "dev": true, "requires": { "inherits": "^2.0.3", @@ -9266,7 +8828,7 @@ "string_decoder": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", - "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "integrity": "sha1-/obnOLGVRK/nBGkkOyoe6SQOro0=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -9316,7 +8878,7 @@ "http-proxy-agent": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", - "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "integrity": "sha1-5IIb7vWyFCogJr1zkm/lN2McVAU=", "dev": true, "requires": { "agent-base": "4", @@ -9326,7 +8888,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -9406,7 +8968,7 @@ "https-proxy-agent": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", - "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "integrity": "sha1-UVUpcPoE1yPgTFbQQXjD+SWSu8A=", "requires": { "agent-base": "^4.1.0", "debug": "^3.1.0" @@ -9415,7 +8977,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "requires": { "ms": "2.0.0" } @@ -9465,7 +9027,7 @@ "ignore": { "version": "3.3.8", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz", - "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg==", + "integrity": "sha1-P46cNdOHCKOn4Omrtsc+fudweys=", "dev": true }, "ignore-by-default": { @@ -9508,7 +9070,7 @@ "import-local": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", - "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "integrity": "sha1-Xk/9wD9P5sAJxnKb6yljHC+CJ7w=", "dev": true, "requires": { "pkg-dir": "^2.0.0", @@ -9558,12 +9120,12 @@ "ini": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" + "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=" }, "inquirer": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", - "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "integrity": "sha1-ndLyrXZdyrH/BEO0kUQqILoifck=", "dev": true, "requires": { "ansi-escapes": "^3.0.0", @@ -9591,7 +9153,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -9600,7 +9162,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -9623,7 +9185,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -9642,7 +9204,7 @@ "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -9668,7 +9230,7 @@ "invariant": { "version": "2.2.4", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "integrity": "sha1-YQ88ksk1nOHbYW5TgAjSP/NRWOY=", "dev": true, "requires": { "loose-envify": "^1.0.0" @@ -9738,7 +9300,7 @@ "is": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/is/-/is-3.3.0.tgz", - "integrity": "sha512-nW24QBoPcFGGHJGUwnfpI7Yc5CdqWNdsyHQszVE/z2pKHXzh7FZ5GWhJqSyaQ9wMkQnsTx+kAI8bHlCX4tKdbg==" + "integrity": "sha1-Yc/23TxBk9uUo9YlggcrROVkXXk=" }, "is-accessor-descriptor": { "version": "0.1.6", @@ -9767,7 +9329,7 @@ "is-buffer": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=" }, "is-builtin-module": { "version": "1.0.0", @@ -9787,7 +9349,7 @@ "is-ci": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", - "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "integrity": "sha1-JH5BYueGDOu9rzC3dNawrH3P56U=", "dev": true, "requires": { "ci-info": "^1.0.0" @@ -9811,7 +9373,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", @@ -9822,7 +9384,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -9914,14 +9476,14 @@ "is-my-ip-valid": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz", - "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==", + "integrity": "sha1-ezUbjo7dTTmV1NBmaA5mTZRpaCQ=", "dev": true, "optional": true }, "is-my-json-valid": { "version": "2.17.2", "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz", - "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==", + "integrity": "sha1-ayEDoojpTvPeXPFdKd2F/Et41lw=", "dev": true, "optional": true, "requires": { @@ -9956,7 +9518,7 @@ "is-odd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", - "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", + "integrity": "sha1-dkZiRnH9fqVYzNmieVGC8pWPGyQ=", "dev": true, "requires": { "is-number": "^4.0.0" @@ -9965,7 +9527,7 @@ "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "integrity": "sha1-ACbjf1RU1z41bf5lZGmYZ8an8P8=", "dev": true } } @@ -9979,7 +9541,7 @@ "is-path-in-cwd": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", - "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "integrity": "sha1-WsSLNF72dTOb1sekipEhELJBz1I=", "dev": true, "requires": { "is-path-inside": "^1.0.0" @@ -9997,7 +9559,7 @@ "is-plain-object": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "integrity": "sha1-LBY7P6+xtgbZ0Xko8FwqHDjgdnc=", "dev": true, "requires": { "isobject": "^3.0.1" @@ -10052,7 +9614,7 @@ "is-resolvable": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", - "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "integrity": "sha1-+xj4fOH+uSUWnJpAfBkxijIG7Yg=", "dev": true }, "is-retry-allowed": { @@ -10085,7 +9647,7 @@ "is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0=", "dev": true }, "is-wsl": { @@ -10175,7 +9737,7 @@ "js-base64": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz", - "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==", + "integrity": "sha1-LlRewrDylX9BNWUQIFIU6Y+tZYI=", "dev": true }, "js-stringify": { @@ -10221,7 +9783,7 @@ "json-loader": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", - "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", + "integrity": "sha1-3KFKcCNf+C8KyaOr62DTN6NlGF0=", "dev": true }, "json-schema": { @@ -10258,7 +9820,7 @@ "json2csv": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/json2csv/-/json2csv-4.3.3.tgz", - "integrity": "sha512-IJjHMFW2W6cJ7+QpA2g5GU8CYACKq/HudbOSr8rqqEmBBsKN6Q2t0BIPtAzmJteSn88CkS+LBEnG/KBrJEkbOQ==", + "integrity": "sha1-VvzXX43eSo+i6oLmMUzVXywf5ow=", "requires": { "commander": "^2.15.1", "jsonparse": "^1.3.1", @@ -10269,7 +9831,7 @@ "commander": { "version": "2.19.0", "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", - "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==" + "integrity": "sha1-9hmKqE5bg8RgVLlN3tv+1e6f8So=" } } }, @@ -10315,7 +9877,7 @@ "jsonwebtoken": { "version": "8.1.1", "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.1.1.tgz", - "integrity": "sha512-+ijVOtfLMlCII8LJkvabaKX3+8tGrGjiCTfzoed2D1b/ebKTO1hIYBQUJHbd9dJ9Fa4kH+dhYEd1qDwyzDLUUw==", + "integrity": "sha1-sE2Lsq2Ee8kyOMPJIXD/290csuo=", "requires": { "jws": "^3.1.4", "lodash.includes": "^4.3.0", @@ -10332,7 +9894,7 @@ "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=" } } }, @@ -10364,7 +9926,7 @@ "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=", "requires": { "asap": "~2.0.3" } @@ -10444,19 +10006,19 @@ "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=", "dev": true }, "colors": { "version": "1.2.5", "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.5.tgz", - "integrity": "sha512-erNRLao/Y3Fv54qUa0LBB+//Uf3YwMUmdJinN20yMXm9zdKKqH9wt7R9IIVZ+K7ShzfpLV/Zg8+VyrBJYB4lpg==", + "integrity": "sha1-icetmjdLwDDfgBMkH2gTbtiDWvw=", "dev": true }, "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -10476,7 +10038,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -10491,7 +10053,7 @@ "rimraf": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", - "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "integrity": "sha1-LtgVDSShbqhlHm1u8PR8QVjOejY=", "dev": true, "requires": { "glob": "^7.0.5" @@ -10500,7 +10062,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true } } @@ -10514,7 +10076,7 @@ "karma-chrome-launcher": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-2.2.0.tgz", - "integrity": "sha512-uf/ZVpAabDBPvdPdveyk1EPgbnloPvFFGgmRhYLTDH7gEB4nZdSBk8yTU47w1g/drLSx5uMOkjKk7IWKfWg/+w==", + "integrity": "sha1-zxudBxNswY/iOTJ9JGVMPbw2is8=", "dev": true, "requires": { "fs-access": "^1.0.0", @@ -10524,7 +10086,7 @@ "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "integrity": "sha1-/wS9/AEO5UfXgL7DjhrBwnd9JTo=", "dev": true, "requires": { "isexe": "^2.0.0" @@ -10569,7 +10131,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -10578,7 +10140,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -10604,7 +10166,7 @@ "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -10621,7 +10183,7 @@ "karma-webpack": { "version": "2.0.13", "resolved": "https://registry.npmjs.org/karma-webpack/-/karma-webpack-2.0.13.tgz", - "integrity": "sha512-2cyII34jfrAabbI2+4Rk4j95Nazl98FvZQhgSiqKUDarT317rxfv/EdzZ60CyATN4PQxJdO5ucR5bOOXkEVrXw==", + "integrity": "sha1-z1bjBWwVt3R6C7IUD8mmvkHdnwI=", "dev": true, "requires": { "async": "^2.0.0", @@ -10635,7 +10197,7 @@ "async": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "integrity": "sha1-YaKau2/MAm/qd+VtHG7FOnlZUfQ=", "dev": true, "requires": { "lodash": "^4.14.0" @@ -10652,7 +10214,7 @@ "keygrip": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.0.3.tgz", - "integrity": "sha512-/PpesirAIfaklxUzp4Yb7xBper9MwP6hNRA6BGGUFCgbJ+BM5CKBtsoxinNXkLHAr+GXS1/lSlF2rP7cv5Fl+g==", + "integrity": "sha1-OZ1wnwrtK6sKBZ4M3TpQI6BT4dw=", "dev": true }, "killable": { @@ -10791,7 +10353,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "optional": true, "requires": { "brace-expansion": "^1.1.7" @@ -10881,7 +10443,7 @@ "less": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz", - "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==", + "integrity": "sha1-zBJg9RyQCp7A2R+2mYE54CUHtjs=", "dev": true, "requires": { "errno": "^0.1.1", @@ -11009,7 +10571,7 @@ "promise": { "version": "7.3.1", "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", + "integrity": "sha1-BktyYCsY+Q8pGSuLG8QY/9Hr078=", "dev": true, "optional": true, "requires": { @@ -11076,7 +10638,7 @@ "less-plugin-autoprefix": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/less-plugin-autoprefix/-/less-plugin-autoprefix-2.0.0.tgz", - "integrity": "sha512-UktaMtHAhCVTIQxjlceo1MiiQiUZws7gi3hfcpxkCLn1CJdVdlRGCb4n1/M64hniw2DLd7YzOl7ojshs1tWYcQ==", + "integrity": "sha1-d45vL+VohDgcT8PHR7CHnpRPhIE=", "dev": true, "requires": { "autoprefixer": "^8.6.3", @@ -11086,7 +10648,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -11095,7 +10657,7 @@ "autoprefixer": { "version": "8.6.5", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.6.5.tgz", - "integrity": "sha512-PLWJN3Xo/rycNkx+mp8iBDMTm3FeWe4VmYaZDSqL5QQB9sLsQkG5k8n+LNDFnhh9kdq2K+egL/icpctOmDHwig==", + "integrity": "sha1-ND89GT7VaLMgjgARehuW62kdTuk=", "dev": true, "requires": { "browserslist": "^3.2.8", @@ -11109,7 +10671,7 @@ "browserslist": { "version": "3.2.8", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "integrity": "sha1-sABTYdZHHw9ZUnl6dvyYXx+Xj8Y=", "dev": true, "requires": { "caniuse-lite": "^1.0.30000844", @@ -11119,13 +10681,13 @@ "caniuse-lite": { "version": "1.0.30000918", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000918.tgz", - "integrity": "sha512-CAZ9QXGViBvhHnmIHhsTPSWFBujDaelKnUj7wwImbyQRxmXynYqKGi3UaZTSz9MoVh+1EVxOS/DFIkrJYgR3aw==", + "integrity": "sha1-Yoj3naPFyLReUC9HrY8+uR8Teak=", "dev": true }, "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -11136,7 +10698,7 @@ "electron-to-chromium": { "version": "1.3.90", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.90.tgz", - "integrity": "sha512-IjJZKRhFbWSOX1w0sdIXgp4CMRguu6UYcTckyFF/Gjtemsu/25eZ+RXwFlV+UWcIueHyQA1UnRJxocTpH5NdGA==", + "integrity": "sha1-tMUbgwO+/xjyt0gXQCv0iY4JVYo=", "dev": true }, "has-flag": { @@ -11148,7 +10710,7 @@ "postcss": { "version": "6.0.23", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", - "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "integrity": "sha1-YcgswyisYOZ3ZF+XkFTrmLwOMyQ=", "dev": true, "requires": { "chalk": "^2.4.1", @@ -11159,13 +10721,13 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -11347,13 +10909,13 @@ "lodash.merge": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==", + "integrity": "sha1-rcJdnLmbk5HFliTzefu6YNcRHVQ=", "dev": true }, "lodash.mergewith": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", - "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "integrity": "sha1-Y5BX5ybDr72z59QnQcqo1uQzWSc=", "dev": true }, "lodash.once": { @@ -11385,7 +10947,7 @@ "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "integrity": "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo=", "dev": true, "requires": { "chalk": "^2.0.1" @@ -11394,7 +10956,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -11403,7 +10965,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -11420,7 +10982,7 @@ "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -11431,7 +10993,7 @@ "log4js": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/log4js/-/log4js-2.6.0.tgz", - "integrity": "sha512-9rG2W9o0D4GJDzQjno1rRpe+hzK0IEG/uGdjzNROStW/DWhV3sNX2r8OdPKppThlK7gr+08C5FSReWqmaRb/Ww==", + "integrity": "sha1-HqpLOnrP1x7NOoIwnGmjZ7tJlg8=", "dev": true, "requires": { "amqplib": "^0.5.2", @@ -11475,13 +11037,13 @@ "circular-json": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.5.4.tgz", - "integrity": "sha512-vnJA8KS0BfOihugYEUkLRcnmq21FbuivbxgzDLXNs3zIk4KllV4Mx4UuTzBXht9F00C7QfD1YqMXg1zP6EXpig==", + "integrity": "sha1-/xrS8uOS7rilFy1NmF+oRu2K1lY=", "dev": true }, "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -11590,7 +11152,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=", "dev": true }, "smtp-connection": { @@ -12078,7 +11640,7 @@ "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", - "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + "integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg=" }, "longest": { "version": "1.0.1", @@ -12106,7 +11668,7 @@ "lowercase-keys": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "integrity": "sha1-b54wtHCE2XGnyCD/FabFFnt0wm8=", "dev": true }, "lru-cache": { @@ -12131,7 +11693,7 @@ "mailchimp-api-v3": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/mailchimp-api-v3/-/mailchimp-api-v3-1.12.0.tgz", - "integrity": "sha512-/1RJLt6JCG0yzXOXeQuXFItqqDwYLAbiR5ASPV25IeuNj4B63sT9//n9OFuVCSX4p8FHyBTzP5hDM8nHEfXk9A==", + "integrity": "sha1-XopZ7zVykazhAh8N8lf+FE0f/vs=", "requires": { "bluebird": "^3.4.0", "lodash": "^4.17.10", @@ -12142,22 +11704,22 @@ "bluebird": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.2.tgz", - "integrity": "sha512-dhHTWMI7kMx5whMQntl7Vr9C6BvV10lFXDAasnqnrMYhXVCzzk6IO9Fo2L75jXHT07WrOngL1WDXOp+yYS91Yg==" + "integrity": "sha1-G+CQjgVKdRdUVJwnBInBUF1KsVo=" }, "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=" }, "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" }, "tar": { "version": "4.4.6", "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.6.tgz", - "integrity": "sha512-tMkTnh9EdzxyfW+6GK6fCahagXsnYk6kE6S9Gr9pjVdys769+laCTbodXDhPAjzVtEBazRgP0gYqOjnk9dQzLg==", + "integrity": "sha1-YxEPCcALTmCsi8/hvzyGYCNfvJs=", "requires": { "chownr": "^1.0.1", "fs-minipass": "^1.2.5", @@ -12187,7 +11749,7 @@ "mailgun-js": { "version": "0.18.0", "resolved": "https://registry.npmjs.org/mailgun-js/-/mailgun-js-0.18.0.tgz", - "integrity": "sha512-o0P6jjZlx5CQj12tvVgDTbgjTqVN0+5h6/6P1+3c6xmozVKBwniQ6Qt3MkCSF0+ueVTbobAfWyGpWRZMJu8t1g==", + "integrity": "sha1-gf7QxmpBHT/2xDVIYa0hOHr8+qo=", "dev": true, "optional": true, "requires": { @@ -12205,7 +11767,7 @@ "async": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "integrity": "sha1-YaKau2/MAm/qd+VtHG7FOnlZUfQ=", "dev": true, "optional": true, "requires": { @@ -12215,7 +11777,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "optional": true, "requires": { @@ -12227,7 +11789,7 @@ "make-dir": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "integrity": "sha1-ecEDO4BRW9bSTsmTPoYMp17ifww=", "dev": true, "requires": { "pify": "^3.0.0" @@ -12236,7 +11798,7 @@ "make-plural": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/make-plural/-/make-plural-4.3.0.tgz", - "integrity": "sha512-xTYd4JVHpSCW+aqDof6w/MebaMVNTVYBZhbB/vi513xXdiPT92JMVCo0Jq8W2UZnzYRFeVbQiQ+I25l13JuKvA==", + "integrity": "sha1-8j3gjv2wysLgybqfMVsN/2tMJzU=", "dev": true, "requires": { "minimist": "^1.2.0" @@ -12277,7 +11839,7 @@ "marked": { "version": "0.3.12", "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.12.tgz", - "integrity": "sha512-k4NaW+vS7ytQn6MgJn3fYpQt20/mOgYM5Ft9BYMfQJDz2QT6yEeS9XJ8k2Nw8JTeWK/znPPW2n3UJGzyYEiMoA==" + "integrity": "sha1-fPJf8iUmMvP+JAa94ljpTu6SdRk=" }, "math-random": { "version": "1.0.1", @@ -12328,7 +11890,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -12349,7 +11911,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -12475,7 +12037,7 @@ "messageformat": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/messageformat/-/messageformat-1.1.1.tgz", - "integrity": "sha512-Q0uXcDtF5pEZsVSyhzDOGgZZK6ykN79VY9CwU3Nv0gsqx62BjdJW0MT+63UkHQ4exe3HE33ZlxR2/YwoJarRTg==", + "integrity": "sha1-zqoubIaSnUgHBYJ1pzcrG9ljvfY=", "dev": true, "requires": { "glob": "~7.0.6", @@ -12502,7 +12064,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -12513,7 +12075,7 @@ "messageformat-parser": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/messageformat-parser/-/messageformat-parser-1.1.0.tgz", - "integrity": "sha512-Hwem6G3MsKDLS1FtBRGIs8T50P1Q00r3srS6QJePCFbad9fq0nYxwf3rnU2BreApRGhmpKMV7oZI06Sy1c9TPA==", + "integrity": "sha1-E7oiUKdrvejg/KDbs0dflcWUqQo=", "dev": true }, "method-override": { @@ -12530,7 +12092,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "requires": { "ms": "2.0.0" } @@ -12597,7 +12159,7 @@ "miller-rabin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "integrity": "sha1-8IA1HIZbDcViqEYpZtqlNUPHik0=", "dev": true, "requires": { "bn.js": "^4.0.0", @@ -12625,13 +12187,13 @@ "mimic-fn": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", - "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI=", "dev": true }, "minimalistic-assert": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "integrity": "sha1-LhlN4ERibUoQ5/f7wAznPoPk1cc=", "dev": true }, "minimalistic-crypto-utils": { @@ -12657,7 +12219,7 @@ "minipass": { "version": "2.3.4", "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.4.tgz", - "integrity": "sha512-mlouk1OHlaUE8Odt1drMtG1bAJA4ZA6B/ehysgV0LUIrDHdKgo1KorZq3pK0b/7Z7LJIQ12MNM6aC+Tn6lUZ5w==", + "integrity": "sha1-R2jXYF7WGU1tV2FpueEu9x6dmVc=", "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -12666,7 +12228,7 @@ "safe-buffer": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + "integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" }, "yallist": { "version": "3.0.2", @@ -12678,7 +12240,7 @@ "minizlib": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.1.0.tgz", - "integrity": "sha512-4T6Ur/GctZ27nHfpt9THOdRZNgyJ9FZchYO1ceg5S8Q3DNLCKYy44nCZzgCJgcvx2UM8czmqak5BCxJMrq37lA==", + "integrity": "sha1-EeE2WM5GvDpwomeqxYNZ0eDCnOs=", "requires": { "minipass": "^2.2.1" } @@ -12686,7 +12248,7 @@ "mixin-deep": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", - "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "integrity": "sha1-pJ5yaNzhoNlpjkUybFYm3zVD0P4=", "dev": true, "requires": { "for-in": "^1.0.2", @@ -12696,7 +12258,7 @@ "is-extendable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "integrity": "sha1-p0cPnkJnM9gb2B4RVSZOOjUHyrQ=", "dev": true, "requires": { "is-plain-object": "^2.0.4" @@ -12706,7 +12268,7 @@ }, "mkdirp": { "version": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha512-SknJC52obPfGQPnjIkXbmA6+5H15E+fR+E4iR2oQ3zzCLbd7/ONua69R/Gw7AgkTLsRG+r5fzksYwWe1AgTyWA==", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" }, @@ -12721,7 +12283,7 @@ "mmmagic": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/mmmagic/-/mmmagic-0.5.2.tgz", - "integrity": "sha512-HBi5MIvBK10yOkNF+7FZ1h8DyxNVZGNeYSWQmA1WDHz8f6XwlHsXxWUHNOEnPjU8kN+FArsImeCqI6Q3PDQq6Q==", + "integrity": "sha1-3EFcCgbvKS3kZfZFZX5Ds/PGXQA=", "requires": { "nan": "^2.11.0" }, @@ -12729,7 +12291,7 @@ "nan": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", - "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==" + "integrity": "sha1-kOIrzLjKV+pM03zIPTgZtS7qZ2Y=" } } }, @@ -12817,7 +12379,7 @@ "moment": { "version": "2.20.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.20.1.tgz", - "integrity": "sha512-Yh9y73JRljxW5QxN08Fner68eFLxM5ynNOAw2LbIB1YAGeQzZT8QFSUvkAz609Zf+IHhhaUxqZK8dG3W/+HEvg==" + "integrity": "sha1-1usaRsvMFKKy+UNBEsH/iQfzE/0=" }, "moment-timezone": { "version": "0.5.14", @@ -12864,7 +12426,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "requires": { "safe-buffer": "~5.1.0" } @@ -12903,7 +12465,7 @@ "readable-stream": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", + "integrity": "sha1-No8lEtefnUb9/HE0mueHi7weuVw=", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -12917,7 +12479,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "requires": { "safe-buffer": "~5.1.0" } @@ -12997,7 +12559,7 @@ "string_decoder": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", + "integrity": "sha1-D8Z9fBQYJd6UKC3VNr7GubzoYKs=", "requires": { "safe-buffer": "~5.1.0" } @@ -13070,7 +12632,7 @@ "multicast-dns": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", - "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "integrity": "sha1-oOx72QVcQoL3kMPIL04o2zsxsik=", "dev": true, "requires": { "dns-packet": "^1.3.1", @@ -13117,7 +12679,7 @@ "nanomatch": { "version": "1.2.9", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", - "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", + "integrity": "sha1-h59xUMstq3pHElkGbBBO7m4Pp8I=", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -13149,7 +12711,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } @@ -13212,7 +12774,7 @@ "neo-async": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz", - "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==", + "integrity": "sha1-rLkJ4yex6H7J7xX0G4omlRKtQe4=", "dev": true }, "netmask": { @@ -13236,7 +12798,7 @@ "node-fetch": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", + "integrity": "sha1-mA9vcthSEaU0fGsrwYxbhMPrR+8=", "requires": { "encoding": "^0.1.11", "is-stream": "^1.0.1" @@ -13255,7 +12817,7 @@ "node-libs-browser": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.1.0.tgz", - "integrity": "sha512-5AzFzdoIMb89hBGMZglEegffzgRg+ZFoUmisQ8HI4j1KDdpx13J0taNp2y9xPbur6W61gepGDDotGBVQ7mfUCg==", + "integrity": "sha1-X5QmPUBPbkR2fXJpAf/wVHjWAN8=", "dev": true, "requires": { "assert": "^1.1.1", @@ -13292,7 +12854,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -13313,7 +12875,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -13489,7 +13051,7 @@ "nodemon": { "version": "1.17.4", "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.17.4.tgz", - "integrity": "sha512-ZQcvYd8I4sWhbLoqImIiCPBTaHcq3YRRQXYwePchFK3Zk5+LT8HYQR4urf1UkSDiY/gSxjq6ao34RxJp7rRe1w==", + "integrity": "sha1-JD/5xp/78RdfJGD5sCPzWgcsFek=", "dev": true, "requires": { "chokidar": "^2.0.2", @@ -13507,7 +13069,7 @@ "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", "dev": true, "requires": { "micromatch": "^3.1.4", @@ -13529,7 +13091,7 @@ "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", "dev": true, "requires": { "arr-flatten": "^1.1.0", @@ -13564,7 +13126,6 @@ "anymatch": "^2.0.0", "async-each": "^1.0.0", "braces": "^2.3.0", - "fsevents": "^1.1.2", "glob-parent": "^3.1.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", @@ -13578,7 +13139,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -13602,7 +13163,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -13669,7 +13230,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", @@ -13680,7 +13241,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -13688,7 +13249,7 @@ "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", "dev": true, "requires": { "array-unique": "^0.3.2", @@ -13774,7 +13335,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -13783,7 +13344,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -13792,7 +13353,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -13850,13 +13411,13 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -13877,7 +13438,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -13886,7 +13447,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -13919,13 +13480,13 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=", "dev": true }, "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -13934,7 +13495,7 @@ "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -13954,7 +13515,7 @@ "normalize-package-data": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", + "integrity": "sha1-EvlaMH1YNSB1oEkHuErIvpisAS8=", "dev": true, "requires": { "hosted-git-info": "^2.1.4", @@ -14004,7 +13565,7 @@ "npmlog": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "integrity": "sha1-CKfyqL9zRgR3mp76StXMcXq7lUs=", "requires": { "are-we-there-yet": "~1.1.2", "console-control-strings": "~1.1.0", @@ -14182,7 +13743,7 @@ "obuf": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "integrity": "sha1-Cb6jND1BhZ69RGKS0RydTbYZCE4=", "dev": true }, "on-finished": { @@ -14497,7 +14058,7 @@ "os-locale": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", + "integrity": "sha1-QrwpAKa1uL0XN2yOiCtlr8zyS/I=", "dev": true, "requires": { "execa": "^0.7.0", @@ -14539,7 +14100,7 @@ "p-limit": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", - "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "integrity": "sha1-DpK2vty1nwIsE9DxlJ3ILRWQnxw=", "dev": true, "requires": { "p-try": "^1.0.0" @@ -14557,7 +14118,7 @@ "p-map": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz", - "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==", + "integrity": "sha1-5OlPMR6rvIYzoeeZCBZfyiYkG2s=", "dev": true }, "p-try": { @@ -14569,7 +14130,7 @@ "pac-proxy-agent": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.2.tgz", - "integrity": "sha512-cDNAN1Ehjbf5EHkNY5qnRhGPUCp6SnpyVof5fRzN800QV1Y2OkzbH9rmjZkbBRa8igof903yOnjIl6z0SlAhxA==", + "integrity": "sha1-kNn2cwqw9NJgfc3NTT1kGqJsOJY=", "dev": true, "optional": true, "requires": { @@ -14586,7 +14147,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "optional": true, "requires": { @@ -14598,7 +14159,7 @@ "pac-resolver": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz", - "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==", + "integrity": "sha1-auoweH2wqJFwTet4AKcip2FabyY=", "dev": true, "optional": true, "requires": { @@ -14624,13 +14185,13 @@ "pako": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.6.tgz", - "integrity": "sha512-lQe48YPsMJAig+yngZ87Lus+NF+3mtu7DVOBu6b/gHO1YpKwIj5AWjZ/TOS7i46HD/UixzWb1zeWDZfGZ3iYcg==", + "integrity": "sha1-AQEhG6pwxLykoPY/Igbpe3368lg=", "dev": true }, "parse-asn1": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", - "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", + "integrity": "sha1-9r8pOBgzK9DatU77Fgh3JHRebKg=", "dev": true, "requires": { "asn1.js": "^4.0.0", @@ -14768,7 +14329,7 @@ "passport-orcid": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/passport-orcid/-/passport-orcid-0.0.3.tgz", - "integrity": "sha512-qHVphWUi6FWXaN7o2geP3+q7Xb8rFjvEsVquBn+pYjIRZXK5jHNJD9Gfr9U+VPwRo//m8qGEmNo4JprXPoCTyQ==", + "integrity": "sha1-gCEmpODawNwUBrlSGymw3RNkTsQ=", "requires": { "passport-oauth2": "^1.4.0" } @@ -14795,7 +14356,7 @@ "xml2js": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz", - "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==", + "integrity": "sha1-aGwg8hMgnpSr8NG88e+qKRx4J6c=", "requires": { "sax": ">=0.6.0", "xmlbuilder": "~9.0.1" @@ -14826,7 +14387,7 @@ "passport-twitter": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/passport-twitter/-/passport-twitter-1.0.4.tgz", - "integrity": "sha512-qvdauqCqCJJci82mJ9hZZQ6nAv7aSHV31svL8+9H7mRlDdXCdfU6AARQrmmJu3DRmv9fvIebM7zzxR7mVufN3A==", + "integrity": "sha1-AaeZ4fdgvy3knyul+6MigvGJMtc=", "requires": { "passport-oauth1": "1.x.x", "xtraverse": "0.1.x" @@ -14930,7 +14491,7 @@ "pbkdf2": { "version": "3.0.16", "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", - "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "integrity": "sha1-dAQgjsawG2LYW/g4U6gGT42cKlw=", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -14983,12 +14544,12 @@ "platform": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", - "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==" + "integrity": "sha1-+2lYxpbgfikY0u7aDwvJRI1zNEQ=" }, "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "integrity": "sha1-KYuJ34uTsCIdv0Ia0rGx6iP8Z3c=", "dev": true }, "pooling": { @@ -15035,7 +14596,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -15052,7 +14613,7 @@ "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", - "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "integrity": "sha1-ut+hSX1GJE9jkPWLMZgw2RB4U8U=", "dev": true, "requires": { "chalk": "^1.1.3", @@ -15101,13 +14662,13 @@ "prettier": { "version": "1.14.3", "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.14.3.tgz", - "integrity": "sha512-qZDVnCrnpsRJJq5nSsiHCE3BYMED2OtsI+cmzIzF1QIfqm5ALf8tEJcO27zV1gKNKRPdhjO0dNWnrzssDQ1tFg==", + "integrity": "sha1-kCON1MBoS37c5fg7D7cyjki9CJU=", "dev": true }, "prettier-eslint": { "version": "8.8.2", "resolved": "https://registry.npmjs.org/prettier-eslint/-/prettier-eslint-8.8.2.tgz", - "integrity": "sha512-2UzApPuxi2yRoyMlXMazgR6UcH9DKJhNgCviIwY3ixZ9THWSSrUww5vkiZ3C48WvpFl1M1y/oU63deSy1puWEA==", + "integrity": "sha1-/LKaSKtFJOI0aAeX/nDp0TbMrws=", "dev": true, "requires": { "babel-runtime": "^6.26.0", @@ -15136,7 +14697,7 @@ "prettier-eslint-cli": { "version": "4.7.1", "resolved": "https://registry.npmjs.org/prettier-eslint-cli/-/prettier-eslint-cli-4.7.1.tgz", - "integrity": "sha512-hQbsGaEVz97oBBcKdsJ46khv0kOGkMyWrXzcFOXW6X8UuetZ/j0yDJkNJgUTVc6PVFbbzBXk+qgd5vos9qzXPQ==", + "integrity": "sha1-PRA8SUuqToC5mtU+K523YgEBhZ8=", "dev": true, "requires": { "arrify": "^1.0.1", @@ -15168,7 +14729,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -15194,7 +14755,7 @@ "chalk": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", - "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "integrity": "sha1-tepI78nBeT3MybR2fJORTT8tUro=", "dev": true, "requires": { "ansi-styles": "^3.1.0", @@ -15235,7 +14796,7 @@ "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -15267,7 +14828,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -15276,7 +14837,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -15312,7 +14873,7 @@ "yargs": { "version": "10.0.3", "resolved": "https://registry.npmjs.org/yargs/-/yargs-10.0.3.tgz", - "integrity": "sha512-DqBpQ8NAUX4GyPP/ijDGHsJya4tYqLQrjPr95HNsr1YwL3+daCfvBwg7+gIC6IdJhR2kATh3hb61vjzMWEtjdw==", + "integrity": "sha1-ZULevZCArVF+xQSPtFTv6eTUqq4=", "dev": true, "requires": { "cliui": "^3.2.0", @@ -15332,7 +14893,7 @@ "yargs-parser": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-8.1.0.tgz", - "integrity": "sha512-yP+6QqN8BmrgW2ggLtTbdrOyBNSI7zBa4IykmiV5R1wl1JWNxQvWhMfMdmzIYtKU7oP3OOInY/tl2ov3BDjnJQ==", + "integrity": "sha1-8TdqM7Ziml0GN4KUTacyYx6WaVA=", "dev": true, "requires": { "camelcase": "^4.1.0" @@ -15343,7 +14904,7 @@ "pretty-format": { "version": "23.6.0", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.6.0.tgz", - "integrity": "sha512-zf9NV1NSlDLDjycnwm6hpFATCGl/K1lt0R/GdkAK2O5LN/rwJoB+Mh93gGJjut4YbmecbfgLWVGSTCr0Ewvvbw==", + "integrity": "sha1-XqrI7razO5h7f+YJfqaooUarV2A=", "dev": true, "requires": { "ansi-regex": "^3.0.0", @@ -15359,7 +14920,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -15370,7 +14931,7 @@ "pretty-ms": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-4.0.0.tgz", - "integrity": "sha512-qG66ahoLCwpLXD09ZPHSCbUWYTqdosB7SMP4OffgTgL2PBKXMuUsrk5Bwg8q4qPkjTXsKBMr+YK3Ltd/6F9s/Q==", + "integrity": "sha1-Mbr0G5T9AiJwmKqgO9YmCOsNbpI=", "requires": { "parse-ms": "^2.0.0" } @@ -15378,7 +14939,7 @@ "private": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "integrity": "sha1-I4Hts2ifelPWUxkAYPz4ItLzaP8=", "dev": true }, "process": { @@ -15437,7 +14998,7 @@ "prop-types": { "version": "15.6.1", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz", - "integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==", + "integrity": "sha1-NmREU1ZCVd3aORGR+zoSXL32VMo=", "requires": { "fbjs": "^0.8.16", "loose-envify": "^1.3.1", @@ -15447,7 +15008,7 @@ "protobufjs": { "version": "6.8.8", "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.8.8.tgz", - "integrity": "sha512-AAmHtD5pXgZfi7GMpllpO3q1Xw1OYldr+dMUlAnffGTAhqkg72WdmSY71uKBF/JuyiKs8psYbtKrhi0ASCD8qw==", + "integrity": "sha1-yLTxKC/XqQ5vWxCe0RyEr4KQjnw=", "requires": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", @@ -15546,7 +15107,7 @@ "pstree.remy": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz", - "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==", + "integrity": "sha1-8q8nJlvT5bMrv8wQ6AusVbp4aIs=", "dev": true, "requires": { "ps-tree": "^1.1.0" @@ -15581,7 +15142,7 @@ "public-encrypt": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", - "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "integrity": "sha1-RuuRByBr9zSJ+LhbadkTNMZhCZQ=", "dev": true, "requires": { "bn.js": "^4.1.0", @@ -15594,7 +15155,7 @@ "pug": { "version": "2.0.0-rc.4", "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.0-rc.4.tgz", - "integrity": "sha512-SL7xovj6E2Loq9N0UgV6ynjMLW4urTFY/L/Fprhvz13Xc5vjzkjZjI1QHKq31200+6PSD8PyU6MqrtCTJj6/XA==", + "integrity": "sha1-t7CPZZm9UwJWgEK3Q2mE+yjIChM=", "requires": { "pug-code-gen": "^2.0.0", "pug-filters": "^2.1.5", @@ -15637,7 +15198,7 @@ "pug-code-gen": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.0.tgz", - "integrity": "sha512-E4oiJT+Jn5tyEIloj8dIJQognbiNNp0i0cAJmYtQTFS0soJ917nlIuFtqVss3IXMEyQKUew3F4gIkBpn18KbVg==", + "integrity": "sha1-lq6jmp5i8exdK2pbQqKdUoxwtD0=", "requires": { "constantinople": "^3.0.1", "doctypes": "^1.1.0", @@ -15691,7 +15252,7 @@ "pug-filters": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-2.1.5.tgz", - "integrity": "sha512-xkw71KtrC4sxleKiq+cUlQzsiLn8pM5+vCgkChW2E6oNOzaqTSIBKIQ5cl4oheuDzvJYCTSYzRaVinMUrV4YLQ==", + "integrity": "sha1-Zr9ugNl/vvgpurCqNe3f8z/JZPM=", "requires": { "clean-css": "^3.3.0", "constantinople": "^3.0.1", @@ -15783,7 +15344,7 @@ "pug-linker": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.3.tgz", - "integrity": "sha512-DCKczglCXOzJ1lr4xUj/lVHYvS+lGmR2+KTCjZjtIpdwaN7lNOoX2SW6KFX5X4ElvW+6ThwB+acSUg08UJFN5A==", + "integrity": "sha1-JfWet1AjfwNo5ZwzeXZCKcAYnEE=", "requires": { "pug-error": "^1.3.2", "pug-walk": "^1.1.5" @@ -15792,7 +15353,7 @@ "pug-load": { "version": "2.0.9", "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.9.tgz", - "integrity": "sha512-BDdZOCru4mg+1MiZwRQZh25+NTRo/R6/qArrdWIf308rHtWA5N9kpoUskRe4H6FslaQujC+DigH9LqlBA4gf6Q==", + "integrity": "sha1-7iF8kUzB2TJNRLhsMtHfJB023no=", "requires": { "object-assign": "^4.1.0", "pug-walk": "^1.1.5" @@ -15801,7 +15362,7 @@ "pug-parser": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-4.0.0.tgz", - "integrity": "sha512-ocEUFPdLG9awwFj0sqi1uiZLNvfoodCMULZzkRqILryIWc/UUlDlxqrKhKjAIIGPX/1SNsvxy63+ayEGocGhQg==", + "integrity": "sha1-yfUjIuTqvkv1vuumTtGDc7tieAE=", "requires": { "pug-error": "^1.3.2", "token-stream": "0.0.1" @@ -15823,7 +15384,7 @@ "pug-walk": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.5.tgz", - "integrity": "sha512-rJlH1lXerCIAtImXBze3dtKq/ykZMA4rpO9FnPcIgsWcxZLOvd8zltaoeOVFyBSSqCkhhJWbEbTMga8UxWUUSA==" + "integrity": "sha1-kOlDrLz3Ah5kVM8bMiRYkcum+FE=" }, "punycode": { "version": "1.4.1", @@ -15838,13 +15399,13 @@ "qjobs": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", - "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "integrity": "sha1-xF6cYYAL0IfviNfiVkI73Unl0HE=", "dev": true }, "qs": { "version": "6.5.1", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" + "integrity": "sha1-NJzfbu+J7EXBLX1es/wMhwNDptg=" }, "querystring": { "version": "0.2.0", @@ -15872,7 +15433,7 @@ "ramda": { "version": "0.25.0", "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.25.0.tgz", - "integrity": "sha512-GXpfrYVPwx3K7RQ6aYT8KPS8XViSXUVJT1ONhoKPE9VAleW42YE+U+8VEyGWt41EnEQW7gwecYJriTI0pKoecQ==", + "integrity": "sha1-j99oIxz/qQvC+UYDkKDLdKKbKak=", "dev": true }, "random-bytes": { @@ -15883,7 +15444,7 @@ "randomatic": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz", - "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==", + "integrity": "sha1-01SQAw6091eN4pLObfsEqRoSiSM=", "dev": true, "requires": { "is-number": "^4.0.0", @@ -15894,13 +15455,13 @@ "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "integrity": "sha1-ACbjf1RU1z41bf5lZGmYZ8an8P8=", "dev": true }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } @@ -15908,7 +15469,7 @@ "randombytes": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", - "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "integrity": "sha1-0wLFIpSFiISKjTAMkytEwkIx2oA=", "dev": true, "requires": { "safe-buffer": "^5.1.0" @@ -15917,7 +15478,7 @@ "randomfill": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "integrity": "sha1-ySGW/IarQr6YPxvzF3giSTHWFFg=", "dev": true, "requires": { "randombytes": "^2.0.5", @@ -15967,7 +15528,7 @@ "iconv-lite": { "version": "0.4.19", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==" + "integrity": "sha1-90aPYBNfXl2tM5nAqBvpoWA6CCs=" } } }, @@ -16017,7 +15578,7 @@ "react-testing-library": { "version": "5.4.4", "resolved": "https://registry.npmjs.org/react-testing-library/-/react-testing-library-5.4.4.tgz", - "integrity": "sha512-/TiERZ+URSNhZQfjrUXh0VLsiLSmhqP1WP+2e2wWqWqrRIWpcAxrfuBxzlT75LYMDNmicEikaXJqRDi/pqCEDg==", + "integrity": "sha1-P6eHmZSSvpSyKORUCnIRVWv0/ZQ=", "dev": true, "requires": { "dom-testing-library": "^3.13.1" @@ -16076,7 +15637,7 @@ "redis": { "version": "2.8.0", "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz", - "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==", + "integrity": "sha1-ICKI4/WMSfYHnZevehDhMDrhSwI=", "requires": { "double-ended-queue": "^2.1.0-0", "redis-commands": "^1.2.0", @@ -16150,7 +15711,7 @@ "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=" }, "mkdirp": { "version": "0.3.5", @@ -16172,19 +15733,19 @@ "regenerate": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "integrity": "sha1-SoVuxLVuQHfFV1icroXnpMiGmhE=", "dev": true }, "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "integrity": "sha1-vgWtf5v30i4Fb5cmzuUBf78Z4uk=", "dev": true }, "regenerator-transform": { "version": "0.10.1", "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", + "integrity": "sha1-HkmWg3Ix2ot/PPQRTXG1aRoGgN0=", "dev": true, "requires": { "babel-runtime": "^6.18.0", @@ -16195,7 +15756,7 @@ "regex-cache": { "version": "0.4.4", "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.4.tgz", - "integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==", + "integrity": "sha1-db3FiioUls7EihKDW8VMjVYjNt0=", "dev": true, "requires": { "is-equal-shallow": "^0.1.3" @@ -16204,7 +15765,7 @@ "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "integrity": "sha1-H07OJ+ALC2XgJHpoEOaoXYOldSw=", "dev": true, "requires": { "extend-shallow": "^3.0.2", @@ -16219,7 +15780,7 @@ "regexpp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", - "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", + "integrity": "sha1-DjUW3Qt5BPQT0tQZPc5GGMOmias=", "dev": true }, "regexpu-core": { @@ -16236,7 +15797,7 @@ "registry-auth-token": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", + "integrity": "sha1-hR/UkDjuy1hpERFa+EUmDuyYPyA=", "dev": true, "requires": { "rc": "^1.1.6", @@ -16304,7 +15865,7 @@ "request": { "version": "2.83.0", "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", - "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", + "integrity": "sha1-ygtl2gLtYpNYh4COb1EDgQNOM1Y=", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.6.0", @@ -16333,7 +15894,7 @@ "requestretry": { "version": "1.13.0", "resolved": "https://registry.npmjs.org/requestretry/-/requestretry-1.13.0.tgz", - "integrity": "sha512-Lmh9qMvnQXADGAQxsXHP4rbgO6pffCfuR8XUBdP9aitJcLQJxhp7YZK4xAVYXnPJ5E52mwrfiKQtKonPL8xsmg==", + "integrity": "sha1-IT7BAG7rdQ6LjOVBdig9FajVXZQ=", "requires": { "extend": "^3.0.0", "lodash": "^4.15.0", @@ -16444,7 +16005,7 @@ "require_optional": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz", - "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==", + "integrity": "sha1-TPNaQkf2TKPfjC7yCMxJSxyo/C4=", "requires": { "resolve-from": "^2.0.0", "semver": "^5.1.0" @@ -16453,7 +16014,7 @@ "requirejs": { "version": "2.3.5", "resolved": "https://registry.npmjs.org/requirejs/-/requirejs-2.3.5.tgz", - "integrity": "sha512-svnO+aNcR/an9Dpi44C7KSAy5fFGLtmPbaaCeQaklUz8BQhS64tWWIIlvEA5jrWICzlO/X9KSzSeXFnZdBu8nw==", + "integrity": "sha1-YXuay7yzNlQO9JFNeQMjqNS4YbA=", "dev": true }, "requires-port": { @@ -16470,7 +16031,7 @@ "resolve": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "integrity": "sha1-HwmsznlsmnYlefMbLBzEw83fnzY=", "requires": { "path-parse": "^1.0.5" } @@ -16516,7 +16077,7 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "integrity": "sha1-uKSCXVvbH8P29Twrwz+BOIaBx7w=", "dev": true }, "retry-as-promised": { @@ -16531,12 +16092,12 @@ "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=" }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "requires": { "ms": "2.0.0" } @@ -16546,12 +16107,12 @@ "retry-axios": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/retry-axios/-/retry-axios-0.3.2.tgz", - "integrity": "sha512-jp4YlI0qyDFfXiXGhkCOliBN1G7fRH03Nqy8YdShzGqbY5/9S2x/IR6C88ls2DFkbWuL3ASkP7QD3pVrNpPgwQ==" + "integrity": "sha1-V1fID1hbTMTEmGqi/9R6YMbTXhM=" }, "retry-request": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-4.0.0.tgz", - "integrity": "sha512-S4HNLaWcMP6r8E4TMH52Y7/pM8uNayOcTDDQNBwsCccL1uI+Ol2TljxRDPzaNfbhOB30+XWP5NnZkB3LiJxi1w==", + "integrity": "sha1-XDZhZiebPhDp16oTJ0RnoFy2kpA=", "requires": { "through2": "^2.0.0" } @@ -16572,7 +16133,7 @@ "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "integrity": "sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw=", "dev": true, "requires": { "hash-base": "^3.0.0", @@ -16626,7 +16187,7 @@ "rxjs": { "version": "5.5.12", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", - "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "integrity": "sha1-b6YbinfD15PbrycL7i9D9lLXQcw=", "dev": true, "requires": { "symbol-observable": "1.0.1" @@ -16635,7 +16196,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "integrity": "sha1-iTMSr2myEj3vcfV4iQAWce6yyFM=" }, "safe-json-stringify": { "version": "1.0.4", @@ -16655,7 +16216,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=" }, "samsam": { "version": "1.1.2", @@ -16684,7 +16245,7 @@ "sanitize-html": { "version": "1.20.0", "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.20.0.tgz", - "integrity": "sha512-BpxXkBoAG+uKCHjoXFmox6kCSYpnulABoGcZ/R3QyY9ndXbIM5S94eOr1IqnzTG8TnbmXaxWoDDzKC5eJv7fEQ==", + "integrity": "sha1-mmAr6xyfr5YPsx+YkPYZEcxNkVY=", "dev": true, "requires": { "chalk": "^2.4.1", @@ -16702,7 +16263,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -16711,7 +16272,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -16728,7 +16289,7 @@ "postcss": { "version": "7.0.7", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.7.tgz", - "integrity": "sha512-HThWSJEPkupqew2fnuQMEI2YcTj/8gMV3n80cMdJsKxfIh5tHf7nM5JigNX6LxVMqo6zkgQNAI88hyFvBk41Pg==", + "integrity": "sha1-J1TQc/d6y07wjxI1w2xXIacgFhQ=", "dev": true, "requires": { "chalk": "^2.4.1", @@ -16739,13 +16300,13 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true }, "supports-color": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -16772,7 +16333,7 @@ "selfsigned": { "version": "1.10.3", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.3.tgz", - "integrity": "sha512-vmZenZ+8Al3NLHkWnhBQ0x6BkML1eCP2xEi3JE+f3D9wW9fipD9NNJHYtE9XJM4TsPaHGZJIamrSI6MTg1dU2Q==", + "integrity": "sha1-1ijs+eNzX4TouvupNrPPhb6kOCM=", "dev": true, "requires": { "node-forge": "0.7.5" @@ -16781,7 +16342,7 @@ "node-forge": { "version": "0.7.5", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz", - "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==", + "integrity": "sha1-bBUsNFzhHFL0ZcKr2VfoY5zWdN8=", "dev": true } } @@ -16874,7 +16435,7 @@ "sequelize": { "version": "3.31.1", "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-3.31.1.tgz", - "integrity": "sha512-fRb2cu3d+A7wwBuHmfe+SP5nhkQ9pDS3nR/KBmjRK0EpBYRJmNggOqfEShuBgX+QztjXLFiemnT0AtjykfVUGw==", + "integrity": "sha1-G4PxwGUiAXWGEltvGYgb+oo5524=", "requires": { "bluebird": "^3.3.4", "depd": "^1.1.0", @@ -16897,7 +16458,7 @@ "bluebird": { "version": "3.5.1", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" + "integrity": "sha1-2VUfnemPH82h5oPRfukaBgLuLrk=" }, "lodash": { "version": "4.12.0", @@ -16934,7 +16495,7 @@ "mime-types": { "version": "2.1.18", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "integrity": "sha1-bzI/YKg9ERRvgx/xH9ZuL+VQO7g=", "dev": true, "requires": { "mime-db": "~1.33.0" @@ -16945,7 +16506,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -16960,7 +16521,7 @@ "mime-db": { "version": "1.33.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "integrity": "sha1-o0kgUKXLm2NFBUHjnZeI0icng9s=", "dev": true }, "negotiator": { @@ -17053,7 +16614,7 @@ "set-value": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", - "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "integrity": "sha1-ca5KiPD+77v1LR6mBPP7MV67YnQ=", "dev": true, "requires": { "extend-shallow": "^2.0.1", @@ -17086,7 +16647,7 @@ "settings-sharelatex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/settings-sharelatex/-/settings-sharelatex-1.1.0.tgz", - "integrity": "sha512-f7D+0lnlohoteSn6IKTH72NE+JnAdMWTKwQglAuimZWTID2FRRItZSGeYMTRpvEnaQApkoVwRp//WRMsiddnqw==", + "integrity": "sha1-Tv4vUpPbjxwVlnEEx5BfqHD/mS0=", "requires": { "coffee-script": "1.6.0" }, @@ -17101,7 +16662,7 @@ "sha.js": { "version": "2.4.11", "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "integrity": "sha1-N6XPC4HsvGlD3hCbopYNGyZYSuc=", "dev": true, "requires": { "inherits": "^2.0.1", @@ -17138,10 +16699,16 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "simple-is": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/simple-is/-/simple-is-0.2.0.tgz", + "integrity": "sha1-Krt1qt453rXMgVzhDmGRFkhQuvA=", + "dev": true + }, "sinon": { "version": "1.17.7", "resolved": "https://registry.npmjs.org/sinon/-/sinon-1.17.7.tgz", - "integrity": "sha512-M9rtyQxKfcTTdB64rpPSRaTzOvunb+HHPv/3PxvNPrEDnFSny95Pi6/3VoD471ody0ay0IHyzT3BErfcLXj6NA==", + "integrity": "sha1-RUKk9JugxFwF6y6d2dID4rjv4L8=", "dev": true, "requires": { "formatio": "1.1.1", @@ -17153,7 +16720,7 @@ "sinon-chai": { "version": "2.14.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-2.14.0.tgz", - "integrity": "sha512-9stIF1utB0ywNHNT7RgiXbdmen8QDCRsrTjw+G9TgKt1Yexjiv8TOWZ6WHsTPz57Yky3DIswZvEqX8fpuHNDtQ==", + "integrity": "sha1-2n3UzIPNaiYLZ8yg96n9riahIF0=", "dev": true }, "sixpack-client": { @@ -17180,7 +16747,7 @@ "slice-ansi": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "integrity": "sha1-BE8aSdiEL/MHqta1Be0Xi9lQE00=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" @@ -17221,7 +16788,7 @@ "snapdragon": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "integrity": "sha1-ZJIufFZbDhQgS6GqfWlkJ40lGC0=", "dev": true, "requires": { "base": "^0.11.1", @@ -17237,7 +16804,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -17272,7 +16839,7 @@ "snapdragon-node": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "integrity": "sha1-bBdfhv8UvbByRWPo88GwIaKGhTs=", "dev": true, "requires": { "define-property": "^1.0.0", @@ -17292,7 +16859,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -17301,7 +16868,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -17310,7 +16877,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -17327,7 +16894,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } @@ -17335,7 +16902,7 @@ "snapdragon-util": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "integrity": "sha1-+VZHlIbyrNeXAGk/b3uAXkWrVuI=", "dev": true, "requires": { "kind-of": "^3.2.0" @@ -17344,7 +16911,7 @@ "sntp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", - "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", + "integrity": "sha1-LGzsFP7cIiJznK+bXD2F0cxaLMg=", "requires": { "hoek": "4.x.x" } @@ -17365,7 +16932,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -17403,7 +16970,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -17414,7 +16981,7 @@ "socket.io-parser": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.3.tgz", - "integrity": "sha512-g0a2HPqLguqAczs3dMECuA1RgoGFPyvDqcbaDEdCWY9g59kdUAz3YRmaJBNKXflrHNwB7Q12Gkf/0CZXfdHR7g==", + "integrity": "sha1-7S2l7nnxCVUDbj2kE7/X8eTYbI4=", "dev": true, "requires": { "component-emitter": "1.2.1", @@ -17426,7 +16993,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -17443,7 +17010,7 @@ "sockjs": { "version": "0.3.19", "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz", - "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==", + "integrity": "sha1-2Xa76ACve9IK4IWY1YI5NQiZPA0=", "dev": true, "requires": { "faye-websocket": "^0.10.0", @@ -17467,7 +17034,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -17497,7 +17064,7 @@ "socks-proxy-agent": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz", - "integrity": "sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA==", + "integrity": "sha1-Lq58+OKoLTRWV2FTmn+XGMVhdlk=", "dev": true, "requires": { "agent-base": "^4.1.0", @@ -17507,7 +17074,7 @@ "source-list-map": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", + "integrity": "sha1-qqR0A/eyRakvvJfqCPJQ1gh+0IU=", "dev": true }, "source-map": { @@ -17521,7 +17088,7 @@ "source-map-resolve": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "integrity": "sha1-cuLMNAlVQ+Q7LGKyxMENSpBU8lk=", "dev": true, "requires": { "atob": "^2.1.1", @@ -17534,7 +17101,7 @@ "source-map-support": { "version": "0.4.18", "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "integrity": "sha1-Aoam3ovkJkEzhZTpfM6nXwosWF8=", "dev": true, "requires": { "source-map": "^0.5.6" @@ -17557,7 +17124,7 @@ "spdx-correct": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "integrity": "sha1-BaW01xU6GVvJLDxCW2nzsqlSTII=", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -17567,13 +17134,13 @@ "spdx-exceptions": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "integrity": "sha1-LHrmEFbHFKW5ubKyr30xHvXHj+k=", "dev": true }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", - "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "integrity": "sha1-meEZt6XaAOBUkcn6M4t5BII7QdA=", "dev": true, "requires": { "spdx-exceptions": "^2.1.0", @@ -17583,7 +17150,7 @@ "spdx-license-ids": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "integrity": "sha1-enzShHDMbToc/m1miG9rxDDTrIc=", "dev": true }, "spdy": { @@ -17603,7 +17170,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -17614,7 +17181,7 @@ "spdy-transport": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz", - "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==", + "integrity": "sha1-S7sVqv/tC+791WrWHb3Iuj4st6E=", "dev": true, "requires": { "debug": "^2.6.8", @@ -17629,7 +17196,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -17644,7 +17211,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -17665,7 +17232,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -17685,7 +17252,7 @@ "split-string": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "integrity": "sha1-fLCd2jqGWFcFxks5pkZgOGguj+I=", "dev": true, "requires": { "extend-shallow": "^3.0.0" @@ -17761,7 +17328,7 @@ "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", - "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==" + "integrity": "sha1-u3PURtonlhBu/MG2AaJT1sRr0Ic=" }, "stream-browserify": { "version": "2.0.1", @@ -17782,7 +17349,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -17803,7 +17370,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -17823,7 +17390,7 @@ "stream-http": { "version": "2.8.2", "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", - "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", + "integrity": "sha1-QSboxrEHAERlkYqi/DVUnndALIc=", "dev": true, "requires": { "builtin-status-codes": "^3.0.0", @@ -17842,7 +17409,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -17863,7 +17430,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -17879,7 +17446,7 @@ "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", - "integrity": "sha512-WREzfy0r0zUqp3lGO096wRuUp7ho1X6uo/7DJfTlEi0Iv/4gT7YHqXDjKC2ioVGBZtE8QzsQD9nx1nIuoZ57jQ==", + "integrity": "sha1-odG3z4PTmvsNYwSaWsv5NJO99ks=", "dev": true, "requires": { "date-format": "^1.2.0", @@ -17891,7 +17458,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -17906,7 +17473,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -17927,7 +17494,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -18012,7 +17579,7 @@ "table": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", - "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "integrity": "sha1-ozRHN1OR52atNNNIbm4q7chNLjY=", "dev": true, "requires": { "ajv": "^5.2.3", @@ -18032,7 +17599,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -18041,7 +17608,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -18064,7 +17631,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -18083,7 +17650,7 @@ "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -18152,7 +17719,7 @@ "teeny-request": { "version": "3.11.3", "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-3.11.3.tgz", - "integrity": "sha512-CKncqSF7sH6p4rzCgkb/z/Pcos5efl0DmolzvlqRQUNcpRIruOhY9+T1FsIlyEbfWd7MsFpodROOwHYh2BaXzw==", + "integrity": "sha1-M1xin3ZF5dZZk2LfLzIwxMvCOlU=", "requires": { "https-proxy-agent": "^2.2.1", "node-fetch": "^2.2.0", @@ -18167,7 +17734,7 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "integrity": "sha1-G0r0lV6zB3xQHCOHL8ZROBFYcTE=" } } }, @@ -18219,7 +17786,7 @@ "through2": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "integrity": "sha1-AcHjnrMdB8t9A6lqcIIyYLIxMs0=", "requires": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" @@ -18233,7 +17800,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=" }, "readable-stream": { "version": "2.3.6", @@ -18252,7 +17819,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "requires": { "safe-buffer": "~5.1.0" } @@ -18291,7 +17858,7 @@ "timers-browserify": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz", - "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==", + "integrity": "sha1-HSjj0qrfHVpZlsTp+VYBzQU0gK4=", "dev": true, "requires": { "setimmediate": "^1.0.4" @@ -18307,7 +17874,7 @@ "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", - "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "integrity": "sha1-bTQzWIl2jSGyvNoKonfO07G/rfk=", "dev": true, "requires": { "os-tmpdir": "~1.0.2" @@ -18348,7 +17915,7 @@ "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "integrity": "sha1-E8/dmzNlUvMLUfM6iuG0Knp1mc4=", "dev": true, "requires": { "define-property": "^2.0.2", @@ -18391,7 +17958,7 @@ "touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", - "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==", + "integrity": "sha1-/jZfX3XsntTlaCXgu3bSSrdK+Ds=", "dev": true, "requires": { "nopt": "~1.0.10" @@ -18461,7 +18028,7 @@ "async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", - "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "integrity": "sha1-skWiPKcZMAROxT+kaqAKPofGphA=", "dev": true, "requires": { "lodash": "^4.17.10" @@ -18470,7 +18037,7 @@ "lodash": { "version": "4.17.11", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "integrity": "sha1-s56mIp72B+zYniyN8SU2iRysm40=", "dev": true } } @@ -18544,13 +18111,13 @@ "typescript": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "integrity": "sha1-HL9h0F1rliaSROtqO85L2RTg8Aw=", "dev": true }, "typescript-eslint-parser": { "version": "16.0.1", "resolved": "https://registry.npmjs.org/typescript-eslint-parser/-/typescript-eslint-parser-16.0.1.tgz", - "integrity": "sha512-IKawLTu4A2xN3aN/cPLxvZ0bhxZHILGDKTZWvWNJ3sLNhJ3PjfMEDQmR2VMpdRPrmWOadgWXRwjLBzSA8AGsaQ==", + "integrity": "sha1-tAaBxwQ7IiuXcnSLcAoACyQcAxs=", "dev": true, "requires": { "lodash.unescape": "4.0.1", @@ -18560,7 +18127,7 @@ "semver": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", - "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "integrity": "sha1-3Eu8emyp2Rbe5dQ1FvAJK1j3uKs=", "dev": true } } @@ -18568,7 +18135,7 @@ "ua-parser-js": { "version": "0.7.17", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", - "integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g==" + "integrity": "sha1-6exflJi57JEOeuOsYmqAXE0J7Kw=" }, "uglify-js": { "version": "2.4.24", @@ -18651,7 +18218,7 @@ "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", - "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==", + "integrity": "sha1-n+FTahCmZKZSZqHjzPhf02MCvJw=", "dev": true }, "undefsafe": { @@ -18666,7 +18233,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -18800,13 +18367,13 @@ "upath": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/upath/-/upath-1.0.5.tgz", - "integrity": "sha512-qbKn90aDQ0YEwvXoLqj0oiuUYroLX2lVHZ+b+xwjozFasAOC4GneDq5+OaIG5Zj+jFmbz/uO+f7a9qxjktJQww==", + "integrity": "sha1-Asq57OvpW77G1fwlZjJXJattGnM=", "dev": true }, "update-notifier": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz", - "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==", + "integrity": "sha1-0HRFk+E/Fh5AassdlAi3LK0Ir/Y=", "dev": true, "requires": { "boxen": "^1.2.1", @@ -18824,7 +18391,7 @@ "ansi-styles": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=", "dev": true, "requires": { "color-convert": "^1.9.0" @@ -18833,7 +18400,7 @@ "chalk": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", + "integrity": "sha1-GMSasWoDe26wFSzIPjRxM4IVtm4=", "dev": true, "requires": { "ansi-styles": "^3.2.1", @@ -18850,7 +18417,7 @@ "supports-color": { "version": "5.4.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", - "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", "dev": true, "requires": { "has-flag": "^3.0.0" @@ -18861,7 +18428,7 @@ "uri-js": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz", - "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==", + "integrity": "sha1-RZWoClHzVhZOIpcN9kx6vWremFA=", "dev": true, "requires": { "punycode": "^2.1.0" @@ -18900,7 +18467,7 @@ "url-parse": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.0.tgz", - "integrity": "sha512-ERuGxDiQ6Xw/agN4tuoCRbmwRuZP0cJ1lJxJubXr5Q/5cDa78+Dc4wfvtxzhzhkm5VvmW6Mf8EVj9SPGN4l8Lg==", + "integrity": "sha1-a/2q1gCYx/4G9iPkKyLeYt4NPXU=", "dev": true, "requires": { "querystringify": "^2.0.0", @@ -18910,7 +18477,7 @@ "querystringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz", - "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==", + "integrity": "sha1-+j7W5o6xUVlFfImze8ZHKDMZV1U=", "dev": true } } @@ -18927,7 +18494,7 @@ "use": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", - "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "integrity": "sha1-FHFr8D/f79AwQK71jYtLhfOnxUQ=", "dev": true, "requires": { "kind-of": "^6.0.2" @@ -18936,7 +18503,7 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true } } @@ -18995,12 +18562,12 @@ "uuid": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + "integrity": "sha1-EsUou51Y0LkmXZovbw/ovhf/HxQ=" }, "uws": { "version": "9.14.0", "resolved": "https://registry.npmjs.org/uws/-/uws-9.14.0.tgz", - "integrity": "sha512-HNMztPP5A1sKuVFmdZ6BPVpBQd5bUjNC8EFMFiICK+oho/OQsAJy5hnIx4btMHiOk8j04f/DbIlqnEZ9d72dqg==", + "integrity": "sha1-+sg4a+/DOno3BcvVjcR7Qwyk3ZU=", "dev": true, "optional": true }, @@ -19037,7 +18604,7 @@ "validate-npm-package-license": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", - "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "integrity": "sha1-gWQ7y+8b3+zUYjeT3EZIlIupgzg=", "dev": true, "requires": { "spdx-correct": "^3.0.0", @@ -19130,7 +18697,7 @@ "vue-eslint-parser": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-2.0.3.tgz", - "integrity": "sha512-ZezcU71Owm84xVF6gfurBQUGg8WQ+WZGxgDEQu1IHFBZNx7BFZg3L1yHxrCBNNwbwFtE1GuvfJKMtb6Xuwc/Bw==", + "integrity": "sha1-wmjJbG2Uz+PZOKX3WTlZsMozYNE=", "dev": true, "requires": { "debug": "^3.1.0", @@ -19144,7 +18711,7 @@ "debug": { "version": "3.2.6", "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "integrity": "sha1-6D0X3hbYp++3cX7b5fsQE17uYps=", "dev": true, "requires": { "ms": "^2.1.1" @@ -19153,7 +18720,7 @@ "ms": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "integrity": "sha1-MKWGTrPrsKZvLr5tcnrwagnYbgo=", "dev": true } } @@ -19161,13 +18728,13 @@ "wait-for-expect": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/wait-for-expect/-/wait-for-expect-1.1.0.tgz", - "integrity": "sha512-vQDokqxyMyknfX3luCDn16bSaRcOyH6gGuUXMIbxBLeTo6nWuEWYqMTT9a+44FmW8c2m6TRWBdNvBBjA1hwEKg==", + "integrity": "sha1-Zgc3XD950yrdNc0sh84T81Gj1FM=", "dev": true }, "watchpack": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "integrity": "sha1-S8EsLr6KonenHx0/FNaFx7RGzQA=", "dev": true, "requires": { "chokidar": "^2.0.2", @@ -19178,7 +18745,7 @@ "anymatch": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "integrity": "sha1-vLJLTzeTTZqnrBe0ra+J58du8us=", "dev": true, "requires": { "micromatch": "^3.1.4", @@ -19200,7 +18767,7 @@ "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "integrity": "sha1-WXn9PxTNUxVl5fot8av/8d+u5yk=", "dev": true, "requires": { "arr-flatten": "^1.1.0", @@ -19229,13 +18796,12 @@ "chokidar": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz", - "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==", + "integrity": "sha1-3L1PbLsqVbR5m6ioQKxSfl9LEXY=", "dev": true, "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.0", "braces": "^2.3.0", - "fsevents": "^1.1.2", "glob-parent": "^3.1.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", @@ -19249,7 +18815,7 @@ "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", "dev": true, "requires": { "ms": "2.0.0" @@ -19331,7 +18897,7 @@ "is-descriptor": { "version": "0.1.6", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "integrity": "sha1-Nm2CQN3kh8pRgjsaufB6EKeCUco=", "dev": true, "requires": { "is-accessor-descriptor": "^0.1.6", @@ -19342,7 +18908,7 @@ "kind-of": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true } } @@ -19350,7 +18916,7 @@ "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "integrity": "sha1-rQD+TcYSqSMuhxhxHcXLWrAoVUM=", "dev": true, "requires": { "array-unique": "^0.3.2", @@ -19430,7 +18996,7 @@ "is-accessor-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "integrity": "sha1-FpwvbT3x+ZJhgHI2XJsOofaHhlY=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -19439,7 +19005,7 @@ "is-data-descriptor": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "integrity": "sha1-2Eh2Mh0Oet0DmQQGq7u9NrqSaMc=", "dev": true, "requires": { "kind-of": "^6.0.0" @@ -19448,7 +19014,7 @@ "is-descriptor": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "integrity": "sha1-OxWXRqZmBLBPjIFSS6NlxfFNhuw=", "dev": true, "requires": { "is-accessor-descriptor": "^1.0.0", @@ -19506,13 +19072,13 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "integrity": "sha1-ARRrNqYhjmTljzqNZt5df8b20FE=", "dev": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "integrity": "sha1-cIWbyVyYQJUvNZoGij/En57PrCM=", "dev": true, "requires": { "arr-diff": "^4.0.0", @@ -19533,7 +19099,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", "dev": true, "requires": { "brace-expansion": "^1.1.7" @@ -19542,7 +19108,7 @@ "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o=", "dev": true }, "readable-stream": { @@ -19575,7 +19141,7 @@ "string_decoder": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=", "dev": true, "requires": { "safe-buffer": "~5.1.0" @@ -19586,7 +19152,7 @@ "wbuf": { "version": "1.7.3", "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "integrity": "sha1-wdjRSTFtPqhShIiVy2oL/oh7h98=", "dev": true, "requires": { "minimalistic-assert": "^1.0.0" @@ -19595,7 +19161,7 @@ "webpack": { "version": "3.12.0", "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz", - "integrity": "sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ==", + "integrity": "sha1-P540NgNwYC/PY56Xk520hvTsDXQ=", "dev": true, "requires": { "acorn": "^5.0.0", @@ -19625,13 +19191,13 @@ "acorn": { "version": "5.5.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", + "integrity": "sha1-9HPdR+AnegjijpvsWu6wR1HwuMk=", "dev": true }, "ajv": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz", - "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==", + "integrity": "sha1-TIr/34CIfY8TLJxSq4otxNC3skw=", "dev": true, "requires": { "fast-deep-equal": "^2.0.1", @@ -19655,7 +19221,7 @@ "async": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", - "integrity": "sha512-xAfGg1/NTLBBKlHFmnd7PlmUW9KhVQIUuSrYem9xzFUZy13ScvtyGGejaae9iAVRiRq9+Cx7DPFaAAhCpyxyPw==", + "integrity": "sha1-YaKau2/MAm/qd+VtHG7FOnlZUfQ=", "dev": true, "requires": { "lodash": "^4.14.0" @@ -19712,7 +19278,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -19771,7 +19337,7 @@ "webpack-dev-middleware": { "version": "1.12.2", "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz", - "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==", + "integrity": "sha1-+PwRIM47T8VoDO7LQ9d3lmshEF4=", "dev": true, "requires": { "memory-fs": "~0.4.1", @@ -19784,7 +19350,7 @@ "mime": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", "dev": true } } @@ -19906,7 +19472,6 @@ "anymatch": "^2.0.0", "async-each": "^1.0.0", "braces": "^2.3.0", - "fsevents": "^1.1.2", "glob-parent": "^3.1.0", "inherits": "^2.0.1", "is-binary-path": "^1.0.0", @@ -20728,7 +20293,7 @@ "webpack-merge": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.1.2.tgz", - "integrity": "sha512-/0QYwW/H1N/CdXYA2PNPVbsxO3u2Fpz34vs72xm03SRfg6bMNGfMJIQEpQjKRvkG2JvT6oRJFpDtSrwbX8Jzvw==", + "integrity": "sha1-XTct3dPh5fiHT1v1qOkp2wn+shY=", "dev": true, "requires": { "lodash": "^4.17.5" @@ -20737,7 +20302,7 @@ "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", - "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "integrity": "sha1-G3eTz3JZ6jj7NmHU04syYK+K5Oc=", "dev": true } } @@ -20745,7 +20310,7 @@ "webpack-sources": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz", - "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==", + "integrity": "sha1-oQHrrlnWUHNU1x2AE5UKOot6WlQ=", "dev": true, "requires": { "source-list-map": "^2.0.0", @@ -20755,7 +20320,7 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", "dev": true } } @@ -20773,13 +20338,13 @@ "websocket-extensions": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz", - "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==", + "integrity": "sha1-XS/yKXcAPsaHpLhwc9+7rBRszyk=", "dev": true }, "whatwg-fetch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", - "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" + "integrity": "sha1-3eal3zFfnTmZGqF2IYU9cguFVm8=" }, "when": { "version": "3.7.8", @@ -20830,7 +20395,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0", @@ -20905,7 +20470,7 @@ "write-file-atomic": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", - "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "integrity": "sha1-H/YVdcLipOjlENb6TiQ8zhg5mas=", "dev": true, "requires": { "graceful-fs": "^4.1.11", @@ -20916,7 +20481,7 @@ "ws": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", - "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "integrity": "sha1-8c+E/i1ekB686U767OeF8YeiKPI=", "dev": true, "requires": { "async-limiter": "~1.0.0", @@ -20948,7 +20513,7 @@ "xhr-status": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/xhr-status/-/xhr-status-1.0.1.tgz", - "integrity": "sha512-VF0WSqtmkf56OmF26LCWsWvRb1a+WYGdHDoQnPPCVUQTM8CVUAOBcUDsm7nP7SQcgEEdrvF4DmhEADuXdGieyw==" + "integrity": "sha1-rSxjGIbM2YqSg0rQ/mlbTO+LrFw=" }, "xml-crypto": { "version": "0.8.5", @@ -21028,12 +20593,12 @@ "xpath.js": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/xpath.js/-/xpath.js-1.1.0.tgz", - "integrity": "sha512-jg+qkfS4K8E7965sqaUl8mRngXiKb3WZGfONgE18pr03FUQiuSV6G+Ej4tS55B+rIQSFEIw3phdVAQ4pPqNWfQ==" + "integrity": "sha1-OBakTtS7NSCRCD0AKjg91RBKX/E=" }, "xregexp": { "version": "4.2.4", "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-4.2.4.tgz", - "integrity": "sha512-sO0bYdYeJAJBcJA8g7MJJX7UrOZIfJPd8U2SC7B2Dd/J24U0aQNoGp33shCaBSWeb0rD5rh6VBUIXOkGal1TZA==", + "integrity": "sha1-AqSuoFbWWkJjLALwIz6rjk1+V+0=", "requires": { "@babel/runtime-corejs2": "^7.2.0" } diff --git a/services/web/package.json b/services/web/package.json index 1f9d0f4331..531d0764aa 100644 --- a/services/web/package.json +++ b/services/web/package.json @@ -119,6 +119,7 @@ "babel-cli": "^6.26.0", "babel-core": "^6.26.0", "babel-loader": "^7.1.2", + "babel-plugin-angularjs-annotate": "^0.10.0", "babel-preset-env": "^1.6.1", "babel-preset-react": "^6.16.0", "bunyan": "0.22.1", diff --git a/services/web/public/src/directives/equals.js b/services/web/public/src/directives/equals.js index 34ccf626ca..dfe8ec92c5 100644 --- a/services/web/public/src/directives/equals.js +++ b/services/web/public/src/directives/equals.js @@ -9,17 +9,15 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.directive('equals', [ - () => ({ - require: 'ngModel', - link(scope, elem, attrs, ctrl) { - const firstField = `#${attrs.equals}` - return elem.add(firstField).on('keyup', () => - scope.$apply(function() { - const equal = elem.val() === $(firstField).val() - return ctrl.$setValidity('areEqual', equal) - }) - ) - } - }) - ])) + App.directive('equals', () => ({ + require: 'ngModel', + link(scope, elem, attrs, ctrl) { + const firstField = `#${attrs.equals}` + return elem.add(firstField).on('keyup', () => + scope.$apply(function() { + const equal = elem.val() === $(firstField).val() + return ctrl.$setValidity('areEqual', equal) + }) + ) + } + }))) diff --git a/services/web/public/src/directives/eventTracking.js b/services/web/public/src/directives/eventTracking.js index 8f5545ef75..7587bf6cf4 100644 --- a/services/web/public/src/directives/eventTracking.js +++ b/services/web/public/src/directives/eventTracking.js @@ -35,72 +35,67 @@ const isInViewport = function(element) { } define(['base'], App => - App.directive('eventTracking', [ - 'event_tracking', - event_tracking => ({ - scope: { - eventTracking: '@', - eventSegmentation: '=?' - }, - link(scope, element, attrs) { - const sendGA = attrs.eventTrackingGa || false - const sendMB = attrs.eventTrackingMb || false - const sendMBFunction = attrs.eventTrackingSendOnce - ? 'sendMBOnce' - : 'sendMB' - const sendGAFunction = attrs.eventTrackingSendOnce - ? 'sendGAOnce' - : 'send' - const segmentation = scope.eventSegmentation || {} - segmentation.page = window.location.pathname + App.directive('eventTracking', event_tracking => ({ + scope: { + eventTracking: '@', + eventSegmentation: '=?' + }, + link(scope, element, attrs) { + const sendGA = attrs.eventTrackingGa || false + const sendMB = attrs.eventTrackingMb || false + const sendMBFunction = attrs.eventTrackingSendOnce + ? 'sendMBOnce' + : 'sendMB' + const sendGAFunction = attrs.eventTrackingSendOnce ? 'sendGAOnce' : 'send' + const segmentation = scope.eventSegmentation || {} + segmentation.page = window.location.pathname - const sendEvent = function(scrollEvent) { - /* + const sendEvent = function(scrollEvent) { + /* @param {boolean} scrollEvent Use to unbind scroll event */ - if (sendMB) { - event_tracking[sendMBFunction](scope.eventTracking, segmentation) - } - if (sendGA) { - event_tracking[sendGAFunction]( - attrs.eventTrackingGa, - attrs.eventTrackingAction || scope.eventTracking, - attrs.eventTrackingLabel || '' - ) - } - if (scrollEvent) { - return $(window).unbind('resize scroll') - } + if (sendMB) { + event_tracking[sendMBFunction](scope.eventTracking, segmentation) } - - if (attrs.eventTrackingTrigger === 'load') { - return sendEvent() - } else if (attrs.eventTrackingTrigger === 'click') { - return element.on('click', e => sendEvent()) - } else if (attrs.eventTrackingTrigger === 'hover') { - let timer = null - let timeoutAmt = 500 - if (attrs.eventHoverAmt) { - timeoutAmt = parseInt(attrs.eventHoverAmt, 10) - } - return element - .on('mouseenter', function() { - timer = setTimeout(() => sendEvent(), timeoutAmt) - }) - .on('mouseleave', () => clearTimeout(timer)) - } else if (attrs.eventTrackingTrigger === 'scroll') { - if (!event_tracking.eventInCache(scope.eventTracking)) { - return $(window).on('resize scroll', () => - _.throttle( - isInViewport(element) && - !event_tracking.eventInCache(scope.eventTracking) - ? sendEvent(true) - : undefined, - 500 - ) - ) - } + if (sendGA) { + event_tracking[sendGAFunction]( + attrs.eventTrackingGa, + attrs.eventTrackingAction || scope.eventTracking, + attrs.eventTrackingLabel || '' + ) + } + if (scrollEvent) { + return $(window).unbind('resize scroll') } } - }) - ])) + + if (attrs.eventTrackingTrigger === 'load') { + return sendEvent() + } else if (attrs.eventTrackingTrigger === 'click') { + return element.on('click', e => sendEvent()) + } else if (attrs.eventTrackingTrigger === 'hover') { + let timer = null + let timeoutAmt = 500 + if (attrs.eventHoverAmt) { + timeoutAmt = parseInt(attrs.eventHoverAmt, 10) + } + return element + .on('mouseenter', function() { + timer = setTimeout(() => sendEvent(), timeoutAmt) + }) + .on('mouseleave', () => clearTimeout(timer)) + } else if (attrs.eventTrackingTrigger === 'scroll') { + if (!event_tracking.eventInCache(scope.eventTracking)) { + return $(window).on('resize scroll', () => + _.throttle( + isInViewport(element) && + !event_tracking.eventInCache(scope.eventTracking) + ? sendEvent(true) + : undefined, + 500 + ) + ) + } + } + } + }))) diff --git a/services/web/public/src/ide/binary-files/controllers/BinaryFileController.js b/services/web/public/src/ide/binary-files/controllers/BinaryFileController.js index 3cd1fd8c13..ed5c8740ae 100644 --- a/services/web/public/src/ide/binary-files/controllers/BinaryFileController.js +++ b/services/web/public/src/ide/binary-files/controllers/BinaryFileController.js @@ -1,197 +1,193 @@ define(['base', 'moment'], (App, moment) => - App.controller('BinaryFileController', [ - '$scope', - '$rootScope', - '$http', - '$timeout', - '$element', - 'ide', - 'waitFor', - function($scope, $rootScope, $http, $timeout, $element, ide, waitFor) { - const MAX_FILE_SIZE = 2 * 1024 * 1024 - const MAX_URL_LENGTH = 60 - const FRONT_OF_URL_LENGTH = 35 - const FILLER = '...' - const TAIL_OF_URL_LENGTH = - MAX_URL_LENGTH - FRONT_OF_URL_LENGTH - FILLER.length + App.controller('BinaryFileController', function( + $scope, + $rootScope, + $http, + $timeout, + $element, + ide, + waitFor + ) { + const MAX_FILE_SIZE = 2 * 1024 * 1024 + const MAX_URL_LENGTH = 60 + const FRONT_OF_URL_LENGTH = 35 + const FILLER = '...' + const TAIL_OF_URL_LENGTH = + MAX_URL_LENGTH - FRONT_OF_URL_LENGTH - FILLER.length - const textExtensions = ['bib', 'tex', 'txt', 'cls', 'sty'] - const imageExtensions = ['png', 'jpg', 'jpeg', 'gif'] - const previewableExtensions = [] + const textExtensions = ['bib', 'tex', 'txt', 'cls', 'sty'] + const imageExtensions = ['png', 'jpg', 'jpeg', 'gif'] + const previewableExtensions = [] - const extension = file => - file.name - .split('.') - .pop() - .toLowerCase() + const extension = file => + file.name + .split('.') + .pop() + .toLowerCase() - $scope.isTextFile = () => - textExtensions.indexOf(extension($scope.openFile)) > -1 - $scope.isImageFile = () => - imageExtensions.indexOf(extension($scope.openFile)) > -1 - $scope.isPreviewableFile = () => - previewableExtensions.indexOf(extension($scope.openFile)) > -1 - $scope.isUnpreviewableFile = () => - !$scope.isTextFile() && - !$scope.isImageFile() && - !$scope.isPreviewableFile() + $scope.isTextFile = () => + textExtensions.indexOf(extension($scope.openFile)) > -1 + $scope.isImageFile = () => + imageExtensions.indexOf(extension($scope.openFile)) > -1 + $scope.isPreviewableFile = () => + previewableExtensions.indexOf(extension($scope.openFile)) > -1 + $scope.isUnpreviewableFile = () => + !$scope.isTextFile() && + !$scope.isImageFile() && + !$scope.isPreviewableFile() - $scope.textPreview = { - loading: false, - shouldShowDots: false, - error: false, - data: null - } - - $scope.refreshing = false - $scope.refreshError = null - - $scope.displayUrl = function(url) { - if (url == null) { - return - } - if (url.length > MAX_URL_LENGTH) { - const front = url.slice(0, FRONT_OF_URL_LENGTH) - const tail = url.slice(url.length - TAIL_OF_URL_LENGTH) - return front + FILLER + tail - } - return url - } - - $scope.refreshFile = function(file) { - $scope.refreshing = true - $scope.refreshError = null - ide.fileTreeManager - .refreshLinkedFile(file) - .then(function(response) { - const { data } = response - const newFileId = data.new_file_id - $timeout( - () => - waitFor( - () => ide.fileTreeManager.findEntityById(newFileId), - 5000 - ) - .then(newFile => ide.binaryFilesManager.openFile(newFile)) - .catch(err => console.warn(err)), - - 0 - ) - $scope.refreshError = null - }) - .catch(response => ($scope.refreshError = response.data)) - .finally(() => { - $scope.refreshing = false - const provider = file.linkedFileData.provider - if ( - provider === 'mendeley' || - provider === 'zotero' || - file.name.match(/^.*\.bib$/) - ) { - ide.$scope.$emit('references:should-reindex', {}) - } - }) - } - - // Callback fired when the `img` tag fails to load, - // `failedLoad` used to show the "No Preview" message - $scope.failedLoad = false - window.sl_binaryFilePreviewError = () => { - $scope.failedLoad = true - $scope.$apply() - } - - // Callback fired when the `img` tag is done loading, - // `imgLoaded` is used to show the spinner gif while loading - $scope.imgLoaded = false - window.sl_binaryFilePreviewLoaded = () => { - $scope.imgLoaded = true - $scope.$apply() - } - - if ($scope.isTextFile()) { - loadTextFilePreview() - } - - function loadTextFilePreview() { - const url = `/project/${window.project_id}/file/${$scope.openFile.id}` - let truncated = false - displayPreviewLoading() - getFileSize(url) - .then(fileSize => { - const opts = {} - if (fileSize > MAX_FILE_SIZE) { - truncated = true - opts.maxSize = MAX_FILE_SIZE - } - return getFileContents(url, opts) - }) - .then(contents => { - const displayedContents = truncated - ? truncateFileContents(contents) - : contents - displayPreview(displayedContents, truncated) - }) - .catch(err => { - console.error(err) - displayPreviewError() - }) - } - - function getFileSize(url) { - return $http.head(url).then(response => { - const size = parseInt(response.headers('Content-Length'), 10) - if (isNaN(size)) { - throw new Error('Could not parse Content-Length header') - } - return size - }) - } - - function getFileContents(url, opts = {}) { - const { maxSize } = opts - if (maxSize != null) { - url += `?range=0-${maxSize}` - } - return $http - .get(url, { - transformResponse: null // Don't parse JSON - }) - .then(response => { - return response.data - }) - } - - function truncateFileContents(contents) { - return contents.replace(/\n.*$/, '') - } - - function displayPreviewLoading() { - $scope.textPreview.data = null - $scope.textPreview.loading = true - $scope.textPreview.shouldShowDots = false - $scope.$apply() - } - - function displayPreview(contents, truncated) { - $scope.textPreview.error = false - $scope.textPreview.data = contents - $scope.textPreview.shouldShowDots = truncated - $timeout(setPreviewHeight, 0) - } - - function displayPreviewError() { - $scope.textPreview.error = true - $scope.textPreview.loading = false - } - - function setPreviewHeight() { - const $preview = $element.find('.text-preview .scroll-container') - const $footer = $element.find('.binary-file-footer') - const maxHeight = $element.height() - $footer.height() - 14 // borders + margin - $preview.css({ 'max-height': maxHeight }) - // Don't show the preview until we've set the height, otherwise we jump around - $scope.textPreview.loading = false - } + $scope.textPreview = { + loading: false, + shouldShowDots: false, + error: false, + data: null } - ])) + + $scope.refreshing = false + $scope.refreshError = null + + $scope.displayUrl = function(url) { + if (url == null) { + return + } + if (url.length > MAX_URL_LENGTH) { + const front = url.slice(0, FRONT_OF_URL_LENGTH) + const tail = url.slice(url.length - TAIL_OF_URL_LENGTH) + return front + FILLER + tail + } + return url + } + + $scope.refreshFile = function(file) { + $scope.refreshing = true + $scope.refreshError = null + ide.fileTreeManager + .refreshLinkedFile(file) + .then(function(response) { + const { data } = response + const newFileId = data.new_file_id + $timeout( + () => + waitFor(() => ide.fileTreeManager.findEntityById(newFileId), 5000) + .then(newFile => ide.binaryFilesManager.openFile(newFile)) + .catch(err => console.warn(err)), + + 0 + ) + $scope.refreshError = null + }) + .catch(response => ($scope.refreshError = response.data)) + .finally(() => { + $scope.refreshing = false + const provider = file.linkedFileData.provider + if ( + provider === 'mendeley' || + provider === 'zotero' || + file.name.match(/^.*\.bib$/) + ) { + ide.$scope.$emit('references:should-reindex', {}) + } + }) + } + + // Callback fired when the `img` tag fails to load, + // `failedLoad` used to show the "No Preview" message + $scope.failedLoad = false + window.sl_binaryFilePreviewError = () => { + $scope.failedLoad = true + $scope.$apply() + } + + // Callback fired when the `img` tag is done loading, + // `imgLoaded` is used to show the spinner gif while loading + $scope.imgLoaded = false + window.sl_binaryFilePreviewLoaded = () => { + $scope.imgLoaded = true + $scope.$apply() + } + + if ($scope.isTextFile()) { + loadTextFilePreview() + } + + function loadTextFilePreview() { + const url = `/project/${window.project_id}/file/${$scope.openFile.id}` + let truncated = false + displayPreviewLoading() + getFileSize(url) + .then(fileSize => { + const opts = {} + if (fileSize > MAX_FILE_SIZE) { + truncated = true + opts.maxSize = MAX_FILE_SIZE + } + return getFileContents(url, opts) + }) + .then(contents => { + const displayedContents = truncated + ? truncateFileContents(contents) + : contents + displayPreview(displayedContents, truncated) + }) + .catch(err => { + console.error(err) + displayPreviewError() + }) + } + + function getFileSize(url) { + return $http.head(url).then(response => { + const size = parseInt(response.headers('Content-Length'), 10) + if (isNaN(size)) { + throw new Error('Could not parse Content-Length header') + } + return size + }) + } + + function getFileContents(url, opts = {}) { + const { maxSize } = opts + if (maxSize != null) { + url += `?range=0-${maxSize}` + } + return $http + .get(url, { + transformResponse: null // Don't parse JSON + }) + .then(response => { + return response.data + }) + } + + function truncateFileContents(contents) { + return contents.replace(/\n.*$/, '') + } + + function displayPreviewLoading() { + $scope.textPreview.data = null + $scope.textPreview.loading = true + $scope.textPreview.shouldShowDots = false + $scope.$apply() + } + + function displayPreview(contents, truncated) { + $scope.textPreview.error = false + $scope.textPreview.data = contents + $scope.textPreview.shouldShowDots = truncated + $timeout(setPreviewHeight, 0) + } + + function displayPreviewError() { + $scope.textPreview.error = true + $scope.textPreview.loading = false + } + + function setPreviewHeight() { + const $preview = $element.find('.text-preview .scroll-container') + const $footer = $element.find('.binary-file-footer') + const maxHeight = $element.height() - $footer.height() - 14 // borders + margin + $preview.css({ 'max-height': maxHeight }) + // Don't show the preview until we've set the height, otherwise we jump around + $scope.textPreview.loading = false + } + })) diff --git a/services/web/public/src/ide/chat/controllers/ChatMessageController.js b/services/web/public/src/ide/chat/controllers/ChatMessageController.js index 967d690ad0..d85ed9fbdd 100644 --- a/services/web/public/src/ide/chat/controllers/ChatMessageController.js +++ b/services/web/public/src/ide/chat/controllers/ChatMessageController.js @@ -12,50 +12,46 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base', 'ide/colors/ColorManager'], (App, ColorManager) => - App.controller('ChatMessageController', [ - '$scope', - 'ide', - function($scope, ide) { - const hslColorConfigs = { - borderSaturation: - (window.uiConfig != null - ? window.uiConfig.chatMessageBorderSaturation - : undefined) || '70%', - borderLightness: - (window.uiConfig != null - ? window.uiConfig.chatMessageBorderLightness - : undefined) || '70%', - bgSaturation: - (window.uiConfig != null - ? window.uiConfig.chatMessageBgSaturation - : undefined) || '60%', - bgLightness: - (window.uiConfig != null - ? window.uiConfig.chatMessageBgLightness - : undefined) || '97%' - } - - const hue = function(user) { - if (user == null) { - return 0 - } else { - return ColorManager.getHueForUserId(user.id) - } - } - - $scope.getMessageStyle = user => ({ - 'border-color': `hsl(${hue(user)}, ${ - hslColorConfigs.borderSaturation - }, ${hslColorConfigs.borderLightness})`, - 'background-color': `hsl(${hue(user)}, ${ - hslColorConfigs.bgSaturation - }, ${hslColorConfigs.bgLightness})` - }) - - return ($scope.getArrowStyle = user => ({ - 'border-color': `hsl(${hue(user)}, ${ - hslColorConfigs.borderSaturation - }, ${hslColorConfigs.borderLightness})` - })) + App.controller('ChatMessageController', function($scope, ide) { + const hslColorConfigs = { + borderSaturation: + (window.uiConfig != null + ? window.uiConfig.chatMessageBorderSaturation + : undefined) || '70%', + borderLightness: + (window.uiConfig != null + ? window.uiConfig.chatMessageBorderLightness + : undefined) || '70%', + bgSaturation: + (window.uiConfig != null + ? window.uiConfig.chatMessageBgSaturation + : undefined) || '60%', + bgLightness: + (window.uiConfig != null + ? window.uiConfig.chatMessageBgLightness + : undefined) || '97%' } - ])) + + const hue = function(user) { + if (user == null) { + return 0 + } else { + return ColorManager.getHueForUserId(user.id) + } + } + + $scope.getMessageStyle = user => ({ + 'border-color': `hsl(${hue(user)}, ${hslColorConfigs.borderSaturation}, ${ + hslColorConfigs.borderLightness + })`, + 'background-color': `hsl(${hue(user)}, ${hslColorConfigs.bgSaturation}, ${ + hslColorConfigs.bgLightness + })` + }) + + return ($scope.getArrowStyle = user => ({ + 'border-color': `hsl(${hue(user)}, ${hslColorConfigs.borderSaturation}, ${ + hslColorConfigs.borderLightness + })` + })) + })) diff --git a/services/web/public/src/ide/directives/layout.js b/services/web/public/src/ide/directives/layout.js index 6fa56478ef..4f615d08e3 100644 --- a/services/web/public/src/ide/directives/layout.js +++ b/services/web/public/src/ide/directives/layout.js @@ -14,198 +14,194 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base', 'libs/jquery-layout', 'libs/jquery.ui.touch-punch'], App => - App.directive('layout', [ - '$parse', - '$compile', - 'ide', - ($parse, $compile, ide) => ({ - compile() { - return { - pre(scope, element, attrs) { - let customTogglerEl, spacingClosed, spacingOpen, state - const name = attrs.layout + App.directive('layout', ($parse, $compile, ide) => ({ + compile() { + return { + pre(scope, element, attrs) { + let customTogglerEl, spacingClosed, spacingOpen, state + const name = attrs.layout - const { customTogglerPane } = attrs - const { customTogglerMsgWhenOpen } = attrs - const { customTogglerMsgWhenClosed } = attrs - const hasCustomToggler = - customTogglerPane != null && - customTogglerMsgWhenOpen != null && - customTogglerMsgWhenClosed != null + const { customTogglerPane } = attrs + const { customTogglerMsgWhenOpen } = attrs + const { customTogglerMsgWhenClosed } = attrs + const hasCustomToggler = + customTogglerPane != null && + customTogglerMsgWhenOpen != null && + customTogglerMsgWhenClosed != null - if (attrs.spacingOpen != null) { - spacingOpen = parseInt(attrs.spacingOpen, 10) - } else { - spacingOpen = window.uiConfig.defaultResizerSizeOpen + if (attrs.spacingOpen != null) { + spacingOpen = parseInt(attrs.spacingOpen, 10) + } else { + spacingOpen = window.uiConfig.defaultResizerSizeOpen + } + + if (attrs.spacingClosed != null) { + spacingClosed = parseInt(attrs.spacingClosed, 10) + } else { + spacingClosed = window.uiConfig.defaultResizerSizeClosed + } + + const options = { + spacing_open: spacingOpen, + spacing_closed: spacingClosed, + slidable: false, + enableCursorHotkey: false, + onopen: pane => { + return onPaneOpen(pane) + }, + onclose: pane => { + return onPaneClose(pane) + }, + onresize: () => { + return onInternalResize() + }, + maskIframesOnResize: scope.$eval( + attrs.maskIframesOnResize || 'false' + ), + east: { + size: scope.$eval(attrs.initialSizeEast), + initClosed: scope.$eval(attrs.initClosedEast) + }, + west: { + size: scope.$eval(attrs.initialSizeEast), + initClosed: scope.$eval(attrs.initClosedWest) } + } - if (attrs.spacingClosed != null) { - spacingClosed = parseInt(attrs.spacingClosed, 10) - } else { - spacingClosed = window.uiConfig.defaultResizerSizeClosed - } - - const options = { - spacing_open: spacingOpen, - spacing_closed: spacingClosed, - slidable: false, - enableCursorHotkey: false, - onopen: pane => { - return onPaneOpen(pane) - }, - onclose: pane => { - return onPaneClose(pane) - }, - onresize: () => { - return onInternalResize() - }, - maskIframesOnResize: scope.$eval( - attrs.maskIframesOnResize || 'false' - ), - east: { - size: scope.$eval(attrs.initialSizeEast), - initClosed: scope.$eval(attrs.initClosedEast) - }, - west: { - size: scope.$eval(attrs.initialSizeEast), - initClosed: scope.$eval(attrs.initClosedWest) + // Restore previously recorded state + if ((state = ide.localStorage(`layout.${name}`)) != null) { + if (state.east != null) { + if ( + attrs.minimumRestoreSizeEast == null || + (state.east.size >= attrs.minimumRestoreSizeEast && + !state.east.initClosed) + ) { + options.east = state.east } } - - // Restore previously recorded state - if ((state = ide.localStorage(`layout.${name}`)) != null) { - if (state.east != null) { - if ( - attrs.minimumRestoreSizeEast == null || - (state.east.size >= attrs.minimumRestoreSizeEast && - !state.east.initClosed) - ) { - options.east = state.east - } - } - if (state.west != null) { - if ( - attrs.minimumRestoreSizeWest == null || - (state.west.size >= attrs.minimumRestoreSizeWest && - !state.west.initClosed) - ) { - options.west = state.west - } + if (state.west != null) { + if ( + attrs.minimumRestoreSizeWest == null || + (state.west.size >= attrs.minimumRestoreSizeWest && + !state.west.initClosed) + ) { + options.west = state.west } } + } - if (window.uiConfig.eastResizerCursor != null) { - options.east.resizerCursor = window.uiConfig.eastResizerCursor - } + if (window.uiConfig.eastResizerCursor != null) { + options.east.resizerCursor = window.uiConfig.eastResizerCursor + } - if (window.uiConfig.westResizerCursor != null) { - options.west.resizerCursor = window.uiConfig.westResizerCursor - } + if (window.uiConfig.westResizerCursor != null) { + options.west.resizerCursor = window.uiConfig.westResizerCursor + } - const repositionControls = function() { - state = element.layout().readState() - if (state.east != null) { - const controls = element.find('> .ui-layout-resizer-controls') - if (state.east.initClosed) { - return controls.hide() - } else { - controls.show() - return controls.css({ - right: state.east.size - }) - } + const repositionControls = function() { + state = element.layout().readState() + if (state.east != null) { + const controls = element.find('> .ui-layout-resizer-controls') + if (state.east.initClosed) { + return controls.hide() + } else { + controls.show() + return controls.css({ + right: state.east.size + }) } } + } - const repositionCustomToggler = function() { - if (customTogglerEl == null) { + const repositionCustomToggler = function() { + if (customTogglerEl == null) { + return + } + state = element.layout().readState() + const positionAnchor = + customTogglerPane === 'east' ? 'right' : 'left' + const paneState = state[customTogglerPane] + if (paneState != null) { + return customTogglerEl.css( + positionAnchor, + paneState.initClosed ? 0 : paneState.size + ) + } + } + + const resetOpenStates = function() { + state = element.layout().readState() + if (attrs.openEast != null && state.east != null) { + const openEast = $parse(attrs.openEast) + return openEast.assign(scope, !state.east.initClosed) + } + } + + // Someone moved the resizer + var onInternalResize = function() { + state = element.layout().readState() + scope.$broadcast(`layout:${name}:resize`, state) + repositionControls() + if (hasCustomToggler) { + repositionCustomToggler() + } + return resetOpenStates() + } + + let oldWidth = element.width() + // Something resized our parent element + const onExternalResize = function() { + if ( + attrs.resizeProportionally != null && + scope.$eval(attrs.resizeProportionally) + ) { + const eastState = element.layout().readState().east + if (eastState != null) { + const newInternalWidth = + (eastState.size / oldWidth) * element.width() + oldWidth = element.width() + element.layout().sizePane('east', newInternalWidth) return } - state = element.layout().readState() - const positionAnchor = - customTogglerPane === 'east' ? 'right' : 'left' - const paneState = state[customTogglerPane] - if (paneState != null) { - return customTogglerEl.css( - positionAnchor, - paneState.initClosed ? 0 : paneState.size - ) - } } - const resetOpenStates = function() { - state = element.layout().readState() - if (attrs.openEast != null && state.east != null) { - const openEast = $parse(attrs.openEast) - return openEast.assign(scope, !state.east.initClosed) - } + return element.layout().resizeAll() + } + + element.layout(options) + element.layout().resizeAll() + + if (attrs.resizeOn != null) { + for (let event of Array.from(attrs.resizeOn.split(','))) { + scope.$on(event, () => onExternalResize()) + } + } + + if (hasCustomToggler) { + state = element.layout().readState() + const customTogglerScope = scope.$new() + + customTogglerScope.isOpen = true + customTogglerScope.isVisible = true + + if ( + (state[customTogglerPane] != null + ? state[customTogglerPane].initClosed + : undefined) === true + ) { + customTogglerScope.isOpen = false } - // Someone moved the resizer - var onInternalResize = function() { - state = element.layout().readState() - scope.$broadcast(`layout:${name}:resize`, state) - repositionControls() - if (hasCustomToggler) { - repositionCustomToggler() - } - return resetOpenStates() + customTogglerScope.tooltipMsgWhenOpen = customTogglerMsgWhenOpen + customTogglerScope.tooltipMsgWhenClosed = customTogglerMsgWhenClosed + + customTogglerScope.tooltipPlacement = + customTogglerPane === 'east' ? 'left' : 'right' + customTogglerScope.handleClick = function() { + element.layout().toggle(customTogglerPane) + return repositionCustomToggler() } - - let oldWidth = element.width() - // Something resized our parent element - const onExternalResize = function() { - if ( - attrs.resizeProportionally != null && - scope.$eval(attrs.resizeProportionally) - ) { - const eastState = element.layout().readState().east - if (eastState != null) { - const newInternalWidth = - (eastState.size / oldWidth) * element.width() - oldWidth = element.width() - element.layout().sizePane('east', newInternalWidth) - return - } - } - - return element.layout().resizeAll() - } - - element.layout(options) - element.layout().resizeAll() - - if (attrs.resizeOn != null) { - for (let event of Array.from(attrs.resizeOn.split(','))) { - scope.$on(event, () => onExternalResize()) - } - } - - if (hasCustomToggler) { - state = element.layout().readState() - const customTogglerScope = scope.$new() - - customTogglerScope.isOpen = true - customTogglerScope.isVisible = true - - if ( - (state[customTogglerPane] != null - ? state[customTogglerPane].initClosed - : undefined) === true - ) { - customTogglerScope.isOpen = false - } - - customTogglerScope.tooltipMsgWhenOpen = customTogglerMsgWhenOpen - customTogglerScope.tooltipMsgWhenClosed = customTogglerMsgWhenClosed - - customTogglerScope.tooltipPlacement = - customTogglerPane === 'east' ? 'left' : 'right' - customTogglerScope.handleClick = function() { - element.layout().toggle(customTogglerPane) - return repositionCustomToggler() - } - customTogglerEl = $compile(`\ + customTogglerEl = $compile(`\ \ `)(customTogglerScope) - element.append(customTogglerEl) - } - - var onPaneOpen = function(pane) { - if (!hasCustomToggler && pane !== customTogglerPane) { - return - } - return customTogglerEl - .scope() - .$applyAsync(() => (customTogglerEl.scope().isOpen = true)) - } - - var onPaneClose = function(pane) { - if (!hasCustomToggler && pane !== customTogglerPane) { - return - } - return customTogglerEl - .scope() - .$applyAsync(() => (customTogglerEl.scope().isOpen = false)) - } - - // Save state when exiting - $(window).unload(() => - ide.localStorage(`layout.${name}`, element.layout().readState()) - ) - - if (attrs.openEast != null) { - scope.$watch(attrs.openEast, function(value, oldValue) { - if (value != null && value !== oldValue) { - if (value) { - element.layout().open('east') - } else { - element.layout().close('east') - } - } - return setTimeout(() => scope.$digest(), 0) - }) - } - - if (attrs.allowOverflowOn != null) { - const layoutObj = element.layout() - const overflowPane = scope.$eval(attrs.allowOverflowOn) - const overflowPaneEl = layoutObj.panes[overflowPane] - // Set the panel as overflowing (gives it higher z-index and sets overflow rules) - layoutObj.allowOverflow(overflowPane) - // Read the given z-index value and increment it, so that it's higher than synctex controls. - const overflowPaneZVal = overflowPaneEl.zIndex() - overflowPaneEl.css('z-index', overflowPaneZVal + 1) - } - - resetOpenStates() - onInternalResize() - - if (attrs.layoutDisabled != null) { - return scope.$watch(attrs.layoutDisabled, function(value) { - if (value) { - element.layout().hide('east') - } else { - element.layout().show('east') - } - if (hasCustomToggler) { - return customTogglerEl.scope().$applyAsync(function() { - customTogglerEl.scope().isOpen = !value - return (customTogglerEl.scope().isVisible = !value) - }) - } - }) - } - }, - - post(scope, element, attrs) { - const name = attrs.layout - const state = element.layout().readState() - return scope.$broadcast(`layout:${name}:linked`, state) + element.append(customTogglerEl) } + + var onPaneOpen = function(pane) { + if (!hasCustomToggler && pane !== customTogglerPane) { + return + } + return customTogglerEl + .scope() + .$applyAsync(() => (customTogglerEl.scope().isOpen = true)) + } + + var onPaneClose = function(pane) { + if (!hasCustomToggler && pane !== customTogglerPane) { + return + } + return customTogglerEl + .scope() + .$applyAsync(() => (customTogglerEl.scope().isOpen = false)) + } + + // Save state when exiting + $(window).unload(() => + ide.localStorage(`layout.${name}`, element.layout().readState()) + ) + + if (attrs.openEast != null) { + scope.$watch(attrs.openEast, function(value, oldValue) { + if (value != null && value !== oldValue) { + if (value) { + element.layout().open('east') + } else { + element.layout().close('east') + } + } + return setTimeout(() => scope.$digest(), 0) + }) + } + + if (attrs.allowOverflowOn != null) { + const layoutObj = element.layout() + const overflowPane = scope.$eval(attrs.allowOverflowOn) + const overflowPaneEl = layoutObj.panes[overflowPane] + // Set the panel as overflowing (gives it higher z-index and sets overflow rules) + layoutObj.allowOverflow(overflowPane) + // Read the given z-index value and increment it, so that it's higher than synctex controls. + const overflowPaneZVal = overflowPaneEl.zIndex() + overflowPaneEl.css('z-index', overflowPaneZVal + 1) + } + + resetOpenStates() + onInternalResize() + + if (attrs.layoutDisabled != null) { + return scope.$watch(attrs.layoutDisabled, function(value) { + if (value) { + element.layout().hide('east') + } else { + element.layout().show('east') + } + if (hasCustomToggler) { + return customTogglerEl.scope().$applyAsync(function() { + customTogglerEl.scope().isOpen = !value + return (customTogglerEl.scope().isVisible = !value) + }) + } + }) + } + }, + + post(scope, element, attrs) { + const name = attrs.layout + const state = element.layout().readState() + return scope.$broadcast(`layout:${name}:linked`, state) } } - }) - ])) + } + }))) diff --git a/services/web/public/src/ide/editor/controllers/SavingNotificationController.js b/services/web/public/src/ide/editor/controllers/SavingNotificationController.js index 1defeea1b5..0efe601146 100644 --- a/services/web/public/src/ide/editor/controllers/SavingNotificationController.js +++ b/services/web/public/src/ide/editor/controllers/SavingNotificationController.js @@ -13,81 +13,76 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base', 'ide/editor/Document'], (App, Document) => - App.controller('SavingNotificationController', [ - '$scope', - '$interval', - 'ide', - function($scope, $interval, ide) { - let warnAboutUnsavedChanges - setInterval(() => pollSavedStatus(), 1000) + App.controller('SavingNotificationController', function( + $scope, + $interval, + ide + ) { + let warnAboutUnsavedChanges + setInterval(() => pollSavedStatus(), 1000) - $(window).bind('beforeunload', () => { - return warnAboutUnsavedChanges() - }) + $(window).bind('beforeunload', () => { + return warnAboutUnsavedChanges() + }) - let lockEditorModal = null // modal showing "connection lost" - const MAX_UNSAVED_SECONDS = 15 // lock the editor after this time if unsaved + let lockEditorModal = null // modal showing "connection lost" + const MAX_UNSAVED_SECONDS = 15 // lock the editor after this time if unsaved - $scope.docSavingStatus = {} - var pollSavedStatus = function() { - let t - const oldStatus = $scope.docSavingStatus - const oldUnsavedCount = $scope.docSavingStatusCount - const newStatus = {} - let newUnsavedCount = 0 - let maxUnsavedSeconds = 0 + $scope.docSavingStatus = {} + var pollSavedStatus = function() { + let t + const oldStatus = $scope.docSavingStatus + const oldUnsavedCount = $scope.docSavingStatusCount + const newStatus = {} + let newUnsavedCount = 0 + let maxUnsavedSeconds = 0 - for (let doc_id in Document.openDocs) { - const doc = Document.openDocs[doc_id] - const saving = doc.pollSavedStatus() - if (!saving) { - newUnsavedCount++ - if (oldStatus[doc_id] != null) { - newStatus[doc_id] = oldStatus[doc_id] - t = newStatus[doc_id].unsavedSeconds += 1 - if (t > maxUnsavedSeconds) { - maxUnsavedSeconds = t - } - } else { - newStatus[doc_id] = { - unsavedSeconds: 0, - doc: ide.fileTreeManager.findEntityById(doc_id) - } + for (let doc_id in Document.openDocs) { + const doc = Document.openDocs[doc_id] + const saving = doc.pollSavedStatus() + if (!saving) { + newUnsavedCount++ + if (oldStatus[doc_id] != null) { + newStatus[doc_id] = oldStatus[doc_id] + t = newStatus[doc_id].unsavedSeconds += 1 + if (t > maxUnsavedSeconds) { + maxUnsavedSeconds = t + } + } else { + newStatus[doc_id] = { + unsavedSeconds: 0, + doc: ide.fileTreeManager.findEntityById(doc_id) } } } - - if ( - newUnsavedCount > 0 && - t > MAX_UNSAVED_SECONDS && - !lockEditorModal - ) { - lockEditorModal = ide.showLockEditorMessageModal( - 'Connection lost', - 'Sorry, the connection to the server is down.' - ) - lockEditorModal.result.finally(() => (lockEditorModal = null)) // unset the modal if connection comes back - } - - if (lockEditorModal && newUnsavedCount === 0) { - lockEditorModal.dismiss('connection back up') - } - - // for performance, only update the display if the old or new - // counts of unsaved files are nonzeror. If both old and new - // unsaved counts are zero then we know we are in a good state - // and don't need to do anything to the UI. - if (newUnsavedCount || oldUnsavedCount) { - $scope.docSavingStatus = newStatus - $scope.docSavingStatusCount = newUnsavedCount - return $scope.$apply() - } } - return (warnAboutUnsavedChanges = function() { - if (Document.hasUnsavedChanges()) { - return 'You have unsaved changes. If you leave now they will not be saved.' - } - }) + if (newUnsavedCount > 0 && t > MAX_UNSAVED_SECONDS && !lockEditorModal) { + lockEditorModal = ide.showLockEditorMessageModal( + 'Connection lost', + 'Sorry, the connection to the server is down.' + ) + lockEditorModal.result.finally(() => (lockEditorModal = null)) // unset the modal if connection comes back + } + + if (lockEditorModal && newUnsavedCount === 0) { + lockEditorModal.dismiss('connection back up') + } + + // for performance, only update the display if the old or new + // counts of unsaved files are nonzeror. If both old and new + // unsaved counts are zero then we know we are in a good state + // and don't need to do anything to the UI. + if (newUnsavedCount || oldUnsavedCount) { + $scope.docSavingStatus = newStatus + $scope.docSavingStatusCount = newUnsavedCount + return $scope.$apply() + } } - ])) + + return (warnAboutUnsavedChanges = function() { + if (Document.hasUnsavedChanges()) { + return 'You have unsaved changes. If you leave now they will not be saved.' + } + }) + })) diff --git a/services/web/public/src/ide/file-tree/controllers/FileTreeController.js b/services/web/public/src/ide/file-tree/controllers/FileTreeController.js index d09dc3b7bf..e856cf983c 100644 --- a/services/web/public/src/ide/file-tree/controllers/FileTreeController.js +++ b/services/web/public/src/ide/file-tree/controllers/FileTreeController.js @@ -16,636 +16,615 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], function(App) { - App.controller('FileTreeController', [ - '$scope', - '$modal', - 'ide', - '$rootScope', - function($scope, $modal, ide, $rootScope) { - $scope.openNewDocModal = () => - $modal.open({ - templateUrl: 'newFileModalTemplate', - controller: 'NewFileModalController', - size: 'lg', - resolve: { - parent_folder() { - return ide.fileTreeManager.getCurrentFolder() - }, - projectFeatures() { - return ide.$scope.project.features - }, - type() { - return 'doc' - }, - userFeatures() { - return ide.$scope.user.features - } + App.controller('FileTreeController', function( + $scope, + $modal, + ide, + $rootScope + ) { + $scope.openNewDocModal = () => + $modal.open({ + templateUrl: 'newFileModalTemplate', + controller: 'NewFileModalController', + size: 'lg', + resolve: { + parent_folder() { + return ide.fileTreeManager.getCurrentFolder() + }, + projectFeatures() { + return ide.$scope.project.features + }, + type() { + return 'doc' + }, + userFeatures() { + return ide.$scope.user.features } - }) - - $scope.openNewFolderModal = () => - $modal.open({ - templateUrl: 'newFolderModalTemplate', - controller: 'NewFolderModalController', - resolve: { - parent_folder() { - return ide.fileTreeManager.getCurrentFolder() - } - } - }) - - $scope.openUploadFileModal = () => - $modal.open({ - templateUrl: 'newFileModalTemplate', - controller: 'NewFileModalController', - size: 'lg', - resolve: { - projectFeatures() { - return ide.$scope.project.features - }, - parent_folder() { - return ide.fileTreeManager.getCurrentFolder() - }, - type() { - return 'upload' - }, - userFeatures() { - return ide.$scope.user.features - } - } - }) - - $scope.orderByFoldersFirst = function(entity) { - if ((entity != null ? entity.type : undefined) === 'folder') { - return '0' - } - return '1' - } - - $scope.startRenamingSelected = () => $scope.$broadcast('rename:selected') - - return ($scope.openDeleteModalForSelected = () => - $scope.$broadcast('delete:selected')) - } - ]) - - App.controller('NewFolderModalController', [ - '$scope', - 'ide', - '$modalInstance', - '$timeout', - 'parent_folder', - function($scope, ide, $modalInstance, $timeout, parent_folder) { - $scope.inputs = { name: 'name' } - $scope.state = { inflight: false } - - $modalInstance.opened.then(() => - $timeout(() => $scope.$broadcast('open'), 200) - ) - - $scope.create = function() { - const { name } = $scope.inputs - if (name == null || name.length === 0) { - return - } - $scope.state.inflight = true - return ide.fileTreeManager - .createFolder(name, $scope.parent_folder) - .then(function() { - $scope.state.inflight = false - return $modalInstance.dismiss('done') - }) - .catch(function(response) { - const { data } = response - $scope.error = data - return ($scope.state.inflight = false) - }) - } - - return ($scope.cancel = () => $modalInstance.dismiss('cancel')) - } - ]) - - App.controller('NewFileModalController', [ - '$scope', - 'ide', - 'type', - 'parent_folder', - '$modalInstance', - 'event_tracking', - 'projectFeatures', - 'userFeatures', - function( - $scope, - ide, - type, - parent_folder, - $modalInstance, - event_tracking, - projectFeatures, - userFeatures - ) { - $scope.type = type - $scope.parent_folder = parent_folder - $scope.state = { - inflight: false, - valid: true - } - $scope.cancel = () => $modalInstance.dismiss('cancel') - $scope.create = () => $scope.$broadcast('create') - - const hasMendeleyFeature = - (projectFeatures && projectFeatures.references) || - (projectFeatures && projectFeatures.mendeley) || - (userFeatures && userFeatures.references) || - (userFeatures && userFeatures.mendeley) - - const hasZoteroFeature = - (projectFeatures && projectFeatures.references) || - (projectFeatures && projectFeatures.zotero) || - (userFeatures && userFeatures.references) || - (userFeatures && userFeatures.zotero) - - $scope.$watch('type', function() { - if ($scope.type === 'mendeley' && !hasMendeleyFeature) { - event_tracking.send( - 'subscription-funnel', - 'editor-click-feature', - $scope.type - ) - } - if ($scope.type === 'zotero' && !hasZoteroFeature) { - event_tracking.send( - 'subscription-funnel', - 'editor-click-feature', - $scope.type - ) } }) - return $scope.$on('done', (e, opts = {}) => { - isBibFile = opts.name && /^.*\.bib$/.test(opts.name) - if (opts.shouldReindexReferences || isBibFile) { - ide.$scope.$emit('references:should-reindex', {}) + + $scope.openNewFolderModal = () => + $modal.open({ + templateUrl: 'newFolderModalTemplate', + controller: 'NewFolderModalController', + resolve: { + parent_folder() { + return ide.fileTreeManager.getCurrentFolder() + } } - $modalInstance.dismiss('done') }) - } - ]) - App.controller('NewDocModalController', [ - '$scope', - 'ide', - '$timeout', - function($scope, ide, $timeout) { - $scope.inputs = { name: 'name.tex' } + $scope.openUploadFileModal = () => + $modal.open({ + templateUrl: 'newFileModalTemplate', + controller: 'NewFileModalController', + size: 'lg', + resolve: { + projectFeatures() { + return ide.$scope.project.features + }, + parent_folder() { + return ide.fileTreeManager.getCurrentFolder() + }, + type() { + return 'upload' + }, + userFeatures() { + return ide.$scope.user.features + } + } + }) - const validate = function() { - const { name } = $scope.inputs - $scope.state.valid = name != null && name.length > 0 + $scope.orderByFoldersFirst = function(entity) { + if ((entity != null ? entity.type : undefined) === 'folder') { + return '0' } - $scope.$watch('inputs.name', validate) + return '1' + } + $scope.startRenamingSelected = () => $scope.$broadcast('rename:selected') + + return ($scope.openDeleteModalForSelected = () => + $scope.$broadcast('delete:selected')) + }) + + App.controller('NewFolderModalController', function( + $scope, + ide, + $modalInstance, + $timeout, + parent_folder + ) { + $scope.inputs = { name: 'name' } + $scope.state = { inflight: false } + + $modalInstance.opened.then(() => $timeout(() => $scope.$broadcast('open'), 200) + ) - return $scope.$on('create', function() { - const { name } = $scope.inputs - if (name == null || name.length === 0) { - return - } - $scope.state.inflight = true - return ide.fileTreeManager - .createDoc(name, $scope.parent_folder) - .then(function() { - $scope.state.inflight = false - return $scope.$emit('done') - }) - .catch(function(response) { - const { data } = response - $scope.error = data - $scope.state.inflight = false - }) - }) + $scope.create = function() { + const { name } = $scope.inputs + if (name == null || name.length === 0) { + return + } + $scope.state.inflight = true + return ide.fileTreeManager + .createFolder(name, $scope.parent_folder) + .then(function() { + $scope.state.inflight = false + return $modalInstance.dismiss('done') + }) + .catch(function(response) { + const { data } = response + $scope.error = data + return ($scope.state.inflight = false) + }) } - ]) - App.controller('UploadFileModalController', [ - '$scope', - '$rootScope', - 'ide', - '$timeout', - '$window', - function($scope, $rootScope, ide, $timeout, $window) { - $scope.parent_folder_id = - $scope.parent_folder != null ? $scope.parent_folder.id : undefined - $scope.project_id = ide.project_id - $scope.tooManyFiles = false - $scope.rateLimitHit = false - $scope.secondsToRedirect = 10 - $scope.notLoggedIn = false - $scope.conflicts = [] - $scope.control = {} + return ($scope.cancel = () => $modalInstance.dismiss('cancel')) + }) - const needToLogBackIn = function() { - $scope.notLoggedIn = true - var decreseTimeout = () => - $timeout(function() { - if ($scope.secondsToRedirect === 0) { - return ($window.location.href = `/login?redir=/project/${ - ide.project_id - }`) - } else { - decreseTimeout() - return ($scope.secondsToRedirect = $scope.secondsToRedirect - 1) - } - }, 1000) + App.controller('NewFileModalController', function( + $scope, + ide, + type, + parent_folder, + $modalInstance, + event_tracking, + projectFeatures, + userFeatures + ) { + $scope.type = type + $scope.parent_folder = parent_folder + $scope.state = { + inflight: false, + valid: true + } + $scope.cancel = () => $modalInstance.dismiss('cancel') + $scope.create = () => $scope.$broadcast('create') - return decreseTimeout() + const hasMendeleyFeature = + (projectFeatures && projectFeatures.references) || + (projectFeatures && projectFeatures.mendeley) || + (userFeatures && userFeatures.references) || + (userFeatures && userFeatures.mendeley) + + const hasZoteroFeature = + (projectFeatures && projectFeatures.references) || + (projectFeatures && projectFeatures.zotero) || + (userFeatures && userFeatures.references) || + (userFeatures && userFeatures.zotero) + + $scope.$watch('type', function() { + if ($scope.type === 'mendeley' && !hasMendeleyFeature) { + event_tracking.send( + 'subscription-funnel', + 'editor-click-feature', + $scope.type + ) } + if ($scope.type === 'zotero' && !hasZoteroFeature) { + event_tracking.send( + 'subscription-funnel', + 'editor-click-feature', + $scope.type + ) + } + }) + return $scope.$on('done', (e, opts = {}) => { + isBibFile = opts.name && /^.*\.bib$/.test(opts.name) + if (opts.shouldReindexReferences || isBibFile) { + ide.$scope.$emit('references:should-reindex', {}) + } + $modalInstance.dismiss('done') + }) + }) - $scope.max_files = 40 - $scope.onComplete = (error, name, response) => + App.controller('NewDocModalController', function($scope, ide, $timeout) { + $scope.inputs = { name: 'name.tex' } + + const validate = function() { + const { name } = $scope.inputs + $scope.state.valid = name != null && name.length > 0 + } + $scope.$watch('inputs.name', validate) + + $timeout(() => $scope.$broadcast('open'), 200) + + return $scope.$on('create', function() { + const { name } = $scope.inputs + if (name == null || name.length === 0) { + return + } + $scope.state.inflight = true + return ide.fileTreeManager + .createDoc(name, $scope.parent_folder) + .then(function() { + $scope.state.inflight = false + return $scope.$emit('done') + }) + .catch(function(response) { + const { data } = response + $scope.error = data + $scope.state.inflight = false + }) + }) + }) + + App.controller('UploadFileModalController', function( + $scope, + $rootScope, + ide, + $timeout, + $window + ) { + $scope.parent_folder_id = + $scope.parent_folder != null ? $scope.parent_folder.id : undefined + $scope.project_id = ide.project_id + $scope.tooManyFiles = false + $scope.rateLimitHit = false + $scope.secondsToRedirect = 10 + $scope.notLoggedIn = false + $scope.conflicts = [] + $scope.control = {} + + const needToLogBackIn = function() { + $scope.notLoggedIn = true + var decreseTimeout = () => $timeout(function() { - uploadCount-- - if (response.success) { - $rootScope.$broadcast('file:upload:complete', response) + if ($scope.secondsToRedirect === 0) { + return ($window.location.href = `/login?redir=/project/${ + ide.project_id + }`) + } else { + decreseTimeout() + return ($scope.secondsToRedirect = $scope.secondsToRedirect - 1) } - if (uploadCount === 0 && response != null && response.success) { - return $scope.$emit('done', { name: name }) - } - }, 250) + }, 1000) - $scope.onValidateBatch = function(files) { - if (files.length > $scope.max_files) { - $timeout(() => ($scope.tooManyFiles = true), 1) - return false - } else { - return true - } - } + return decreseTimeout() + } - $scope.onError = function(id, name, reason) { - console.log(id, name, reason) - if (reason.indexOf('429') !== -1) { - return ($scope.rateLimitHit = true) - } else if (reason.indexOf('403') !== -1) { - return needToLogBackIn() + $scope.max_files = 40 + $scope.onComplete = (error, name, response) => + $timeout(function() { + uploadCount-- + if (response.success) { + $rootScope.$broadcast('file:upload:complete', response) } - } + if (uploadCount === 0 && response != null && response.success) { + return $scope.$emit('done', { name: name }) + } + }, 250) - let _uploadTimer = null - const uploadIfNoConflicts = function() { - if ($scope.conflicts.length === 0) { - return $scope.doUpload() - } - } - - var uploadCount = 0 - $scope.onSubmit = function(id, name) { - uploadCount++ - if (ide.fileTreeManager.existsInFolder($scope.parent_folder_id, name)) { - $scope.conflicts.push(name) - $scope.$apply() - } - if (_uploadTimer == null) { - _uploadTimer = setTimeout(function() { - _uploadTimer = null - return uploadIfNoConflicts() - }, 0) - } + $scope.onValidateBatch = function(files) { + if (files.length > $scope.max_files) { + $timeout(() => ($scope.tooManyFiles = true), 1) + return false + } else { return true } - - $scope.onCancel = function(id, name) { - uploadCount-- - const index = $scope.conflicts.indexOf(name) - if (index > -1) { - $scope.conflicts.splice(index, 1) - } - $scope.$apply() - return uploadIfNoConflicts() - } - - return ($scope.doUpload = () => - __guard__($scope.control != null ? $scope.control.q : undefined, x => - x.uploadStoredFiles() - )) } - ]) - App.controller('ProjectLinkedFileModalController', [ - '$scope', - 'ide', - '$timeout', - function($scope, ide, $timeout) { - $scope.data = { - projects: null, // or [] - selectedProjectId: null, - projectEntities: null, // or [] - projectOutputFiles: null, // or [] - selectedProjectEntity: null, - selectedProjectOutputFile: null, - buildId: null, - name: null + $scope.onError = function(id, name, reason) { + console.log(id, name, reason) + if (reason.indexOf('429') !== -1) { + return ($scope.rateLimitHit = true) + } else if (reason.indexOf('403') !== -1) { + return needToLogBackIn() } - $scope.state.inFlight = { - projects: false, - entities: false, - compile: false + } + + let _uploadTimer = null + const uploadIfNoConflicts = function() { + if ($scope.conflicts.length === 0) { + return $scope.doUpload() } - $scope.state.isOutputFilesMode = false - $scope.state.error = false + } - $scope.$watch('data.selectedProjectId', function(newVal, oldVal) { - if (!newVal) { - return - } - $scope.data.selectedProjectEntity = null - $scope.data.selectedProjectOutputFile = null - if ($scope.state.isOutputFilesMode) { - return $scope.compileProjectAndGetOutputFiles( - $scope.data.selectedProjectId - ) - } else { - return $scope.getProjectEntities($scope.data.selectedProjectId) - } - }) + var uploadCount = 0 + $scope.onSubmit = function(id, name) { + uploadCount++ + if (ide.fileTreeManager.existsInFolder($scope.parent_folder_id, name)) { + $scope.conflicts.push(name) + $scope.$apply() + } + if (_uploadTimer == null) { + _uploadTimer = setTimeout(function() { + _uploadTimer = null + return uploadIfNoConflicts() + }, 0) + } + return true + } - $scope.$watch('state.isOutputFilesMode', function(newVal, oldVal) { - if (!newVal && !oldVal) { - return - } - $scope.data.selectedProjectOutputFile = null - if (newVal === true) { - return $scope.compileProjectAndGetOutputFiles( - $scope.data.selectedProjectId - ) - } else { - return $scope.getProjectEntities($scope.data.selectedProjectId) - } - }) + $scope.onCancel = function(id, name) { + uploadCount-- + const index = $scope.conflicts.indexOf(name) + if (index > -1) { + $scope.conflicts.splice(index, 1) + } + $scope.$apply() + return uploadIfNoConflicts() + } - // auto-set filename based on selected file - $scope.$watch('data.selectedProjectEntity', function(newVal, oldVal) { - if (!newVal) { - return - } + return ($scope.doUpload = () => + __guard__($scope.control != null ? $scope.control.q : undefined, x => + x.uploadStoredFiles() + )) + }) + + App.controller('ProjectLinkedFileModalController', function( + $scope, + ide, + $timeout + ) { + $scope.data = { + projects: null, // or [] + selectedProjectId: null, + projectEntities: null, // or [] + projectOutputFiles: null, // or [] + selectedProjectEntity: null, + selectedProjectOutputFile: null, + buildId: null, + name: null + } + $scope.state.inFlight = { + projects: false, + entities: false, + compile: false + } + $scope.state.isOutputFilesMode = false + $scope.state.error = false + + $scope.$watch('data.selectedProjectId', function(newVal, oldVal) { + if (!newVal) { + return + } + $scope.data.selectedProjectEntity = null + $scope.data.selectedProjectOutputFile = null + if ($scope.state.isOutputFilesMode) { + return $scope.compileProjectAndGetOutputFiles( + $scope.data.selectedProjectId + ) + } else { + return $scope.getProjectEntities($scope.data.selectedProjectId) + } + }) + + $scope.$watch('state.isOutputFilesMode', function(newVal, oldVal) { + if (!newVal && !oldVal) { + return + } + $scope.data.selectedProjectOutputFile = null + if (newVal === true) { + return $scope.compileProjectAndGetOutputFiles( + $scope.data.selectedProjectId + ) + } else { + return $scope.getProjectEntities($scope.data.selectedProjectId) + } + }) + + // auto-set filename based on selected file + $scope.$watch('data.selectedProjectEntity', function(newVal, oldVal) { + if (!newVal) { + return + } + const fileName = newVal.split('/').reverse()[0] + if (fileName) { + $scope.data.name = fileName + } + }) + + // auto-set filename based on selected file + $scope.$watch('data.selectedProjectOutputFile', function(newVal, oldVal) { + if (!newVal) { + return + } + if (newVal === 'output.pdf') { + const project = _.find( + $scope.data.projects, + p => p._id === $scope.data.selectedProjectId + ) + $scope.data.name = + (project != null ? project.name : undefined) != null + ? `${project.name}.pdf` + : 'output.pdf' + } else { const fileName = newVal.split('/').reverse()[0] if (fileName) { $scope.data.name = fileName } - }) + } + }) - // auto-set filename based on selected file - $scope.$watch('data.selectedProjectOutputFile', function(newVal, oldVal) { - if (!newVal) { - return - } - if (newVal === 'output.pdf') { - const project = _.find( - $scope.data.projects, - p => p._id === $scope.data.selectedProjectId + const _setInFlight = type => ($scope.state.inFlight[type] = true) + + const _reset = function(opts) { + const isError = opts.err === true + const { inFlight } = $scope.state + inFlight.projects = inFlight.entities = inFlight.compile = false + $scope.state.inflight = false + return ($scope.state.error = isError) + } + + $scope.toggleOutputFilesMode = function() { + if (!$scope.data.selectedProjectId) { + return + } + return ($scope.state.isOutputFilesMode = !$scope.state.isOutputFilesMode) + } + + $scope.shouldEnableProjectSelect = function() { + const { state, data } = $scope + return !state.inFlight.projects && data.projects + } + + $scope.hasNoProjects = function() { + const { state, data } = $scope + return ( + !state.inFlight.projects && + (data.projects == null || data.projects.length === 0) + ) + } + + $scope.shouldEnableProjectEntitySelect = function() { + const { state, data } = $scope + return ( + !state.inFlight.projects && + !state.inFlight.entities && + data.projects && + data.selectedProjectId + ) + } + + $scope.shouldEnableProjectOutputFileSelect = function() { + const { state, data } = $scope + return ( + !state.inFlight.projects && + !state.inFlight.compile && + data.projects && + data.selectedProjectId + ) + } + + const validate = function() { + const { state } = $scope + const { data } = $scope + $scope.state.valid = + !state.inFlight.projects && + !state.inFlight.entities && + data.projects && + data.selectedProjectId && + ((!$scope.state.isOutputFilesMode && + data.projectEntities && + data.selectedProjectEntity) || + ($scope.state.isOutputFilesMode && + data.projectOutputFiles && + data.selectedProjectOutputFile)) && + data.name + } + $scope.$watch('state', validate, true) + $scope.$watch('data', validate, true) + + $scope.getUserProjects = function() { + _setInFlight('projects') + return ide.$http + .get('/user/projects', { + _csrf: window.csrfToken + }) + .then(function(resp) { + $scope.data.projectEntities = null + $scope.data.projects = resp.data.projects.filter( + p => p._id !== ide.project_id ) - $scope.data.name = - (project != null ? project.name : undefined) != null - ? `${project.name}.pdf` - : 'output.pdf' - } else { - const fileName = newVal.split('/').reverse()[0] - if (fileName) { - $scope.data.name = fileName - } - } - }) + return _reset({ err: false }) + }) + .catch(err => _reset({ err: true })) + } - const _setInFlight = type => ($scope.state.inFlight[type] = true) - - const _reset = function(opts) { - const isError = opts.err === true - const { inFlight } = $scope.state - inFlight.projects = inFlight.entities = inFlight.compile = false - $scope.state.inflight = false - return ($scope.state.error = isError) - } - - $scope.toggleOutputFilesMode = function() { - if (!$scope.data.selectedProjectId) { - return - } - return ($scope.state.isOutputFilesMode = !$scope.state - .isOutputFilesMode) - } - - $scope.shouldEnableProjectSelect = function() { - const { state, data } = $scope - return !state.inFlight.projects && data.projects - } - - $scope.hasNoProjects = function() { - const { state, data } = $scope - return ( - !state.inFlight.projects && - (data.projects == null || data.projects.length === 0) - ) - } - - $scope.shouldEnableProjectEntitySelect = function() { - const { state, data } = $scope - return ( - !state.inFlight.projects && - !state.inFlight.entities && - data.projects && - data.selectedProjectId - ) - } - - $scope.shouldEnableProjectOutputFileSelect = function() { - const { state, data } = $scope - return ( - !state.inFlight.projects && - !state.inFlight.compile && - data.projects && - data.selectedProjectId - ) - } - - const validate = function() { - const { state } = $scope - const { data } = $scope - $scope.state.valid = - !state.inFlight.projects && - !state.inFlight.entities && - data.projects && - data.selectedProjectId && - ((!$scope.state.isOutputFilesMode && - data.projectEntities && - data.selectedProjectEntity) || - ($scope.state.isOutputFilesMode && - data.projectOutputFiles && - data.selectedProjectOutputFile)) && - data.name - } - $scope.$watch('state', validate, true) - $scope.$watch('data', validate, true) - - $scope.getUserProjects = function() { - _setInFlight('projects') - return ide.$http - .get('/user/projects', { - _csrf: window.csrfToken - }) - .then(function(resp) { - $scope.data.projectEntities = null - $scope.data.projects = resp.data.projects.filter( - p => p._id !== ide.project_id - ) + $scope.getProjectEntities = project_id => { + _setInFlight('entities') + return ide.$http + .get(`/project/${project_id}/entities`, { + _csrf: window.csrfToken + }) + .then(function(resp) { + if ($scope.data.selectedProjectId === resp.data.project_id) { + $scope.data.projectEntities = resp.data.entities return _reset({ err: false }) - }) - .catch(err => _reset({ err: true })) - } + } + }) + .catch(err => _reset({ err: true })) + } - $scope.getProjectEntities = project_id => { - _setInFlight('entities') - return ide.$http - .get(`/project/${project_id}/entities`, { - _csrf: window.csrfToken - }) - .then(function(resp) { - if ($scope.data.selectedProjectId === resp.data.project_id) { - $scope.data.projectEntities = resp.data.entities - return _reset({ err: false }) - } - }) - .catch(err => _reset({ err: true })) - } - - $scope.compileProjectAndGetOutputFiles = project_id => { - _setInFlight('compile') - return ide.$http - .post(`/project/${project_id}/compile`, { - check: 'silent', - draft: false, - incrementalCompilesEnabled: false, - _csrf: window.csrfToken - }) - .then(function(resp) { - if (resp.data.status === 'success') { - const filteredFiles = resp.data.outputFiles.filter(f => - f.path.match(/.*\.(pdf|png|jpeg|jpg|gif)/) - ) - $scope.data.projectOutputFiles = filteredFiles - $scope.data.buildId = __guard__( - filteredFiles != null ? filteredFiles[0] : undefined, - x => x.build - ) - console.log('>> build_id', $scope.data.buildId) - return _reset({ err: false }) - } else { - $scope.data.projectOutputFiles = null - return _reset({ err: true }) - } - }) - .catch(function(err) { - console.error(err) + $scope.compileProjectAndGetOutputFiles = project_id => { + _setInFlight('compile') + return ide.$http + .post(`/project/${project_id}/compile`, { + check: 'silent', + draft: false, + incrementalCompilesEnabled: false, + _csrf: window.csrfToken + }) + .then(function(resp) { + if (resp.data.status === 'success') { + const filteredFiles = resp.data.outputFiles.filter(f => + f.path.match(/.*\.(pdf|png|jpeg|jpg|gif)/) + ) + $scope.data.projectOutputFiles = filteredFiles + $scope.data.buildId = __guard__( + filteredFiles != null ? filteredFiles[0] : undefined, + x => x.build + ) + console.log('>> build_id', $scope.data.buildId) + return _reset({ err: false }) + } else { + $scope.data.projectOutputFiles = null return _reset({ err: true }) - }) - } - - $scope.init = () => $scope.getUserProjects() - $timeout($scope.init, 0) - - return $scope.$on('create', function() { - let payload, provider - const projectId = $scope.data.selectedProjectId - const { name } = $scope.data - if ($scope.state.isOutputFilesMode) { - provider = 'project_output_file' - payload = { - source_project_id: projectId, - source_output_file_path: $scope.data.selectedProjectOutputFile, - build_id: $scope.data.buildId } - } else { - provider = 'project_file' - payload = { - source_project_id: projectId, - source_entity_path: $scope.data.selectedProjectEntity - } - } - _setInFlight('create') - ide.fileTreeManager - .createLinkedFile(name, $scope.parent_folder, provider, payload) - .then(function() { - _reset({ err: false }) - return $scope.$emit('done', { name: name }) - }) - .catch(function(response) { - const { data } = response - $scope.error = data - }) - }) + }) + .catch(function(err) { + console.error(err) + return _reset({ err: true }) + }) } - ]) - return App.controller('UrlLinkedFileModalController', [ - '$scope', - 'ide', - '$timeout', - function($scope, ide, $timeout) { - $scope.inputs = { - name: '', - url: '' - } - $scope.nameChangedByUser = false + $scope.init = () => $scope.getUserProjects() + $timeout($scope.init, 0) - $timeout(() => $scope.$broadcast('open'), 200) - - const validate = function() { - const { name, url } = $scope.inputs - if (name == null || name.length === 0) { - return ($scope.state.valid = false) - } else if (url == null || url.length === 0) { - return ($scope.state.valid = false) - } else { - return ($scope.state.valid = true) + return $scope.$on('create', function() { + let payload, provider + const projectId = $scope.data.selectedProjectId + const { name } = $scope.data + if ($scope.state.isOutputFilesMode) { + provider = 'project_output_file' + payload = { + source_project_id: projectId, + source_output_file_path: $scope.data.selectedProjectOutputFile, + build_id: $scope.data.buildId + } + } else { + provider = 'project_file' + payload = { + source_project_id: projectId, + source_entity_path: $scope.data.selectedProjectEntity } } - $scope.$watch('inputs.name', validate) - $scope.$watch('inputs.url', validate) + _setInFlight('create') + ide.fileTreeManager + .createLinkedFile(name, $scope.parent_folder, provider, payload) + .then(function() { + _reset({ err: false }) + return $scope.$emit('done', { name: name }) + }) + .catch(function(response) { + const { data } = response + $scope.error = data + }) + }) + }) - $scope.$watch('inputs.url', function(url) { - if (url != null && url !== '' && !$scope.nameChangedByUser) { - url = url.replace('://', '') // Ignore http:// etc - const parts = url.split('/').reverse() - if (parts.length > 1) { - // Wait for at one / - return ($scope.inputs.name = parts[0]) - } - } - }) - - return $scope.$on('create', function() { - const { name, url } = $scope.inputs - if (name == null || name.length === 0) { - return - } - if (url == null || url.length === 0) { - return - } - $scope.state.inflight = true - return ide.fileTreeManager - .createLinkedFile(name, $scope.parent_folder, 'url', { url }) - .then(function() { - $scope.state.inflight = false - return $scope.$emit('done', { name: name }) - }) - .catch(function(response) { - const { data } = response - $scope.error = data - return ($scope.state.inflight = false) - }) - }) + return App.controller('UrlLinkedFileModalController', function( + $scope, + ide, + $timeout + ) { + $scope.inputs = { + name: '', + url: '' } - ]) + $scope.nameChangedByUser = false + + $timeout(() => $scope.$broadcast('open'), 200) + + const validate = function() { + const { name, url } = $scope.inputs + if (name == null || name.length === 0) { + return ($scope.state.valid = false) + } else if (url == null || url.length === 0) { + return ($scope.state.valid = false) + } else { + return ($scope.state.valid = true) + } + } + $scope.$watch('inputs.name', validate) + $scope.$watch('inputs.url', validate) + + $scope.$watch('inputs.url', function(url) { + if (url != null && url !== '' && !$scope.nameChangedByUser) { + url = url.replace('://', '') // Ignore http:// etc + const parts = url.split('/').reverse() + if (parts.length > 1) { + // Wait for at one / + return ($scope.inputs.name = parts[0]) + } + } + }) + + return $scope.$on('create', function() { + const { name, url } = $scope.inputs + if (name == null || name.length === 0) { + return + } + if (url == null || url.length === 0) { + return + } + $scope.state.inflight = true + return ide.fileTreeManager + .createLinkedFile(name, $scope.parent_folder, 'url', { url }) + .then(function() { + $scope.state.inflight = false + return $scope.$emit('done', { name: name }) + }) + .catch(function(response) { + const { data } = response + $scope.error = data + return ($scope.state.inflight = false) + }) + }) + }) }) function __guard__(value, transform) { diff --git a/services/web/public/src/ide/file-tree/controllers/FileTreeEntityController.js b/services/web/public/src/ide/file-tree/controllers/FileTreeEntityController.js index beea0e64a9..4030d33e65 100644 --- a/services/web/public/src/ide/file-tree/controllers/FileTreeEntityController.js +++ b/services/web/public/src/ide/file-tree/controllers/FileTreeEntityController.js @@ -17,125 +17,119 @@ define(['base', 'ide/file-tree/util/iconTypeFromName'], function( App, iconTypeFromName ) { - App.controller('FileTreeEntityController', [ - '$scope', - 'ide', - '$modal', - function($scope, ide, $modal) { - $scope.select = function(e) { - if (e.ctrlKey || e.metaKey) { - e.stopPropagation() - const initialMultiSelectCount = ide.fileTreeManager.multiSelectedCount() - ide.fileTreeManager.toggleMultiSelectEntity($scope.entity) === 0 - if (initialMultiSelectCount === 0) { - // On first multi selection, also include the current active/open file. - return ide.fileTreeManager.multiSelectSelectedEntity() - } - } else { - ide.fileTreeManager.selectEntity($scope.entity) - return $scope.$emit('entity:selected', $scope.entity) + App.controller('FileTreeEntityController', function($scope, ide, $modal) { + $scope.select = function(e) { + if (e.ctrlKey || e.metaKey) { + e.stopPropagation() + const initialMultiSelectCount = ide.fileTreeManager.multiSelectedCount() + ide.fileTreeManager.toggleMultiSelectEntity($scope.entity) === 0 + if (initialMultiSelectCount === 0) { + // On first multi selection, also include the current active/open file. + return ide.fileTreeManager.multiSelectSelectedEntity() } + } else { + ide.fileTreeManager.selectEntity($scope.entity) + return $scope.$emit('entity:selected', $scope.entity) + } + } + + $scope.draggableHelper = function() { + if (ide.fileTreeManager.multiSelectedCount() > 0) { + return $( + `${ide.fileTreeManager.multiSelectedCount()} Files` + ) + } else { + return $(`${$scope.entity.name}`) + } + } + + $scope.inputs = { name: $scope.entity.name } + + $scope.startRenaming = () => ($scope.entity.renaming = true) + + let invalidModalShowing = false + $scope.finishRenaming = function() { + // avoid double events when blur and on-enter fire together + if (!$scope.entity.renaming) { + return } - $scope.draggableHelper = function() { - if (ide.fileTreeManager.multiSelectedCount() > 0) { - return $( - `${ide.fileTreeManager.multiSelectedCount()} Files` - ) - } else { - return $(`${$scope.entity.name}`) - } - } + const { name } = $scope.inputs - $scope.inputs = { name: $scope.entity.name } - - $scope.startRenaming = () => ($scope.entity.renaming = true) - - let invalidModalShowing = false - $scope.finishRenaming = function() { - // avoid double events when blur and on-enter fire together - if (!$scope.entity.renaming) { + // validator will set name to undefined for invalid filenames + if (name == null) { + // Showing the modal blurs the rename box which calls us again + // so track this with the invalidModalShowing flag + if (invalidModalShowing) { return } - - const { name } = $scope.inputs - - // validator will set name to undefined for invalid filenames - if (name == null) { - // Showing the modal blurs the rename box which calls us again - // so track this with the invalidModalShowing flag - if (invalidModalShowing) { - return - } - invalidModalShowing = true - const modal = $modal.open({ - templateUrl: 'invalidFileNameModalTemplate' - }) - modal.result.then(() => (invalidModalShowing = false)) - return - } - - delete $scope.entity.renaming - if (name == null || name.length === 0) { - $scope.inputs.name = $scope.entity.name - return - } - return ide.fileTreeManager.renameEntity($scope.entity, name) - } - - $scope.$on('rename:selected', function() { - if ($scope.entity.selected) { - return $scope.startRenaming() - } - }) - - $scope.openDeleteModal = function() { - let entities - if (ide.fileTreeManager.multiSelectedCount() > 0) { - entities = ide.fileTreeManager.getMultiSelectedEntityChildNodes() - } else { - entities = [$scope.entity] - } - return $modal.open({ - templateUrl: 'deleteEntityModalTemplate', - controller: 'DeleteEntityModalController', - resolve: { - entities() { - return entities - } - } + invalidModalShowing = true + const modal = $modal.open({ + templateUrl: 'invalidFileNameModalTemplate' }) + modal.result.then(() => (invalidModalShowing = false)) + return } - $scope.$on('delete:selected', function() { - if ($scope.entity.selected) { - return $scope.openDeleteModal() + delete $scope.entity.renaming + if (name == null || name.length === 0) { + $scope.inputs.name = $scope.entity.name + return + } + return ide.fileTreeManager.renameEntity($scope.entity, name) + } + + $scope.$on('rename:selected', function() { + if ($scope.entity.selected) { + return $scope.startRenaming() + } + }) + + $scope.openDeleteModal = function() { + let entities + if (ide.fileTreeManager.multiSelectedCount() > 0) { + entities = ide.fileTreeManager.getMultiSelectedEntityChildNodes() + } else { + entities = [$scope.entity] + } + return $modal.open({ + templateUrl: 'deleteEntityModalTemplate', + controller: 'DeleteEntityModalController', + resolve: { + entities() { + return entities + } } }) - - return ($scope.iconTypeFromName = iconTypeFromName) } - ]) - return App.controller('DeleteEntityModalController', [ - '$scope', - 'ide', - '$modalInstance', - 'entities', - function($scope, ide, $modalInstance, entities) { - $scope.state = { inflight: false } - - $scope.entities = entities - - $scope.delete = function() { - $scope.state.inflight = true - for (let entity of Array.from($scope.entities)) { - ide.fileTreeManager.deleteEntity(entity) - } - return $modalInstance.close() + $scope.$on('delete:selected', function() { + if ($scope.entity.selected) { + return $scope.openDeleteModal() } + }) - return ($scope.cancel = () => $modalInstance.dismiss('cancel')) + return ($scope.iconTypeFromName = iconTypeFromName) + }) + + return App.controller('DeleteEntityModalController', function( + $scope, + ide, + $modalInstance, + entities + ) { + $scope.state = { inflight: false } + + $scope.entities = entities + + $scope.delete = function() { + $scope.state.inflight = true + for (let entity of Array.from($scope.entities)) { + ide.fileTreeManager.deleteEntity(entity) + } + return $modalInstance.close() } - ]) + + return ($scope.cancel = () => $modalInstance.dismiss('cancel')) + }) }) diff --git a/services/web/public/src/ide/file-tree/controllers/FileTreeRootFolderController.js b/services/web/public/src/ide/file-tree/controllers/FileTreeRootFolderController.js index d22b8f7100..2c4b815b11 100644 --- a/services/web/public/src/ide/file-tree/controllers/FileTreeRootFolderController.js +++ b/services/web/public/src/ide/file-tree/controllers/FileTreeRootFolderController.js @@ -13,26 +13,22 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('FileTreeRootFolderController', [ - '$scope', - 'ide', - function($scope, ide) { - const { rootFolder } = $scope - return ($scope.onDrop = function(events, ui) { - let entities - if (ide.fileTreeManager.multiSelectedCount()) { - entities = ide.fileTreeManager.getMultiSelectedEntityChildNodes() - } else { - entities = [$(ui.draggable).scope().entity] - } - for (let dropped_entity of Array.from(entities)) { - ide.fileTreeManager.moveEntity(dropped_entity, rootFolder) - } - $scope.$digest() - // clear highlight explicitly - return $('.file-tree-inner .droppable-hover').removeClass( - 'droppable-hover' - ) - }) - } - ])) + App.controller('FileTreeRootFolderController', function($scope, ide) { + const { rootFolder } = $scope + return ($scope.onDrop = function(events, ui) { + let entities + if (ide.fileTreeManager.multiSelectedCount()) { + entities = ide.fileTreeManager.getMultiSelectedEntityChildNodes() + } else { + entities = [$(ui.draggable).scope().entity] + } + for (let dropped_entity of Array.from(entities)) { + ide.fileTreeManager.moveEntity(dropped_entity, rootFolder) + } + $scope.$digest() + // clear highlight explicitly + return $('.file-tree-inner .droppable-hover').removeClass( + 'droppable-hover' + ) + }) + })) diff --git a/services/web/public/src/ide/file-tree/directives/fileEntity.js b/services/web/public/src/ide/file-tree/directives/fileEntity.js index e325c40d02..bdbec95a99 100644 --- a/services/web/public/src/ide/file-tree/directives/fileEntity.js +++ b/services/web/public/src/ide/file-tree/directives/fileEntity.js @@ -12,36 +12,33 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.directive('fileEntity', [ - 'RecursionHelper', - RecursionHelper => ({ - restrict: 'E', - scope: { - entity: '=', - permissions: '=' - }, - templateUrl: 'entityListItemTemplate', - compile(element) { - return RecursionHelper.compile(element, function( - scope, - element, - attrs, - ctrl - ) { - // Don't freak out if we're already in an apply callback - scope.$originalApply = scope.$apply - return (scope.$apply = function(fn) { - if (fn == null) { - fn = function() {} - } - const phase = this.$root.$$phase - if (phase === '$apply' || phase === '$digest') { - return fn() - } else { - return this.$originalApply(fn) - } - }) + App.directive('fileEntity', RecursionHelper => ({ + restrict: 'E', + scope: { + entity: '=', + permissions: '=' + }, + templateUrl: 'entityListItemTemplate', + compile(element) { + return RecursionHelper.compile(element, function( + scope, + element, + attrs, + ctrl + ) { + // Don't freak out if we're already in an apply callback + scope.$originalApply = scope.$apply + return (scope.$apply = function(fn) { + if (fn == null) { + fn = function() {} + } + const phase = this.$root.$$phase + if (phase === '$apply' || phase === '$digest') { + return fn() + } else { + return this.$originalApply(fn) + } }) - } - }) - ])) + }) + } + }))) diff --git a/services/web/public/src/ide/history/controllers/HistoryListController.js b/services/web/public/src/ide/history/controllers/HistoryListController.js index 51786bcf99..78efe899a9 100644 --- a/services/web/public/src/ide/history/controllers/HistoryListController.js +++ b/services/web/public/src/ide/history/controllers/HistoryListController.js @@ -18,73 +18,118 @@ define(['base', 'ide/history/util/displayNameForUser'], function( App, displayNameForUser ) { - App.controller('HistoryListController', [ - '$scope', - '$modal', - 'ide', - function($scope, $modal, ide) { - $scope.hoveringOverListSelectors = false + App.controller('HistoryListController', function($scope, $modal, ide) { + $scope.hoveringOverListSelectors = false - $scope.projectUsers = [] + $scope.projectUsers = [] - $scope.$watch('project.members', function(newVal) { - if (newVal != null) { - return ($scope.projectUsers = newVal.concat($scope.project.owner)) + $scope.$watch('project.members', function(newVal) { + if (newVal != null) { + return ($scope.projectUsers = newVal.concat($scope.project.owner)) + } + }) + + // This method (and maybe the one below) will be removed soon. User details data will be + // injected into the history API responses, so we won't need to fetch user data from other + // local data structures. + const _getUserById = id => + _.find($scope.projectUsers, function(user) { + const curUserId = + (user != null ? user._id : undefined) || + (user != null ? user.id : undefined) + return curUserId === id + }) + + $scope.getDisplayNameById = id => displayNameForUser(_getUserById(id)) + + $scope.deleteLabel = labelDetails => + $modal.open({ + templateUrl: 'historyV2DeleteLabelModalTemplate', + controller: 'HistoryV2DeleteLabelModalController', + resolve: { + labelDetails() { + return labelDetails + } } }) - // This method (and maybe the one below) will be removed soon. User details data will be - // injected into the history API responses, so we won't need to fetch user data from other - // local data structures. - const _getUserById = id => - _.find($scope.projectUsers, function(user) { - const curUserId = - (user != null ? user._id : undefined) || - (user != null ? user.id : undefined) - return curUserId === id - }) + $scope.loadMore = () => { + return ide.historyManager.fetchNextBatchOfUpdates() + } - $scope.getDisplayNameById = id => displayNameForUser(_getUserById(id)) - - $scope.deleteLabel = labelDetails => - $modal.open({ - templateUrl: 'historyV2DeleteLabelModalTemplate', - controller: 'HistoryV2DeleteLabelModalController', - resolve: { - labelDetails() { - return labelDetails - } + $scope.recalculateSelectedUpdates = function() { + let beforeSelection = true + let afterSelection = false + $scope.history.selection.updates = [] + return (() => { + const result = [] + for (let update of Array.from($scope.history.updates)) { + var inSelection + if (update.selectedTo) { + inSelection = true + beforeSelection = false } - }) - $scope.loadMore = () => { - return ide.historyManager.fetchNextBatchOfUpdates() + update.beforeSelection = beforeSelection + update.inSelection = inSelection + update.afterSelection = afterSelection + + if (inSelection) { + $scope.history.selection.updates.push(update) + } + + if (update.selectedFrom) { + inSelection = false + result.push((afterSelection = true)) + } else { + result.push(undefined) + } + } + return result + })() + } + + $scope.recalculateHoveredUpdates = function() { + let inHoverSelection + let hoverSelectedFrom = false + let hoverSelectedTo = false + for (var update of Array.from($scope.history.updates)) { + // Figure out whether the to or from selector is hovered over + if (update.hoverSelectedFrom) { + hoverSelectedFrom = true + } + if (update.hoverSelectedTo) { + hoverSelectedTo = true + } } - $scope.recalculateSelectedUpdates = function() { - let beforeSelection = true - let afterSelection = false - $scope.history.selection.updates = [] + if (hoverSelectedFrom) { + // We want to 'hover select' everything between hoverSelectedFrom and selectedTo + inHoverSelection = false + for (update of Array.from($scope.history.updates)) { + if (update.selectedTo) { + update.hoverSelectedTo = true + inHoverSelection = true + } + update.inHoverSelection = inHoverSelection + if (update.hoverSelectedFrom) { + inHoverSelection = false + } + } + } + if (hoverSelectedTo) { + // We want to 'hover select' everything between hoverSelectedTo and selectedFrom + inHoverSelection = false return (() => { const result = [] - for (let update of Array.from($scope.history.updates)) { - var inSelection - if (update.selectedTo) { - inSelection = true - beforeSelection = false + for (update of Array.from($scope.history.updates)) { + if (update.hoverSelectedTo) { + inHoverSelection = true } - - update.beforeSelection = beforeSelection - update.inSelection = inSelection - update.afterSelection = afterSelection - - if (inSelection) { - $scope.history.selection.updates.push(update) - } - + update.inHoverSelection = inHoverSelection if (update.selectedFrom) { - inSelection = false - result.push((afterSelection = true)) + update.hoverSelectedFrom = true + result.push((inHoverSelection = false)) } else { result.push(undefined) } @@ -92,132 +137,81 @@ define(['base', 'ide/history/util/displayNameForUser'], function( return result })() } - - $scope.recalculateHoveredUpdates = function() { - let inHoverSelection - let hoverSelectedFrom = false - let hoverSelectedTo = false - for (var update of Array.from($scope.history.updates)) { - // Figure out whether the to or from selector is hovered over - if (update.hoverSelectedFrom) { - hoverSelectedFrom = true - } - if (update.hoverSelectedTo) { - hoverSelectedTo = true - } - } - - if (hoverSelectedFrom) { - // We want to 'hover select' everything between hoverSelectedFrom and selectedTo - inHoverSelection = false - for (update of Array.from($scope.history.updates)) { - if (update.selectedTo) { - update.hoverSelectedTo = true - inHoverSelection = true - } - update.inHoverSelection = inHoverSelection - if (update.hoverSelectedFrom) { - inHoverSelection = false - } - } - } - if (hoverSelectedTo) { - // We want to 'hover select' everything between hoverSelectedTo and selectedFrom - inHoverSelection = false - return (() => { - const result = [] - for (update of Array.from($scope.history.updates)) { - if (update.hoverSelectedTo) { - inHoverSelection = true - } - update.inHoverSelection = inHoverSelection - if (update.selectedFrom) { - update.hoverSelectedFrom = true - result.push((inHoverSelection = false)) - } else { - result.push(undefined) - } - } - return result - })() - } - } - - $scope.resetHoverState = () => - (() => { - const result = [] - for (let update of Array.from($scope.history.updates)) { - delete update.hoverSelectedFrom - delete update.hoverSelectedTo - result.push(delete update.inHoverSelection) - } - return result - })() - - return $scope.$watch('history.updates.length', () => - $scope.recalculateSelectedUpdates() - ) } - ]) - return App.controller('HistoryListItemController', [ - '$scope', - 'event_tracking', - function($scope, event_tracking) { - $scope.$watch('update.selectedFrom', function( - selectedFrom, - oldSelectedFrom - ) { - if (selectedFrom) { - for (let update of Array.from($scope.history.updates)) { - if (update !== $scope.update) { - update.selectedFrom = false - } - } - return $scope.recalculateSelectedUpdates() + $scope.resetHoverState = () => + (() => { + const result = [] + for (let update of Array.from($scope.history.updates)) { + delete update.hoverSelectedFrom + delete update.hoverSelectedTo + result.push(delete update.inHoverSelection) } - }) + return result + })() - $scope.$watch('update.selectedTo', function(selectedTo, oldSelectedTo) { - if (selectedTo) { - for (let update of Array.from($scope.history.updates)) { - if (update !== $scope.update) { - update.selectedTo = false - } + return $scope.$watch('history.updates.length', () => + $scope.recalculateSelectedUpdates() + ) + }) + + return App.controller('HistoryListItemController', function( + $scope, + event_tracking + ) { + $scope.$watch('update.selectedFrom', function( + selectedFrom, + oldSelectedFrom + ) { + if (selectedFrom) { + for (let update of Array.from($scope.history.updates)) { + if (update !== $scope.update) { + update.selectedFrom = false } - return $scope.recalculateSelectedUpdates() } - }) - - $scope.select = function() { - event_tracking.sendMB('history-view-change') - $scope.update.selectedTo = true - return ($scope.update.selectedFrom = true) + return $scope.recalculateSelectedUpdates() } + }) - $scope.mouseOverSelectedFrom = function() { - $scope.history.hoveringOverListSelectors = true - $scope.update.hoverSelectedFrom = true - return $scope.recalculateHoveredUpdates() + $scope.$watch('update.selectedTo', function(selectedTo, oldSelectedTo) { + if (selectedTo) { + for (let update of Array.from($scope.history.updates)) { + if (update !== $scope.update) { + update.selectedTo = false + } + } + return $scope.recalculateSelectedUpdates() } + }) - $scope.mouseOutSelectedFrom = function() { - $scope.history.hoveringOverListSelectors = false - return $scope.resetHoverState() - } - - $scope.mouseOverSelectedTo = function() { - $scope.history.hoveringOverListSelectors = true - $scope.update.hoverSelectedTo = true - return $scope.recalculateHoveredUpdates() - } - - $scope.mouseOutSelectedTo = function() { - $scope.history.hoveringOverListSelectors = false - return $scope.resetHoverState() - } - - return ($scope.displayName = displayNameForUser) + $scope.select = function() { + event_tracking.sendMB('history-view-change') + $scope.update.selectedTo = true + return ($scope.update.selectedFrom = true) } - ]) + + $scope.mouseOverSelectedFrom = function() { + $scope.history.hoveringOverListSelectors = true + $scope.update.hoverSelectedFrom = true + return $scope.recalculateHoveredUpdates() + } + + $scope.mouseOutSelectedFrom = function() { + $scope.history.hoveringOverListSelectors = false + return $scope.resetHoverState() + } + + $scope.mouseOverSelectedTo = function() { + $scope.history.hoveringOverListSelectors = true + $scope.update.hoverSelectedTo = true + return $scope.recalculateHoveredUpdates() + } + + $scope.mouseOutSelectedTo = function() { + $scope.history.hoveringOverListSelectors = false + return $scope.resetHoverState() + } + + return ($scope.displayName = displayNameForUser) + }) }) diff --git a/services/web/public/src/ide/history/controllers/HistoryV2AddLabelModalController.js b/services/web/public/src/ide/history/controllers/HistoryV2AddLabelModalController.js index efa277d21e..2b5b69fc6a 100644 --- a/services/web/public/src/ide/history/controllers/HistoryV2AddLabelModalController.js +++ b/services/web/public/src/ide/history/controllers/HistoryV2AddLabelModalController.js @@ -11,40 +11,39 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('HistoryV2AddLabelModalController', [ - '$scope', - '$modalInstance', - 'ide', - 'update', - function($scope, $modalInstance, ide, update) { - $scope.update = update - $scope.inputs = { labelName: null } - $scope.state = { - inflight: false, - error: false - } - - $modalInstance.opened.then(() => - $scope.$applyAsync(() => $scope.$broadcast('open')) - ) - - return ($scope.addLabelModalFormSubmit = function() { - $scope.state.inflight = true - return ide.historyManager - .labelCurrentVersion($scope.inputs.labelName) - .then(function(response) { - $scope.state.inflight = false - return $modalInstance.close() - }) - .catch(function(response) { - const { data, status } = response - $scope.state.inflight = false - if (status === 400) { - return ($scope.state.error = { message: data }) - } else { - return ($scope.state.error = true) - } - }) - }) + App.controller('HistoryV2AddLabelModalController', function( + $scope, + $modalInstance, + ide, + update + ) { + $scope.update = update + $scope.inputs = { labelName: null } + $scope.state = { + inflight: false, + error: false } - ])) + + $modalInstance.opened.then(() => + $scope.$applyAsync(() => $scope.$broadcast('open')) + ) + + return ($scope.addLabelModalFormSubmit = function() { + $scope.state.inflight = true + return ide.historyManager + .labelCurrentVersion($scope.inputs.labelName) + .then(function(response) { + $scope.state.inflight = false + return $modalInstance.close() + }) + .catch(function(response) { + const { data, status } = response + $scope.state.inflight = false + if (status === 400) { + return ($scope.state.error = { message: data }) + } else { + return ($scope.state.error = true) + } + }) + }) + })) diff --git a/services/web/public/src/ide/history/controllers/HistoryV2DeleteLabelModalController.js b/services/web/public/src/ide/history/controllers/HistoryV2DeleteLabelModalController.js index 45ad900d30..730416413d 100644 --- a/services/web/public/src/ide/history/controllers/HistoryV2DeleteLabelModalController.js +++ b/services/web/public/src/ide/history/controllers/HistoryV2DeleteLabelModalController.js @@ -11,35 +11,34 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('HistoryV2DeleteLabelModalController', [ - '$scope', - '$modalInstance', - 'ide', - 'labelDetails', - function($scope, $modalInstance, ide, labelDetails) { - $scope.labelDetails = labelDetails - $scope.state = { - inflight: false, - error: false - } - - return ($scope.deleteLabel = function() { - $scope.state.inflight = true - return ide.historyManager - .deleteLabel(labelDetails) - .then(function(response) { - $scope.state.inflight = false - return $modalInstance.close() - }) - .catch(function(response) { - const { data, status } = response - $scope.state.inflight = false - if (status === 400) { - return ($scope.state.error = { message: data }) - } else { - return ($scope.state.error = true) - } - }) - }) + App.controller('HistoryV2DeleteLabelModalController', function( + $scope, + $modalInstance, + ide, + labelDetails + ) { + $scope.labelDetails = labelDetails + $scope.state = { + inflight: false, + error: false } - ])) + + return ($scope.deleteLabel = function() { + $scope.state.inflight = true + return ide.historyManager + .deleteLabel(labelDetails) + .then(function(response) { + $scope.state.inflight = false + return $modalInstance.close() + }) + .catch(function(response) { + const { data, status } = response + $scope.state.inflight = false + if (status === 400) { + return ($scope.state.error = { message: data }) + } else { + return ($scope.state.error = true) + } + }) + }) + })) diff --git a/services/web/public/src/ide/history/controllers/HistoryV2FileTreeController.js b/services/web/public/src/ide/history/controllers/HistoryV2FileTreeController.js index 557753a670..25c99c51c1 100644 --- a/services/web/public/src/ide/history/controllers/HistoryV2FileTreeController.js +++ b/services/web/public/src/ide/history/controllers/HistoryV2FileTreeController.js @@ -12,12 +12,8 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('HistoryV2FileTreeController', [ - '$scope', - 'ide', - function($scope, ide) { - $scope.handleFileSelection = file => { - ide.historyManager.selectFile(file) - } + App.controller('HistoryV2FileTreeController', function($scope, ide) { + $scope.handleFileSelection = file => { + ide.historyManager.selectFile(file) } - ])) + })) diff --git a/services/web/public/src/ide/history/controllers/HistoryV2ListController.js b/services/web/public/src/ide/history/controllers/HistoryV2ListController.js index 80ff7ed248..5621816477 100644 --- a/services/web/public/src/ide/history/controllers/HistoryV2ListController.js +++ b/services/web/public/src/ide/history/controllers/HistoryV2ListController.js @@ -15,48 +15,40 @@ define(['base', 'ide/history/util/displayNameForUser'], ( App, displayNameForUser ) => - App.controller('HistoryV2ListController', [ - '$scope', - '$modal', - 'ide', - function($scope, $modal, ide) { - $scope.hoveringOverListSelectors = false - $scope.listConfig = { showOnlyLabelled: false } + App.controller('HistoryV2ListController', function($scope, $modal, ide) { + $scope.hoveringOverListSelectors = false + $scope.listConfig = { showOnlyLabelled: false } - $scope.projectUsers = [] + $scope.projectUsers = [] - $scope.$watch('project.members', function(newVal) { - if (newVal != null) { - return ($scope.projectUsers = newVal.concat($scope.project.owner)) - } - }) - - $scope.loadMore = () => { - return ide.historyManager.fetchNextBatchOfUpdates() + $scope.$watch('project.members', function(newVal) { + if (newVal != null) { + return ($scope.projectUsers = newVal.concat($scope.project.owner)) } + }) - $scope.handleVersionSelect = version => - $scope.$applyAsync(() => - ide.historyManager.selectVersionForPointInTime(version) - ) - - $scope.handleRangeSelect = (selectedToV, selectedFromV) => - $scope.$applyAsync(() => - ide.historyManager.selectVersionsForCompare( - selectedToV, - selectedFromV - ) - ) - - return ($scope.handleLabelDelete = labelDetails => - $modal.open({ - templateUrl: 'historyV2DeleteLabelModalTemplate', - controller: 'HistoryV2DeleteLabelModalController', - resolve: { - labelDetails() { - return labelDetails - } - } - })) + $scope.loadMore = () => { + return ide.historyManager.fetchNextBatchOfUpdates() } - ])) + + $scope.handleVersionSelect = version => + $scope.$applyAsync(() => + ide.historyManager.selectVersionForPointInTime(version) + ) + + $scope.handleRangeSelect = (selectedToV, selectedFromV) => + $scope.$applyAsync(() => + ide.historyManager.selectVersionsForCompare(selectedToV, selectedFromV) + ) + + return ($scope.handleLabelDelete = labelDetails => + $modal.open({ + templateUrl: 'historyV2DeleteLabelModalTemplate', + controller: 'HistoryV2DeleteLabelModalController', + resolve: { + labelDetails() { + return labelDetails + } + } + })) + })) diff --git a/services/web/public/src/ide/history/controllers/HistoryV2ToolbarController.js b/services/web/public/src/ide/history/controllers/HistoryV2ToolbarController.js index 0b19c8f54f..78104fadad 100644 --- a/services/web/public/src/ide/history/controllers/HistoryV2ToolbarController.js +++ b/services/web/public/src/ide/history/controllers/HistoryV2ToolbarController.js @@ -12,12 +12,8 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('HistoryV2ToolbarController', [ - '$scope', - '$modal', - 'ide', - 'event_tracking', - 'waitFor', + App.controller( + 'HistoryV2ToolbarController', ($scope, $modal, ide, event_tracking, waitFor) => { let openEntity @@ -126,4 +122,4 @@ define(['base'], App => .catch(err => console.warn(err)) } } - ])) + )) diff --git a/services/web/public/src/ide/pdf/controllers/PdfController.js b/services/web/public/src/ide/pdf/controllers/PdfController.js index f1315f07ae..0f5eb2a858 100644 --- a/services/web/public/src/ide/pdf/controllers/PdfController.js +++ b/services/web/public/src/ide/pdf/controllers/PdfController.js @@ -30,7 +30,7 @@ define([ // and then again on ack. const AUTO_COMPILE_DEBOUNCE = 2000 - App.filter('trusted', ['$sce', $sce => url => $sce.trustAsResourceUrl(url)]) + App.filter('trusted', $sce => url => $sce.trustAsResourceUrl(url)) App.controller('PdfController', function( $scope, @@ -898,188 +898,175 @@ define([ })) }) - App.factory('synctex', [ - 'ide', - '$http', - '$q', - function(ide, $http, $q) { - // enable per-user containers by default - const perUserCompile = true + App.factory('synctex', function(ide, $http, $q) { + // enable per-user containers by default + const perUserCompile = true - const synctex = { - syncToPdf(cursorPosition) { - const deferred = $q.defer() - - const doc_id = ide.editorManager.getCurrentDocId() - if (doc_id == null) { - deferred.reject() - return deferred.promise - } - const doc = ide.fileTreeManager.findEntityById(doc_id) - if (doc == null) { - deferred.reject() - return deferred.promise - } - let path = ide.fileTreeManager.getEntityPath(doc) - if (path == null) { - deferred.reject() - return deferred.promise - } - - // If the root file is folder/main.tex, then synctex sees the - // path as folder/./main.tex - const rootDocDirname = ide.fileTreeManager.getRootDocDirname() - if (rootDocDirname != null && rootDocDirname !== '') { - path = path.replace( - RegExp(`^${rootDocDirname}`), - `${rootDocDirname}/.` - ) - } - - const { row, column } = cursorPosition - - $http({ - url: `/project/${ide.project_id}/sync/code`, - method: 'GET', - params: { - file: path, - line: row + 1, - column, - clsiserverid: ide.clsiServerId - } - }) - .then(function(response) { - const { data } = response - return deferred.resolve(data.pdf || []) - }) - .catch(function(response) { - const error = response.data - return deferred.reject(error) - }) + const synctex = { + syncToPdf(cursorPosition) { + const deferred = $q.defer() + const doc_id = ide.editorManager.getCurrentDocId() + if (doc_id == null) { + deferred.reject() return deferred.promise - }, + } + const doc = ide.fileTreeManager.findEntityById(doc_id) + if (doc == null) { + deferred.reject() + return deferred.promise + } + let path = ide.fileTreeManager.getEntityPath(doc) + if (path == null) { + deferred.reject() + return deferred.promise + } - syncToCode(position, options) { - let v - if (options == null) { - options = {} + // If the root file is folder/main.tex, then synctex sees the + // path as folder/./main.tex + const rootDocDirname = ide.fileTreeManager.getRootDocDirname() + if (rootDocDirname != null && rootDocDirname !== '') { + path = path.replace( + RegExp(`^${rootDocDirname}`), + `${rootDocDirname}/.` + ) + } + + const { row, column } = cursorPosition + + $http({ + url: `/project/${ide.project_id}/sync/code`, + method: 'GET', + params: { + file: path, + line: row + 1, + column, + clsiserverid: ide.clsiServerId } - const deferred = $q.defer() - if (position == null) { - deferred.reject() - return deferred.promise - } - - // FIXME: this actually works better if it's halfway across the - // page (or the visible part of the page). Synctex doesn't - // always find the right place in the file when the point is at - // the edge of the page, it sometimes returns the start of the - // next paragraph instead. - const h = position.offset.left - - // Compute the vertical position to pass to synctex, which - // works with coordinates increasing from the top of the page - // down. This matches the browser's DOM coordinate of the - // click point, but the pdf position is measured from the - // bottom of the page so we need to invert it. - if ( - options.fromPdfPosition && - (position.pageSize != null - ? position.pageSize.height - : undefined) != null - ) { - v = position.pageSize.height - position.offset.top || 0 // measure from pdf point (inverted) - } else { - v = position.offset.top || 0 // measure from html click position - } - - // It's not clear exactly where we should sync to if it wasn't directly - // clicked on, but a little bit down from the very top seems best. - if (options.includeVisualOffset) { - v += 72 // use the same value as in pdfViewer highlighting visual offset - } - - $http({ - url: `/project/${ide.project_id}/sync/pdf`, - method: 'GET', - params: { - page: position.page + 1, - h: h.toFixed(2), - v: v.toFixed(2), - clsiserverid: ide.clsiServerId - } + }) + .then(function(response) { + const { data } = response + return deferred.resolve(data.pdf || []) }) - .then(function(response) { - const { data } = response - if ( - data.code != null && - data.code.length > 0 && - data.code[0].file !== '' - ) { - const doc = ide.fileTreeManager.findEntityByPath( - data.code[0].file - ) - if (doc == null) { - return - } - return deferred.resolve({ doc, line: data.code[0].line }) - } else if (data.code[0].file === '') { - ide.$scope.sync_tex_error = true - setTimeout(() => (ide.$scope.sync_tex_error = false), 4000) + .catch(function(response) { + const error = response.data + return deferred.reject(error) + }) + + return deferred.promise + }, + + syncToCode(position, options) { + let v + if (options == null) { + options = {} + } + const deferred = $q.defer() + if (position == null) { + deferred.reject() + return deferred.promise + } + + // FIXME: this actually works better if it's halfway across the + // page (or the visible part of the page). Synctex doesn't + // always find the right place in the file when the point is at + // the edge of the page, it sometimes returns the start of the + // next paragraph instead. + const h = position.offset.left + + // Compute the vertical position to pass to synctex, which + // works with coordinates increasing from the top of the page + // down. This matches the browser's DOM coordinate of the + // click point, but the pdf position is measured from the + // bottom of the page so we need to invert it. + if ( + options.fromPdfPosition && + (position.pageSize != null ? position.pageSize.height : undefined) != + null + ) { + v = position.pageSize.height - position.offset.top || 0 // measure from pdf point (inverted) + } else { + v = position.offset.top || 0 // measure from html click position + } + + // It's not clear exactly where we should sync to if it wasn't directly + // clicked on, but a little bit down from the very top seems best. + if (options.includeVisualOffset) { + v += 72 // use the same value as in pdfViewer highlighting visual offset + } + + $http({ + url: `/project/${ide.project_id}/sync/pdf`, + method: 'GET', + params: { + page: position.page + 1, + h: h.toFixed(2), + v: v.toFixed(2), + clsiserverid: ide.clsiServerId + } + }) + .then(function(response) { + const { data } = response + if ( + data.code != null && + data.code.length > 0 && + data.code[0].file !== '' + ) { + const doc = ide.fileTreeManager.findEntityByPath( + data.code[0].file + ) + if (doc == null) { + return } - }) - .catch(function(response) { - const error = response.data - return deferred.reject(error) - }) - - return deferred.promise - } - } - - return synctex - } - ]) - - App.controller('PdfSynctexController', [ - '$scope', - 'synctex', - 'ide', - function($scope, synctex, ide) { - this.cursorPosition = null - ide.$scope.$on('cursor:editor:update', (event, cursorPosition) => { - this.cursorPosition = cursorPosition - }) - - $scope.syncToPdf = () => { - if (this.cursorPosition == null) { - return - } - return synctex - .syncToPdf(this.cursorPosition) - .then(highlights => ($scope.pdf.highlights = highlights)) - } - - ide.$scope.$on('cursor:editor:syncToPdf', $scope.syncToPdf) - - return ($scope.syncToCode = () => - synctex - .syncToCode($scope.pdf.position, { - includeVisualOffset: true, - fromPdfPosition: true + return deferred.resolve({ doc, line: data.code[0].line }) + } else if (data.code[0].file === '') { + ide.$scope.sync_tex_error = true + setTimeout(() => (ide.$scope.sync_tex_error = false), 4000) + } + }) + .catch(function(response) { + const error = response.data + return deferred.reject(error) }) - .then(function(data) { - const { doc, line } = data - return ide.editorManager.openDoc(doc, { gotoLine: line }) - })) - } - ]) - App.controller('PdfLogEntryController', [ - '$scope', - 'ide', - 'event_tracking', + return deferred.promise + } + } + + return synctex + }) + + App.controller('PdfSynctexController', function($scope, synctex, ide) { + this.cursorPosition = null + ide.$scope.$on('cursor:editor:update', (event, cursorPosition) => { + this.cursorPosition = cursorPosition + }) + + $scope.syncToPdf = () => { + if (this.cursorPosition == null) { + return + } + return synctex + .syncToPdf(this.cursorPosition) + .then(highlights => ($scope.pdf.highlights = highlights)) + } + + ide.$scope.$on('cursor:editor:syncToPdf', $scope.syncToPdf) + + return ($scope.syncToCode = () => + synctex + .syncToCode($scope.pdf.position, { + includeVisualOffset: true, + fromPdfPosition: true + }) + .then(function(data) { + const { doc, line } = data + return ide.editorManager.openDoc(doc, { gotoLine: line }) + })) + }) + + App.controller( + 'PdfLogEntryController', ($scope, ide, event_tracking) => ($scope.openInEditor = function(entry) { let column, line @@ -1099,25 +1086,24 @@ define([ gotoColumn: column }) }) - ]) + ) - return App.controller('ClearCacheModalController', [ - '$scope', - '$modalInstance', - function($scope, $modalInstance) { - $scope.state = { inflight: false } + return App.controller('ClearCacheModalController', function( + $scope, + $modalInstance + ) { + $scope.state = { inflight: false } - $scope.clear = function() { - $scope.state.inflight = true - return $scope.clearCache().then(function() { - $scope.state.inflight = false - return $modalInstance.close() - }) - } - - return ($scope.cancel = () => $modalInstance.dismiss('cancel')) + $scope.clear = function() { + $scope.state.inflight = true + return $scope.clearCache().then(function() { + $scope.state.inflight = false + return $modalInstance.close() + }) } - ]) + + return ($scope.cancel = () => $modalInstance.dismiss('cancel')) + }) }) function __guard__(value, transform) { diff --git a/services/web/public/src/ide/pdfng/directives/pdfHighlights.js b/services/web/public/src/ide/pdfng/directives/pdfHighlights.js index b3bb0dcdec..277557c93c 100644 --- a/services/web/public/src/ide/pdfng/directives/pdfHighlights.js +++ b/services/web/public/src/ide/pdfng/directives/pdfHighlights.js @@ -16,41 +16,39 @@ define(['base', 'pdfjs-dist/build/pdf'], (App, PDFJS) => // app = angular.module 'pdfHighlights', [] - App.factory('pdfHighlights', [ - function() { - let pdfHighlights - return (pdfHighlights = class pdfHighlights { - constructor(options) { - this.highlightsLayerDiv = options.highlights[0] - this.highlightElements = [] - } + App.factory('pdfHighlights', function() { + let pdfHighlights + return (pdfHighlights = class pdfHighlights { + constructor(options) { + this.highlightsLayerDiv = options.highlights[0] + this.highlightElements = [] + } - addHighlight(viewport, left, top, width, height) { - let rect = viewport.convertToViewportRectangle([ - left, - top, - left + width, - top + height - ]) - rect = PDFJS.Util.normalizeRect(rect) - const element = document.createElement('div') - element.style.left = Math.floor(rect[0]) + 'px' - element.style.top = Math.floor(rect[1]) + 'px' - element.style.width = Math.ceil(rect[2] - rect[0]) + 'px' - element.style.height = Math.ceil(rect[3] - rect[1]) + 'px' - this.highlightElements.push(element) - this.highlightsLayerDiv.appendChild(element) - return element - } + addHighlight(viewport, left, top, width, height) { + let rect = viewport.convertToViewportRectangle([ + left, + top, + left + width, + top + height + ]) + rect = PDFJS.Util.normalizeRect(rect) + const element = document.createElement('div') + element.style.left = Math.floor(rect[0]) + 'px' + element.style.top = Math.floor(rect[1]) + 'px' + element.style.width = Math.ceil(rect[2] - rect[0]) + 'px' + element.style.height = Math.ceil(rect[3] - rect[1]) + 'px' + this.highlightElements.push(element) + this.highlightsLayerDiv.appendChild(element) + return element + } - clearHighlights() { - for (let h of Array.from(this.highlightElements)) { - if (h != null) { - h.parentNode.removeChild(h) - } + clearHighlights() { + for (let h of Array.from(this.highlightElements)) { + if (h != null) { + h.parentNode.removeChild(h) } - return (this.highlightElements = []) } - }) - } - ])) + return (this.highlightElements = []) + } + }) + })) diff --git a/services/web/public/src/ide/pdfng/directives/pdfJs.js b/services/web/public/src/ide/pdfng/directives/pdfJs.js index 1f039c02f4..561ae2a814 100644 --- a/services/web/public/src/ide/pdfng/directives/pdfJs.js +++ b/services/web/public/src/ide/pdfng/directives/pdfJs.js @@ -14,148 +14,143 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base', 'ide/pdfng/directives/pdfViewer'], (App, pdfViewer) => - App.directive('pdfng', [ - '$timeout', - 'localStorage', - ($timeout, localStorage) => ({ - scope: { - pdfSrc: '=', - highlights: '=', - position: '=', - dblClickCallback: '=' - }, - link(scope, element, attrs) { - scope.loading = false - scope.pleaseJumpTo = null - scope.scale = null - let initializedPosition = false - const initializePosition = function() { - let position, scale - if (initializedPosition) { + App.directive('pdfng', ($timeout, localStorage) => ({ + scope: { + pdfSrc: '=', + highlights: '=', + position: '=', + dblClickCallback: '=' + }, + link(scope, element, attrs) { + scope.loading = false + scope.pleaseJumpTo = null + scope.scale = null + let initializedPosition = false + const initializePosition = function() { + let position, scale + if (initializedPosition) { + return + } + initializedPosition = true + + if ((scale = localStorage('pdf.scale')) != null) { + scope.scale = { scaleMode: scale.scaleMode, scale: +scale.scale } + } else { + scope.scale = { scaleMode: 'scale_mode_fit_width' } + } + + if ((position = localStorage(`pdf.position.${attrs.key}`))) { + scope.position = { + page: +position.page, + offset: { + top: +position.offset.top, + left: +position.offset.left + } + } + } + + scope.$on('$destroy', () => { + localStorage('pdf.scale', scope.scale) + return localStorage(`pdf.position.${attrs.key}`, scope.position) + }) + + return $(window).unload(() => { + localStorage('pdf.scale', scope.scale) + return localStorage(`pdf.position.${attrs.key}`, scope.position) + }) + } + + const flashControls = () => + scope.$evalAsync(function() { + scope.flashControls = true + return $timeout(() => (scope.flashControls = false), 1000) + }) + + scope.$on( + 'pdfDoubleClick', + (event, e) => + typeof scope.dblClickCallback === 'function' + ? scope.dblClickCallback({ + page: e.page - 1, + offset: { top: e.y, left: e.x } + }) + : undefined + ) + + scope.$on('flash-controls', () => flashControls()) + + scope.$watch('pdfSrc', function(url) { + if (url) { + scope.loading = true + scope.loaded = false + scope.progress = 1 + initializePosition() + return flashControls() + } + }) + + scope.$on('loaded', function() { + scope.loaded = true + scope.progress = 100 + return $timeout(function() { + scope.loading = false + return delete scope.progress + }, 500) + }) + + scope.fitToHeight = function() { + const scale = angular.copy(scope.scale) + scale.scaleMode = 'scale_mode_fit_height' + return (scope.scale = scale) + } + + scope.fitToWidth = function() { + const scale = angular.copy(scope.scale) + scale.scaleMode = 'scale_mode_fit_width' + return (scope.scale = scale) + } + + scope.zoomIn = function() { + const scale = angular.copy(scope.scale) + scale.scaleMode = 'scale_mode_value' + scale.scale = scale.scale * 1.2 + return (scope.scale = scale) + } + + scope.zoomOut = function() { + const scale = angular.copy(scope.scale) + scale.scaleMode = 'scale_mode_value' + scale.scale = scale.scale / 1.2 + return (scope.scale = scale) + } + + if (attrs.resizeOn != null) { + for (let event of Array.from(attrs.resizeOn.split(','))) { + scope.$on(event, function(e) {}) + } + } + // console.log 'got a resize event', event, e + + scope.$on('progress', (event, progress) => + scope.$apply(function() { + if (scope.loaded) { return } - initializedPosition = true - - if ((scale = localStorage('pdf.scale')) != null) { - scope.scale = { scaleMode: scale.scaleMode, scale: +scale.scale } - } else { - scope.scale = { scaleMode: 'scale_mode_fit_width' } + scope.progress = Math.floor((progress.loaded / progress.total) * 100) + if (scope.progress > 100) { + scope.progress = 100 } - - if ((position = localStorage(`pdf.position.${attrs.key}`))) { - scope.position = { - page: +position.page, - offset: { - top: +position.offset.top, - left: +position.offset.left - } - } - } - - scope.$on('$destroy', () => { - localStorage('pdf.scale', scope.scale) - return localStorage(`pdf.position.${attrs.key}`, scope.position) - }) - - return $(window).unload(() => { - localStorage('pdf.scale', scope.scale) - return localStorage(`pdf.position.${attrs.key}`, scope.position) - }) - } - - const flashControls = () => - scope.$evalAsync(function() { - scope.flashControls = true - return $timeout(() => (scope.flashControls = false), 1000) - }) - - scope.$on( - 'pdfDoubleClick', - (event, e) => - typeof scope.dblClickCallback === 'function' - ? scope.dblClickCallback({ - page: e.page - 1, - offset: { top: e.y, left: e.x } - }) - : undefined - ) - - scope.$on('flash-controls', () => flashControls()) - - scope.$watch('pdfSrc', function(url) { - if (url) { - scope.loading = true - scope.loaded = false - scope.progress = 1 - initializePosition() - return flashControls() + if (scope.progress < 0) { + return (scope.progress = 0) } }) + ) - scope.$on('loaded', function() { - scope.loaded = true - scope.progress = 100 - return $timeout(function() { - scope.loading = false - return delete scope.progress - }, 500) - }) + return scope.$on('$destroy', function() {}) + }, + // console.log 'pdfjs destroy event' - scope.fitToHeight = function() { - const scale = angular.copy(scope.scale) - scale.scaleMode = 'scale_mode_fit_height' - return (scope.scale = scale) - } - - scope.fitToWidth = function() { - const scale = angular.copy(scope.scale) - scale.scaleMode = 'scale_mode_fit_width' - return (scope.scale = scale) - } - - scope.zoomIn = function() { - const scale = angular.copy(scope.scale) - scale.scaleMode = 'scale_mode_value' - scale.scale = scale.scale * 1.2 - return (scope.scale = scale) - } - - scope.zoomOut = function() { - const scale = angular.copy(scope.scale) - scale.scaleMode = 'scale_mode_value' - scale.scale = scale.scale / 1.2 - return (scope.scale = scale) - } - - if (attrs.resizeOn != null) { - for (let event of Array.from(attrs.resizeOn.split(','))) { - scope.$on(event, function(e) {}) - } - } - // console.log 'got a resize event', event, e - - scope.$on('progress', (event, progress) => - scope.$apply(function() { - if (scope.loaded) { - return - } - scope.progress = Math.floor( - (progress.loaded / progress.total) * 100 - ) - if (scope.progress > 100) { - scope.progress = 100 - } - if (scope.progress < 0) { - return (scope.progress = 0) - } - }) - ) - - return scope.$on('$destroy', function() {}) - }, - // console.log 'pdfjs destroy event' - - template: `\ + template: `\
@@ -201,5 +196,4 @@ define(['base', 'ide/pdfng/directives/pdfViewer'], (App, pdfViewer) =>
\ ` - }) - ])) + }))) diff --git a/services/web/public/src/ide/pdfng/directives/pdfPage.js b/services/web/public/src/ide/pdfng/directives/pdfPage.js index b1345123e7..ad5ccf48e7 100644 --- a/services/web/public/src/ide/pdfng/directives/pdfPage.js +++ b/services/web/public/src/ide/pdfng/directives/pdfPage.js @@ -17,13 +17,9 @@ define(['base'], App => // App = angular.module 'pdfPage', ['pdfHighlights'] - App.directive('pdfPage', [ - '$timeout', - 'pdfHighlights', - 'pdfSpinner', - ($timeout, pdfHighlights, pdfSpinner) => ({ - require: '^pdfViewer', - template: `\ + App.directive('pdfPage', ($timeout, pdfHighlights, pdfSpinner) => ({ + require: '^pdfViewer', + template: `\
@@ -31,141 +27,140 @@ define(['base'], App =>
\ `, - link(scope, element, attrs, ctrl) { - const canvasElement = $(element).find('.pdf-canvas') - const textElement = $(element).find('.text-layer') - const annotationsElement = $(element).find('.annotations-layer') - const highlightsElement = $(element).find('.highlights-layer') + link(scope, element, attrs, ctrl) { + const canvasElement = $(element).find('.pdf-canvas') + const textElement = $(element).find('.text-layer') + const annotationsElement = $(element).find('.annotations-layer') + const highlightsElement = $(element).find('.highlights-layer') - const updatePageSize = function(size) { - const h = Math.floor(size[0]) - const w = Math.floor(size[1]) - element.height(h) - element.width(w) - canvasElement.height(h) - canvasElement.width(w) - return (scope.page.sized = true) - } - - // keep track of our page element, so we can access it in the - // parent with scope.pages[i].element, and the contained - // elements for each part - scope.page.element = element - scope.page.elementChildren = { - canvas: canvasElement, - text: textElement, - annotations: annotationsElement, - highlights: highlightsElement, - container: element - } - - if (!scope.page.sized) { - if (scope.defaultPageSize != null) { - updatePageSize(scope.defaultPageSize) - } else { - // shouldn't get here - the default page size should now - // always be set before redraw is called - var handler = scope.$watch('defaultPageSize', function( - defaultPageSize - ) { - if (defaultPageSize == null) { - return - } - updatePageSize(defaultPageSize) - return handler() - }) - } - } - - if (scope.page.current) { - // console.log 'we must scroll to this page', scope.page.pageNum, 'at position', scope.page.position - // this is the current page, we want to scroll it into view - // and render it immediately - scope.document.renderPage(scope.page) - ctrl.setPdfPosition(scope.page, scope.page.position) - } - - element.on('dblclick', function(e) { - const offset = $(element) - .find('.pdf-canvas') - .offset() - const dx = e.pageX - offset.left - const dy = e.pageY - offset.top - return scope.document - .getPdfViewport(scope.page.pageNum) - .then(function(viewport) { - const pdfPoint = viewport.convertToPdfPoint(dx, dy) - const event = { - page: scope.page.pageNum, - x: pdfPoint[0], - y: viewport.viewBox[3] - pdfPoint[1] - } - return scope.$emit('pdfDoubleClick', event) - }) - }) - - const highlightsLayer = new pdfHighlights({ - highlights: highlightsElement - }) - - scope.$on('pdf:highlights', function(event, highlights) { - let h - if (highlights == null) { - return - } - if (!(highlights.length > 0)) { - return - } - if (scope.timeoutHandler) { - $timeout.cancel(scope.timeoutHandler) - highlightsLayer.clearHighlights() - scope.timeoutHandler = null - } - - // console.log 'got highlight watch in pdfPage', scope.page - const pageHighlights = (() => { - const result = [] - for (h of Array.from(highlights)) { - if (h.page === scope.page.pageNum) { - result.push(h) - } - } - return result - })() - if (!pageHighlights.length) { - return - } - scope.document.getPdfViewport(scope.page.pageNum).then(viewport => - (() => { - const result1 = [] - for (let hl of Array.from(pageHighlights)) { - // console.log 'adding highlight', h, viewport - const top = viewport.viewBox[3] - hl.v - result1.push( - highlightsLayer.addHighlight( - viewport, - hl.h, - top, - hl.width, - hl.height - ) - ) - } - return result1 - })() - ) - return (scope.timeoutHandler = $timeout(function() { - highlightsLayer.clearHighlights() - return (scope.timeoutHandler = null) - }, 1000)) - }) - - return scope.$on('$destroy', function() { - if (scope.timeoutHandler != null) { - $timeout.cancel(scope.timeoutHandler) - return highlightsLayer.clearHighlights() - } - }) + const updatePageSize = function(size) { + const h = Math.floor(size[0]) + const w = Math.floor(size[1]) + element.height(h) + element.width(w) + canvasElement.height(h) + canvasElement.width(w) + return (scope.page.sized = true) } - }) - ])) + + // keep track of our page element, so we can access it in the + // parent with scope.pages[i].element, and the contained + // elements for each part + scope.page.element = element + scope.page.elementChildren = { + canvas: canvasElement, + text: textElement, + annotations: annotationsElement, + highlights: highlightsElement, + container: element + } + + if (!scope.page.sized) { + if (scope.defaultPageSize != null) { + updatePageSize(scope.defaultPageSize) + } else { + // shouldn't get here - the default page size should now + // always be set before redraw is called + var handler = scope.$watch('defaultPageSize', function( + defaultPageSize + ) { + if (defaultPageSize == null) { + return + } + updatePageSize(defaultPageSize) + return handler() + }) + } + } + + if (scope.page.current) { + // console.log 'we must scroll to this page', scope.page.pageNum, 'at position', scope.page.position + // this is the current page, we want to scroll it into view + // and render it immediately + scope.document.renderPage(scope.page) + ctrl.setPdfPosition(scope.page, scope.page.position) + } + + element.on('dblclick', function(e) { + const offset = $(element) + .find('.pdf-canvas') + .offset() + const dx = e.pageX - offset.left + const dy = e.pageY - offset.top + return scope.document + .getPdfViewport(scope.page.pageNum) + .then(function(viewport) { + const pdfPoint = viewport.convertToPdfPoint(dx, dy) + const event = { + page: scope.page.pageNum, + x: pdfPoint[0], + y: viewport.viewBox[3] - pdfPoint[1] + } + return scope.$emit('pdfDoubleClick', event) + }) + }) + + const highlightsLayer = new pdfHighlights({ + highlights: highlightsElement + }) + + scope.$on('pdf:highlights', function(event, highlights) { + let h + if (highlights == null) { + return + } + if (!(highlights.length > 0)) { + return + } + if (scope.timeoutHandler) { + $timeout.cancel(scope.timeoutHandler) + highlightsLayer.clearHighlights() + scope.timeoutHandler = null + } + + // console.log 'got highlight watch in pdfPage', scope.page + const pageHighlights = (() => { + const result = [] + for (h of Array.from(highlights)) { + if (h.page === scope.page.pageNum) { + result.push(h) + } + } + return result + })() + if (!pageHighlights.length) { + return + } + scope.document.getPdfViewport(scope.page.pageNum).then(viewport => + (() => { + const result1 = [] + for (let hl of Array.from(pageHighlights)) { + // console.log 'adding highlight', h, viewport + const top = viewport.viewBox[3] - hl.v + result1.push( + highlightsLayer.addHighlight( + viewport, + hl.h, + top, + hl.width, + hl.height + ) + ) + } + return result1 + })() + ) + return (scope.timeoutHandler = $timeout(function() { + highlightsLayer.clearHighlights() + return (scope.timeoutHandler = null) + }, 1000)) + }) + + return scope.$on('$destroy', function() { + if (scope.timeoutHandler != null) { + $timeout.cancel(scope.timeoutHandler) + return highlightsLayer.clearHighlights() + } + }) + } + }))) diff --git a/services/web/public/src/ide/pdfng/directives/pdfRenderer.js b/services/web/public/src/ide/pdfng/directives/pdfRenderer.js index 240f97c18c..2d1f01456b 100644 --- a/services/web/public/src/ide/pdfng/directives/pdfRenderer.js +++ b/services/web/public/src/ide/pdfng/directives/pdfRenderer.js @@ -21,512 +21,503 @@ define(['base', 'pdfjs-dist/build/pdf'], (App, PDFJS) => // App = angular.module 'PDFRenderer', ['pdfAnnotations', 'pdfTextLayer'] - App.factory('PDFRenderer', [ - '$q', - '$timeout', - 'pdfAnnotations', - 'pdfTextLayer', - 'pdfSpinner', - function($q, $timeout, pdfAnnotations, pdfTextLayer, pdfSpinner) { - let PDFRenderer - return (PDFRenderer = (function() { - PDFRenderer = class PDFRenderer { - static initClass() { - this.prototype.JOB_QUEUE_INTERVAL = 25 - this.prototype.PAGE_LOAD_TIMEOUT = 60 * 1000 - this.prototype.INDICATOR_DELAY1 = 100 // time to delay before showing the indicator - this.prototype.INDICATOR_DELAY2 = 250 // time until the indicator starts animating - this.prototype.TEXTLAYER_TIMEOUT = 100 + App.factory('PDFRenderer', function( + $q, + $timeout, + pdfAnnotations, + pdfTextLayer, + pdfSpinner + ) { + let PDFRenderer + return (PDFRenderer = (function() { + PDFRenderer = class PDFRenderer { + static initClass() { + this.prototype.JOB_QUEUE_INTERVAL = 25 + this.prototype.PAGE_LOAD_TIMEOUT = 60 * 1000 + this.prototype.INDICATOR_DELAY1 = 100 // time to delay before showing the indicator + this.prototype.INDICATOR_DELAY2 = 250 // time until the indicator starts animating + this.prototype.TEXTLAYER_TIMEOUT = 100 + } + + constructor(url, options) { + // set up external character mappings - needed for Japanese etc + this.url = url + this.options = options + + this.scale = this.options.scale || 1 + + let disableFontFace + if ( + __guard__( + window.location != null ? window.location.search : undefined, + x => x.indexOf('disable-font-face=true') + ) >= 0 + ) { + disableFontFace = true + } else { + disableFontFace = false } - - constructor(url, options) { - // set up external character mappings - needed for Japanese etc - this.url = url - this.options = options - - this.scale = this.options.scale || 1 - - let disableFontFace - if ( - __guard__( - window.location != null ? window.location.search : undefined, - x => x.indexOf('disable-font-face=true') - ) >= 0 - ) { - disableFontFace = true - } else { - disableFontFace = false - } - this.pdfjs = PDFJS.getDocument({ - url: this.url, - cMapUrl: window.pdfCMapsPath, - cMapPacked: true, - disableFontFace, - // Enable fetching with Range headers to restrict individual - // requests to 128kb. - // To do this correctly we must: - // a) disable auto-fetching of the whole file upfront - // b) disable streaming (which in this context means streaming of - // the response into memory). This isn't supported when using - // Range headers, but shouldn't be a problem since we are already - // limiting individual response size through chunked range - // requests - rangeChunkSize: 128 * 1024, - disableAutoFetch: !!this.options.disableAutoFetch, - disableStream: !!this.options.disableAutoFetch + this.pdfjs = PDFJS.getDocument({ + url: this.url, + cMapUrl: window.pdfCMapsPath, + cMapPacked: true, + disableFontFace, + // Enable fetching with Range headers to restrict individual + // requests to 128kb. + // To do this correctly we must: + // a) disable auto-fetching of the whole file upfront + // b) disable streaming (which in this context means streaming of + // the response into memory). This isn't supported when using + // Range headers, but shouldn't be a problem since we are already + // limiting individual response size through chunked range + // requests + rangeChunkSize: 128 * 1024, + disableAutoFetch: !!this.options.disableAutoFetch, + disableStream: !!this.options.disableAutoFetch + }) + this.pdfjs.onProgress = this.options.progressCallback + this.document = $q.when(this.pdfjs) + this.navigateFn = this.options.navigateFn + this.spinner = new pdfSpinner() + this.resetState() + this.document.then(pdfDocument => { + return pdfDocument.getDownloadInfo().then(() => { + return this.options.loadedCallback() }) - this.pdfjs.onProgress = this.options.progressCallback - this.document = $q.when(this.pdfjs) - this.navigateFn = this.options.navigateFn - this.spinner = new pdfSpinner() - this.resetState() - this.document.then(pdfDocument => { - return pdfDocument.getDownloadInfo().then(() => { - return this.options.loadedCallback() - }) - }) - this.errorCallback = this.options.errorCallback - this.pageSizeChangeCallback = this.options.pageSizeChangeCallback - this.pdfjs.promise.catch(exception => { - // error getting document - return this.errorCallback(exception) - }) - } + }) + this.errorCallback = this.options.errorCallback + this.pageSizeChangeCallback = this.options.pageSizeChangeCallback + this.pdfjs.promise.catch(exception => { + // error getting document + return this.errorCallback(exception) + }) + } - resetState() { - this.renderQueue = [] - if (this.queueTimer != null) { - clearTimeout(this.queueTimer) - } - // clear any existing timers, render tasks - for (let timer of Array.from(this.spinTimer || [])) { - clearTimeout(timer) - } - for (let page of Array.from(this.pageState || [])) { - __guard__(page != null ? page.loadTask : undefined, x => - x.cancel() - ) - __guard__(page != null ? page.renderTask : undefined, x1 => - x1.cancel() - ) - } - // initialise/reset the state - this.pageState = [] - this.spinTimer = [] // timers for starting the spinners (to avoid jitter) - this.spinTimerDone = [] // array of pages where the spinner has activated - return (this.jobs = 0) + resetState() { + this.renderQueue = [] + if (this.queueTimer != null) { + clearTimeout(this.queueTimer) } - - getNumPages() { - return this.document.then(pdfDocument => pdfDocument.numPages) + // clear any existing timers, render tasks + for (let timer of Array.from(this.spinTimer || [])) { + clearTimeout(timer) } - - getPage(pageNum) { - return this.document.then(pdfDocument => - pdfDocument.getPage(pageNum) + for (let page of Array.from(this.pageState || [])) { + __guard__(page != null ? page.loadTask : undefined, x => x.cancel()) + __guard__(page != null ? page.renderTask : undefined, x1 => + x1.cancel() ) } + // initialise/reset the state + this.pageState = [] + this.spinTimer = [] // timers for starting the spinners (to avoid jitter) + this.spinTimerDone = [] // array of pages where the spinner has activated + return (this.jobs = 0) + } - getPdfViewport(pageNum, scale) { - if (scale == null) { - ;({ scale } = this) - } - return this.document.then(pdfDocument => { - return pdfDocument.getPage(pageNum).then( - function(page) { - let viewport - return (viewport = page.getViewport(scale)) - }, - error => { - return typeof this.errorCallback === 'function' - ? this.errorCallback(error) - : undefined - } - ) - }) + getNumPages() { + return this.document.then(pdfDocument => pdfDocument.numPages) + } + + getPage(pageNum) { + return this.document.then(pdfDocument => pdfDocument.getPage(pageNum)) + } + + getPdfViewport(pageNum, scale) { + if (scale == null) { + ;({ scale } = this) } - - getDestinations() { - return this.document.then(pdfDocument => - pdfDocument.getDestinations() - ) - } - - getDestination(dest) { - return this.document.then( - pdfDocument => pdfDocument.getDestination(dest), + return this.document.then(pdfDocument => { + return pdfDocument.getPage(pageNum).then( + function(page) { + let viewport + return (viewport = page.getViewport(scale)) + }, error => { return typeof this.errorCallback === 'function' ? this.errorCallback(error) : undefined } ) - } + }) + } - getPageIndex(ref) { - return this.document.then(pdfDocument => { - return pdfDocument.getPageIndex(ref).then( - idx => idx, - error => { - return typeof this.errorCallback === 'function' - ? this.errorCallback(error) - : undefined - } - ) - }) - } + getDestinations() { + return this.document.then(pdfDocument => + pdfDocument.getDestinations() + ) + } - getScale() { - return this.scale - } - - setScale(scale) { - this.scale = scale - return this.resetState() - } - - triggerRenderQueue(interval) { - if (interval == null) { - interval = this.JOB_QUEUE_INTERVAL + getDestination(dest) { + return this.document.then( + pdfDocument => pdfDocument.getDestination(dest), + error => { + return typeof this.errorCallback === 'function' + ? this.errorCallback(error) + : undefined } - if (this.queueTimer != null) { - clearTimeout(this.queueTimer) - } - return (this.queueTimer = setTimeout(() => { - this.queueTimer = null - return this.processRenderQueue() - }, interval)) - } + ) + } - removeCompletedJob(pagenum) { - this.jobs = this.jobs - 1 - return this.triggerRenderQueue(0) - } + getPageIndex(ref) { + return this.document.then(pdfDocument => { + return pdfDocument.getPageIndex(ref).then( + idx => idx, + error => { + return typeof this.errorCallback === 'function' + ? this.errorCallback(error) + : undefined + } + ) + }) + } - renderPages(pages) { - if (this.shuttingDown) { - return - } - this.renderQueue = Array.from(pages).map(page => ({ - element: page.elementChildren, - pagenum: page.pageNum - })) - return this.triggerRenderQueue() - } + getScale() { + return this.scale + } - renderPage(page) { - if (this.shuttingDown) { - return - } - const current = { - element: page.elementChildren, - pagenum: page.pageNum - } - this.renderQueue.push(current) + setScale(scale) { + this.scale = scale + return this.resetState() + } + + triggerRenderQueue(interval) { + if (interval == null) { + interval = this.JOB_QUEUE_INTERVAL + } + if (this.queueTimer != null) { + clearTimeout(this.queueTimer) + } + return (this.queueTimer = setTimeout(() => { + this.queueTimer = null return this.processRenderQueue() + }, interval)) + } + + removeCompletedJob(pagenum) { + this.jobs = this.jobs - 1 + return this.triggerRenderQueue(0) + } + + renderPages(pages) { + if (this.shuttingDown) { + return } + this.renderQueue = Array.from(pages).map(page => ({ + element: page.elementChildren, + pagenum: page.pageNum + })) + return this.triggerRenderQueue() + } - getPageDetails(page) { - return [page.element.canvas, page.pagenum] + renderPage(page) { + if (this.shuttingDown) { + return } + const current = { + element: page.elementChildren, + pagenum: page.pageNum + } + this.renderQueue.push(current) + return this.processRenderQueue() + } - // handle the loading indicators for each page + getPageDetails(page) { + return [page.element.canvas, page.pagenum] + } - startIndicators() { - // make an array of the pages in the queue - this.queuedPages = [] - for (var page of Array.from(this.renderQueue)) { - this.queuedPages[page.pagenum] = true + // handle the loading indicators for each page + + startIndicators() { + // make an array of the pages in the queue + this.queuedPages = [] + for (var page of Array.from(this.renderQueue)) { + this.queuedPages[page.pagenum] = true + } + // clear any unfinished spinner timers on pages that aren't in the queue any more + for (let pagenum in this.spinTimer) { + if (!this.queuedPages[pagenum]) { + clearTimeout(this.spinTimer[pagenum]) + delete this.spinTimer[pagenum] } - // clear any unfinished spinner timers on pages that aren't in the queue any more - for (let pagenum in this.spinTimer) { - if (!this.queuedPages[pagenum]) { - clearTimeout(this.spinTimer[pagenum]) - delete this.spinTimer[pagenum] + } + // add indicators for any new pages in the current queue + return (() => { + const result = [] + for (page of Array.from(this.renderQueue)) { + if ( + !this.spinTimer[page.pagenum] && + !this.spinTimerDone[page.pagenum] + ) { + result.push(this.startIndicator(page)) } } - // add indicators for any new pages in the current queue - return (() => { - const result = [] - for (page of Array.from(this.renderQueue)) { - if ( - !this.spinTimer[page.pagenum] && - !this.spinTimerDone[page.pagenum] - ) { - result.push(this.startIndicator(page)) - } - } - return result - })() - } + return result + })() + } - startIndicator(page) { - const [canvas, pagenum] = Array.from(this.getPageDetails(page)) - canvas.addClass('pdfng-loading') + startIndicator(page) { + const [canvas, pagenum] = Array.from(this.getPageDetails(page)) + canvas.addClass('pdfng-loading') + return (this.spinTimer[pagenum] = setTimeout(() => { + for (let queuedPage of Array.from(this.renderQueue)) { + if (pagenum === queuedPage.pagenum) { + this.spinner.add(canvas, { static: true }) + this.spinTimerDone[pagenum] = true + break + } + } + return delete this.spinTimer[pagenum] + }, this.INDICATOR_DELAY1)) + } + + updateIndicator(page) { + const [canvas, pagenum] = Array.from(this.getPageDetails(page)) + // did the spinner insert itself already? + if (this.spinTimerDone[pagenum]) { return (this.spinTimer[pagenum] = setTimeout(() => { - for (let queuedPage of Array.from(this.renderQueue)) { - if (pagenum === queuedPage.pagenum) { - this.spinner.add(canvas, { static: true }) - this.spinTimerDone[pagenum] = true - break - } - } + this.spinner.start(canvas) return delete this.spinTimer[pagenum] - }, this.INDICATOR_DELAY1)) - } - - updateIndicator(page) { - const [canvas, pagenum] = Array.from(this.getPageDetails(page)) - // did the spinner insert itself already? - if (this.spinTimerDone[pagenum]) { + }, this.INDICATOR_DELAY2)) + } else { + // stop the existing spin timer + clearTimeout(this.spinTimer[pagenum]) + // start a new one which will also start spinning + return (this.spinTimer[pagenum] = setTimeout(() => { + this.spinner.add(canvas, { static: true }) + this.spinTimerDone[pagenum] = true return (this.spinTimer[pagenum] = setTimeout(() => { this.spinner.start(canvas) return delete this.spinTimer[pagenum] }, this.INDICATOR_DELAY2)) - } else { - // stop the existing spin timer - clearTimeout(this.spinTimer[pagenum]) - // start a new one which will also start spinning - return (this.spinTimer[pagenum] = setTimeout(() => { - this.spinner.add(canvas, { static: true }) - this.spinTimerDone[pagenum] = true - return (this.spinTimer[pagenum] = setTimeout(() => { - this.spinner.start(canvas) - return delete this.spinTimer[pagenum] - }, this.INDICATOR_DELAY2)) - }, this.INDICATOR_DELAY1)) - } + }, this.INDICATOR_DELAY1)) + } + } + + clearIndicator(page) { + const [canvas, pagenum] = Array.from(this.getPageDetails(page)) + this.spinner.stop(canvas) + clearTimeout(this.spinTimer[pagenum]) + delete this.spinTimer[pagenum] + return (this.spinTimerDone[pagenum] = true) + } + + // handle the queue of pages to be rendered + + processRenderQueue() { + let pageState + if (this.shuttingDown) { + return + } + // mark all pages in the queue as loading + this.startIndicators() + // bail out if there is already a render job running + if (this.jobs > 0) { + return + } + // take the first page in the queue + let page = this.renderQueue.shift() + // check if it is in action already + while (page != null && this.pageState[page.pagenum] != null) { + page = this.renderQueue.shift() + } + if (page == null) { + return + } + const [element, pagenum] = Array.from([page.element, page.pagenum]) + this.jobs = this.jobs + 1 + + // update the spinner to make it spinning (signifies loading has begun) + this.updateIndicator(page) + + let timedOut = false + const timer = $timeout(() => { + // page load timed out + if (loadTask.cancelled) { + return + } // return from cancelled page load + __guardMethod__(window.Raven, 'captureMessage', o => + o.captureMessage( + `pdfng page load timed out after ${this.PAGE_LOAD_TIMEOUT}ms` + ) + ) + timedOut = true + this.clearIndicator(page) + // @jobs = @jobs - 1 + // @triggerRenderQueue(0) + return typeof this.errorCallback === 'function' + ? this.errorCallback('timeout') + : undefined + }, this.PAGE_LOAD_TIMEOUT) + + var loadTask = this.getPage(pagenum) + + loadTask.cancel = function() { + return (this.cancelled = true) } - clearIndicator(page) { - const [canvas, pagenum] = Array.from(this.getPageDetails(page)) - this.spinner.stop(canvas) - clearTimeout(this.spinTimer[pagenum]) - delete this.spinTimer[pagenum] - return (this.spinTimerDone[pagenum] = true) - } + this.pageState[pagenum] = pageState = { loadTask } - // handle the queue of pages to be rendered - - processRenderQueue() { - let pageState - if (this.shuttingDown) { - return - } - // mark all pages in the queue as loading - this.startIndicators() - // bail out if there is already a render job running - if (this.jobs > 0) { - return - } - // take the first page in the queue - let page = this.renderQueue.shift() - // check if it is in action already - while (page != null && this.pageState[page.pagenum] != null) { - page = this.renderQueue.shift() - } - if (page == null) { - return - } - const [element, pagenum] = Array.from([page.element, page.pagenum]) - this.jobs = this.jobs + 1 - - // update the spinner to make it spinning (signifies loading has begun) - this.updateIndicator(page) - - let timedOut = false - const timer = $timeout(() => { - // page load timed out + return loadTask + .then(pageObject => { + // page load success + $timeout.cancel(timer) if (loadTask.cancelled) { return } // return from cancelled page load - __guardMethod__(window.Raven, 'captureMessage', o => - o.captureMessage( - `pdfng page load timed out after ${this.PAGE_LOAD_TIMEOUT}ms` - ) + pageState.renderTask = this.doRender(element, pagenum, pageObject) + return pageState.renderTask.then( + () => { + // render task success + this.clearIndicator(page) + pageState.complete = true + delete pageState.renderTask + return this.removeCompletedJob(pagenum) + }, + () => { + // render task failed + // could display an error icon + pageState.complete = false + delete pageState.renderTask + return this.removeCompletedJob(pagenum) + } ) - timedOut = true - this.clearIndicator(page) - // @jobs = @jobs - 1 - // @triggerRenderQueue(0) - return typeof this.errorCallback === 'function' - ? this.errorCallback('timeout') - : undefined - }, this.PAGE_LOAD_TIMEOUT) + }) + .catch(error => { + // page load error + $timeout.cancel(timer) + return this.clearIndicator(page) + }) + } - var loadTask = this.getPage(pagenum) + doRender(element, pagenum, page) { + const self = this + const { scale } = this - loadTask.cancel = function() { - return (this.cancelled = true) - } - - this.pageState[pagenum] = pageState = { loadTask } - - return loadTask - .then(pageObject => { - // page load success - $timeout.cancel(timer) - if (loadTask.cancelled) { - return - } // return from cancelled page load - pageState.renderTask = this.doRender( - element, - pagenum, - pageObject - ) - return pageState.renderTask.then( - () => { - // render task success - this.clearIndicator(page) - pageState.complete = true - delete pageState.renderTask - return this.removeCompletedJob(pagenum) - }, - () => { - // render task failed - // could display an error icon - pageState.complete = false - delete pageState.renderTask - return this.removeCompletedJob(pagenum) - } - ) - }) - .catch(error => { - // page load error - $timeout.cancel(timer) - return this.clearIndicator(page) - }) + if (scale == null) { + // scale is undefined, returning + return } - doRender(element, pagenum, page) { - const self = this - const { scale } = this + const canvas = $( + '' + ) + // In Windows+IE we must have the canvas in the DOM during + // rendering to see the fonts defined in the DOM. If we try to + // render 'offscreen' then all the text will be sans-serif. + // Previously we rendered offscreen and added in the canvas + // when rendering was complete. + element.canvas.replaceWith(canvas) - if (scale == null) { - // scale is undefined, returning - return + const viewport = page.getViewport(scale) + + const devicePixelRatio = window.devicePixelRatio || 1 + + const ctx = canvas[0].getContext('2d') + const backingStoreRatio = + ctx.webkitBackingStorePixelRatio || + ctx.mozBackingStorePixelRatio || + ctx.msBackingStorePixelRatio || + ctx.oBackingStorePixelRatio || + ctx.backingStorePixelRatio || + 1 + const pixelRatio = devicePixelRatio / backingStoreRatio + + const scaledWidth = (Math.floor(viewport.width) * pixelRatio) | 0 + const scaledHeight = (Math.floor(viewport.height) * pixelRatio) | 0 + + const newWidth = Math.floor(viewport.width) + const newHeight = Math.floor(viewport.height) + + canvas[0].height = scaledHeight + canvas[0].width = scaledWidth + + canvas.height(newHeight + 'px') + canvas.width(newWidth + 'px') + + const oldHeight = element.canvas.height() + const oldWidth = element.canvas.width() + if (newHeight !== oldHeight || newWidth !== oldWidth) { + element.canvas.height(newHeight + 'px') + element.canvas.width(newWidth + 'px') + element.container.height(newHeight + 'px') + element.container.width(newWidth + 'px') + if (typeof this.pageSizeChangeCallback === 'function') { + this.pageSizeChangeCallback(pagenum, newHeight - oldHeight) } + } - const canvas = $( - '' - ) - // In Windows+IE we must have the canvas in the DOM during - // rendering to see the fonts defined in the DOM. If we try to - // render 'offscreen' then all the text will be sans-serif. - // Previously we rendered offscreen and added in the canvas - // when rendering was complete. - element.canvas.replaceWith(canvas) + const textLayer = new pdfTextLayer({ + textLayerDiv: element.text[0], + viewport, + renderer: PDFJS.renderTextLayer + }) - const viewport = page.getViewport(scale) + const annotationsLayer = new pdfAnnotations({ + annotations: element.annotations[0], + viewport, + navigateFn: this.navigateFn + }) - const devicePixelRatio = window.devicePixelRatio || 1 + const result = page.render({ + canvasContext: ctx, + viewport, + transform: [pixelRatio, 0, 0, pixelRatio, 0, 0] + }) - const ctx = canvas[0].getContext('2d') - const backingStoreRatio = - ctx.webkitBackingStorePixelRatio || - ctx.mozBackingStorePixelRatio || - ctx.msBackingStorePixelRatio || - ctx.oBackingStorePixelRatio || - ctx.backingStorePixelRatio || - 1 - const pixelRatio = devicePixelRatio / backingStoreRatio + const textLayerTimeout = this.TEXTLAYER_TIMEOUT - const scaledWidth = (Math.floor(viewport.width) * pixelRatio) | 0 - const scaledHeight = (Math.floor(viewport.height) * pixelRatio) | 0 - - const newWidth = Math.floor(viewport.width) - const newHeight = Math.floor(viewport.height) - - canvas[0].height = scaledHeight - canvas[0].width = scaledWidth - - canvas.height(newHeight + 'px') - canvas.width(newWidth + 'px') - - const oldHeight = element.canvas.height() - const oldWidth = element.canvas.width() - if (newHeight !== oldHeight || newWidth !== oldWidth) { - element.canvas.height(newHeight + 'px') - element.canvas.width(newWidth + 'px') - element.container.height(newHeight + 'px') - element.container.width(newWidth + 'px') - if (typeof this.pageSizeChangeCallback === 'function') { - this.pageSizeChangeCallback(pagenum, newHeight - oldHeight) - } - } - - const textLayer = new pdfTextLayer({ - textLayerDiv: element.text[0], - viewport, - renderer: PDFJS.renderTextLayer - }) - - const annotationsLayer = new pdfAnnotations({ - annotations: element.annotations[0], - viewport, - navigateFn: this.navigateFn - }) - - const result = page.render({ - canvasContext: ctx, - viewport, - transform: [pixelRatio, 0, 0, pixelRatio, 0, 0] - }) - - const textLayerTimeout = this.TEXTLAYER_TIMEOUT - - result - .then(function() { - // page render success - canvas.removeClass('pdfng-rendering') - page.getTextContent({ normalizeWhitespace: true }).then( - function(textContent) { - textLayer.setTextContent(textContent) - return textLayer.render(textLayerTimeout) - }, + result + .then(function() { + // page render success + canvas.removeClass('pdfng-rendering') + page.getTextContent({ normalizeWhitespace: true }).then( + function(textContent) { + textLayer.setTextContent(textContent) + return textLayer.render(textLayerTimeout) + }, + error => + typeof self.errorCallback === 'function' + ? self.errorCallback(error) + : undefined + ) + return page + .getAnnotations() + .then( + annotations => annotationsLayer.setAnnotations(annotations), error => typeof self.errorCallback === 'function' ? self.errorCallback(error) : undefined ) - return page - .getAnnotations() - .then( - annotations => annotationsLayer.setAnnotations(annotations), - error => - typeof self.errorCallback === 'function' - ? self.errorCallback(error) - : undefined - ) - }) - .catch(function(error) { - // page render failed - if (error.name === 'RenderingCancelledException') { - // do nothing when cancelled - } else { - return typeof self.errorCallback === 'function' - ? self.errorCallback(error) - : undefined - } - }) - - return result - } - - destroy() { - this.shuttingDown = true - this.resetState() - return this.pdfjs.then(function(document) { - document.cleanup() - return document.destroy() }) - } + .catch(function(error) { + // page render failed + if (error.name === 'RenderingCancelledException') { + // do nothing when cancelled + } else { + return typeof self.errorCallback === 'function' + ? self.errorCallback(error) + : undefined + } + }) + + return result } - PDFRenderer.initClass() - return PDFRenderer - })()) - } - ])) + + destroy() { + this.shuttingDown = true + this.resetState() + return this.pdfjs.then(function(document) { + document.cleanup() + return document.destroy() + }) + } + } + PDFRenderer.initClass() + return PDFRenderer + })()) + })) function __guard__(value, transform) { return typeof value !== 'undefined' && value !== null diff --git a/services/web/public/src/ide/pdfng/directives/pdfSpinner.js b/services/web/public/src/ide/pdfng/directives/pdfSpinner.js index 1d88a68a00..b8272a8117 100644 --- a/services/web/public/src/ide/pdfng/directives/pdfSpinner.js +++ b/services/web/public/src/ide/pdfng/directives/pdfSpinner.js @@ -13,35 +13,33 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.factory('pdfSpinner', [ - function() { - let pdfSpinner - return (pdfSpinner = class pdfSpinner { - constructor() {} - // handler for spinners + App.factory('pdfSpinner', function() { + let pdfSpinner + return (pdfSpinner = class pdfSpinner { + constructor() {} + // handler for spinners - add(element, options) { - const size = 64 - const spinner = $( - `
` - ) - spinner.css({ 'font-size': size + 'px' }) - return element.append(spinner) - } + add(element, options) { + const size = 64 + const spinner = $( + `
` + ) + spinner.css({ 'font-size': size + 'px' }) + return element.append(spinner) + } - start(element) { - return element.find('.fa-spinner').addClass('fa-spin') - } + start(element) { + return element.find('.fa-spinner').addClass('fa-spin') + } - stop(element) { - return element.find('.fa-spinner').removeClass('fa-spin') - } + stop(element) { + return element.find('.fa-spinner').removeClass('fa-spin') + } - remove(element) { - return element.find('.fa-spinner').remove() - } - }) - } - ])) + remove(element) { + return element.find('.fa-spinner').remove() + } + }) + })) diff --git a/services/web/public/src/ide/pdfng/directives/pdfTextLayer.js b/services/web/public/src/ide/pdfng/directives/pdfTextLayer.js index 8924588f35..b48ccf63a7 100644 --- a/services/web/public/src/ide/pdfng/directives/pdfTextLayer.js +++ b/services/web/public/src/ide/pdfng/directives/pdfTextLayer.js @@ -16,65 +16,63 @@ define(['base'], App => // uses the PDFJS text layer renderer to provide invisible overlayed // text for searching - App.factory('pdfTextLayer', [ - function() { - let pdfTextLayer - return (pdfTextLayer = class pdfTextLayer { - constructor(options) { - this.textLayerDiv = options.textLayerDiv - this.divContentDone = false - this.viewport = options.viewport - this.textDivs = [] - this.renderer = options.renderer - this.renderingDone = false + App.factory('pdfTextLayer', function() { + let pdfTextLayer + return (pdfTextLayer = class pdfTextLayer { + constructor(options) { + this.textLayerDiv = options.textLayerDiv + this.divContentDone = false + this.viewport = options.viewport + this.textDivs = [] + this.renderer = options.renderer + this.renderingDone = false + } + + render(timeout) { + if (this.renderingDone || !this.divContentDone) { + return } - render(timeout) { - if (this.renderingDone || !this.divContentDone) { - return - } - - if (this.textLayerRenderTask != null) { - this.textLayerRenderTask.cancel() - this.textLayerRenderTask = null - } - - this.textDivs = [] - const textLayerFrag = document.createDocumentFragment() - - this.textLayerRenderTask = this.renderer({ - textContent: this.textContent, - container: textLayerFrag, - viewport: this.viewport, - textDivs: this.textDivs, - timeout, - enhanceTextSelection: this.enhanceTextSelection - }) - - const textLayerSuccess = () => { - this.textLayerDiv.appendChild(textLayerFrag) - return (this.renderingDone = true) - } - - const textLayerFailure = function() { - // canceled or failed to render text layer -- skipping errors - } - - return this.textLayerRenderTask.promise.then( - textLayerSuccess, - textLayerFailure - ) + if (this.textLayerRenderTask != null) { + this.textLayerRenderTask.cancel() + this.textLayerRenderTask = null } - setTextContent(textContent) { - if (this.textLayerRenderTask) { - this.textLayerRenderTask.cancel() - this.textLayerRenderTask = null - } + this.textDivs = [] + const textLayerFrag = document.createDocumentFragment() - this.textContent = textContent - return (this.divContentDone = true) + this.textLayerRenderTask = this.renderer({ + textContent: this.textContent, + container: textLayerFrag, + viewport: this.viewport, + textDivs: this.textDivs, + timeout, + enhanceTextSelection: this.enhanceTextSelection + }) + + const textLayerSuccess = () => { + this.textLayerDiv.appendChild(textLayerFrag) + return (this.renderingDone = true) } - }) - } - ])) + + const textLayerFailure = function() { + // canceled or failed to render text layer -- skipping errors + } + + return this.textLayerRenderTask.promise.then( + textLayerSuccess, + textLayerFailure + ) + } + + setTextContent(textContent) { + if (this.textLayerRenderTask) { + this.textLayerRenderTask.cancel() + this.textLayerRenderTask = null + } + + this.textContent = textContent + return (this.divContentDone = true) + } + }) + })) diff --git a/services/web/public/src/ide/pdfng/directives/pdfViewer.js b/services/web/public/src/ide/pdfng/directives/pdfViewer.js index eae287b807..01edb8f29e 100644 --- a/services/web/public/src/ide/pdfng/directives/pdfViewer.js +++ b/services/web/public/src/ide/pdfng/directives/pdfViewer.js @@ -38,633 +38,488 @@ define([ ) { // App = angular.module 'pdfViewerApp', ['pdfPage', 'PDFRenderer', 'pdfHighlights'] - App.controller('pdfViewerController', [ - '$scope', - '$q', - '$timeout', - 'PDFRenderer', - '$element', - 'pdfHighlights', - 'pdfSpinner', - function( - $scope, - $q, - $timeout, - PDFRenderer, - $element, - pdfHighlights, - pdfSpinner - ) { - this.load = function() { - // $scope.pages = [] + App.controller('pdfViewerController', function( + $scope, + $q, + $timeout, + PDFRenderer, + $element, + pdfHighlights, + pdfSpinner + ) { + this.load = function() { + // $scope.pages = [] - if ($scope.document != null) { - $scope.document.destroy() - } - $scope.loadCount = $scope.loadCount != null ? $scope.loadCount + 1 : 1 - // TODO need a proper url manipulation library to add to query string - let url = $scope.pdfSrc - // add 'pdfng=true' to show that we are using the angular pdfjs viewer - const queryStringExists = /\?/.test(url) - url = url + (!queryStringExists ? '?' : '&') + 'pdfng=true' - // for isolated compiles, load the pdf on-demand because nobody will overwrite it - const onDemandLoading = true - $scope.document = new PDFRenderer(url, { - scale: 1, - disableAutoFetch: onDemandLoading ? true : undefined, - navigateFn(ref) { - // this function captures clicks on the annotation links - $scope.navigateTo = ref - return $scope.$apply() - }, - progressCallback(progress) { - return $scope.$emit('progress', progress) - }, - loadedCallback() { - return $scope.$emit('loaded') - }, - errorCallback(error) { - __guardMethod__(window.Raven, 'captureMessage', o => - o.captureMessage(`pdfng error ${error}`) - ) - return $scope.$emit('pdf:error', error) - }, - pageSizeChangeCallback(pageNum, deltaH) { - return $scope.$broadcast('pdf:page:size-change', pageNum, deltaH) - } - }) - - // we will have all the main information needed to start display - // after the following promise is resolved - return ($scope.loaded = $q - .all({ - numPages: $scope.document.getNumPages(), - // get size of first page as default @ scale 1 - pdfViewport: $scope.document.getPdfViewport(1, 1) - }) - .then(function(result) { - $scope.pdfViewport = result.pdfViewport - $scope.pdfPageSize = [ - result.pdfViewport.height, - result.pdfViewport.width - ] - // console.log 'resolved q.all, page size is', result - $scope.$emit('loaded') - return ($scope.numPages = result.numPages) - }) - .catch(function(error) { - $scope.$emit('pdf:error', error) - return $q.reject(error) - })) + if ($scope.document != null) { + $scope.document.destroy() } + $scope.loadCount = $scope.loadCount != null ? $scope.loadCount + 1 : 1 + // TODO need a proper url manipulation library to add to query string + let url = $scope.pdfSrc + // add 'pdfng=true' to show that we are using the angular pdfjs viewer + const queryStringExists = /\?/.test(url) + url = url + (!queryStringExists ? '?' : '&') + 'pdfng=true' + // for isolated compiles, load the pdf on-demand because nobody will overwrite it + const onDemandLoading = true + $scope.document = new PDFRenderer(url, { + scale: 1, + disableAutoFetch: onDemandLoading ? true : undefined, + navigateFn(ref) { + // this function captures clicks on the annotation links + $scope.navigateTo = ref + return $scope.$apply() + }, + progressCallback(progress) { + return $scope.$emit('progress', progress) + }, + loadedCallback() { + return $scope.$emit('loaded') + }, + errorCallback(error) { + __guardMethod__(window.Raven, 'captureMessage', o => + o.captureMessage(`pdfng error ${error}`) + ) + return $scope.$emit('pdf:error', error) + }, + pageSizeChangeCallback(pageNum, deltaH) { + return $scope.$broadcast('pdf:page:size-change', pageNum, deltaH) + } + }) - this.setScale = (scale, containerHeight, containerWidth) => - $scope.loaded - .then(function() { - let numScale - if (scale == null) { - scale = {} - } - if (containerHeight === 0 || containerWidth === 0) { - numScale = 1 - } else if (scale.scaleMode === 'scale_mode_fit_width') { - // TODO make this dynamic - numScale = (containerWidth - 40) / $scope.pdfPageSize[1] - } else if (scale.scaleMode === 'scale_mode_fit_height') { - // TODO magic numbers for jquery ui layout - numScale = (containerHeight - 20) / $scope.pdfPageSize[0] - } else if (scale.scaleMode === 'scale_mode_value') { - numScale = scale.scale - } else if (scale.scaleMode === 'scale_mode_auto') { - // TODO - } else { - scale.scaleMode = 'scale_mode_fit_width' - numScale = (containerWidth - 40) / $scope.pdfPageSize[1] - } - // TODO - $scope.scale.scale = numScale - $scope.document.setScale(numScale) - return ($scope.defaultPageSize = [ - numScale * $scope.pdfPageSize[0], - numScale * $scope.pdfPageSize[1] - ]) - }) - // console.log 'in setScale result', $scope.scale.scale, $scope.defaultPageSize - .catch(function(error) { - $scope.$emit('pdf:error', error) - return $q.reject(error) - }) - - this.redraw = function(position) { - // console.log 'in redraw' - // console.log 'reseting pages array for', $scope.numPages - $scope.pages = __range__(0, $scope.numPages - 1, true).map(i => ({ - pageNum: i + 1 + // we will have all the main information needed to start display + // after the following promise is resolved + return ($scope.loaded = $q + .all({ + numPages: $scope.document.getNumPages(), + // get size of first page as default @ scale 1 + pdfViewport: $scope.document.getPdfViewport(1, 1) + }) + .then(function(result) { + $scope.pdfViewport = result.pdfViewport + $scope.pdfPageSize = [ + result.pdfViewport.height, + result.pdfViewport.width + ] + // console.log 'resolved q.all, page size is', result + $scope.$emit('loaded') + return ($scope.numPages = result.numPages) + }) + .catch(function(error) { + $scope.$emit('pdf:error', error) + return $q.reject(error) })) - if (position != null && position.page != null) { - // console.log 'position is', position.page, position.offset - // console.log 'setting current page', position.page - let pagenum = position.page - if (pagenum > $scope.numPages - 1) { - pagenum = $scope.numPages - 1 - } - $scope.pages[pagenum].current = true - return ($scope.pages[pagenum].position = position) - } - } - - this.zoomIn = function() { - // console.log 'zoom in' - const newScale = $scope.scale.scale * 1.2 - return ($scope.forceScale = { - scaleMode: 'scale_mode_value', - scale: newScale - }) - } - - this.zoomOut = function() { - // console.log 'zoom out' - const newScale = $scope.scale.scale / 1.2 - return ($scope.forceScale = { - scaleMode: 'scale_mode_value', - scale: newScale - }) - } - - this.fitWidth = () => - // console.log 'fit width' - ($scope.forceScale = { scaleMode: 'scale_mode_fit_width' }) - - this.fitHeight = () => - // console.log 'fit height' - ($scope.forceScale = { scaleMode: 'scale_mode_fit_height' }) - - this.checkPosition = () => - // console.log 'check position' - ($scope.forceCheck = ($scope.forceCheck || 0) + 1) - - this.showRandomHighlights = () => - // console.log 'show highlights' - ($scope.highlights = [ - { - page: 3, - h: 100, - v: 100, - height: 30, - width: 200 - } - ]) - - // we work with (pagenumber, % of height down page from top) - // pdfListView works with (pagenumber, vertical position up page from - // bottom measured in pts) - - this.getPdfPosition = function() { - // console.log 'in getPdfPosition' - let canvasOffset, pdfOffset, viewport - let topPageIdx = 0 - let topPage = $scope.pages[0] - // find first visible page - const visible = $scope.pages.some(function(page, i) { - if (page.visible) { - let ref - return ([topPageIdx, topPage] = Array.from((ref = [i, page]))), ref - } - }) - if (visible && topPage.element != null) { - // console.log 'found it', topPageIdx - } else { - // console.log 'CANNOT FIND TOP PAGE' - return - } - - // console.log 'top page is', topPage.pageNum, topPage.elemTop, topPage.elemBottom, topPage - const { top } = topPage.element.offset() - const bottom = top + topPage.element.innerHeight() - const viewportTop = $element.offset().top - const viewportBottom = viewportTop + $element.height() - const topVisible = top >= viewportTop && top < viewportBottom - const someContentVisible = top < viewportTop && bottom > viewportTop - // console.log 'in PdfListView', top, topVisible, someContentVisible, viewportTop - if (topVisible) { - canvasOffset = 0 - } else if (someContentVisible) { - canvasOffset = viewportTop - top - } else { - canvasOffset = null - } - // console.log 'pdfListview position = ', canvasOffset - // instead of using promise, check if size is known and revert to - // default otherwise - // console.log 'looking up viewport', topPage.viewport, $scope.pdfViewport - if (topPage.viewport) { - ;({ viewport } = topPage) - pdfOffset = viewport.convertToPdfPoint(0, canvasOffset) - } else { - // console.log 'WARNING: had to default to global page size' - viewport = $scope.pdfViewport - const scaledOffset = canvasOffset / $scope.scale.scale - pdfOffset = viewport.convertToPdfPoint(0, scaledOffset) - } - // console.log 'converted to offset = ', pdfOffset - const newPosition = { - page: topPageIdx, - offset: { top: pdfOffset[1], left: 0 }, - pageSize: { height: viewport.viewBox[3], width: viewport.viewBox[2] } - } - return newPosition - } - - this.computeOffset = function(page, position) { - // console.log 'computing offset for', page, position - const { element } = page - // console.log 'element =', $(element), 'parent =', $(element).parent() - const t1 = __guard__($(element).offset(), x => x.top) - const t2 = __guard__( - $(element) - .parent() - .offset(), - x1 => x1.top - ) - if (!(t1 != null && t2 != null)) { - return $q((resolve, reject) => reject('elements destroyed')) - } - const pageTop = - $(element).offset().top - - $(element) - .parent() - .offset().top - // console.log('top of page scroll is', pageTop, 'vs', page.elemTop) - // console.log('inner height is', $(element).innerHeight()) - const currentScroll = $(element) - .parent() - .scrollTop() - const { offset } = position - // convert offset to pixels - return $scope.document - .getPdfViewport(page.pageNum) - .then(function(viewport) { - page.viewport = viewport - const pageOffset = viewport.convertToViewportPoint( - offset.left, - offset.top - ) - // if the passed-in position doesn't have the page height/width add them now - if (position.pageSize == null) { - position.pageSize = { - height: viewport.viewBox[3], - width: viewport.viewBox[2] - } - } - // console.log 'addition offset =', pageOffset - // console.log 'total', pageTop + pageOffset[1] - return Math.round(pageTop + pageOffset[1] + currentScroll) - }) // # 10 is margin - } - - this.setPdfPosition = function(page, position) { - // console.log 'required pdf Position is', position - return this.computeOffset(page, position).then(function(offset) { - $scope.pleaseScrollTo = offset - return ($scope.position = position) - }) - } - - return this } - ]) - return App.directive('pdfViewer', [ - '$q', - '$timeout', - 'pdfSpinner', - ($q, $timeout, pdfSpinner) => ({ - controller: 'pdfViewerController', - controllerAs: 'ctrl', - scope: { - pdfSrc: '=', - highlights: '=', - position: '=', - scale: '=', - pleaseJumpTo: '=' - }, - template: `\ + this.setScale = (scale, containerHeight, containerWidth) => + $scope.loaded + .then(function() { + let numScale + if (scale == null) { + scale = {} + } + if (containerHeight === 0 || containerWidth === 0) { + numScale = 1 + } else if (scale.scaleMode === 'scale_mode_fit_width') { + // TODO make this dynamic + numScale = (containerWidth - 40) / $scope.pdfPageSize[1] + } else if (scale.scaleMode === 'scale_mode_fit_height') { + // TODO magic numbers for jquery ui layout + numScale = (containerHeight - 20) / $scope.pdfPageSize[0] + } else if (scale.scaleMode === 'scale_mode_value') { + numScale = scale.scale + } else if (scale.scaleMode === 'scale_mode_auto') { + // TODO + } else { + scale.scaleMode = 'scale_mode_fit_width' + numScale = (containerWidth - 40) / $scope.pdfPageSize[1] + } + // TODO + $scope.scale.scale = numScale + $scope.document.setScale(numScale) + return ($scope.defaultPageSize = [ + numScale * $scope.pdfPageSize[0], + numScale * $scope.pdfPageSize[1] + ]) + }) + // console.log 'in setScale result', $scope.scale.scale, $scope.defaultPageSize + .catch(function(error) { + $scope.$emit('pdf:error', error) + return $q.reject(error) + }) + + this.redraw = function(position) { + // console.log 'in redraw' + // console.log 'reseting pages array for', $scope.numPages + $scope.pages = __range__(0, $scope.numPages - 1, true).map(i => ({ + pageNum: i + 1 + })) + if (position != null && position.page != null) { + // console.log 'position is', position.page, position.offset + // console.log 'setting current page', position.page + let pagenum = position.page + if (pagenum > $scope.numPages - 1) { + pagenum = $scope.numPages - 1 + } + $scope.pages[pagenum].current = true + return ($scope.pages[pagenum].position = position) + } + } + + this.zoomIn = function() { + // console.log 'zoom in' + const newScale = $scope.scale.scale * 1.2 + return ($scope.forceScale = { + scaleMode: 'scale_mode_value', + scale: newScale + }) + } + + this.zoomOut = function() { + // console.log 'zoom out' + const newScale = $scope.scale.scale / 1.2 + return ($scope.forceScale = { + scaleMode: 'scale_mode_value', + scale: newScale + }) + } + + this.fitWidth = () => + // console.log 'fit width' + ($scope.forceScale = { scaleMode: 'scale_mode_fit_width' }) + + this.fitHeight = () => + // console.log 'fit height' + ($scope.forceScale = { scaleMode: 'scale_mode_fit_height' }) + + this.checkPosition = () => + // console.log 'check position' + ($scope.forceCheck = ($scope.forceCheck || 0) + 1) + + this.showRandomHighlights = () => + // console.log 'show highlights' + ($scope.highlights = [ + { + page: 3, + h: 100, + v: 100, + height: 30, + width: 200 + } + ]) + + // we work with (pagenumber, % of height down page from top) + // pdfListView works with (pagenumber, vertical position up page from + // bottom measured in pts) + + this.getPdfPosition = function() { + // console.log 'in getPdfPosition' + let canvasOffset, pdfOffset, viewport + let topPageIdx = 0 + let topPage = $scope.pages[0] + // find first visible page + const visible = $scope.pages.some(function(page, i) { + if (page.visible) { + let ref + return ([topPageIdx, topPage] = Array.from((ref = [i, page]))), ref + } + }) + if (visible && topPage.element != null) { + // console.log 'found it', topPageIdx + } else { + // console.log 'CANNOT FIND TOP PAGE' + return + } + + // console.log 'top page is', topPage.pageNum, topPage.elemTop, topPage.elemBottom, topPage + const { top } = topPage.element.offset() + const bottom = top + topPage.element.innerHeight() + const viewportTop = $element.offset().top + const viewportBottom = viewportTop + $element.height() + const topVisible = top >= viewportTop && top < viewportBottom + const someContentVisible = top < viewportTop && bottom > viewportTop + // console.log 'in PdfListView', top, topVisible, someContentVisible, viewportTop + if (topVisible) { + canvasOffset = 0 + } else if (someContentVisible) { + canvasOffset = viewportTop - top + } else { + canvasOffset = null + } + // console.log 'pdfListview position = ', canvasOffset + // instead of using promise, check if size is known and revert to + // default otherwise + // console.log 'looking up viewport', topPage.viewport, $scope.pdfViewport + if (topPage.viewport) { + ;({ viewport } = topPage) + pdfOffset = viewport.convertToPdfPoint(0, canvasOffset) + } else { + // console.log 'WARNING: had to default to global page size' + viewport = $scope.pdfViewport + const scaledOffset = canvasOffset / $scope.scale.scale + pdfOffset = viewport.convertToPdfPoint(0, scaledOffset) + } + // console.log 'converted to offset = ', pdfOffset + const newPosition = { + page: topPageIdx, + offset: { top: pdfOffset[1], left: 0 }, + pageSize: { height: viewport.viewBox[3], width: viewport.viewBox[2] } + } + return newPosition + } + + this.computeOffset = function(page, position) { + // console.log 'computing offset for', page, position + const { element } = page + // console.log 'element =', $(element), 'parent =', $(element).parent() + const t1 = __guard__($(element).offset(), x => x.top) + const t2 = __guard__( + $(element) + .parent() + .offset(), + x1 => x1.top + ) + if (!(t1 != null && t2 != null)) { + return $q((resolve, reject) => reject('elements destroyed')) + } + const pageTop = + $(element).offset().top - + $(element) + .parent() + .offset().top + // console.log('top of page scroll is', pageTop, 'vs', page.elemTop) + // console.log('inner height is', $(element).innerHeight()) + const currentScroll = $(element) + .parent() + .scrollTop() + const { offset } = position + // convert offset to pixels + return $scope.document + .getPdfViewport(page.pageNum) + .then(function(viewport) { + page.viewport = viewport + const pageOffset = viewport.convertToViewportPoint( + offset.left, + offset.top + ) + // if the passed-in position doesn't have the page height/width add them now + if (position.pageSize == null) { + position.pageSize = { + height: viewport.viewBox[3], + width: viewport.viewBox[2] + } + } + // console.log 'addition offset =', pageOffset + // console.log 'total', pageTop + pageOffset[1] + return Math.round(pageTop + pageOffset[1] + currentScroll) + }) // # 10 is margin + } + + this.setPdfPosition = function(page, position) { + // console.log 'required pdf Position is', position + return this.computeOffset(page, position).then(function(offset) { + $scope.pleaseScrollTo = offset + return ($scope.position = position) + }) + } + + return this + }) + + return App.directive('pdfViewer', ($q, $timeout, pdfSpinner) => ({ + controller: 'pdfViewerController', + controllerAs: 'ctrl', + scope: { + pdfSrc: '=', + highlights: '=', + position: '=', + scale: '=', + pleaseJumpTo: '=' + }, + template: `\
\ `, - link(scope, element, attrs, ctrl) { - // console.log 'in pdfViewer element is', element - // console.log 'attrs', attrs - const spinner = new pdfSpinner() - let layoutReady = $q.defer() - layoutReady.notify('waiting for layout') - layoutReady.promise.then(function() {}) - // console.log 'layoutReady was resolved' + link(scope, element, attrs, ctrl) { + // console.log 'in pdfViewer element is', element + // console.log 'attrs', attrs + const spinner = new pdfSpinner() + let layoutReady = $q.defer() + layoutReady.notify('waiting for layout') + layoutReady.promise.then(function() {}) + // console.log 'layoutReady was resolved' - const renderVisiblePages = function() { - const visiblePages = getVisiblePages() - const pages = getExtraPages(visiblePages) - return scope.document.renderPages(pages) - } + const renderVisiblePages = function() { + const visiblePages = getVisiblePages() + const pages = getExtraPages(visiblePages) + return scope.document.renderPages(pages) + } - var getVisiblePages = function() { - const top = element[0].scrollTop - const bottom = top + element[0].clientHeight - const visiblePages = _.filter(scope.pages, function(page) { - if (page.element == null) { - return false - } - const pageElement = page.element[0] - const pageTop = pageElement.offsetTop - const pageBottom = pageTop + pageElement.clientHeight - page.visible = pageTop < bottom && pageBottom > top - return page.visible - }) - return visiblePages - } - - var getExtraPages = function(visiblePages) { - const extra = [] - if (visiblePages.length > 0) { - const firstVisiblePage = visiblePages[0].pageNum - const firstVisiblePageIdx = firstVisiblePage - 1 - const len = visiblePages.length - const lastVisiblePage = visiblePages[len - 1].pageNum - const lastVisiblePageIdx = lastVisiblePage - 1 - // first page after - if (lastVisiblePageIdx + 1 < scope.pages.length) { - extra.push(scope.pages[lastVisiblePageIdx + 1]) - } - // page before - if (firstVisiblePageIdx > 0) { - extra.push(scope.pages[firstVisiblePageIdx - 1]) - } - // second page after - if (lastVisiblePageIdx + 2 < scope.pages.length) { - extra.push(scope.pages[lastVisiblePageIdx + 2]) - } - } - return visiblePages.concat(extra) - } - - let rescaleTimer = null - const queueRescale = function(scale) { - // console.log 'call to queueRescale' - if ( - rescaleTimer != null || - layoutTimer != null || - elementTimer != null - ) { - return - } - // console.log 'adding to rescale queue' - return (rescaleTimer = setTimeout(function() { - doRescale(scale) - return (rescaleTimer = null) - }, 0)) - } - - let spinnerTimer = null - var doRescale = function(scale) { - // console.log 'doRescale', scale - if (scale == null) { - return - } - const origposition = angular.copy(scope.position) - // console.log 'origposition', origposition - - if (spinnerTimer == null) { - spinnerTimer = setTimeout(function() { - spinner.add(element) - return (spinnerTimer = null) - }, 100) - } - return layoutReady.promise.then(function(parentSize) { - const [h, w] = Array.from(parentSize) - // console.log 'in promise', h, w - return ctrl - .setScale(scale, h, w) - .then(() => - // console.log 'in setscale then', scale, h, w - scope.$evalAsync(function() { - if (spinnerTimer) { - clearTimeout(spinnerTimer) - } else { - spinner.remove(element) - } - // stop displaying the text layer - element.removeClass('pdfjs-viewer-show-text') - ctrl.redraw(origposition) - $timeout(renderVisiblePages) - return (scope.loadSuccess = true) - }) - ) - .catch(error => scope.$emit('pdf:error', error)) - }) - } - - var elementTimer = null - var updateLayout = function() { - // if element is zero-sized keep checking until it is ready - // console.log 'checking element ready', element.height(), element.width() - if (element.height() === 0 || element.width() === 0) { - if (elementTimer != null) { - return - } - return (elementTimer = setTimeout(function() { - elementTimer = null - return updateLayout() - }, 1000)) - } else { - scope.parentSize = [element.innerHeight(), element.innerWidth()] - // console.log 'resolving layoutReady with', scope.parentSize - return $timeout(function() { - layoutReady.resolve(scope.parentSize) - return scope.$emit('flash-controls') - }) - } - } - - var layoutTimer = null - const queueLayout = function() { - // console.log 'call to queue layout' - if (layoutTimer != null) { - return - } - // console.log 'added to queue layoyt' - layoutReady = $q.defer() - return (layoutTimer = setTimeout(function() { - // console.log 'calling update layout' - updateLayout() - // console.log 'setting layout timer to null' - return (layoutTimer = null) - }, 0)) - } - - queueLayout() - - // scope.$on 'layout:pdf:view', (e, args) -> - // console.log 'pdf view change', element, e, args - // queueLayout() - - scope.$on('layout:main:resize', () => - // console.log 'GOT LAYOUT-MAIN-RESIZE EVENT' - queueLayout() - ) - - scope.$on('layout:pdf:resize', () => - // FIXME we get this event twice - // also we need to start a new layout when we get it - // console.log 'GOT LAYOUT-PDF-RESIZE EVENT' - queueLayout() - ) - - scope.$on('pdf:error', function(event, error) { - if (error.name === 'RenderingCancelledException') { - return - } - // check if too many retries or file is missing - const message = (error != null ? error.message : undefined) || error - if ( - scope.loadCount > 3 || - /^Missing PDF/i.test(message) || - /^loading/i.test(message) - ) { - scope.$emit('pdf:error:display') - return - } - if (scope.loadSuccess) { - return ctrl - .load() - .then( - () => - // trigger a redraw - (scope.scale = angular.copy(scope.scale)) - ) - .catch(error => scope.$emit('pdf:error:display')) - } else { - scope.$emit('pdf:error:display') - } - }) - - scope.$on('pdf:page:size-change', function(event, pageNum, delta) { - // console.log 'page size change event', pageNum, delta - const origposition = angular.copy(scope.position) - // console.log 'orig position', JSON.stringify(origposition) - if ( - origposition != null && - pageNum - 1 < origposition.page && - delta !== 0 - ) { - const currentScrollTop = element.scrollTop() - // console.log 'adjusting scroll from', currentScrollTop, 'by', delta - scope.adjustingScroll = true - return element.scrollTop(currentScrollTop + delta) - } - }) - - element.on('mousedown', function(e) { - // We're checking that the event target isn't the directive root element - // to make sure that the click was within a PDF page - no point in showing - // the text layer when the click is outside. - // If the user clicks a PDF page, the mousedown target will be the canvas - // element (or the text layer one). Alternatively, if the event target is - // the root element, we can assume that the user has clicked either the - // grey background area or the scrollbars. - if (e.target !== element[0] && !_hasSelection()) { - element.addClass('pdfjs-viewer-show-text') - return _setMouseUpHandler() - } - }) - - let mouseUpHandler = null // keep track of the handler to avoid adding multiple times - - var _setMouseUpHandler = function() { - if (mouseUpHandler == null) { - return (mouseUpHandler = $(document.body).one( - 'mouseup', - _handleSelectionMouseUp - )) - } - } - - var _handleSelectionMouseUp = function() { - mouseUpHandler = null // reset handler, has now fired - window.setTimeout(function() { - const removedClass = _removeClassIfNoSelection() - // if we still have a selection we need to keep the handler going - if (!removedClass) { - return _setMouseUpHandler() - } - }, 10) - return true - } - - var _removeClassIfNoSelection = function() { - if (_hasSelection()) { - return false // didn't remove the text layer - } else { - element.removeClass('pdfjs-viewer-show-text') - return true - } - } - - var _hasSelection = function() { - const selection = - typeof window.getSelection === 'function' - ? window.getSelection() - : undefined - // check the selection collapsed state in preference to - // using selection.toString() as the latter is "" when - // the selection is hidden (e.g. while viewing logs) - return ( - selection != null && - _isSelectionWithinPDF(selection) && - !selection.isCollapsed - ) - } - - var _isSelectionWithinPDF = function(selection) { - if (selection.rangeCount === 0) { + var getVisiblePages = function() { + const top = element[0].scrollTop + const bottom = top + element[0].clientHeight + const visiblePages = _.filter(scope.pages, function(page) { + if (page.element == null) { return false } - const selectionAncestorNode = selection.getRangeAt(0) - .commonAncestorContainer - return ( - element.find(selectionAncestorNode).length > 0 || - element.is(selectionAncestorNode) - ) - } - - element.on('scroll', function() { - // console.log 'scroll event', element.scrollTop(), 'adjusting?', scope.adjustingScroll - // scope.scrollPosition = element.scrollTop() - if (scope.adjustingScroll) { - renderVisiblePages() - scope.adjustingScroll = false - return - } - if (scope.scrollHandlerTimeout) { - clearTimeout(scope.scrollHandlerTimeout) - } - return (scope.scrollHandlerTimeout = setTimeout(scrollHandler, 25)) + const pageElement = page.element[0] + const pageTop = pageElement.offsetTop + const pageBottom = pageTop + pageElement.clientHeight + page.visible = pageTop < bottom && pageBottom > top + return page.visible }) + return visiblePages + } - var scrollHandler = function() { - renderVisiblePages() - const newPosition = ctrl.getPdfPosition() - if (newPosition != null) { - scope.position = newPosition + var getExtraPages = function(visiblePages) { + const extra = [] + if (visiblePages.length > 0) { + const firstVisiblePage = visiblePages[0].pageNum + const firstVisiblePageIdx = firstVisiblePage - 1 + const len = visiblePages.length + const lastVisiblePage = visiblePages[len - 1].pageNum + const lastVisiblePageIdx = lastVisiblePage - 1 + // first page after + if (lastVisiblePageIdx + 1 < scope.pages.length) { + extra.push(scope.pages[lastVisiblePageIdx + 1]) + } + // page before + if (firstVisiblePageIdx > 0) { + extra.push(scope.pages[firstVisiblePageIdx - 1]) + } + // second page after + if (lastVisiblePageIdx + 2 < scope.pages.length) { + extra.push(scope.pages[lastVisiblePageIdx + 2]) } - return (scope.scrollHandlerTimeout = null) } + return visiblePages.concat(extra) + } - scope.$watch('pdfSrc', function(newVal, oldVal) { - // console.log 'loading pdf', newVal, oldVal - if (newVal == null) { + let rescaleTimer = null + const queueRescale = function(scale) { + // console.log 'call to queueRescale' + if ( + rescaleTimer != null || + layoutTimer != null || + elementTimer != null + ) { + return + } + // console.log 'adding to rescale queue' + return (rescaleTimer = setTimeout(function() { + doRescale(scale) + return (rescaleTimer = null) + }, 0)) + } + + let spinnerTimer = null + var doRescale = function(scale) { + // console.log 'doRescale', scale + if (scale == null) { + return + } + const origposition = angular.copy(scope.position) + // console.log 'origposition', origposition + + if (spinnerTimer == null) { + spinnerTimer = setTimeout(function() { + spinner.add(element) + return (spinnerTimer = null) + }, 100) + } + return layoutReady.promise.then(function(parentSize) { + const [h, w] = Array.from(parentSize) + // console.log 'in promise', h, w + return ctrl + .setScale(scale, h, w) + .then(() => + // console.log 'in setscale then', scale, h, w + scope.$evalAsync(function() { + if (spinnerTimer) { + clearTimeout(spinnerTimer) + } else { + spinner.remove(element) + } + // stop displaying the text layer + element.removeClass('pdfjs-viewer-show-text') + ctrl.redraw(origposition) + $timeout(renderVisiblePages) + return (scope.loadSuccess = true) + }) + ) + .catch(error => scope.$emit('pdf:error', error)) + }) + } + + var elementTimer = null + var updateLayout = function() { + // if element is zero-sized keep checking until it is ready + // console.log 'checking element ready', element.height(), element.width() + if (element.height() === 0 || element.width() === 0) { + if (elementTimer != null) { return } - scope.loadCount = 0 // new pdf, so reset load count - scope.loadSuccess = false + return (elementTimer = setTimeout(function() { + elementTimer = null + return updateLayout() + }, 1000)) + } else { + scope.parentSize = [element.innerHeight(), element.innerWidth()] + // console.log 'resolving layoutReady with', scope.parentSize + return $timeout(function() { + layoutReady.resolve(scope.parentSize) + return scope.$emit('flash-controls') + }) + } + } + + var layoutTimer = null + const queueLayout = function() { + // console.log 'call to queue layout' + if (layoutTimer != null) { + return + } + // console.log 'added to queue layoyt' + layoutReady = $q.defer() + return (layoutTimer = setTimeout(function() { + // console.log 'calling update layout' + updateLayout() + // console.log 'setting layout timer to null' + return (layoutTimer = null) + }, 0)) + } + + queueLayout() + + // scope.$on 'layout:pdf:view', (e, args) -> + // console.log 'pdf view change', element, e, args + // queueLayout() + + scope.$on('layout:main:resize', () => + // console.log 'GOT LAYOUT-MAIN-RESIZE EVENT' + queueLayout() + ) + + scope.$on('layout:pdf:resize', () => + // FIXME we get this event twice + // also we need to start a new layout when we get it + // console.log 'GOT LAYOUT-PDF-RESIZE EVENT' + queueLayout() + ) + + scope.$on('pdf:error', function(event, error) { + if (error.name === 'RenderingCancelledException') { + return + } + // check if too many retries or file is missing + const message = (error != null ? error.message : undefined) || error + if ( + scope.loadCount > 3 || + /^Missing PDF/i.test(message) || + /^loading/i.test(message) + ) { + scope.$emit('pdf:error:display') + return + } + if (scope.loadSuccess) { return ctrl .load() .then( @@ -672,191 +527,320 @@ define([ // trigger a redraw (scope.scale = angular.copy(scope.scale)) ) - .catch(error => scope.$emit('pdf:error', error)) - }) + .catch(error => scope.$emit('pdf:error:display')) + } else { + scope.$emit('pdf:error:display') + } + }) - scope.$watch('scale', function(newVal, oldVal) { - // no need to set scale when initialising, done in pdfSrc - if (newVal === oldVal) { - return - } - // console.log 'XXX calling Setscale in scale watch' - return queueRescale(newVal) - }) + scope.$on('pdf:page:size-change', function(event, pageNum, delta) { + // console.log 'page size change event', pageNum, delta + const origposition = angular.copy(scope.position) + // console.log 'orig position', JSON.stringify(origposition) + if ( + origposition != null && + pageNum - 1 < origposition.page && + delta !== 0 + ) { + const currentScrollTop = element.scrollTop() + // console.log 'adjusting scroll from', currentScrollTop, 'by', delta + scope.adjustingScroll = true + return element.scrollTop(currentScrollTop + delta) + } + }) - scope.$watch('forceScale', function(newVal, oldVal) { - // console.log 'got change in numscale watcher', newVal, oldVal - if (newVal == null) { - return - } - return queueRescale(newVal) - }) + element.on('mousedown', function(e) { + // We're checking that the event target isn't the directive root element + // to make sure that the click was within a PDF page - no point in showing + // the text layer when the click is outside. + // If the user clicks a PDF page, the mousedown target will be the canvas + // element (or the text layer one). Alternatively, if the event target is + // the root element, we can assume that the user has clicked either the + // grey background area or the scrollbars. + if (e.target !== element[0] && !_hasSelection()) { + element.addClass('pdfjs-viewer-show-text') + return _setMouseUpHandler() + } + }) - // scope.$watch 'position', (newVal, oldVal) -> - // console.log 'got change in position watcher', newVal, oldVal + let mouseUpHandler = null // keep track of the handler to avoid adding multiple times - scope.$watch('forceCheck', function(newVal, oldVal) { - // console.log 'forceCheck', newVal, oldVal - if (newVal == null) { - return - } - scope.adjustingScroll = true // temporarily disable scroll - return queueRescale(scope.scale) - }) - - scope.$watch( - 'parentSize', - function(newVal, oldVal) { - // console.log 'XXX in parentSize watch', newVal, oldVal - // if newVal == oldVal - // console.log 'returning because old and new are the same' - // return - // return unless oldVal? - // console.log 'XXX calling setScale in parentSize watcher' - if (newVal == null) { - return - } - return queueRescale(scope.scale) - }, - true - ) - - // scope.$watch 'elementWidth', (newVal, oldVal) -> - // console.log '*** watch INTERVAL element width is', newVal, oldVal - - scope.$watch('pleaseScrollTo', function(newVal, oldVal) { - // console.log 'got request to ScrollTo', newVal, 'oldVal', oldVal - if (newVal == null) { - return - } - scope.adjustingScroll = true // temporarily disable scroll - // handler while we reposition - $(element).scrollTop(newVal) - return (scope.pleaseScrollTo = undefined) - }) - - scope.$watch('pleaseJumpTo', function(newPosition, oldPosition) { - // console.log 'in pleaseJumpTo', newPosition, oldPosition - if (newPosition == null) { - return - } - return ctrl.setPdfPosition( - scope.pages[newPosition.page - 1], - newPosition - ) - }) - - scope.$watch('navigateTo', function(newVal, oldVal) { - if (newVal == null) { - return - } - // console.log 'got request to navigate to', newVal, 'oldVal', oldVal - scope.navigateTo = undefined - // console.log 'navigate to', newVal - // console.log 'look up page num' - return scope.document.getDestination(newVal.dest).then(r => - // console.log 'need to go to', r - // console.log 'page ref is', r[0] - scope.document.getPageIndex(r[0]).then(function(pidx) { - // console.log 'page num is', pidx - const page = scope.pages[pidx] - return scope.document - .getPdfViewport(page.pageNum) - .then(function(viewport) { - // console.log 'got viewport', viewport - const coords = viewport.convertToViewportPoint(r[2], r[3]) - // console.log 'viewport position', coords - // console.log 'r is', r, 'r[1]', r[1], 'r[1].name', r[1].name - if (r[1].name === 'XYZ') { - // console.log 'XYZ:', r[2], r[3] - const newPosition = { - page: pidx, - offset: { top: r[3], left: r[2] } - } - return ctrl.setPdfPosition(scope.pages[pidx], newPosition) - } - }) - }) - ) - }) // XXX? - - scope.$watch('highlights', function(areas) { - // console.log 'got HIGHLIGHTS in pdfViewer', areas - if (areas == null) { - return - } - // console.log 'areas are', areas - const highlights = Array.from(areas || []).map(area => ({ - page: area.page - 1, - highlight: { - left: area.h, - top: area.v, - height: area.height, - width: area.width - } - })) - // console.log 'highlights', highlights - - if (!highlights.length) { - return - } - - scope.$broadcast('pdf:highlights', areas) - - const first = highlights[0] - - // switching between split and full pdf views can cause - // highlights to appear before rendering - if (!scope.pages) { - return // ignore highlight scroll if still rendering - } - - const pageNum = - scope.pages[first.page] != null - ? scope.pages[first.page].pageNum - : undefined - - if (pageNum == null) { - return // ignore highlight scroll if page not found - } - - // use a visual offset of 72pt to match the offset in PdfController syncToCode - return scope.document - .getPdfViewport(pageNum) - .then(function(viewport) { - const position = { - page: first.page, - offset: { - left: first.highlight.left, - top: - viewport.viewBox[3] - - first.highlight.top + - first.highlight.height + - 72 - } - } - return ctrl.setPdfPosition(scope.pages[first.page], position) - }) - }) - - return scope.$on('$destroy', function() { - // console.log 'handle pdfng directive destroy' - if (elementTimer != null) { - clearTimeout(elementTimer) - } - if (layoutTimer != null) { - clearTimeout(layoutTimer) - } - if (rescaleTimer != null) { - clearTimeout(rescaleTimer) - } - if (spinnerTimer != null) { - return clearTimeout(spinnerTimer) - } - }) + var _setMouseUpHandler = function() { + if (mouseUpHandler == null) { + return (mouseUpHandler = $(document.body).one( + 'mouseup', + _handleSelectionMouseUp + )) + } } - }) - ]) + + var _handleSelectionMouseUp = function() { + mouseUpHandler = null // reset handler, has now fired + window.setTimeout(function() { + const removedClass = _removeClassIfNoSelection() + // if we still have a selection we need to keep the handler going + if (!removedClass) { + return _setMouseUpHandler() + } + }, 10) + return true + } + + var _removeClassIfNoSelection = function() { + if (_hasSelection()) { + return false // didn't remove the text layer + } else { + element.removeClass('pdfjs-viewer-show-text') + return true + } + } + + var _hasSelection = function() { + const selection = + typeof window.getSelection === 'function' + ? window.getSelection() + : undefined + // check the selection collapsed state in preference to + // using selection.toString() as the latter is "" when + // the selection is hidden (e.g. while viewing logs) + return ( + selection != null && + _isSelectionWithinPDF(selection) && + !selection.isCollapsed + ) + } + + var _isSelectionWithinPDF = function(selection) { + if (selection.rangeCount === 0) { + return false + } + const selectionAncestorNode = selection.getRangeAt(0) + .commonAncestorContainer + return ( + element.find(selectionAncestorNode).length > 0 || + element.is(selectionAncestorNode) + ) + } + + element.on('scroll', function() { + // console.log 'scroll event', element.scrollTop(), 'adjusting?', scope.adjustingScroll + // scope.scrollPosition = element.scrollTop() + if (scope.adjustingScroll) { + renderVisiblePages() + scope.adjustingScroll = false + return + } + if (scope.scrollHandlerTimeout) { + clearTimeout(scope.scrollHandlerTimeout) + } + return (scope.scrollHandlerTimeout = setTimeout(scrollHandler, 25)) + }) + + var scrollHandler = function() { + renderVisiblePages() + const newPosition = ctrl.getPdfPosition() + if (newPosition != null) { + scope.position = newPosition + } + return (scope.scrollHandlerTimeout = null) + } + + scope.$watch('pdfSrc', function(newVal, oldVal) { + // console.log 'loading pdf', newVal, oldVal + if (newVal == null) { + return + } + scope.loadCount = 0 // new pdf, so reset load count + scope.loadSuccess = false + return ctrl + .load() + .then( + () => + // trigger a redraw + (scope.scale = angular.copy(scope.scale)) + ) + .catch(error => scope.$emit('pdf:error', error)) + }) + + scope.$watch('scale', function(newVal, oldVal) { + // no need to set scale when initialising, done in pdfSrc + if (newVal === oldVal) { + return + } + // console.log 'XXX calling Setscale in scale watch' + return queueRescale(newVal) + }) + + scope.$watch('forceScale', function(newVal, oldVal) { + // console.log 'got change in numscale watcher', newVal, oldVal + if (newVal == null) { + return + } + return queueRescale(newVal) + }) + + // scope.$watch 'position', (newVal, oldVal) -> + // console.log 'got change in position watcher', newVal, oldVal + + scope.$watch('forceCheck', function(newVal, oldVal) { + // console.log 'forceCheck', newVal, oldVal + if (newVal == null) { + return + } + scope.adjustingScroll = true // temporarily disable scroll + return queueRescale(scope.scale) + }) + + scope.$watch( + 'parentSize', + function(newVal, oldVal) { + // console.log 'XXX in parentSize watch', newVal, oldVal + // if newVal == oldVal + // console.log 'returning because old and new are the same' + // return + // return unless oldVal? + // console.log 'XXX calling setScale in parentSize watcher' + if (newVal == null) { + return + } + return queueRescale(scope.scale) + }, + true + ) + + // scope.$watch 'elementWidth', (newVal, oldVal) -> + // console.log '*** watch INTERVAL element width is', newVal, oldVal + + scope.$watch('pleaseScrollTo', function(newVal, oldVal) { + // console.log 'got request to ScrollTo', newVal, 'oldVal', oldVal + if (newVal == null) { + return + } + scope.adjustingScroll = true // temporarily disable scroll + // handler while we reposition + $(element).scrollTop(newVal) + return (scope.pleaseScrollTo = undefined) + }) + + scope.$watch('pleaseJumpTo', function(newPosition, oldPosition) { + // console.log 'in pleaseJumpTo', newPosition, oldPosition + if (newPosition == null) { + return + } + return ctrl.setPdfPosition( + scope.pages[newPosition.page - 1], + newPosition + ) + }) + + scope.$watch('navigateTo', function(newVal, oldVal) { + if (newVal == null) { + return + } + // console.log 'got request to navigate to', newVal, 'oldVal', oldVal + scope.navigateTo = undefined + // console.log 'navigate to', newVal + // console.log 'look up page num' + return scope.document.getDestination(newVal.dest).then(r => + // console.log 'need to go to', r + // console.log 'page ref is', r[0] + scope.document.getPageIndex(r[0]).then(function(pidx) { + // console.log 'page num is', pidx + const page = scope.pages[pidx] + return scope.document + .getPdfViewport(page.pageNum) + .then(function(viewport) { + // console.log 'got viewport', viewport + const coords = viewport.convertToViewportPoint(r[2], r[3]) + // console.log 'viewport position', coords + // console.log 'r is', r, 'r[1]', r[1], 'r[1].name', r[1].name + if (r[1].name === 'XYZ') { + // console.log 'XYZ:', r[2], r[3] + const newPosition = { + page: pidx, + offset: { top: r[3], left: r[2] } + } + return ctrl.setPdfPosition(scope.pages[pidx], newPosition) + } + }) + }) + ) + }) // XXX? + + scope.$watch('highlights', function(areas) { + // console.log 'got HIGHLIGHTS in pdfViewer', areas + if (areas == null) { + return + } + // console.log 'areas are', areas + const highlights = Array.from(areas || []).map(area => ({ + page: area.page - 1, + highlight: { + left: area.h, + top: area.v, + height: area.height, + width: area.width + } + })) + // console.log 'highlights', highlights + + if (!highlights.length) { + return + } + + scope.$broadcast('pdf:highlights', areas) + + const first = highlights[0] + + // switching between split and full pdf views can cause + // highlights to appear before rendering + if (!scope.pages) { + return // ignore highlight scroll if still rendering + } + + const pageNum = + scope.pages[first.page] != null + ? scope.pages[first.page].pageNum + : undefined + + if (pageNum == null) { + return // ignore highlight scroll if page not found + } + + // use a visual offset of 72pt to match the offset in PdfController syncToCode + return scope.document.getPdfViewport(pageNum).then(function(viewport) { + const position = { + page: first.page, + offset: { + left: first.highlight.left, + top: + viewport.viewBox[3] - + first.highlight.top + + first.highlight.height + + 72 + } + } + return ctrl.setPdfPosition(scope.pages[first.page], position) + }) + }) + + return scope.$on('$destroy', function() { + // console.log 'handle pdfng directive destroy' + if (elementTimer != null) { + clearTimeout(elementTimer) + } + if (layoutTimer != null) { + clearTimeout(layoutTimer) + } + if (rescaleTimer != null) { + clearTimeout(rescaleTimer) + } + if (spinnerTimer != null) { + return clearTimeout(spinnerTimer) + } + }) + } + })) }) function __guardMethod__(obj, methodName, transform) { diff --git a/services/web/public/src/ide/services/ide.js b/services/web/public/src/ide/services/ide.js index c49bb68069..eda33ea8bc 100644 --- a/services/web/public/src/ide/services/ide.js +++ b/services/web/public/src/ide/services/ide.js @@ -16,113 +16,111 @@ define(['base'], function(App) { // We create and provide this as service so that we can access the global ide // from within other parts of the angular app. - App.factory('ide', [ - '$http', - 'queuedHttp', - '$modal', - '$q', - '$filter', - '$timeout', - function($http, queuedHttp, $modal, $q, $filter, $timeout) { - const ide = {} - ide.$http = $http - ide.queuedHttp = queuedHttp - ide.$q = $q - ide.$filter = $filter - ide.$timeout = $timeout + App.factory('ide', function( + $http, + queuedHttp, + $modal, + $q, + $filter, + $timeout + ) { + const ide = {} + ide.$http = $http + ide.queuedHttp = queuedHttp + ide.$q = $q + ide.$filter = $filter + ide.$timeout = $timeout - this.recentEvents = [] - ide.pushEvent = (type, meta) => { - if (meta == null) { - meta = {} - } - sl_console.log('event', type, meta) - this.recentEvents.push({ type, meta, date: new Date() }) - if (this.recentEvents.length > 100) { - return this.recentEvents.shift() - } + this.recentEvents = [] + ide.pushEvent = (type, meta) => { + if (meta == null) { + meta = {} } + sl_console.log('event', type, meta) + this.recentEvents.push({ type, meta, date: new Date() }) + if (this.recentEvents.length > 100) { + return this.recentEvents.shift() + } + } - ide.reportError = (error, meta) => { - if (meta == null) { - meta = {} - } - meta.client_id = __guard__( + ide.reportError = (error, meta) => { + if (meta == null) { + meta = {} + } + meta.client_id = __guard__( + this.socket != null ? this.socket.socket : undefined, + x => x.sessionid + ) + meta.transport = __guard__( + __guard__( this.socket != null ? this.socket.socket : undefined, - x => x.sessionid - ) - meta.transport = __guard__( - __guard__( - this.socket != null ? this.socket.socket : undefined, - x2 => x2.transport - ), - x1 => x1.name - ) - meta.client_now = new Date() - meta.recent_events = this.recentEvents - const errorObj = {} - if (typeof error === 'object') { - for (let key of Array.from(Object.getOwnPropertyNames(error))) { - errorObj[key] = error[key] - } - } else if (typeof error === 'string') { - errorObj.message = error + x2 => x2.transport + ), + x1 => x1.name + ) + meta.client_now = new Date() + meta.recent_events = this.recentEvents + const errorObj = {} + if (typeof error === 'object') { + for (let key of Array.from(Object.getOwnPropertyNames(error))) { + errorObj[key] = error[key] } - return $http.post('/error/client', { - error: errorObj, - meta, - _csrf: window.csrfToken - }) + } else if (typeof error === 'string') { + errorObj.message = error } + return $http.post('/error/client', { + error: errorObj, + meta, + _csrf: window.csrfToken + }) + } - ide.showGenericMessageModal = (title, message) => - $modal.open({ - templateUrl: 'genericMessageModalTemplate', - controller: 'GenericMessageModalController', - resolve: { - title() { - return title - }, - message() { - return message - } - } - }) - - ide.showLockEditorMessageModal = (title, message) => - // modal to block the editor when connection is down - $modal.open({ - templateUrl: 'lockEditorModalTemplate', - controller: 'GenericMessageModalController', - backdrop: 'static', // prevent dismiss by click on background - keyboard: false, // prevent dismiss via keyboard - resolve: { - title() { - return title - }, - message() { - return message - } + ide.showGenericMessageModal = (title, message) => + $modal.open({ + templateUrl: 'genericMessageModalTemplate', + controller: 'GenericMessageModalController', + resolve: { + title() { + return title }, - windowClass: 'lock-editor-modal' - }) + message() { + return message + } + } + }) - return ide - } - ]) + ide.showLockEditorMessageModal = (title, message) => + // modal to block the editor when connection is down + $modal.open({ + templateUrl: 'lockEditorModalTemplate', + controller: 'GenericMessageModalController', + backdrop: 'static', // prevent dismiss by click on background + keyboard: false, // prevent dismiss via keyboard + resolve: { + title() { + return title + }, + message() { + return message + } + }, + windowClass: 'lock-editor-modal' + }) - return App.controller('GenericMessageModalController', [ - '$scope', - '$modalInstance', - 'title', - 'message', - function($scope, $modalInstance, title, message) { - $scope.title = title - $scope.message = message + return ide + }) - return ($scope.done = () => $modalInstance.close()) - } - ]) + return App.controller('GenericMessageModalController', function( + $scope, + $modalInstance, + title, + message + ) { + $scope.title = title + $scope.message = message + + return ($scope.done = () => $modalInstance.close()) + }) }) function __guard__(value, transform) { diff --git a/services/web/public/src/ide/settings/controllers/ProjectNameController.js b/services/web/public/src/ide/settings/controllers/ProjectNameController.js index 6ea02777b4..c14651b4b3 100644 --- a/services/web/public/src/ide/settings/controllers/ProjectNameController.js +++ b/services/web/public/src/ide/settings/controllers/ProjectNameController.js @@ -14,68 +14,67 @@ */ define(['base'], function(App) { const MAX_PROJECT_NAME_LENGTH = 150 - return App.controller('ProjectNameController', [ - '$scope', - '$element', - 'settings', - 'ide', - function($scope, $element, settings, ide) { - const projectNameReadOnlyEl = $element.find('.name')[0] + return App.controller('ProjectNameController', function( + $scope, + $element, + settings, + ide + ) { + const projectNameReadOnlyEl = $element.find('.name')[0] - $scope.state = { - renaming: false, - overflowed: false - } - - $scope.inputs = {} - - $scope.startRenaming = function() { - $scope.inputs.name = $scope.project.name - $scope.state.renaming = true - return $scope.$emit('project:rename:start') - } - - $scope.finishRenaming = function() { - $scope.state.renaming = false - const newName = $scope.inputs.name - if ($scope.project.name === newName) { - return - } - const oldName = $scope.project.name - $scope.project.name = newName - return settings - .saveProjectSettings({ name: $scope.project.name }) - .catch(function(response) { - const { data, status } = response - $scope.project.name = oldName - if (status === 400) { - return ide.showGenericMessageModal('Error renaming project', data) - } else { - return ide.showGenericMessageModal( - 'Error renaming project', - 'Please try again in a moment' - ) - } - }) - } - - ide.socket.on('projectNameUpdated', name => - $scope.$apply(() => ($scope.project.name = name)) - ) - - return $scope.$watch('project.name', function(name) { - if (name != null) { - window.document.title = - name + ` - Online LaTeX Editor ${ExposedSettings.appName}` - return $scope.$applyAsync( - () => - // This ensures that the element is measured *after* the binding is done (i.e. project name is rendered). - ($scope.state.overflowed = - projectNameReadOnlyEl.scrollWidth > - projectNameReadOnlyEl.clientWidth) - ) - } - }) + $scope.state = { + renaming: false, + overflowed: false } - ]) + + $scope.inputs = {} + + $scope.startRenaming = function() { + $scope.inputs.name = $scope.project.name + $scope.state.renaming = true + return $scope.$emit('project:rename:start') + } + + $scope.finishRenaming = function() { + $scope.state.renaming = false + const newName = $scope.inputs.name + if ($scope.project.name === newName) { + return + } + const oldName = $scope.project.name + $scope.project.name = newName + return settings + .saveProjectSettings({ name: $scope.project.name }) + .catch(function(response) { + const { data, status } = response + $scope.project.name = oldName + if (status === 400) { + return ide.showGenericMessageModal('Error renaming project', data) + } else { + return ide.showGenericMessageModal( + 'Error renaming project', + 'Please try again in a moment' + ) + } + }) + } + + ide.socket.on('projectNameUpdated', name => + $scope.$apply(() => ($scope.project.name = name)) + ) + + return $scope.$watch('project.name', function(name) { + if (name != null) { + window.document.title = + name + ` - Online LaTeX Editor ${ExposedSettings.appName}` + return $scope.$applyAsync( + () => + // This ensures that the element is measured *after* the binding is done (i.e. project name is rendered). + ($scope.state.overflowed = + projectNameReadOnlyEl.scrollWidth > + projectNameReadOnlyEl.clientWidth) + ) + } + }) + }) }) diff --git a/services/web/public/src/ide/settings/controllers/SettingsController.js b/services/web/public/src/ide/settings/controllers/SettingsController.js index 898eaa56c5..e8e44f3b19 100644 --- a/services/web/public/src/ide/settings/controllers/SettingsController.js +++ b/services/web/public/src/ide/settings/controllers/SettingsController.js @@ -13,206 +13,194 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('SettingsController', [ - '$scope', - 'settings', - 'ide', - '_', - function($scope, settings, ide, _) { - $scope.overallThemesList = window.overallThemes - $scope.ui = { loadingStyleSheet: false } + App.controller('SettingsController', function($scope, settings, ide, _) { + $scope.overallThemesList = window.overallThemes + $scope.ui = { loadingStyleSheet: false } - const _updateCSSFile = function(theme) { - $scope.ui.loadingStyleSheet = true - const docHeadEl = document.querySelector('head') - const oldStyleSheetEl = document.getElementById('main-stylesheet') - const newStyleSheetEl = document.createElement('link') - newStyleSheetEl.addEventListener('load', e => { - return $scope.$applyAsync(() => { - $scope.ui.loadingStyleSheet = false - return docHeadEl.removeChild(oldStyleSheetEl) - }) + const _updateCSSFile = function(theme) { + $scope.ui.loadingStyleSheet = true + const docHeadEl = document.querySelector('head') + const oldStyleSheetEl = document.getElementById('main-stylesheet') + const newStyleSheetEl = document.createElement('link') + newStyleSheetEl.addEventListener('load', e => { + return $scope.$applyAsync(() => { + $scope.ui.loadingStyleSheet = false + return docHeadEl.removeChild(oldStyleSheetEl) }) - newStyleSheetEl.setAttribute('rel', 'stylesheet') - newStyleSheetEl.setAttribute('id', 'main-stylesheet') - newStyleSheetEl.setAttribute('href', theme.path) - return docHeadEl.appendChild(newStyleSheetEl) - } - - if (!['default', 'vim', 'emacs'].includes($scope.settings.mode)) { - $scope.settings.mode = 'default' - } - - if (!['pdfjs', 'native'].includes($scope.settings.pdfViewer)) { - $scope.settings.pdfViewer = 'pdfjs' - } - - if ( - $scope.settings.fontFamily != null && - !['monaco', 'lucida'].includes($scope.settings.fontFamily) - ) { - delete $scope.settings.fontFamily - } - - if ( - $scope.settings.lineHeight != null && - !['compact', 'normal', 'wide'].includes($scope.settings.lineHeight) - ) { - delete $scope.settings.lineHeight - } - - $scope.fontSizeAsStr = function(newVal) { - if (newVal != null) { - $scope.settings.fontSize = newVal - } - return $scope.settings.fontSize.toString() - } - - $scope.$watch('settings.editorTheme', (editorTheme, oldEditorTheme) => { - if (editorTheme !== oldEditorTheme) { - return settings.saveSettings({ editorTheme }) - } - }) - - $scope.$watch( - 'settings.overallTheme', - (overallTheme, oldOverallTheme) => { - if (overallTheme !== oldOverallTheme) { - const chosenTheme = _.find( - $scope.overallThemesList, - theme => theme.val === overallTheme - ) - if (chosenTheme != null) { - _updateCSSFile(chosenTheme) - return settings.saveSettings({ overallTheme }) - } - } - } - ) - - $scope.$watch('settings.fontSize', (fontSize, oldFontSize) => { - if (fontSize !== oldFontSize) { - return settings.saveSettings({ fontSize: parseInt(fontSize, 10) }) - } - }) - - $scope.$watch('settings.mode', (mode, oldMode) => { - if (mode !== oldMode) { - return settings.saveSettings({ mode }) - } - }) - - $scope.$watch( - 'settings.autoComplete', - (autoComplete, oldAutoComplete) => { - if (autoComplete !== oldAutoComplete) { - return settings.saveSettings({ autoComplete }) - } - } - ) - - $scope.$watch( - 'settings.autoPairDelimiters', - (autoPairDelimiters, oldAutoPairDelimiters) => { - if (autoPairDelimiters !== oldAutoPairDelimiters) { - return settings.saveSettings({ autoPairDelimiters }) - } - } - ) - - $scope.$watch('settings.pdfViewer', (pdfViewer, oldPdfViewer) => { - if (pdfViewer !== oldPdfViewer) { - return settings.saveSettings({ pdfViewer }) - } - }) - - $scope.$watch( - 'settings.syntaxValidation', - (syntaxValidation, oldSyntaxValidation) => { - if (syntaxValidation !== oldSyntaxValidation) { - return settings.saveSettings({ syntaxValidation }) - } - } - ) - - $scope.$watch('settings.fontFamily', (fontFamily, oldFontFamily) => { - if (fontFamily !== oldFontFamily) { - return settings.saveSettings({ fontFamily }) - } - }) - - $scope.$watch('settings.lineHeight', (lineHeight, oldLineHeight) => { - if (lineHeight !== oldLineHeight) { - return settings.saveSettings({ lineHeight }) - } - }) - - $scope.$watch('project.spellCheckLanguage', (language, oldLanguage) => { - if (this.ignoreUpdates) { - return - } - if (oldLanguage != null && language !== oldLanguage) { - settings.saveProjectSettings({ spellCheckLanguage: language }) - // Also set it as the default for the user - return settings.saveSettings({ spellCheckLanguage: language }) - } - }) - - $scope.$watch('project.compiler', (compiler, oldCompiler) => { - if (this.ignoreUpdates) { - return - } - if (oldCompiler != null && compiler !== oldCompiler) { - return settings.saveProjectSettings({ compiler }) - } - }) - - $scope.$watch('project.imageName', (imageName, oldImageName) => { - if (this.ignoreUpdates) { - return - } - if (oldImageName != null && imageName !== oldImageName) { - return settings.saveProjectSettings({ imageName }) - } - }) - - $scope.$watch('project.rootDoc_id', (rootDoc_id, oldRootDoc_id) => { - if (this.ignoreUpdates) { - return - } - // don't save on initialisation, Angular passes oldRootDoc_id as - // undefined in this case. - if (typeof oldRootDoc_id === 'undefined') { - return - } - // otherwise only save changes, null values are allowed - if (rootDoc_id !== oldRootDoc_id) { - return settings.saveProjectSettings({ rootDocId: rootDoc_id }) - } - }) - - ide.socket.on('compilerUpdated', compiler => { - this.ignoreUpdates = true - $scope.$apply(() => { - return ($scope.project.compiler = compiler) - }) - return delete this.ignoreUpdates - }) - - ide.socket.on('imageNameUpdated', imageName => { - this.ignoreUpdates = true - $scope.$apply(() => { - return ($scope.project.imageName = imageName) - }) - return delete this.ignoreUpdates - }) - - return ide.socket.on('spellCheckLanguageUpdated', languageCode => { - this.ignoreUpdates = true - $scope.$apply(() => { - return ($scope.project.spellCheckLanguage = languageCode) - }) - return delete this.ignoreUpdates }) + newStyleSheetEl.setAttribute('rel', 'stylesheet') + newStyleSheetEl.setAttribute('id', 'main-stylesheet') + newStyleSheetEl.setAttribute('href', theme.path) + return docHeadEl.appendChild(newStyleSheetEl) } - ])) + + if (!['default', 'vim', 'emacs'].includes($scope.settings.mode)) { + $scope.settings.mode = 'default' + } + + if (!['pdfjs', 'native'].includes($scope.settings.pdfViewer)) { + $scope.settings.pdfViewer = 'pdfjs' + } + + if ( + $scope.settings.fontFamily != null && + !['monaco', 'lucida'].includes($scope.settings.fontFamily) + ) { + delete $scope.settings.fontFamily + } + + if ( + $scope.settings.lineHeight != null && + !['compact', 'normal', 'wide'].includes($scope.settings.lineHeight) + ) { + delete $scope.settings.lineHeight + } + + $scope.fontSizeAsStr = function(newVal) { + if (newVal != null) { + $scope.settings.fontSize = newVal + } + return $scope.settings.fontSize.toString() + } + + $scope.$watch('settings.editorTheme', (editorTheme, oldEditorTheme) => { + if (editorTheme !== oldEditorTheme) { + return settings.saveSettings({ editorTheme }) + } + }) + + $scope.$watch('settings.overallTheme', (overallTheme, oldOverallTheme) => { + if (overallTheme !== oldOverallTheme) { + const chosenTheme = _.find( + $scope.overallThemesList, + theme => theme.val === overallTheme + ) + if (chosenTheme != null) { + _updateCSSFile(chosenTheme) + return settings.saveSettings({ overallTheme }) + } + } + }) + + $scope.$watch('settings.fontSize', (fontSize, oldFontSize) => { + if (fontSize !== oldFontSize) { + return settings.saveSettings({ fontSize: parseInt(fontSize, 10) }) + } + }) + + $scope.$watch('settings.mode', (mode, oldMode) => { + if (mode !== oldMode) { + return settings.saveSettings({ mode }) + } + }) + + $scope.$watch('settings.autoComplete', (autoComplete, oldAutoComplete) => { + if (autoComplete !== oldAutoComplete) { + return settings.saveSettings({ autoComplete }) + } + }) + + $scope.$watch( + 'settings.autoPairDelimiters', + (autoPairDelimiters, oldAutoPairDelimiters) => { + if (autoPairDelimiters !== oldAutoPairDelimiters) { + return settings.saveSettings({ autoPairDelimiters }) + } + } + ) + + $scope.$watch('settings.pdfViewer', (pdfViewer, oldPdfViewer) => { + if (pdfViewer !== oldPdfViewer) { + return settings.saveSettings({ pdfViewer }) + } + }) + + $scope.$watch( + 'settings.syntaxValidation', + (syntaxValidation, oldSyntaxValidation) => { + if (syntaxValidation !== oldSyntaxValidation) { + return settings.saveSettings({ syntaxValidation }) + } + } + ) + + $scope.$watch('settings.fontFamily', (fontFamily, oldFontFamily) => { + if (fontFamily !== oldFontFamily) { + return settings.saveSettings({ fontFamily }) + } + }) + + $scope.$watch('settings.lineHeight', (lineHeight, oldLineHeight) => { + if (lineHeight !== oldLineHeight) { + return settings.saveSettings({ lineHeight }) + } + }) + + $scope.$watch('project.spellCheckLanguage', (language, oldLanguage) => { + if (this.ignoreUpdates) { + return + } + if (oldLanguage != null && language !== oldLanguage) { + settings.saveProjectSettings({ spellCheckLanguage: language }) + // Also set it as the default for the user + return settings.saveSettings({ spellCheckLanguage: language }) + } + }) + + $scope.$watch('project.compiler', (compiler, oldCompiler) => { + if (this.ignoreUpdates) { + return + } + if (oldCompiler != null && compiler !== oldCompiler) { + return settings.saveProjectSettings({ compiler }) + } + }) + + $scope.$watch('project.imageName', (imageName, oldImageName) => { + if (this.ignoreUpdates) { + return + } + if (oldImageName != null && imageName !== oldImageName) { + return settings.saveProjectSettings({ imageName }) + } + }) + + $scope.$watch('project.rootDoc_id', (rootDoc_id, oldRootDoc_id) => { + if (this.ignoreUpdates) { + return + } + // don't save on initialisation, Angular passes oldRootDoc_id as + // undefined in this case. + if (typeof oldRootDoc_id === 'undefined') { + return + } + // otherwise only save changes, null values are allowed + if (rootDoc_id !== oldRootDoc_id) { + return settings.saveProjectSettings({ rootDocId: rootDoc_id }) + } + }) + + ide.socket.on('compilerUpdated', compiler => { + this.ignoreUpdates = true + $scope.$apply(() => { + return ($scope.project.compiler = compiler) + }) + return delete this.ignoreUpdates + }) + + ide.socket.on('imageNameUpdated', imageName => { + this.ignoreUpdates = true + $scope.$apply(() => { + return ($scope.project.imageName = imageName) + }) + return delete this.ignoreUpdates + }) + + return ide.socket.on('spellCheckLanguageUpdated', languageCode => { + this.ignoreUpdates = true + $scope.$apply(() => { + return ($scope.project.spellCheckLanguage = languageCode) + }) + return delete this.ignoreUpdates + }) + })) diff --git a/services/web/public/src/ide/settings/services/settings.js b/services/web/public/src/ide/settings/services/settings.js index 14197a695d..f35ced9fb5 100644 --- a/services/web/public/src/ide/settings/services/settings.js +++ b/services/web/public/src/ide/settings/services/settings.js @@ -12,56 +12,52 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.factory('settings', [ - 'ide', - 'event_tracking', - (ide, event_tracking) => ({ - saveSettings(data) { - // Tracking code. - for (let key of Array.from(Object.keys(data))) { - const changedSetting = key - const changedSettingVal = data[key] - event_tracking.sendMB('setting-changed', { - changedSetting, - changedSettingVal - }) - } - // End of tracking code. - - data._csrf = window.csrfToken - return ide.$http.post('/user/settings', data) - }, - - saveProjectSettings(data) { - // Tracking code. - for (let key of Array.from(Object.keys(data))) { - const changedSetting = key - const changedSettingVal = data[key] - event_tracking.sendMB('project-setting-changed', { - changedSetting, - changedSettingVal - }) - } - // End of tracking code. - - data._csrf = window.csrfToken - return ide.$http.post(`/project/${ide.project_id}/settings`, data) - }, - - saveProjectAdminSettings(data) { - // Tracking code. - for (let key of Array.from(Object.keys(data))) { - const changedSetting = key - const changedSettingVal = data[key] - event_tracking.sendMB('project-admin-setting-changed', { - changedSetting, - changedSettingVal - }) - } - // End of tracking code. - - data._csrf = window.csrfToken - return ide.$http.post(`/project/${ide.project_id}/settings/admin`, data) + App.factory('settings', (ide, event_tracking) => ({ + saveSettings(data) { + // Tracking code. + for (let key of Array.from(Object.keys(data))) { + const changedSetting = key + const changedSettingVal = data[key] + event_tracking.sendMB('setting-changed', { + changedSetting, + changedSettingVal + }) } - }) - ])) + // End of tracking code. + + data._csrf = window.csrfToken + return ide.$http.post('/user/settings', data) + }, + + saveProjectSettings(data) { + // Tracking code. + for (let key of Array.from(Object.keys(data))) { + const changedSetting = key + const changedSettingVal = data[key] + event_tracking.sendMB('project-setting-changed', { + changedSetting, + changedSettingVal + }) + } + // End of tracking code. + + data._csrf = window.csrfToken + return ide.$http.post(`/project/${ide.project_id}/settings`, data) + }, + + saveProjectAdminSettings(data) { + // Tracking code. + for (let key of Array.from(Object.keys(data))) { + const changedSetting = key + const changedSettingVal = data[key] + event_tracking.sendMB('project-admin-setting-changed', { + changedSetting, + changedSettingVal + }) + } + // End of tracking code. + + data._csrf = window.csrfToken + return ide.$http.post(`/project/${ide.project_id}/settings/admin`, data) + } + }))) diff --git a/services/web/public/src/ide/share/controllers/ShareController.js b/services/web/public/src/ide/share/controllers/ShareController.js index cda9e7486b..442aa2c675 100644 --- a/services/web/public/src/ide/share/controllers/ShareController.js +++ b/services/web/public/src/ide/share/controllers/ShareController.js @@ -13,66 +13,58 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('ShareController', [ - '$scope', - '$modal', - 'ide', - 'projectInvites', - 'projectMembers', - 'event_tracking', - function( - $scope, - $modal, - ide, - projectInvites, - projectMembers, - event_tracking - ) { - $scope.openShareProjectModal = function(isAdmin) { - $scope.isAdmin = isAdmin - event_tracking.sendMBOnce('ide-open-share-modal-once') + App.controller('ShareController', function( + $scope, + $modal, + ide, + projectInvites, + projectMembers, + event_tracking + ) { + $scope.openShareProjectModal = function(isAdmin) { + $scope.isAdmin = isAdmin + event_tracking.sendMBOnce('ide-open-share-modal-once') - return $modal.open({ - templateUrl: 'shareProjectModalTemplate', - controller: 'ShareProjectModalController', - scope: $scope - }) - } - - ide.socket.on('project:tokens:changed', data => { - if (data.tokens != null) { - ide.$scope.project.tokens = data.tokens - return $scope.$digest() - } - }) - - return ide.socket.on('project:membership:changed', data => { - if (data.members) { - projectMembers - .getMembers() - .then(response => { - ;({ data } = response) - if (data.members) { - return ($scope.project.members = data.members) - } - }) - .catch(() => { - return console.error('Error fetching members for project') - }) - } - if (data.invites) { - return projectInvites - .getInvites() - .then(response => { - ;({ data } = response) - if (data.invites) { - return ($scope.project.invites = data.invites) - } - }) - .catch(() => { - return console.error('Error fetching invites for project') - }) - } + return $modal.open({ + templateUrl: 'shareProjectModalTemplate', + controller: 'ShareProjectModalController', + scope: $scope }) } - ])) + + ide.socket.on('project:tokens:changed', data => { + if (data.tokens != null) { + ide.$scope.project.tokens = data.tokens + return $scope.$digest() + } + }) + + return ide.socket.on('project:membership:changed', data => { + if (data.members) { + projectMembers + .getMembers() + .then(response => { + ;({ data } = response) + if (data.members) { + return ($scope.project.members = data.members) + } + }) + .catch(() => { + return console.error('Error fetching members for project') + }) + } + if (data.invites) { + return projectInvites + .getInvites() + .then(response => { + ;({ data } = response) + if (data.invites) { + return ($scope.project.invites = data.invites) + } + }) + .catch(() => { + return console.error('Error fetching invites for project') + }) + } + }) + })) diff --git a/services/web/public/src/ide/share/services/projectInvites.js b/services/web/public/src/ide/share/services/projectInvites.js index 12bba74c6e..e4c3a32624 100644 --- a/services/web/public/src/ide/share/services/projectInvites.js +++ b/services/web/public/src/ide/share/services/projectInvites.js @@ -10,45 +10,41 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.factory('projectInvites', [ - 'ide', - '$http', - (ide, $http) => ({ - sendInvite(email, privileges, grecaptchaResponse) { - return $http.post(`/project/${ide.project_id}/invite`, { - email, - privileges, - _csrf: window.csrfToken, - 'g-recaptcha-response': grecaptchaResponse - }) - }, + App.factory('projectInvites', (ide, $http) => ({ + sendInvite(email, privileges, grecaptchaResponse) { + return $http.post(`/project/${ide.project_id}/invite`, { + email, + privileges, + _csrf: window.csrfToken, + 'g-recaptcha-response': grecaptchaResponse + }) + }, - revokeInvite(inviteId) { - return $http({ - url: `/project/${ide.project_id}/invite/${inviteId}`, - method: 'DELETE', - headers: { - 'X-Csrf-Token': window.csrfToken - } - }) - }, + revokeInvite(inviteId) { + return $http({ + url: `/project/${ide.project_id}/invite/${inviteId}`, + method: 'DELETE', + headers: { + 'X-Csrf-Token': window.csrfToken + } + }) + }, - resendInvite(inviteId, privileges) { - return $http.post( - `/project/${ide.project_id}/invite/${inviteId}/resend`, - { - _csrf: window.csrfToken - } - ) - }, + resendInvite(inviteId, privileges) { + return $http.post( + `/project/${ide.project_id}/invite/${inviteId}/resend`, + { + _csrf: window.csrfToken + } + ) + }, - getInvites() { - return $http.get(`/project/${ide.project_id}/invites`, { - json: true, - headers: { - 'X-Csrf-Token': window.csrfToken - } - }) - } - }) - ])) + getInvites() { + return $http.get(`/project/${ide.project_id}/invites`, { + json: true, + headers: { + 'X-Csrf-Token': window.csrfToken + } + }) + } + }))) diff --git a/services/web/public/src/ide/share/services/projectMembers.js b/services/web/public/src/ide/share/services/projectMembers.js index b8ac1465c8..1730771157 100644 --- a/services/web/public/src/ide/share/services/projectMembers.js +++ b/services/web/public/src/ide/share/services/projectMembers.js @@ -10,35 +10,31 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.factory('projectMembers', [ - 'ide', - '$http', - (ide, $http) => ({ - removeMember(member) { - return $http({ - url: `/project/${ide.project_id}/users/${member._id}`, - method: 'DELETE', - headers: { - 'X-Csrf-Token': window.csrfToken - } - }) - }, + App.factory('projectMembers', (ide, $http) => ({ + removeMember(member) { + return $http({ + url: `/project/${ide.project_id}/users/${member._id}`, + method: 'DELETE', + headers: { + 'X-Csrf-Token': window.csrfToken + } + }) + }, - addGroup(group_id, privileges) { - return $http.post(`/project/${ide.project_id}/group`, { - group_id, - privileges, - _csrf: window.csrfToken - }) - }, + addGroup(group_id, privileges) { + return $http.post(`/project/${ide.project_id}/group`, { + group_id, + privileges, + _csrf: window.csrfToken + }) + }, - getMembers() { - return $http.get(`/project/${ide.project_id}/members`, { - json: true, - headers: { - 'X-Csrf-Token': window.csrfToken - } - }) - } - }) - ])) + getMembers() { + return $http.get(`/project/${ide.project_id}/members`, { + json: true, + headers: { + 'X-Csrf-Token': window.csrfToken + } + }) + } + }))) diff --git a/services/web/public/src/main/account-settings.js b/services/web/public/src/main/account-settings.js index c090f12df6..80914ddf54 100644 --- a/services/web/public/src/main/account-settings.js +++ b/services/web/public/src/main/account-settings.js @@ -14,129 +14,120 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], function(App) { - App.controller('AccountSettingsController', [ - '$scope', - '$http', - '$modal', - 'event_tracking', - 'UserAffiliationsDataService', - 'UserOauthDataService', - function( - $scope, - $http, - $modal, - event_tracking, - UserAffiliationsDataService, - UserOauthDataService - ) { - $scope.subscribed = true + App.controller('AccountSettingsController', function( + $scope, + $http, + $modal, + event_tracking, + UserAffiliationsDataService, + UserOauthDataService + ) { + $scope.subscribed = true - $scope.unsubscribe = function() { - $scope.unsubscribing = true - return $http({ - method: 'DELETE', - url: '/user/newsletter/unsubscribe', - headers: { - 'X-CSRF-Token': window.csrfToken + $scope.unsubscribe = function() { + $scope.unsubscribing = true + return $http({ + method: 'DELETE', + url: '/user/newsletter/unsubscribe', + headers: { + 'X-CSRF-Token': window.csrfToken + } + }) + .then(function() { + $scope.unsubscribing = false + return ($scope.subscribed = false) + }) + .catch(() => ($scope.unsubscribing = true)) + } + + $scope.deleteAccount = function() { + let modalInstance + return (modalInstance = $modal.open({ + templateUrl: 'deleteAccountModalTemplate', + controller: 'DeleteAccountModalController', + resolve: { + userDefaultEmail() { + return UserAffiliationsDataService.getUserDefaultEmail() + .then( + defaultEmailDetails => + (defaultEmailDetails != null + ? defaultEmailDetails.email + : undefined) || null + ) + .catch(() => null) + } + } + })) + } + + return ($scope.upgradeIntegration = service => + event_tracking.send('subscription-funnel', 'settings-page', service)) + }) + + return App.controller('DeleteAccountModalController', function( + $scope, + $modalInstance, + $timeout, + $http, + userDefaultEmail + ) { + $scope.state = { + isValid: false, + deleteText: '', + password: '', + confirmV1Purge: false, + confirmSharelatexDelete: false, + inflight: false, + error: null + } + + $scope.userDefaultEmail = userDefaultEmail + + $modalInstance.opened.then(() => + $timeout(() => $scope.$broadcast('open'), 700) + ) + + $scope.checkValidation = () => + ($scope.state.isValid = + userDefaultEmail != null && + $scope.state.deleteText.toLowerCase() === + userDefaultEmail.toLowerCase() && + $scope.state.password.length > 0 && + $scope.state.confirmV1Purge && + $scope.state.confirmSharelatexDelete) + + $scope.delete = function() { + $scope.state.inflight = true + $scope.state.error = null + return $http({ + method: 'POST', + url: '/user/delete', + headers: { + 'X-CSRF-Token': window.csrfToken, + 'Content-Type': 'application/json' + }, + data: { + password: $scope.state.password + }, + disableAutoLoginRedirect: true // we want to handle errors ourselves + }) + .then(function() { + $modalInstance.close() + $scope.state.inflight = false + $scope.state.error = null + return setTimeout(() => (window.location = '/login'), 1000) + }) + .catch(function(response) { + const { data, status } = response + $scope.state.inflight = false + if (status === 403) { + $scope.state.error = { code: 'InvalidCredentialsError' } + } else { + $scope.state.error = { code: data.error } } }) - .then(function() { - $scope.unsubscribing = false - return ($scope.subscribed = false) - }) - .catch(() => ($scope.unsubscribing = true)) - } - - $scope.deleteAccount = function() { - let modalInstance - return (modalInstance = $modal.open({ - templateUrl: 'deleteAccountModalTemplate', - controller: 'DeleteAccountModalController', - resolve: { - userDefaultEmail() { - return UserAffiliationsDataService.getUserDefaultEmail() - .then( - defaultEmailDetails => - (defaultEmailDetails != null - ? defaultEmailDetails.email - : undefined) || null - ) - .catch(() => null) - } - } - })) - } - - return ($scope.upgradeIntegration = service => - event_tracking.send('subscription-funnel', 'settings-page', service)) } - ]) - return App.controller('DeleteAccountModalController', [ - '$scope', - '$modalInstance', - '$timeout', - '$http', - 'userDefaultEmail', - function($scope, $modalInstance, $timeout, $http, userDefaultEmail) { - $scope.state = { - isValid: false, - deleteText: '', - password: '', - confirmV1Purge: false, - confirmSharelatexDelete: false, - inflight: false, - error: null - } - - $scope.userDefaultEmail = userDefaultEmail - - $modalInstance.opened.then(() => - $timeout(() => $scope.$broadcast('open'), 700) - ) - - $scope.checkValidation = () => - ($scope.state.isValid = - userDefaultEmail != null && - $scope.state.deleteText.toLowerCase() === - userDefaultEmail.toLowerCase() && - $scope.state.password.length > 0 && - $scope.state.confirmV1Purge && - $scope.state.confirmSharelatexDelete) - - $scope.delete = function() { - $scope.state.inflight = true - $scope.state.error = null - return $http({ - method: 'POST', - url: '/user/delete', - headers: { - 'X-CSRF-Token': window.csrfToken, - 'Content-Type': 'application/json' - }, - data: { - password: $scope.state.password - }, - disableAutoLoginRedirect: true // we want to handle errors ourselves - }) - .then(function() { - $modalInstance.close() - $scope.state.inflight = false - $scope.state.error = null - return setTimeout(() => (window.location = '/login'), 1000) - }) - .catch(function(response) { - const { data, status } = response - $scope.state.inflight = false - if (status === 403) { - $scope.state.error = { code: 'InvalidCredentialsError' } - } else { - $scope.state.error = { code: data.error } - } - }) - } - - return ($scope.cancel = () => $modalInstance.dismiss('cancel')) - } - ]) + return ($scope.cancel = () => $modalInstance.dismiss('cancel')) + }) }) diff --git a/services/web/public/src/main/affiliations/controllers/UserAffiliationsController.js b/services/web/public/src/main/affiliations/controllers/UserAffiliationsController.js index bcf15e95b9..84baef4413 100644 --- a/services/web/public/src/main/affiliations/controllers/UserAffiliationsController.js +++ b/services/web/public/src/main/affiliations/controllers/UserAffiliationsController.js @@ -15,250 +15,249 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('UserAffiliationsController', [ - '$scope', - 'UserAffiliationsDataService', - '$q', - '_', - function($scope, UserAffiliationsDataService, $q, _) { - $scope.userEmails = [] + App.controller('UserAffiliationsController', function( + $scope, + UserAffiliationsDataService, + $q, + _ + ) { + $scope.userEmails = [] - const LOCAL_AND_DOMAIN_REGEX = /([^@]+)@(.+)/ - const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\ ".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA -Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ + const LOCAL_AND_DOMAIN_REGEX = /([^@]+)@(.+)/ + const EMAIL_REGEX = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\ ".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA -Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ - const _matchLocalAndDomain = function(userEmailInput) { - const match = - userEmailInput != null - ? userEmailInput.match(LOCAL_AND_DOMAIN_REGEX) - : undefined - if (match != null) { - return { local: match[1], domain: match[2] } - } else { - return { local: null, domain: null } - } + const _matchLocalAndDomain = function(userEmailInput) { + const match = + userEmailInput != null + ? userEmailInput.match(LOCAL_AND_DOMAIN_REGEX) + : undefined + if (match != null) { + return { local: match[1], domain: match[2] } + } else { + return { local: null, domain: null } } + } - $scope.getEmailSuggestion = function(userInput) { - const userInputLocalAndDomain = _matchLocalAndDomain(userInput) - $scope.ui.isValidEmail = EMAIL_REGEX.test(userInput) - $scope.ui.isBlacklistedEmail = false - $scope.ui.showManualUniversitySelectionUI = false - if (userInputLocalAndDomain.domain != null) { - $scope.ui.isBlacklistedEmail = UserAffiliationsDataService.isDomainBlacklisted( - userInputLocalAndDomain.domain - ) - return UserAffiliationsDataService.getUniversityDomainFromPartialDomainInput( - userInputLocalAndDomain.domain - ) - .then(function(universityDomain) { - const currentUserInputLocalAndDomain = _matchLocalAndDomain( - $scope.newAffiliation.email - ) - if ( - currentUserInputLocalAndDomain.domain === - universityDomain.hostname - ) { - $scope.newAffiliation.university = universityDomain.university - $scope.newAffiliation.department = universityDomain.department - } else { - $scope.newAffiliation.university = null - $scope.newAffiliation.department = null - } - return $q.resolve( - `${userInputLocalAndDomain.local}@${universityDomain.hostname}` - ) - }) - .catch(function() { + $scope.getEmailSuggestion = function(userInput) { + const userInputLocalAndDomain = _matchLocalAndDomain(userInput) + $scope.ui.isValidEmail = EMAIL_REGEX.test(userInput) + $scope.ui.isBlacklistedEmail = false + $scope.ui.showManualUniversitySelectionUI = false + if (userInputLocalAndDomain.domain != null) { + $scope.ui.isBlacklistedEmail = UserAffiliationsDataService.isDomainBlacklisted( + userInputLocalAndDomain.domain + ) + return UserAffiliationsDataService.getUniversityDomainFromPartialDomainInput( + userInputLocalAndDomain.domain + ) + .then(function(universityDomain) { + const currentUserInputLocalAndDomain = _matchLocalAndDomain( + $scope.newAffiliation.email + ) + if ( + currentUserInputLocalAndDomain.domain === + universityDomain.hostname + ) { + $scope.newAffiliation.university = universityDomain.university + $scope.newAffiliation.department = universityDomain.department + } else { $scope.newAffiliation.university = null $scope.newAffiliation.department = null - return $q.reject(null) - }) - } else { - $scope.newAffiliation.university = null - $scope.newAffiliation.department = null - return $q.reject(null) - } - } - - $scope.selectUniversityManually = function() { + } + return $q.resolve( + `${userInputLocalAndDomain.local}@${universityDomain.hostname}` + ) + }) + .catch(function() { + $scope.newAffiliation.university = null + $scope.newAffiliation.department = null + return $q.reject(null) + }) + } else { $scope.newAffiliation.university = null $scope.newAffiliation.department = null - return ($scope.ui.showManualUniversitySelectionUI = true) + return $q.reject(null) } + } - $scope.changeAffiliation = function(userEmail) { - if ( - __guard__( - userEmail.affiliation != null - ? userEmail.affiliation.institution - : undefined, - x => x.id - ) != null - ) { - UserAffiliationsDataService.getUniversityDetails( - userEmail.affiliation.institution.id - ).then( - universityDetails => - ($scope.affiliationToChange.university = universityDetails) - ) - } + $scope.selectUniversityManually = function() { + $scope.newAffiliation.university = null + $scope.newAffiliation.department = null + return ($scope.ui.showManualUniversitySelectionUI = true) + } - $scope.affiliationToChange.email = userEmail.email - $scope.affiliationToChange.role = userEmail.affiliation.role - return ($scope.affiliationToChange.department = - userEmail.affiliation.department) - } - - $scope.saveAffiliationChange = function(userEmail) { - userEmail.affiliation.role = $scope.affiliationToChange.role - userEmail.affiliation.department = $scope.affiliationToChange.department - _resetAffiliationToChange() - return _monitorRequest( - UserAffiliationsDataService.addRoleAndDepartment( - userEmail.email, - userEmail.affiliation.role, - userEmail.affiliation.department - ) - ).then(() => setTimeout(() => _getUserEmails())) - } - - $scope.cancelAffiliationChange = email => _resetAffiliationToChange() - - $scope.isChangingAffiliation = email => - $scope.affiliationToChange.email === email - - $scope.showAddEmailForm = () => ($scope.ui.showAddEmailUI = true) - - $scope.addNewEmail = function() { - let addEmailPromise - if ($scope.newAffiliation.university == null) { - addEmailPromise = UserAffiliationsDataService.addUserEmail( - $scope.newAffiliation.email - ) - } else { - if ($scope.newAffiliation.university.isUserSuggested) { - addEmailPromise = UserAffiliationsDataService.addUserAffiliationWithUnknownUniversity( - $scope.newAffiliation.email, - $scope.newAffiliation.university.name, - $scope.newAffiliation.country.code, - $scope.newAffiliation.role, - $scope.newAffiliation.department - ) - } else { - addEmailPromise = UserAffiliationsDataService.addUserAffiliation( - $scope.newAffiliation.email, - $scope.newAffiliation.university.id, - $scope.newAffiliation.role, - $scope.newAffiliation.department - ) - } - } - - $scope.ui.isAddingNewEmail = true - $scope.ui.showAddEmailUI = false - return _monitorRequest(addEmailPromise) - .then(function() { - _resetNewAffiliation() - _resetAddingEmail() - return setTimeout(() => _getUserEmails()) - }) - .finally(() => ($scope.ui.isAddingNewEmail = false)) - } - - $scope.setDefaultUserEmail = userEmail => - _monitorRequest( - UserAffiliationsDataService.setDefaultUserEmail(userEmail.email) - ).then(function() { - for (let email of Array.from($scope.userEmails || [])) { - email.default = false - } - return (userEmail.default = true) - }) - - $scope.removeUserEmail = function(userEmail) { - $scope.userEmails = $scope.userEmails.filter(ue => ue !== userEmail) - return _monitorRequest( - UserAffiliationsDataService.removeUserEmail(userEmail.email) + $scope.changeAffiliation = function(userEmail) { + if ( + __guard__( + userEmail.affiliation != null + ? userEmail.affiliation.institution + : undefined, + x => x.id + ) != null + ) { + UserAffiliationsDataService.getUniversityDetails( + userEmail.affiliation.institution.id + ).then( + universityDetails => + ($scope.affiliationToChange.university = universityDetails) ) } - $scope.resendConfirmationEmail = function(userEmail) { - $scope.ui.isResendingConfirmation = true - return _monitorRequest( - UserAffiliationsDataService.resendConfirmationEmail(userEmail.email) - ).finally(() => ($scope.ui.isResendingConfirmation = false)) - } + $scope.affiliationToChange.email = userEmail.email + $scope.affiliationToChange.role = userEmail.affiliation.role + return ($scope.affiliationToChange.department = + userEmail.affiliation.department) + } - $scope.acknowledgeError = function() { - _reset() - return _getUserEmails() - } + $scope.saveAffiliationChange = function(userEmail) { + userEmail.affiliation.role = $scope.affiliationToChange.role + userEmail.affiliation.department = $scope.affiliationToChange.department + _resetAffiliationToChange() + return _monitorRequest( + UserAffiliationsDataService.addRoleAndDepartment( + userEmail.email, + userEmail.affiliation.role, + userEmail.affiliation.department + ) + ).then(() => setTimeout(() => _getUserEmails())) + } - var _resetAffiliationToChange = () => - ($scope.affiliationToChange = { - email: '', - university: null, - role: null, - department: null - }) + $scope.cancelAffiliationChange = email => _resetAffiliationToChange() - var _resetNewAffiliation = () => - ($scope.newAffiliation = { - email: '', - country: null, - university: null, - role: null, - department: null - }) + $scope.isChangingAffiliation = email => + $scope.affiliationToChange.email === email - var _resetAddingEmail = function() { - $scope.ui.showAddEmailUI = false - $scope.ui.isValidEmail = false - $scope.ui.isBlacklistedEmail = false - return ($scope.ui.showManualUniversitySelectionUI = false) - } + $scope.showAddEmailForm = () => ($scope.ui.showAddEmailUI = true) - var _reset = function() { - $scope.ui = { - hasError: false, - errorMessage: '', - showChangeAffiliationUI: false, - isMakingRequest: false, - isLoadingEmails: false, - isAddingNewEmail: false, - isResendingConfirmation: false + $scope.addNewEmail = function() { + let addEmailPromise + if ($scope.newAffiliation.university == null) { + addEmailPromise = UserAffiliationsDataService.addUserEmail( + $scope.newAffiliation.email + ) + } else { + if ($scope.newAffiliation.university.isUserSuggested) { + addEmailPromise = UserAffiliationsDataService.addUserAffiliationWithUnknownUniversity( + $scope.newAffiliation.email, + $scope.newAffiliation.university.name, + $scope.newAffiliation.country.code, + $scope.newAffiliation.role, + $scope.newAffiliation.department + ) + } else { + addEmailPromise = UserAffiliationsDataService.addUserAffiliation( + $scope.newAffiliation.email, + $scope.newAffiliation.university.id, + $scope.newAffiliation.role, + $scope.newAffiliation.department + ) } - _resetAffiliationToChange() - _resetNewAffiliation() - return _resetAddingEmail() } + + $scope.ui.isAddingNewEmail = true + $scope.ui.showAddEmailUI = false + return _monitorRequest(addEmailPromise) + .then(function() { + _resetNewAffiliation() + _resetAddingEmail() + return setTimeout(() => _getUserEmails()) + }) + .finally(() => ($scope.ui.isAddingNewEmail = false)) + } + + $scope.setDefaultUserEmail = userEmail => + _monitorRequest( + UserAffiliationsDataService.setDefaultUserEmail(userEmail.email) + ).then(function() { + for (let email of Array.from($scope.userEmails || [])) { + email.default = false + } + return (userEmail.default = true) + }) + + $scope.removeUserEmail = function(userEmail) { + $scope.userEmails = $scope.userEmails.filter(ue => ue !== userEmail) + return _monitorRequest( + UserAffiliationsDataService.removeUserEmail(userEmail.email) + ) + } + + $scope.resendConfirmationEmail = function(userEmail) { + $scope.ui.isResendingConfirmation = true + return _monitorRequest( + UserAffiliationsDataService.resendConfirmationEmail(userEmail.email) + ).finally(() => ($scope.ui.isResendingConfirmation = false)) + } + + $scope.acknowledgeError = function() { _reset() - - var _monitorRequest = function(promise) { - $scope.ui.hasError = false - $scope.ui.isMakingRequest = true - promise - .catch(function(response) { - $scope.ui.hasError = true - return ($scope.ui.errorMessage = __guard__( - response != null ? response.data : undefined, - x => x.message - )) - }) - .finally(() => ($scope.ui.isMakingRequest = false)) - return promise - } - - // Populates the emails table - var _getUserEmails = function() { - $scope.ui.isLoadingEmails = true - return _monitorRequest(UserAffiliationsDataService.getUserEmails()) - .then(emails => ($scope.userEmails = emails)) - .finally(() => ($scope.ui.isLoadingEmails = false)) - } return _getUserEmails() } - ])) + + var _resetAffiliationToChange = () => + ($scope.affiliationToChange = { + email: '', + university: null, + role: null, + department: null + }) + + var _resetNewAffiliation = () => + ($scope.newAffiliation = { + email: '', + country: null, + university: null, + role: null, + department: null + }) + + var _resetAddingEmail = function() { + $scope.ui.showAddEmailUI = false + $scope.ui.isValidEmail = false + $scope.ui.isBlacklistedEmail = false + return ($scope.ui.showManualUniversitySelectionUI = false) + } + + var _reset = function() { + $scope.ui = { + hasError: false, + errorMessage: '', + showChangeAffiliationUI: false, + isMakingRequest: false, + isLoadingEmails: false, + isAddingNewEmail: false, + isResendingConfirmation: false + } + _resetAffiliationToChange() + _resetNewAffiliation() + return _resetAddingEmail() + } + _reset() + + var _monitorRequest = function(promise) { + $scope.ui.hasError = false + $scope.ui.isMakingRequest = true + promise + .catch(function(response) { + $scope.ui.hasError = true + return ($scope.ui.errorMessage = __guard__( + response != null ? response.data : undefined, + x => x.message + )) + }) + .finally(() => ($scope.ui.isMakingRequest = false)) + return promise + } + + // Populates the emails table + var _getUserEmails = function() { + $scope.ui.isLoadingEmails = true + return _monitorRequest(UserAffiliationsDataService.getUserEmails()) + .then(emails => ($scope.userEmails = emails)) + .finally(() => ($scope.ui.isLoadingEmails = false)) + } + return _getUserEmails() + })) function __guard__(value, transform) { return typeof value !== 'undefined' && value !== null ? transform(value) diff --git a/services/web/public/src/main/affiliations/factories/UserAffiliationsDataService.js b/services/web/public/src/main/affiliations/factories/UserAffiliationsDataService.js index 7cef74b0a4..18fe30a150 100644 --- a/services/web/public/src/main/affiliations/factories/UserAffiliationsDataService.js +++ b/services/web/public/src/main/affiliations/factories/UserAffiliationsDataService.js @@ -414,151 +414,145 @@ define(['base'], function(App) { } } - return App.factory('UserAffiliationsDataService', [ - '$http', - '$q', - '_', - function($http, $q, _) { - const getCountries = () => $q.resolve(countriesList) + return App.factory('UserAffiliationsDataService', function($http, $q, _) { + const getCountries = () => $q.resolve(countriesList) - const getDefaultRoleHints = () => $q.resolve(defaultRoleHints) + const getDefaultRoleHints = () => $q.resolve(defaultRoleHints) - const getDefaultDepartmentHints = () => $q.resolve(defaultDepartmentHints) + const getDefaultDepartmentHints = () => $q.resolve(defaultDepartmentHints) - const getUserEmails = () => - $http.get('/user/emails').then(response => response.data) + const getUserEmails = () => + $http.get('/user/emails').then(response => response.data) - const getUserDefaultEmail = () => - getUserEmails().then(userEmails => - _.find(userEmails, userEmail => userEmail.default) - ) + const getUserDefaultEmail = () => + getUserEmails().then(userEmails => + _.find(userEmails, userEmail => userEmail.default) + ) - const getUniversitiesFromCountry = function(country) { - let universitiesFromCountry - if (universities[country.code] != null) { - universitiesFromCountry = universities[country.code] - } else { - universitiesFromCountry = $http - .get('/institutions/list', { - params: { country_code: country.code } - }) - .then(response => (universities[country.code] = response.data)) - } - return $q.resolve(universitiesFromCountry) + const getUniversitiesFromCountry = function(country) { + let universitiesFromCountry + if (universities[country.code] != null) { + universitiesFromCountry = universities[country.code] + } else { + universitiesFromCountry = $http + .get('/institutions/list', { + params: { country_code: country.code } + }) + .then(response => (universities[country.code] = response.data)) } + return $q.resolve(universitiesFromCountry) + } - const getUniversityDomainFromPartialDomainInput = function( - partialDomainInput - ) { - if (universitiesByDomain[partialDomainInput] != null) { - return $q.resolve(universitiesByDomain[partialDomainInput]) - } else { - return $http - .get('/institutions/domains', { - params: { hostname: partialDomainInput, limit: 1 } - }) - .then(function(response) { - const university = response.data[0] - if ( - university != null && - !isDomainBlacklisted(university.hostname) - ) { - universitiesByDomain[university.hostname] = university - return $q.resolve(university) - } else { - return $q.reject(null) - } - }) - } - } - - const getUniversityDetails = universityId => - $http - .get(`/institutions/list/${universityId}`) - .then(response => response.data) - - const addUserEmail = email => - $http.post('/user/emails', { - email, - _csrf: window.csrfToken - }) - - const addUserAffiliationWithUnknownUniversity = ( - email, - unknownUniversityName, - unknownUniversityCountryCode, - role, - department - ) => - $http.post('/user/emails', { - email, - university: { - name: unknownUniversityName, - country_code: unknownUniversityCountryCode - }, - role, - department, - _csrf: window.csrfToken - }) - - const addUserAffiliation = (email, universityId, role, department) => - $http.post('/user/emails', { - email, - university: { - id: universityId - }, - role, - department, - _csrf: window.csrfToken - }) - - const addRoleAndDepartment = (email, role, department) => - $http.post('/user/emails/endorse', { - email, - role, - department, - _csrf: window.csrfToken - }) - - const setDefaultUserEmail = email => - $http.post('/user/emails/default', { - email, - _csrf: window.csrfToken - }) - - const removeUserEmail = email => - $http.post('/user/emails/delete', { - email, - _csrf: window.csrfToken - }) - - const resendConfirmationEmail = email => - $http.post('/user/emails/resend_confirmation', { - email, - _csrf: window.csrfToken - }) - - var isDomainBlacklisted = domain => - domain.toLowerCase() in domainsBlackList - - return { - getCountries, - getDefaultRoleHints, - getDefaultDepartmentHints, - getUserEmails, - getUserDefaultEmail, - getUniversitiesFromCountry, - getUniversityDomainFromPartialDomainInput, - getUniversityDetails, - addUserEmail, - addUserAffiliationWithUnknownUniversity, - addUserAffiliation, - addRoleAndDepartment, - setDefaultUserEmail, - removeUserEmail, - resendConfirmationEmail, - isDomainBlacklisted + const getUniversityDomainFromPartialDomainInput = function( + partialDomainInput + ) { + if (universitiesByDomain[partialDomainInput] != null) { + return $q.resolve(universitiesByDomain[partialDomainInput]) + } else { + return $http + .get('/institutions/domains', { + params: { hostname: partialDomainInput, limit: 1 } + }) + .then(function(response) { + const university = response.data[0] + if ( + university != null && + !isDomainBlacklisted(university.hostname) + ) { + universitiesByDomain[university.hostname] = university + return $q.resolve(university) + } else { + return $q.reject(null) + } + }) } } - ]) + + const getUniversityDetails = universityId => + $http + .get(`/institutions/list/${universityId}`) + .then(response => response.data) + + const addUserEmail = email => + $http.post('/user/emails', { + email, + _csrf: window.csrfToken + }) + + const addUserAffiliationWithUnknownUniversity = ( + email, + unknownUniversityName, + unknownUniversityCountryCode, + role, + department + ) => + $http.post('/user/emails', { + email, + university: { + name: unknownUniversityName, + country_code: unknownUniversityCountryCode + }, + role, + department, + _csrf: window.csrfToken + }) + + const addUserAffiliation = (email, universityId, role, department) => + $http.post('/user/emails', { + email, + university: { + id: universityId + }, + role, + department, + _csrf: window.csrfToken + }) + + const addRoleAndDepartment = (email, role, department) => + $http.post('/user/emails/endorse', { + email, + role, + department, + _csrf: window.csrfToken + }) + + const setDefaultUserEmail = email => + $http.post('/user/emails/default', { + email, + _csrf: window.csrfToken + }) + + const removeUserEmail = email => + $http.post('/user/emails/delete', { + email, + _csrf: window.csrfToken + }) + + const resendConfirmationEmail = email => + $http.post('/user/emails/resend_confirmation', { + email, + _csrf: window.csrfToken + }) + + var isDomainBlacklisted = domain => domain.toLowerCase() in domainsBlackList + + return { + getCountries, + getDefaultRoleHints, + getDefaultDepartmentHints, + getUserEmails, + getUserDefaultEmail, + getUniversitiesFromCountry, + getUniversityDomainFromPartialDomainInput, + getUniversityDetails, + addUserEmail, + addUserAffiliationWithUnknownUniversity, + addUserAffiliation, + addRoleAndDepartment, + setDefaultUserEmail, + removeUserEmail, + resendConfirmationEmail, + isDomainBlacklisted + } + }) }) diff --git a/services/web/public/src/main/clear-sessions.js b/services/web/public/src/main/clear-sessions.js index fd709963e7..256d8c8bbc 100644 --- a/services/web/public/src/main/clear-sessions.js +++ b/services/web/public/src/main/clear-sessions.js @@ -11,29 +11,25 @@ * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md */ define(['base'], App => - App.controller('ClearSessionsController', [ - '$scope', - '$http', - function($scope, $http) { - $scope.state = { - otherSessions: window.otherSessions, - error: false, - success: false - } - - return ($scope.clearSessions = function() { - console.log('>> clearing all sessions') - return $http({ - method: 'POST', - url: '/user/sessions/clear', - headers: { 'X-CSRF-Token': window.csrfToken } - }) - .then(function() { - $scope.state.otherSessions = [] - $scope.state.error = false - return ($scope.state.success = true) - }) - .catch(() => ($scope.state.error = true)) - }) + App.controller('ClearSessionsController', function($scope, $http) { + $scope.state = { + otherSessions: window.otherSessions, + error: false, + success: false } - ])) + + return ($scope.clearSessions = function() { + console.log('>> clearing all sessions') + return $http({ + method: 'POST', + url: '/user/sessions/clear', + headers: { 'X-CSRF-Token': window.csrfToken } + }) + .then(function() { + $scope.state.otherSessions = [] + $scope.state.error = false + return ($scope.state.success = true) + }) + .catch(() => ($scope.state.error = true)) + }) + })) diff --git a/services/web/public/src/main/oauth/controllers/UserOauthController.js b/services/web/public/src/main/oauth/controllers/UserOauthController.js index abc0417b93..368d41ddf6 100644 --- a/services/web/public/src/main/oauth/controllers/UserOauthController.js +++ b/services/web/public/src/main/oauth/controllers/UserOauthController.js @@ -1,92 +1,91 @@ define(['base'], App => - App.controller('UserOauthController', [ - '$http', - '$scope', - '$q', - '_', - 'UserOauthDataService', - function($http, $scope, $q, _, UserOauthDataService) { - const _monitorRequest = function(promise) { - $scope.ui.hasError = false - $scope.ui.isLoadingV1Ids = true - promise - .catch(response => { - $scope.ui.hasError = true - $scope.ui.errorMessage = - response && response.data && response.data.message - ? response.data.message - : 'error' - }) - .finally(() => { - $scope.ui.isLoadingV1Ids = false - }) - return promise + App.controller('UserOauthController', function( + $http, + $scope, + $q, + _, + UserOauthDataService + ) { + const _monitorRequest = function(promise) { + $scope.ui.hasError = false + $scope.ui.isLoadingV1Ids = true + promise + .catch(response => { + $scope.ui.hasError = true + $scope.ui.errorMessage = + response && response.data && response.data.message + ? response.data.message + : 'error' + }) + .finally(() => { + $scope.ui.isLoadingV1Ids = false + }) + return promise + } + const _reset = function() { + $scope.ui = { + hasError: false, + errorMessage: '', + isLoadingV1Ids: false } - const _reset = function() { - $scope.ui = { + $scope.providers = window.oauthProviders + $scope.thirdPartyIds = window.thirdPartyIds + // until oauthUseV2=true, we will use OAuth data via v1 DB, + // except for Collabratec, which is only writing to the v2 DB. + // $scope.v2ThirdPartyIds is required for Collabratec, + // and only until v2 is authoritative. Though, we should leave this + // until we stop double writes, in case we need to flip. + // Double writes for OAuth will stop when oauthFallback=false + $scope.v2ThirdPartyIds = window.thirdPartyIds + } + const _getUserV1OauthProviders = () => { + $scope.ui.isLoadingV1Ids = true + return _monitorRequest(UserOauthDataService.getUserOauthV1()).then( + thirdPartyIds => { + $scope.thirdPartyIds = thirdPartyIds + } + ) + } + const _unlinkError = (providerId, err) => { + $scope.providers[providerId].ui.hasError = true + $scope.providers[providerId].ui.errorMessage = + err && err.data && err.data.message ? err.data.message : 'error' + } + + $scope.unlink = providerId => { + if (window.ExposedSettings.isOverleaf) { + // UI + $scope.providers[providerId].ui = { hasError: false, - errorMessage: '', - isLoadingV1Ids: false + isProcessing: true } - $scope.providers = window.oauthProviders - $scope.thirdPartyIds = window.thirdPartyIds - // until oauthUseV2=true, we will use OAuth data via v1 DB, - // except for Collabratec, which is only writing to the v2 DB. - // $scope.v2ThirdPartyIds is required for Collabratec, - // and only until v2 is authoritative. Though, we should leave this - // until we stop double writes, in case we need to flip. - // Double writes for OAuth will stop when oauthFallback=false - $scope.v2ThirdPartyIds = window.thirdPartyIds - } - const _getUserV1OauthProviders = () => { - $scope.ui.isLoadingV1Ids = true - return _monitorRequest(UserOauthDataService.getUserOauthV1()).then( - thirdPartyIds => { - $scope.thirdPartyIds = thirdPartyIds - } - ) - } - const _unlinkError = (providerId, err) => { - $scope.providers[providerId].ui.hasError = true - $scope.providers[providerId].ui.errorMessage = - err && err.data && err.data.message ? err.data.message : 'error' - } - - $scope.unlink = providerId => { - if (window.ExposedSettings.isOverleaf) { - // UI - $scope.providers[providerId].ui = { - hasError: false, - isProcessing: true - } - // Data for update - const data = { - _csrf: window.csrfToken, - link: false, - providerId - } - $http - .post('/user/oauth-unlink', data) - .catch(error => { - $scope.providers[providerId].ui.isProcessing = false - _unlinkError(providerId, error) - }) - .then(response => { - $scope.providers[providerId].ui.isProcessing = false - if (response.status === 200) { - $scope.thirdPartyIds[providerId] = null - // v2thirdPartyIds below can be removed post user c11n - $scope.v2ThirdPartyIds[providerId] = null - } else { - _unlinkError(providerId, response) - } - }) + // Data for update + const data = { + _csrf: window.csrfToken, + link: false, + providerId } - } - - _reset() - if (!window.oauthUseV2) { - _getUserV1OauthProviders() + $http + .post('/user/oauth-unlink', data) + .catch(error => { + $scope.providers[providerId].ui.isProcessing = false + _unlinkError(providerId, error) + }) + .then(response => { + $scope.providers[providerId].ui.isProcessing = false + if (response.status === 200) { + $scope.thirdPartyIds[providerId] = null + // v2thirdPartyIds below can be removed post user c11n + $scope.v2ThirdPartyIds[providerId] = null + } else { + _unlinkError(providerId, response) + } + }) } } - ])) + + _reset() + if (!window.oauthUseV2) { + _getUserV1OauthProviders() + } + })) diff --git a/services/web/public/src/main/oauth/factories/UserOauthDataService.js b/services/web/public/src/main/oauth/factories/UserOauthDataService.js index 52b8204e1a..9339c06bd5 100644 --- a/services/web/public/src/main/oauth/factories/UserOauthDataService.js +++ b/services/web/public/src/main/oauth/factories/UserOauthDataService.js @@ -1,20 +1,17 @@ define(['base'], function(App) { - return App.factory('UserOauthDataService', [ - '$http', - function($http) { - const getUserOauthV1 = () => { - if (window.ExposedSettings.isOverleaf) { - return $http.get('/user/v1-oauth-uids').then(response => { - return response.data - }) - } else { - return {} - } - } - - return { - getUserOauthV1 + return App.factory('UserOauthDataService', function($http) { + const getUserOauthV1 = () => { + if (window.ExposedSettings.isOverleaf) { + return $http.get('/user/v1-oauth-uids').then(response => { + return response.data + }) + } else { + return {} } } - ]) + + return { + getUserOauthV1 + } + }) }) diff --git a/services/web/public/src/main/project-list/services/project-list.js b/services/web/public/src/main/project-list/services/project-list.js index 5f87c687ce..c840d4a26a 100644 --- a/services/web/public/src/main/project-list/services/project-list.js +++ b/services/web/public/src/main/project-list/services/project-list.js @@ -2,33 +2,31 @@ camelcase */ define(['base'], App => - App.service('ProjectListService', [ - () => ({ - getOwnerName(project) { - if (project.accessLevel === 'owner') { - return 'You' - } else if (project.owner != null) { - return this.getUserName(project.owner) - } else { - return 'None' - } - }, - - getUserName(user) { - if (user && user._id === window.user_id) { - return 'You' - } else if (user) { - const { first_name, last_name, email } = user - if (first_name || last_name) { - return [first_name, last_name].filter(n => n != null).join(' ') - } else if (email) { - return email - } else { - return 'An Overleaf v1 User' - } - } else { - return 'None' - } + App.service('ProjectListService', () => ({ + getOwnerName(project) { + if (project.accessLevel === 'owner') { + return 'You' + } else if (project.owner != null) { + return this.getUserName(project.owner) + } else { + return 'None' } - }) - ])) + }, + + getUserName(user) { + if (user && user._id === window.user_id) { + return 'You' + } else if (user) { + const { first_name, last_name, email } = user + if (first_name || last_name) { + return [first_name, last_name].filter(n => n != null).join(' ') + } else if (email) { + return email + } else { + return 'An Overleaf v1 User' + } + } else { + return 'None' + } + } + }))) diff --git a/services/web/public/src/modules/errorCatcher.js b/services/web/public/src/modules/errorCatcher.js index 1c9e841ebd..967cc8c31e 100644 --- a/services/web/public/src/modules/errorCatcher.js +++ b/services/web/public/src/modules/errorCatcher.js @@ -42,36 +42,30 @@ app.config([ // Interceptor to check auth failures in all $http requests // http://bahmutov.calepin.co/catch-all-errors-in-angular-app.html -app.factory('unAuthHttpResponseInterceptor', [ - '$q', - '$location', - ($q, $location) => ({ - responseError(response) { - // redirect any unauthorised or forbidden responses back to /login - // - // set disableAutoLoginRedirect:true in the http request config - // to disable this behaviour - if ( - [401, 403].includes(response.status) && - !(response.config != null - ? response.config.disableAutoLoginRedirect - : undefined) - ) { - // for /project urls set the ?redir parameter to come back here - // otherwise just go to the login page - if (window.location.pathname.match(/^\/project/)) { - window.location = `/login?redir=${encodeURI( - window.location.pathname - )}` - } else { - window.location = '/login' - } +app.factory('unAuthHttpResponseInterceptor', ($q, $location) => ({ + responseError(response) { + // redirect any unauthorised or forbidden responses back to /login + // + // set disableAutoLoginRedirect:true in the http request config + // to disable this behaviour + if ( + [401, 403].includes(response.status) && + !(response.config != null + ? response.config.disableAutoLoginRedirect + : undefined) + ) { + // for /project urls set the ?redir parameter to come back here + // otherwise just go to the login page + if (window.location.pathname.match(/^\/project/)) { + window.location = `/login?redir=${encodeURI(window.location.pathname)}` + } else { + window.location = '/login' } - // pass the response back to the original requester - return $q.reject(response) } - }) -]) + // pass the response back to the original requester + return $q.reject(response) + } +})) app.config([ '$httpProvider',