diff --git a/browser.html b/browser.html
index 377a656..d7c8941 100644
--- a/browser.html
+++ b/browser.html
@@ -7,7 +7,7 @@
-
+
@@ -22,7 +22,7 @@
SSB browser demo
Public |
Private |
Notifications |
- Chat |
+ Collab |
Profile |
Invites |
Settings
diff --git a/css/chat.css b/css/chat.css
deleted file mode 100644
index 1c00957..0000000
--- a/css/chat.css
+++ /dev/null
@@ -1,25 +0,0 @@
-#chat > #myId {
- padding: 10px
-}
-
-#chat > #acceptConnections {
- margin-right: 1rem;
-}
-
-#chat > #tunnelConnect {
- padding: 5px;
- width: 24rem;
- margin-bottom: 12px;
- margin-left: 1rem;
-}
-
-#chat > #chatMessage {
- padding: 5px;
- width: 40rem;
-}
-
-#chat > #chatDescription {
- font-size: smaller;
- margin-bottom: 10px;
- margin-top: -10px;
-}
diff --git a/css/prose.css b/css/prose.css
new file mode 100644
index 0000000..cfe118d
--- /dev/null
+++ b/css/prose.css
@@ -0,0 +1,363 @@
+#prose > #myId {
+ padding: 10px
+}
+
+#prose > #acceptConnections {
+ margin-right: 1rem;
+}
+
+#prose > #tunnelConnect {
+ padding: 5px;
+ width: 19rem;
+ margin-bottom: 12px;
+ margin-left: 1rem;
+ margin-right: 1rem;
+}
+
+#prose > div > #chatMessage {
+ padding: 5px;
+ width: 45rem;
+}
+
+#prose > #description {
+ font-size: smaller;
+ margin-bottom: 10px;
+ margin-top: -10px;
+}
+
+#prose > div > #markdown > textarea {
+ width: 100%;
+ height: 10rem;
+}
+
+/* from example */
+
+.ProseMirror {
+ position: relative;
+}
+
+.ProseMirror {
+ word-wrap: break-word;
+ white-space: pre-wrap;
+ -webkit-font-variant-ligatures: none;
+ font-variant-ligatures: none;
+}
+
+.ProseMirror pre {
+ white-space: pre-wrap;
+}
+
+.ProseMirror li {
+ position: relative;
+}
+
+.ProseMirror-hideselection *::selection { background: transparent; }
+.ProseMirror-hideselection *::-moz-selection { background: transparent; }
+.ProseMirror-hideselection { caret-color: transparent; }
+
+.ProseMirror-selectednode {
+ outline: 2px solid #8cf;
+}
+
+/* Make sure li selections wrap around markers */
+
+li.ProseMirror-selectednode {
+ outline: none;
+}
+
+li.ProseMirror-selectednode:after {
+ content: "";
+ position: absolute;
+ left: -32px;
+ right: -2px; top: -2px; bottom: -2px;
+ border: 2px solid #8cf;
+ pointer-events: none;
+}
+.ProseMirror-textblock-dropdown {
+ min-width: 3em;
+}
+
+.ProseMirror-menu {
+ margin: 0 -4px;
+ line-height: 1;
+}
+
+.ProseMirror-tooltip .ProseMirror-menu {
+ width: -webkit-fit-content;
+ width: fit-content;
+ white-space: pre;
+}
+
+.ProseMirror-menuitem {
+ margin-right: 3px;
+ display: inline-block;
+}
+
+.ProseMirror-menuseparator {
+ border-right: 1px solid #ddd;
+ margin-right: 3px;
+}
+
+.ProseMirror-menu-dropdown, .ProseMirror-menu-dropdown-menu {
+ font-size: 90%;
+ white-space: nowrap;
+}
+
+.ProseMirror-menu-dropdown {
+ vertical-align: 1px;
+ cursor: pointer;
+ position: relative;
+ padding-right: 15px;
+}
+
+.ProseMirror-menu-dropdown-wrap {
+ padding: 1px 0 1px 4px;
+ display: inline-block;
+ position: relative;
+}
+
+.ProseMirror-menu-dropdown:after {
+ content: "";
+ border-left: 4px solid transparent;
+ border-right: 4px solid transparent;
+ border-top: 4px solid currentColor;
+ opacity: .6;
+ position: absolute;
+ right: 4px;
+ top: calc(50% - 2px);
+}
+
+.ProseMirror-menu-dropdown-menu, .ProseMirror-menu-submenu {
+ position: absolute;
+ background: white;
+ color: #666;
+ border: 1px solid #aaa;
+ padding: 2px;
+}
+
+.ProseMirror-menu-dropdown-menu {
+ z-index: 15;
+ min-width: 6em;
+}
+
+.ProseMirror-menu-dropdown-item {
+ cursor: pointer;
+ padding: 2px 8px 2px 4px;
+}
+
+.ProseMirror-menu-dropdown-item:hover {
+ background: #f2f2f2;
+}
+
+.ProseMirror-menu-submenu-wrap {
+ position: relative;
+ margin-right: -4px;
+}
+
+.ProseMirror-menu-submenu-label:after {
+ content: "";
+ border-top: 4px solid transparent;
+ border-bottom: 4px solid transparent;
+ border-left: 4px solid currentColor;
+ opacity: .6;
+ position: absolute;
+ right: 4px;
+ top: calc(50% - 4px);
+}
+
+.ProseMirror-menu-submenu {
+ display: none;
+ min-width: 4em;
+ left: 100%;
+ top: -3px;
+}
+
+.ProseMirror-menu-active {
+ background: #eee;
+ border-radius: 4px;
+}
+
+.ProseMirror-menu-active {
+ background: #eee;
+ border-radius: 4px;
+}
+
+.ProseMirror-menu-disabled {
+ opacity: .3;
+}
+
+.ProseMirror-menu-submenu-wrap:hover .ProseMirror-menu-submenu, .ProseMirror-menu-submenu-wrap-active .ProseMirror-menu-submenu {
+ display: block;
+}
+
+.ProseMirror-menubar {
+ border-top-left-radius: inherit;
+ border-top-right-radius: inherit;
+ position: relative;
+ min-height: 1em;
+ color: #666;
+ padding: 1px 6px;
+ top: 0; left: 0; right: 0;
+ border-bottom: 1px solid silver;
+ background: white;
+ z-index: 10;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ overflow: visible;
+}
+
+.ProseMirror-icon {
+ display: inline-block;
+ line-height: .8;
+ vertical-align: -2px; /* Compensate for padding */
+ padding: 2px 8px;
+ cursor: pointer;
+}
+
+.ProseMirror-menu-disabled.ProseMirror-icon {
+ cursor: default;
+}
+
+.ProseMirror-icon svg {
+ fill: currentColor;
+ height: 1em;
+}
+
+.ProseMirror-icon span {
+ vertical-align: text-top;
+}
+.ProseMirror-gapcursor {
+ display: none;
+ pointer-events: none;
+ position: absolute;
+}
+
+.ProseMirror-gapcursor:after {
+ content: "";
+ display: block;
+ position: absolute;
+ top: -2px;
+ width: 20px;
+ border-top: 1px solid black;
+ animation: ProseMirror-cursor-blink 1.1s steps(2, start) infinite;
+}
+
+@keyframes ProseMirror-cursor-blink {
+ to {
+ visibility: hidden;
+ }
+}
+
+.ProseMirror-focused .ProseMirror-gapcursor {
+ display: block;
+}
+/* Add space around the hr to make clicking it easier */
+
+.ProseMirror-example-setup-style hr {
+ padding: 2px 10px;
+ border: none;
+ margin: 1em 0;
+}
+
+.ProseMirror-example-setup-style hr:after {
+ content: "";
+ display: block;
+ height: 1px;
+ background-color: silver;
+ line-height: 2px;
+}
+
+.ProseMirror ul, .ProseMirror ol {
+ padding-left: 30px;
+}
+
+.ProseMirror blockquote {
+ padding-left: 1em;
+ border-left: 3px solid #eee;
+ margin-left: 0; margin-right: 0;
+}
+
+.ProseMirror-example-setup-style img {
+ cursor: default;
+}
+
+.ProseMirror-prompt {
+ background: white;
+ padding: 5px 10px 5px 15px;
+ border: 1px solid silver;
+ position: fixed;
+ border-radius: 3px;
+ z-index: 11;
+ box-shadow: -.5px 2px 5px rgba(0, 0, 0, .2);
+}
+
+.ProseMirror-prompt h5 {
+ margin: 0;
+ font-weight: normal;
+ font-size: 100%;
+ color: #444;
+}
+
+.ProseMirror-prompt input[type="text"],
+.ProseMirror-prompt textarea {
+ background: #eee;
+ border: none;
+ outline: none;
+}
+
+.ProseMirror-prompt input[type="text"] {
+ padding: 0 4px;
+}
+
+.ProseMirror-prompt-close {
+ position: absolute;
+ left: 2px; top: 1px;
+ color: #666;
+ border: none; background: transparent; padding: 0;
+}
+
+.ProseMirror-prompt-close:after {
+ content: "✕";
+ font-size: 12px;
+}
+
+.ProseMirror-invalid {
+ background: #ffc;
+ border: 1px solid #cc7;
+ border-radius: 4px;
+ padding: 5px 10px;
+ position: absolute;
+ min-width: 10em;
+}
+
+.ProseMirror-prompt-buttons {
+ margin-top: 5px;
+ display: none;
+}
+#editor, .editor {
+ background: white;
+ color: black;
+ background-clip: padding-box;
+ border-radius: 4px;
+ border: 2px solid rgba(0, 0, 0, 0.2);
+ padding: 5px 0;
+ margin-bottom: 23px;
+}
+
+.ProseMirror p:first-child,
+.ProseMirror h1:first-child,
+.ProseMirror h2:first-child,
+.ProseMirror h3:first-child,
+.ProseMirror h4:first-child,
+.ProseMirror h5:first-child,
+.ProseMirror h6:first-child {
+ margin-top: 10px;
+}
+
+.ProseMirror {
+ padding: 4px 8px 4px 14px;
+ line-height: 1.2;
+ outline: none;
+}
+
+.ProseMirror p { margin-bottom: 1em }
diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json
index a33c836..4261c14 100644
--- a/npm-shrinkwrap.json
+++ b/npm-shrinkwrap.json
@@ -4,6 +4,270 @@
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "@babel/code-frame": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz",
+ "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.8.3"
+ }
+ },
+ "@babel/core": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz",
+ "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.8.3",
+ "@babel/generator": "^7.9.0",
+ "@babel/helper-module-transforms": "^7.9.0",
+ "@babel/helpers": "^7.9.0",
+ "@babel/parser": "^7.9.0",
+ "@babel/template": "^7.8.6",
+ "@babel/traverse": "^7.9.0",
+ "@babel/types": "^7.9.0",
+ "convert-source-map": "^1.7.0",
+ "debug": "^4.1.0",
+ "gensync": "^1.0.0-beta.1",
+ "json5": "^2.1.2",
+ "lodash": "^4.17.13",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
+ },
+ "@babel/generator": {
+ "version": "7.9.4",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz",
+ "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.9.0",
+ "jsesc": "^2.5.1",
+ "lodash": "^4.17.13",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz",
+ "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.8.3",
+ "@babel/template": "^7.8.3",
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz",
+ "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-member-expression-to-functions": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz",
+ "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-module-imports": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz",
+ "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-module-transforms": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz",
+ "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-imports": "^7.8.3",
+ "@babel/helper-replace-supers": "^7.8.6",
+ "@babel/helper-simple-access": "^7.8.3",
+ "@babel/helper-split-export-declaration": "^7.8.3",
+ "@babel/template": "^7.8.6",
+ "@babel/types": "^7.9.0",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/helper-optimise-call-expression": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz",
+ "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-plugin-utils": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.8.3.tgz",
+ "integrity": "sha512-j+fq49Xds2smCUNYmEHF9kGNkhbet6yVIBp4e6oeQpH1RUs/Ir06xUKzDjDkGcaaokPiTNs2JBWHjaE4csUkZQ==",
+ "dev": true
+ },
+ "@babel/helper-replace-supers": {
+ "version": "7.8.6",
+ "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz",
+ "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-member-expression-to-functions": "^7.8.3",
+ "@babel/helper-optimise-call-expression": "^7.8.3",
+ "@babel/traverse": "^7.8.6",
+ "@babel/types": "^7.8.6"
+ }
+ },
+ "@babel/helper-simple-access": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz",
+ "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.8.3",
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz",
+ "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.8.3"
+ }
+ },
+ "@babel/helper-validator-identifier": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz",
+ "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==",
+ "dev": true
+ },
+ "@babel/helpers": {
+ "version": "7.9.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz",
+ "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.8.3",
+ "@babel/traverse": "^7.9.0",
+ "@babel/types": "^7.9.0"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.9.0.tgz",
+ "integrity": "sha512-lJZPilxX7Op3Nv/2cvFdnlepPXDxi29wxteT57Q965oc5R9v86ztx0jfxVrTcBk8C2kcPkkDa2Z4T3ZsPPVWsQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.9.0",
+ "chalk": "^2.0.0",
+ "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"
+ }
+ },
+ "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/parser": {
+ "version": "7.9.4",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz",
+ "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==",
+ "dev": true
+ },
+ "@babel/plugin-syntax-async-generators": {
+ "version": "7.8.4",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz",
+ "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-dynamic-import": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz",
+ "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-syntax-object-rest-spread": {
+ "version": "7.8.3",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz",
+ "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-plugin-utils": "^7.8.0"
+ }
+ },
+ "@babel/plugin-transform-modules-commonjs": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz",
+ "integrity": "sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-module-transforms": "^7.9.0",
+ "@babel/helper-plugin-utils": "^7.8.3",
+ "@babel/helper-simple-access": "^7.8.3",
+ "babel-plugin-dynamic-import-node": "^2.3.0"
+ }
+ },
"@babel/runtime": {
"version": "7.6.2",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.2.tgz",
@@ -12,6 +276,45 @@
"regenerator-runtime": "^0.13.2"
}
},
+ "@babel/template": {
+ "version": "7.8.6",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz",
+ "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.8.3",
+ "@babel/parser": "^7.8.6",
+ "@babel/types": "^7.8.6"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz",
+ "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.8.3",
+ "@babel/generator": "^7.9.0",
+ "@babel/helper-function-name": "^7.8.3",
+ "@babel/helper-split-export-declaration": "^7.8.3",
+ "@babel/parser": "^7.9.0",
+ "@babel/types": "^7.9.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.13"
+ }
+ },
+ "@babel/types": {
+ "version": "7.9.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz",
+ "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-validator-identifier": "^7.9.0",
+ "lodash": "^4.17.13",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
"@goto-bus-stop/common-shake": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@goto-bus-stop/common-shake/-/common-shake-2.3.0.tgz",
@@ -221,6 +524,25 @@
"idb-kv-store": "^4.4.0"
}
},
+ "babel-code-frame": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
+ "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ },
+ "dependencies": {
+ "js-tokens": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
+ "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
+ "dev": true
+ }
+ }
+ },
"babel-extract-comments": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/babel-extract-comments/-/babel-extract-comments-1.0.0.tgz",
@@ -229,6 +551,33 @@
"babylon": "^6.18.0"
}
},
+ "babel-messages": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
+ "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0"
+ }
+ },
+ "babel-plugin-dynamic-import-node": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz",
+ "integrity": "sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ==",
+ "dev": true,
+ "requires": {
+ "object.assign": "^4.1.0"
+ }
+ },
+ "babel-plugin-import-to-require": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-import-to-require/-/babel-plugin-import-to-require-1.0.0.tgz",
+ "integrity": "sha512-dc843CwrFivjO8AVgxcHvxl0cb7J7Ed8ZGFP8+PjH3X1CnyzYtAU1WL1349m9Wc/+oqk4ETx2+cIEO2jlp3XyQ==",
+ "dev": true,
+ "requires": {
+ "babel-template": "^6.26.0"
+ }
+ },
"babel-plugin-syntax-object-rest-spread": {
"version": "6.13.0",
"resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz",
@@ -259,6 +608,79 @@
}
}
},
+ "babel-template": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
+ "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
+ }
+ },
+ "babel-traverse": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
+ "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
+ "dev": true,
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "babel-types": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+ "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
+ },
+ "dependencies": {
+ "to-fast-properties": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+ "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=",
+ "dev": true
+ }
+ }
+ },
"babylon": {
"version": "6.18.0",
"resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
@@ -595,6 +1017,21 @@
"resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
},
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
"combine-source-map": {
"version": "0.8.0",
"resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz",
@@ -812,6 +1249,11 @@
}
}
},
+ "crelt": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.4.tgz",
+ "integrity": "sha512-l1cwMUOssGLEj5zgbut4lxJq95ZabOXVZnDybNqQRUtXh1lvUK7e7kJNm8SfvTQzYpE3AVJhIVUJKf382lMA7A=="
+ },
"crypto-browserify": {
"version": "3.12.0",
"resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
@@ -1269,6 +1711,24 @@
"estraverse": "^4.1.1"
}
},
+ "esmify": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/esmify/-/esmify-2.1.1.tgz",
+ "integrity": "sha512-GyOVgjG7sNyYB5Mbo15Ll4aGrcXZzZ3LI22rbLOjCI7L/wYelzQpBHRZkZkqbPNZ/QIRilcaHqzgNCLcEsi1lQ==",
+ "dev": true,
+ "requires": {
+ "@babel/core": "^7.2.2",
+ "@babel/plugin-syntax-async-generators": "^7.2.0",
+ "@babel/plugin-syntax-dynamic-import": "^7.2.0",
+ "@babel/plugin-syntax-object-rest-spread": "^7.2.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.2.0",
+ "babel-plugin-import-to-require": "^1.0.0",
+ "cached-path-relative": "^1.0.2",
+ "concat-stream": "^1.6.2",
+ "duplexer2": "^0.1.4",
+ "through2": "^2.0.5"
+ }
+ },
"esprima": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
@@ -1486,6 +1946,12 @@
"is-property": "^1.0.0"
}
},
+ "gensync": {
+ "version": "1.0.0-beta.1",
+ "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz",
+ "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==",
+ "dev": true
+ },
"get-assigned-identifiers": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz",
@@ -1509,6 +1975,12 @@
"path-is-absolute": "^1.0.0"
}
},
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
"gossip-query": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/gossip-query/-/gossip-query-2.0.2.tgz",
@@ -1540,6 +2012,12 @@
"ansi-regex": "^2.0.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
+ },
"has-symbols": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz",
@@ -1698,6 +2176,15 @@
}
}
},
+ "invariant": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
+ "dev": true,
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ },
"ip": {
"version": "1.1.5",
"resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
@@ -1802,6 +2289,23 @@
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
+ "isomorphic.js": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/isomorphic.js/-/isomorphic.js-0.1.3.tgz",
+ "integrity": "sha512-pabBRLDwYefSsNS+qCazJ97o7P5xDTrNoxSYFTM09JlZTxPrOEPGKekwqUy3/Np4C4PHnVUXHYsZPOix0jELsA=="
+ },
+ "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
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
"json-buffer": {
"version": "2.0.11",
"resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-2.0.11.tgz",
@@ -1816,6 +2320,23 @@
"jsonify": "~0.0.0"
}
},
+ "json5": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz",
+ "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.5"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
+ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
+ "dev": true
+ }
+ }
+ },
"jsonfile": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
@@ -2021,6 +2542,14 @@
"type-check": "~0.3.2"
}
},
+ "lib0": {
+ "version": "0.2.22",
+ "resolved": "https://registry.npmjs.org/lib0/-/lib0-0.2.22.tgz",
+ "integrity": "sha512-SFzX7/SGgrOK6VABQugczhAwaaZLW1VcrE9xG+cVG1+AMQWmcu/7SZaJq0KORnfHr1xK4P6JUBWfoxSCwBcgLA==",
+ "requires": {
+ "isomorphic.js": "^0.1.3"
+ }
+ },
"libnested": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/libnested/-/libnested-1.5.0.tgz",
@@ -2047,6 +2576,12 @@
"uc.micro": "^1.0.1"
}
},
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+ "dev": true
+ },
"lodash._reinterpolate": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
@@ -2100,6 +2635,15 @@
"resolved": "https://registry.npmjs.org/looper/-/looper-4.0.0.tgz",
"integrity": "sha1-dwat7VmpntygbmtUu4bI7BnJUVU="
},
+ "loose-envify": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
+ "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
+ "dev": true,
+ "requires": {
+ "js-tokens": "^3.0.0 || ^4.0.0"
+ }
+ },
"lossy-store": {
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lossy-store/-/lossy-store-1.2.4.tgz",
@@ -2498,6 +3042,11 @@
"resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz",
"integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8="
},
+ "orderedmap": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-1.1.1.tgz",
+ "integrity": "sha512-3Ux8um0zXbVacKUkcytc0u3HgC0b0bBLT+I60r2J/En72cI0nZffqrA7Xtf2Hqs27j1g82llR5Mhbd0Z1XW4AQ=="
+ },
"os-browserify": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz",
@@ -2651,6 +3200,145 @@
"resolved": "https://registry.npmjs.org/promisize/-/promisize-1.1.2.tgz",
"integrity": "sha1-m0fiyyrkl+seutwsQZHWTRXJSdE="
},
+ "prosemirror-commands": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.1.3.tgz",
+ "integrity": "sha512-YVbKwTR4likoyhuwIUC9egbzHvnFrFUNbiesB0DB/HZ8hBcopQ42Tb4KGlYrS3n+pNDTFObN73CLFY6mYLN2IQ==",
+ "requires": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "prosemirror-dropcursor": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.3.2.tgz",
+ "integrity": "sha512-4c94OUGyobGnwcQI70OXyMhE/9T4aTgjU+CHxkd5c7D+jH/J0mKM/lk+jneFVKt7+E4/M0D9HzRPifu8U28Thw==",
+ "requires": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0",
+ "prosemirror-view": "^1.1.0"
+ }
+ },
+ "prosemirror-example-setup": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-example-setup/-/prosemirror-example-setup-1.1.2.tgz",
+ "integrity": "sha512-MTpIMyqk08jFnzxeRMCinCEMtVSTUtxKgQBGxfCbVe9C6zIOqp9qZZJz5Ojaad1GETySyuj8+OIHHvQsIaaaGQ==",
+ "requires": {
+ "prosemirror-commands": "^1.0.0",
+ "prosemirror-dropcursor": "^1.0.0",
+ "prosemirror-gapcursor": "^1.0.0",
+ "prosemirror-history": "^1.0.0",
+ "prosemirror-inputrules": "^1.0.0",
+ "prosemirror-keymap": "^1.0.0",
+ "prosemirror-menu": "^1.0.0",
+ "prosemirror-schema-list": "^1.0.0",
+ "prosemirror-state": "^1.0.0"
+ }
+ },
+ "prosemirror-gapcursor": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.1.4.tgz",
+ "integrity": "sha512-6WJRDcd5jeKDZfzM6nD8aLtA9y54aPgUzVD0rudNrirq8qWgugiN29BfvIVdiDzV0Q+/cwr2yNs5/ssSAvZ0Kw==",
+ "requires": {
+ "prosemirror-keymap": "^1.0.0",
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-view": "^1.0.0"
+ }
+ },
+ "prosemirror-history": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.1.3.tgz",
+ "integrity": "sha512-zGDotijea+vnfnyyUGyiy1wfOQhf0B/b6zYcCouBV8yo6JmrE9X23M5q7Nf/nATywEZbgRLG70R4DmfSTC+gfg==",
+ "requires": {
+ "prosemirror-state": "^1.2.2",
+ "prosemirror-transform": "^1.0.0",
+ "rope-sequence": "^1.3.0"
+ }
+ },
+ "prosemirror-inputrules": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.1.2.tgz",
+ "integrity": "sha512-Ja5Z3BWestlHYGvtSGqyvxMeB8QEuBjlHM8YnKtLGUXMDp965qdDV4goV8lJb17kIWHk7e7JNj6Catuoa3302g==",
+ "requires": {
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "prosemirror-keymap": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.1.3.tgz",
+ "integrity": "sha512-PRA4NzkUMzV/NFf5pyQ6tmlIHiW/qjQ1kGWUlV2rF/dvlOxtpGpTEjIMhWgLuMf+HiDEFnUEP7uhYXu+t+491g==",
+ "requires": {
+ "prosemirror-state": "^1.0.0",
+ "w3c-keyname": "^2.2.0"
+ }
+ },
+ "prosemirror-markdown": {
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.4.4.tgz",
+ "integrity": "sha512-qh6d9WKjahLSlV4V7PZNJifp+fLKrOFV/ZqajQ15Labqh49Zs/TGGk10SkT6n+ROTNIHHU/P5oBi5ei7BvwmuA==",
+ "requires": {
+ "markdown-it": "^10.0.0",
+ "prosemirror-model": "^1.0.0"
+ }
+ },
+ "prosemirror-menu": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.1.4.tgz",
+ "integrity": "sha512-2ROsji/X9ciDnVSRvSTqFygI34GEdHfQSsK4zBKjPxSEroeiHHcdRMS1ofNIf2zM0Vpp5/YqfpxynElymQkqzg==",
+ "requires": {
+ "crelt": "^1.0.0",
+ "prosemirror-commands": "^1.0.0",
+ "prosemirror-history": "^1.0.0",
+ "prosemirror-state": "^1.0.0"
+ }
+ },
+ "prosemirror-model": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.9.1.tgz",
+ "integrity": "sha512-Qblh8pm1c7Ll64sYLauwwzjimo/tFg1zW3Q3IWhKRhvfOEgRKqa6dC5pRrAa+XHOIjBFEYrqbi52J5bqA2dV8Q==",
+ "requires": {
+ "orderedmap": "^1.1.0"
+ }
+ },
+ "prosemirror-schema-list": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.1.2.tgz",
+ "integrity": "sha512-dgM9PwtM4twa5WsgSYMB+J8bwjnR43DAD3L9MsR9rKm/nZR5Y85xcjB7gusVMSsbQ2NomMZF03RE6No6mTnclQ==",
+ "requires": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "prosemirror-state": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.3.3.tgz",
+ "integrity": "sha512-PLXh2VJsIgvlgSTH6I2Yg6vk1CzPDp21DFreVpQtDMY2S6WaMmrQgDTLRcsrD8X38v8Yc873H7+ogdGzyIPn+w==",
+ "requires": {
+ "prosemirror-model": "^1.0.0",
+ "prosemirror-transform": "^1.0.0"
+ }
+ },
+ "prosemirror-transform": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.2.4.tgz",
+ "integrity": "sha512-0A668uf0EN89L9O9brE05kHcqp7FHmT5YN7Tom58Kj926QqOBs7iNRHDLWxrSaQB5MNZtzDOD9T3EyJ88YDcBg==",
+ "requires": {
+ "prosemirror-model": "^1.0.0"
+ }
+ },
+ "prosemirror-view": {
+ "version": "1.14.6",
+ "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.14.6.tgz",
+ "integrity": "sha512-0qNSFWVBHPrdQaZtIO3aou/NRsxMGER3IuI3cePHYbk5pf9wSsbMIWWaeHtXqblL+rqtgkLfcw0D2na6+WBgpA==",
+ "requires": {
+ "prosemirror-model": "^1.1.0",
+ "prosemirror-state": "^1.0.0",
+ "prosemirror-transform": "^1.1.0"
+ }
+ },
"prr": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
@@ -3171,6 +3859,11 @@
"resolved": "https://registry.npmjs.org/rng/-/rng-0.2.2.tgz",
"integrity": "sha1-30PoDZvIKtRDC8/vA/SccX6LLow="
},
+ "rope-sequence": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.2.tgz",
+ "integrity": "sha512-ku6MFrwEVSVmXLvy3dYph3LAMNS0890K7fabn+0YIRQ2T96T9F4gkFf0vf0WW0JUraNWwGRtInEpH7yO4tbQZg=="
+ },
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
@@ -3428,9 +4121,9 @@
}
},
"ssb-browser-core": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ssb-browser-core/-/ssb-browser-core-3.0.0.tgz",
- "integrity": "sha512-mkhx/cWScD6XRbB+eKQE6TKzmf+tdAKuySiju6X3voqV0iu1IP7oSK6j2l/HOAren6N+f1tG53BJopaNwH4VoQ==",
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/ssb-browser-core/-/ssb-browser-core-3.1.0.tgz",
+ "integrity": "sha512-UBBrBcoviL5IIU7Z5IIsziKd5CuQtU79PlJlb5OWraD+tAQoE1KZYvgH6SK7q/5e8Zr8EyRhvC8LUSxTw9/mTA==",
"requires": {
"flumecodec": "0.0.1",
"flumedb": "^2.1.1",
@@ -4080,6 +4773,12 @@
"to-space-case": "^1.0.0"
}
},
+ "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
+ },
"to-no-case": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz",
@@ -4299,9 +4998,14 @@
"integrity": "sha512-GYhn2ynaZlysZMkFE5oCHRUTqE8BWs/a9YbKpNLi0i7xD6KG1EzDqpHQmv1F5gXjr8kL5iIVS8EOtRaVUEXTqA=="
},
"vue-select": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/vue-select/-/vue-select-3.4.0.tgz",
- "integrity": "sha512-UHd0fiUjPgRmHIGhI6yUKtnJsHOdvzD00QUGUtD+FaxWWZRWF2AAb7KPZRj0j/egVfZQvey6M6woHn78GbTogA=="
+ "version": "3.9.5",
+ "resolved": "https://registry.npmjs.org/vue-select/-/vue-select-3.9.5.tgz",
+ "integrity": "sha512-r392oaLYepNxY+uY1EN7r05VPOqSWGEfZ3LtJ3NqhrRbWCpWQ5EPSMN3QL80HdN3H+o1ueQA9P58K1vgGZ5P3Q=="
+ },
+ "w3c-keyname": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.4.tgz",
+ "integrity": "sha512-tOhfEwEzFLJzf6d1ZPkYfGj+FWhIpBux9ppoP3rlclw3Z0BZv3N7b7030Z1kYth+6rDuAsXUFr+d0VE6Ed1ikw=="
},
"word-wrap": {
"version": "1.2.3",
@@ -4471,6 +5175,22 @@
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+ },
+ "y-prosemirror": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/y-prosemirror/-/y-prosemirror-0.3.3.tgz",
+ "integrity": "sha512-+vgwV+Up90rIEhwfxiHCoB7arChUuNaS+O0cUDpVhObJ1BNkVoEGYRu/c6BQC8S+Wpsl9AnAGnKKsyCxaatQfQ==",
+ "requires": {
+ "lib0": "^0.2.15"
+ }
+ },
+ "yjs": {
+ "version": "13.0.5",
+ "resolved": "https://registry.npmjs.org/yjs/-/yjs-13.0.5.tgz",
+ "integrity": "sha512-xBqT+iFmRKkhxYXCa+8sgxISugEfi3toQnEcT2ahgC4uEmSekKuUb2nvqJyFLWXzL4CmZ6My7HgWcnRIRDkIhA==",
+ "requires": {
+ "lib0": "^0.2.22"
+ }
}
}
}
diff --git a/package.json b/package.json
index f070a63..15cf5dd 100644
--- a/package.json
+++ b/package.json
@@ -11,10 +11,14 @@
"human-time": "0.0.2",
"lodash.throttle": "^4.1.1",
"node-emoji": "^1.10.0",
+ "prosemirror-example-setup": "^1.1.2",
+ "prosemirror-markdown": "^1.4.4",
+ "prosemirror-state": "^1.3.3",
+ "prosemirror-view": "^1.14.6",
"pull-abortable": "^4.1.1",
"pull-stream": "^3.6.14",
"rimraf": "^3.0.0",
- "ssb-browser-core": "^3.0.0",
+ "ssb-browser-core": "^3.1.0",
"ssb-contact-msg": "^1.1.0",
"ssb-keys-mnemonic": "^0.2.0",
"ssb-markdown": "^6.0.7",
@@ -22,19 +26,22 @@
"ssb-ref": "^2.13.3",
"vue": "^2.6.11",
"vue-router": "^3.1.6",
- "vue-select": "^3.4.0",
- "workbox-build": "^4.3.1"
+ "vue-select": "^3.9.5",
+ "workbox-build": "^4.3.1",
+ "y-prosemirror": "^0.3.3",
+ "yjs": "^13.0.5"
},
"devDependencies": {
"browserify": "^16.5.1",
"common-shakeify": "^0.6.2",
"deep-object-diff": "^1.1.0",
+ "esmify": "^2.1.1",
"ssb-client": "^4.7.9",
"uglifyify": "^5.0.2"
},
"scripts": {
- "build": "mkdir -p build && browserify --full-paths ui/browser.js > build/bundle-ui.js && node write-dist.js",
- "release": "mkdir -p build && browserify -g uglifyify -p common-shakeify ui/browser.js > build/bundle-ui.js && node write-dist.js"
+ "build": "mkdir -p build && browserify -p esmify --full-paths ui/browser.js > build/bundle-ui.js && node write-dist.js",
+ "release": "mkdir -p build && browserify -g uglifyify -p esmify -p common-shakeify ui/browser.js > build/bundle-ui.js && node write-dist.js"
},
"author": "arj",
"license": "beerware"
diff --git a/ui/browser.js b/ui/browser.js
index fef7afb..773c9e8 100644
--- a/ui/browser.js
+++ b/ui/browser.js
@@ -7,14 +7,14 @@
})
}
- SSB.events.on('SSB: loaded', function() {
+ function ssbLoaded() {
const Public = require('./public')(componentsState)
const Profile = require('./profile')()
const Notifications = require('./notifications')()
const Channel = require('./channel')()
const Thread = require('./thread')()
const Private = require('./private')(componentsState)
- const Chat = require('./chat')()
+ const Prose = require('./prose')()
const Invites = require('./invites')()
const Settings = require('./settings')()
@@ -36,7 +36,7 @@
{ name: 'profile', path: '/profile/:feedId', component: Profile, props: true },
{ name: 'notifications', path: '/notifications', component: Notifications },
{ path: '/private', component: Private },
- { path: '/chat', component: Chat },
+ { path: '/collab', component: Prose },
{ path: '/invites', component: Invites },
{ path: '/settings', component: Settings },
{ path: '/', redirect: 'public' },
@@ -68,5 +68,10 @@
}
}).$mount('#app')
- })
+ }
+
+ if (SSB.events._events["SSB: loaded"])
+ ssbLoaded()
+ else
+ SSB.events.once('SSB: loaded', ssbLoaded)
})()
diff --git a/ui/chat.js b/ui/chat.js
deleted file mode 100644
index 9d2b7c4..0000000
--- a/ui/chat.js
+++ /dev/null
@@ -1,72 +0,0 @@
-const pull = require('pull-stream')
-const pullAbort = require('pull-abortable')
-
-module.exports = function () {
- var abortablePullStream = null
-
- return {
- template: `
-
Your id: {{ SSB.net.id }}
-
Accept incoming connections or
-
-
-
Off-chain messages
-
Off-chain messages are messages sent
- encrypted between you and the other end through the magic of
- tunnels. These messages are ephemeral and will be gone forever
- when you change view!
-
-
`,
-
- data: function() {
- return {
- remoteId: "",
- chatText: ""
- }
- },
-
- methods: {
- acceptMessages: function() {
- SSB.net.tunnelMessage.acceptMessages((remoteId) => {
- return confirm("Allow connection from: " + remoteId + "?")
- })
- },
-
- connect: function() {
- SSB.net.tunnelMessage.connect(this.remoteId)
- },
-
- onChatSend: function() {
- SSB.net.tunnelMessage.sendMessage("chat", this.chatText)
- this.chatText = ''
- }
- },
-
- created: function() {
- abortablePullStream = pullAbort()
- pull(
- SSB.net.tunnelMessage.messages(),
- abortablePullStream,
- pull.drain((msg) => {
- var user = msg.user
- if (msg.type == "chat")
- user = user.substr(0, 10)
-
- if (SSB.profiles[msg.user])
- user = SSB.profiles[msg.user].name
- else if (msg.user == SSB.net.id)
- user = "me"
- document.getElementById("messages").innerHTML += `${user}> ${msg.data} `
- })
- )
- },
-
- beforeRouteLeave: function(from, to, next) {
- if (abortablePullStream != null) {
- abortablePullStream.abort()
- abortablePullStream = null
- }
- next()
- }
- }
-}
diff --git a/ui/connected.js b/ui/connected.js
index 75e5ad1..128e912 100644
--- a/ui/connected.js
+++ b/ui/connected.js
@@ -1,8 +1,8 @@
Vue.component('connected', {
template: `
-
- 🦄
- `,
+
+ 🦄
+ `,
data: function() {
return {
diff --git a/ui/prose.js b/ui/prose.js
new file mode 100644
index 0000000..08f148f
--- /dev/null
+++ b/ui/prose.js
@@ -0,0 +1,207 @@
+const pull = require('pull-stream')
+const pullAbort = require('pull-abortable')
+
+const Y = require('yjs')
+const { ySyncPlugin, yUndoPlugin, undo, redo } = require('y-prosemirror')
+const { EditorState } = require('prosemirror-state')
+const { EditorView } = require('prosemirror-view')
+const { schema, defaultMarkdownParser, defaultMarkdownSerializer } = require('prosemirror-markdown')
+const { exampleSetup, buildMenuItems } = require('prosemirror-example-setup')
+const { keymap } = require('prosemirror-keymap')
+
+module.exports = function () {
+ var abortablePullStream = null
+ const ydoc = new Y.Doc()
+ var connected = 0
+
+ function uint8ArrayToStrBase64(a) {
+ return btoa(String.fromCharCode.apply(null, a))
+ }
+
+ function strBase64ToUint8Array(s) {
+ return Uint8Array.from([].map.call(atob(s), c => c.charCodeAt(0)))
+ }
+
+ function createProseMirrorView(content) {
+ const type = ydoc.getXmlFragment('prosemirror')
+ const editor = document.getElementById('editor')
+
+ const mi = buildMenuItems(schema)
+
+ return new EditorView(editor, {
+ state: EditorState.create({
+ doc: defaultMarkdownParser.parse(content),
+ schema,
+ plugins: [
+ ySyncPlugin(type),
+ yUndoPlugin(),
+ keymap({
+ 'Mod-z': undo,
+ 'Mod-y': redo,
+ 'Mod-Shift-z': redo
+ })
+ ].concat(exampleSetup({
+ schema,
+ menuContent: [
+ [mi.toggleStrong, mi.toggleEm],
+ [mi.makeHead1, mi.makeHead2],
+ [mi.wrapBulletList, mi.wrapOrderedList, mi.wrapBlockQuote]
+ ]
+ }))
+ })
+ })
+ }
+
+ function sendInitialState() {
+ // FIXME: maybe save their state and only send them updates based on that
+ const state = uint8ArrayToStrBase64(Y.encodeStateAsUpdate(ydoc))
+ //console.log("sending initial state", state)
+ SSB.net.tunnelMessage.sendMessage("prose-current-state", state)
+ }
+
+ function sendInitialStateOnConnect() {
+ SSB.net.once('rpc:connect', function (rpc, isClient) {
+ if (rpc.id == '@' + SSB.remoteAddress.split(':')[3]) {
+ sendInitialStateOnConnect() // a tunnel is multiple connects
+ return
+ }
+
+ sendInitialState()
+ })
+ }
+
+ return {
+ template: `
+
+
Your id: {{ SSB.net.id }}
+
Host session or
+
{{ connectText }}
+
+
Shared document
+
+
+ The state of the shared document is synchronized using
+ off-chain messages sent encrypted between you and the
+ other end through the magic of tunnels and CRDTs.
+
+
+
+
+
Export text as markdown to clipboard
+
+
+
+
+
Messages
+
+
+
`,
+
+ data: function() {
+ return {
+ connectText: "Connect to host",
+ remoteId: "",
+ documentText: "",
+ chatText: "",
+ proseMirrorView: null
+ }
+ },
+
+ methods: {
+ acceptMessages: function() {
+ SSB.net.tunnelMessage.acceptMessages((remoteId) => {
+ sendInitialStateOnConnect()
+ return confirm("Allow connection from: " + remoteId + "?")
+ })
+ },
+
+ connectDisconnect: function() {
+ if (this.connectText == "Connect to host") {
+ SSB.net.tunnelMessage.connect(this.remoteId, sendInitialState)
+ this.connectText = "Disconnect from host"
+ } else {
+ SSB.net.tunnelMessage.disconnect()
+ this.connectText = "Connect to host"
+ }
+ },
+
+ onChatSend: function() {
+ SSB.net.tunnelMessage.sendMessage("chat", this.chatText)
+ this.chatText = ''
+ },
+
+ exportMarkdown: function() {
+ const md = defaultMarkdownSerializer.serialize(this.proseMirrorView.state.doc)
+ navigator.clipboard.writeText(md)
+ alert("Exported markdown text to clipboard")
+ }
+ },
+
+ created: function() {
+ abortablePullStream = pullAbort()
+ pull(
+ SSB.net.tunnelMessage.messages(),
+ abortablePullStream,
+ pull.drain((msg) => {
+ var user = msg.user
+ if (msg.type == "chat")
+ user = user.substr(0, 10)
+
+ if (SSB.profiles[msg.user])
+ user = SSB.profiles[msg.user].name
+ else if (msg.user == SSB.net.id)
+ user = "me"
+
+ if (msg.type == 'info' && msg.data == "connected") {
+ connected++
+ document.getElementById("status").innerHTML += `${user} connected `
+ }
+ else if (msg.type == 'info' && msg.data == "disconnected") {
+ connected--
+ document.getElementById("status").innerHTML += `${user} disconnected `
+ this.connectText = "Connect to host"
+ }
+ else if (msg.type == 'info' && msg.data == "waiting for accept") {
+ document.getElementById("status").innerHTML += `waiting for ${user} to accept `
+ }
+ else if (user != "me" && (msg.type == "prose-current-state" || msg.type == "prose-state-update"))
+ {
+ //console.log("got update msg", msg.data)
+ Y.applyUpdate(ydoc, strBase64ToUint8Array(msg.data))
+ }
+ else if (user == "me" && (msg.type == "prose-current-state" || msg.type == "prose-state-update"))
+ {
+ // skip own state updates
+ }
+ else if (msg.type == 'chat') {
+ document.getElementById("status").innerHTML += `${user}> ${msg.data} `
+ }
+ else
+ console.log("got unknown msg", msg)
+ })
+ )
+ },
+
+ mounted: function() {
+ ydoc.on('update', update => {
+ if (connected > 0) {
+ const state = uint8ArrayToStrBase64(update)
+ SSB.net.tunnelMessage.sendMessage("prose-state-update", state)
+ }
+ })
+
+ this.proseMirrorView = createProseMirrorView("")
+ },
+
+ beforeRouteLeave: function(from, to, next) {
+ if (abortablePullStream != null) {
+ abortablePullStream.abort()
+ abortablePullStream = null
+ }
+ next()
+ }
+ }
+}