diff --git a/.DS_Store b/.DS_Store
index a60aef9a74828569b9d446436c2f527514292dbd..5c7ed6f292f4fca62a3d2f51bdf88e26fe282c42 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/.gitignore b/.gitignore
index 45382360ad552e4351ad285b49f34dd53cd4c27c..496ee2ca6a2f08396a4076fe43dedf3dc0da8b6d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1 @@
-
 .DS_Store
\ No newline at end of file
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 22ee1a5f6d87a3e1014c46bc30a90de43d16d31a..89182125a3f9870cfa747ef137fa50ffad1cbdbd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,104 @@
+# 0.1.47
+
+_23rd December 2020_
+
+### Changed
+
+- Hiding shortcut tips now will stay hidden per session. (n.b this hides them on all views)
+- Focusses input when creating new node enabling fasting entry.
+  - in Collect view press n, instantly type in ideas, press tab, press n for next idea (SO FAST!)
+
+### Fixed
+
+- Fixed min width and height on nodes (support towards better auto resizing).
+- Keyboard shortcut n key more fixes in Organise and Card view.(should work all the time)
+
+### Removed
+
+- Removed Specific offline component as if app goes offline mid connection it should work just fine, in all views.
+
+# 0.1.46
+
+_18th Decemeber 2020_
+
+### Fixed
+
+- The initial onboarding microcosm should not longer allow you to save nodes.
+- Keyboard shortcut n now works on Collect view on first visit to new microcosm.
+
+# 0.1.45
+
+_17th December 2020_
+
+### Changed
+
+- Card view can now be sorted however this is not saved yet.
+
+### Fixed
+
+- Some sync bug fixes.
+- You can now colour nodes in Collect and Card views.
+- initial node creation failed on new microcosm without switching views.
+- Force load on Collect view.
+
+# 0.1.44
+
+_14th December 2020_
+
+### Changed
+
+- Upload is now smarter and will generate markdown for images, video and audio "automagically", media that is not recognised will be uploaded and generated as a plain URL (link).
+- Now using Cloudflare's IPFS Gateway as we move towards more robust upload support.
+- Video is using using infura gateway (cloudflares gateway doesnt like playing back video)
+
+### Added
+
+- You can now Drag and drop to upload.
+
+# 0.1.43
+
+_12th December 2020_
+
+### Fixed
+
+- Partial fix so that nodes will resize to fit content (after dragging into position)
+
+# 0.1.42
+
+_11th December 2020_
+
+### Added
+
+- You can now colour code your nodes.
+
+# 0.1.41
+
+_11th December 2020_
+
+### Changed
+
+- added basic z-index incrementing, when you touch a node it will jump to the front a node gets to within max z-index > 2147483640 all nodes will reset to 0.
+
+# 0.1.40
+
+_9th December 2020_
+
+## Fixed
+
+- Connections are now working in the same way as before but using native SVG code and no longer the pixi library.
+
+# 0.1.39
+
+_8th December 2020_
+
+### Changed
+
+- edits to the new computed filter to use watch / unwatch over a timer for initial load should mean doesn't matter on hardware or network all nodes will load when ready.
+
+### Fixed
+
+- brought back selecting text and not dragging missed class.
+
 # 0.1.38
 
 _7th December 2020_
@@ -7,9 +108,13 @@ _7th December 2020_
 - read mode is now attached to each node instead of positions.
 - node text and positioning is now using a computed filter - so the iterating should be less CPU intensive.
 
+### Fixed
+
+- pressing n on keyboard when editing node in card view no longer creates nodes.
+
 ### Removed
 
-- Pixi.js for drawing connections (temporary removal).
+- Pixi.js for drawing connections (temporary removal replacement tech needed).
 
 # 0.1.37
 
diff --git a/app/package-lock.json b/app/package-lock.json
index b211b55844b321782cb787d13a14e0ef025ae740..265814bb4489114e0530a70191ae8bdc70cc4314 100644
--- a/app/package-lock.json
+++ b/app/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "nodenogg.in",
-  "version": "0.1.36",
+  "version": "0.1.47",
   "lockfileVersion": 1,
   "requires": true,
   "dependencies": {
@@ -1302,9 +1302,9 @@
       }
     },
     "@eslint/eslintrc": {
-      "version": "0.2.1",
-      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.1.tgz",
-      "integrity": "sha512-XRUeBZ5zBWLYgSANMpThFddrZZkEbGHgUdt5UJjZfnlN9BGCiUBrf+nvbRupSjMvqzwnQN0qwCmOxITt1cfywA==",
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-0.2.2.tgz",
+      "integrity": "sha512-EfB5OHNYp1F4px/LI/FEnGylop7nOqkQ1LRzCM0KccA2U8tvV8w01KBv37LbO7nW4H+YhKyo2LcJhRwjjV17QQ==",
       "dev": true,
       "requires": {
         "ajv": "^6.12.4",
@@ -1329,9 +1329,9 @@
           }
         },
         "import-fresh": {
-          "version": "3.2.2",
-          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
-          "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+          "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
           "dev": true,
           "requires": {
             "parent-module": "^1.0.0",
@@ -1399,9 +1399,9 @@
       }
     },
     "@hapi/boom": {
-      "version": "9.1.0",
-      "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.0.tgz",
-      "integrity": "sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ==",
+      "version": "9.1.1",
+      "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.1.tgz",
+      "integrity": "sha512-VNR8eDbBrOxBgbkddRYIe7+8DZ+vSbV6qlmaN2x7eWjsUjy2VmQgChkOKcVZIeupEZYj+I0dqNg430OhwzagjA==",
       "requires": {
         "@hapi/hoek": "9.x.x"
       },
@@ -1897,356 +1897,6 @@
       "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
       "dev": true
     },
-    "@pixi/accessibility": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/accessibility/-/accessibility-5.3.3.tgz",
-      "integrity": "sha512-wC/enJtw5CrdWnu6l5u3VN9UIZPumNSNXlGez2BULY0osiLTywHJPdHpmXMz2YPXw75GsEBzkEvK4LTtnTp21A==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/app": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/app/-/app-5.3.3.tgz",
-      "integrity": "sha512-OkO7Kq3N+FPRshVmApuiHKBpobic56VYbLVCMYPy6rjV0hc5ctkchKGFyouJuPt/rHeI6FrqZ0TaON1TShnKiA==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3"
-      }
-    },
-    "@pixi/constants": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/constants/-/constants-5.3.3.tgz",
-      "integrity": "sha512-IybgxzLlEPm7ihp70cLNKc3IPyqkFuW+idk9Zw2St+OayJTw5ctCnLAg9cducwIVHjPYTvN46BYDa+n0KRWZYw=="
-    },
-    "@pixi/core": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/core/-/core-5.3.3.tgz",
-      "integrity": "sha512-taw50LnzV+TQVMx5HQA2ZJgF9wuhZ6DeoXHW2KkevYB0ekKYnEO2VMMiRDMcmchtyvHclJebzjeHZLGqDtKDgw==",
-      "requires": {
-        "@pixi/constants": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/runner": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/ticker": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/display": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/display/-/display-5.3.3.tgz",
-      "integrity": "sha512-dPm7Vk2BH9byu6RHBYsI9MtjUU8x1HNm/PIi6lIlxANhTjWnhxwfvmrGE7ZcRLThTenNdDVlZ2ke2XAXP98UgA==",
-      "requires": {
-        "@pixi/math": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/extract": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/extract/-/extract-5.3.3.tgz",
-      "integrity": "sha512-CE0GA+tEBPurpaXER2B1aq1sdumKLtCqE/Mms6fYUkIKF9D0Ogw9rqo79QCL9XkLMexa7xVeC3KPPiXW5wrOaA==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/filter-alpha": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/filter-alpha/-/filter-alpha-5.3.3.tgz",
-      "integrity": "sha512-AxyHLnvO892va9raZbMMtMtEGDVqO8SvEHHNnCjTBEZ67kVKy0HEYXFOBA6nJZ6BiTgGp9js+7kevi11tfqnJQ==",
-      "requires": {
-        "@pixi/core": "5.3.3"
-      }
-    },
-    "@pixi/filter-blur": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/filter-blur/-/filter-blur-5.3.3.tgz",
-      "integrity": "sha512-vLN1DL6PQXo4p7j/32PZIf+lhcBVfb9hdphSmtbxlAlpbhMWI52n3YUkeInwHs7Ev08NyhI/UhNWHqjN/lAM3w==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/settings": "5.3.3"
-      }
-    },
-    "@pixi/filter-color-matrix": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/filter-color-matrix/-/filter-color-matrix-5.3.3.tgz",
-      "integrity": "sha512-HFr+vth5ZHHEFJYcjtWZ+O0s7Z2YWJyDyxr+nTd5Q8AT7gMDTVehpNVrm7ByaCKeEovOZzZI6A347+WmHcNpGg==",
-      "requires": {
-        "@pixi/core": "5.3.3"
-      }
-    },
-    "@pixi/filter-displacement": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/filter-displacement/-/filter-displacement-5.3.3.tgz",
-      "integrity": "sha512-kvrKMgqW4ELg+yT2p5vmu6h/IER/L8GD1PWyXovnzpI8RG7k8l136F9VvA3wkB6sYuNcXiDtqMtRQy5e6O4+rw==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/math": "5.3.3"
-      }
-    },
-    "@pixi/filter-fxaa": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/filter-fxaa/-/filter-fxaa-5.3.3.tgz",
-      "integrity": "sha512-p4vKdBwaoGRNZcoHz2ET8hBF1SoWvy9xU2B3Ci32+c0dg89ZUdGTEW0zimUHi2gMdU+2v/T0lqZ9NC9B6WVYAg==",
-      "requires": {
-        "@pixi/core": "5.3.3"
-      }
-    },
-    "@pixi/filter-noise": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/filter-noise/-/filter-noise-5.3.3.tgz",
-      "integrity": "sha512-HCky3XPk6BYGXTS7d9/FnAHnqq7Rwm5Rlj2XtWW3JItXGCScEBII227xYwrJu5Ke84tpVlDXK4W1/BevZ1AwlQ==",
-      "requires": {
-        "@pixi/core": "5.3.3"
-      }
-    },
-    "@pixi/graphics": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/graphics/-/graphics-5.3.3.tgz",
-      "integrity": "sha512-1bn9Jptg3JXgVOw0SrEMdmjSwkTBYDm6fPnPnh4goF3yDozh0xEqmXobVtCgy2fulMfHRzIfbgtRxrBf2mkCAg==",
-      "requires": {
-        "@pixi/constants": "5.3.3",
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/sprite": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/interaction": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/interaction/-/interaction-5.3.3.tgz",
-      "integrity": "sha512-Tjuw4XwmrG1fhGzfn5oGspRJT2OtlH+6V7AHscH0v5Ht1Kvk6aKjNncZuSCXllhGGlIuMu3Nn9WPvDEIvW3JNw==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/ticker": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/loaders": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/loaders/-/loaders-5.3.3.tgz",
-      "integrity": "sha512-wj0DzniApfDoZA/buMmO/CgCB7Q7SsESForHh7wSd7UC8rrCmz5prUTEICmJGhdHpBuVB7KDPtwaaLtr9Q/kQg==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/utils": "5.3.3",
-        "resource-loader": "^3.0.1"
-      }
-    },
-    "@pixi/math": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/math/-/math-5.3.3.tgz",
-      "integrity": "sha512-k5C3kQpxlGm2AdBJEUjjW2l2YlSvTKf+54vNOjD4UcEfRoDevC5p4Zg49q3UAu855lrs5qw49AbkrFKsQvPIRA=="
-    },
-    "@pixi/mesh": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/mesh/-/mesh-5.3.3.tgz",
-      "integrity": "sha512-q8w70oAFNdArzOHVnsn7ban68NmO5S5TMg6qSez4A8te6cebMRQsNrT/0dQ/nZcG7ACFK4jiYfbXRQivO+jgVA==",
-      "requires": {
-        "@pixi/constants": "5.3.3",
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/mesh-extras": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/mesh-extras/-/mesh-extras-5.3.3.tgz",
-      "integrity": "sha512-V2hARC7nUPaTEFxd+B8GDkSMrMZ38S8/IInqtYzGUy6FtFs7IYKty9Rz/G665eN7ThIq8tZrOVZOl6JRBtEC8A==",
-      "requires": {
-        "@pixi/constants": "5.3.3",
-        "@pixi/core": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/mesh": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/mixin-cache-as-bitmap": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-5.3.3.tgz",
-      "integrity": "sha512-P1mo3HKDWS8IZLgaP8gujiy4We4vRcxJH6EvQAevf+GsBzdjKfcGgkKzVb9HlyQvsXML5gpTOJuw5eKgRTxSQA==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/sprite": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/mixin-get-child-by-name": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-5.3.3.tgz",
-      "integrity": "sha512-CksDZ5ZG4/tHZfDOwSuznANduasJg5JR89X3D6E9DVYx4CLVE3G2K1sbeiOJNXfGIKy30UoSD7Y7IFmUzLxp/g==",
-      "requires": {
-        "@pixi/display": "5.3.3"
-      }
-    },
-    "@pixi/mixin-get-global-position": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/mixin-get-global-position/-/mixin-get-global-position-5.3.3.tgz",
-      "integrity": "sha512-M3faQYDW/ISa1+lhVkjHXRALJ33BMzLN+7x9ucx8VeCmUWvcaLlRo3CaxZsgiR+52Fii5WHl/PF/cMzdkRMF9g==",
-      "requires": {
-        "@pixi/display": "5.3.3",
-        "@pixi/math": "5.3.3"
-      }
-    },
-    "@pixi/particles": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/particles/-/particles-5.3.3.tgz",
-      "integrity": "sha512-t+lG8iGNYyS6ujKvC9qQjKzyxvjxqbFxvB6hkXcOKR98JWM2726ZguHouFlIbOzOxYAGoeuHIWSDlnQNvnVE2g==",
-      "requires": {
-        "@pixi/constants": "5.3.3",
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/polyfill": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/polyfill/-/polyfill-5.3.3.tgz",
-      "integrity": "sha512-gmx67A6VmwKllxfIMQWzMUNJ8wJfWPT5FlUR0SoPastdTB/SfbgbyQBgKLZHqgmc6LOh2CrOLhN423lNiAroeA==",
-      "requires": {
-        "es6-promise-polyfill": "^1.2.0",
-        "object-assign": "^4.1.1"
-      }
-    },
-    "@pixi/prepare": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/prepare/-/prepare-5.3.3.tgz",
-      "integrity": "sha512-DPsKWfYJ97J67YCjPU6uvU+LBdw+64O9LG9vmzfChmYXom5VMQF9yUC6ZoYTHUPmH31iilqzGeMlPUTobnqSog==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/graphics": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/text": "5.3.3",
-        "@pixi/ticker": "5.3.3"
-      }
-    },
-    "@pixi/runner": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/runner/-/runner-5.3.3.tgz",
-      "integrity": "sha512-7eLZxxT+PwxuwzcRL1egrnEdLHwD41yFb24pMSo6XM86ppP1tdBjrv5+pLDnUuDEfNjZQxx07FAlZY+sMKANmw=="
-    },
-    "@pixi/settings": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/settings/-/settings-5.3.3.tgz",
-      "integrity": "sha512-1MYJokqpPUtvYEX0BVi0Pq2Xi6KGmWDV5hlQnTXY9NGv6tmqrPYvIb/uHFaDyVUWmrqsFL3xZ4W5zMo+c/dwVA==",
-      "requires": {
-        "ismobilejs": "^1.1.0"
-      }
-    },
-    "@pixi/sprite": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/sprite/-/sprite-5.3.3.tgz",
-      "integrity": "sha512-qo7DG0oWS1uIBqfxw2jZPn34RCR6gQ+IjZRBpFxZPKPB1cL359scZmDBqBbQ4bd4rJ/6QXQfzUdGhXfQJtc9oQ==",
-      "requires": {
-        "@pixi/constants": "5.3.3",
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/sprite-animated": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/sprite-animated/-/sprite-animated-5.3.3.tgz",
-      "integrity": "sha512-nG5j8veJ/cFXQTgzafPLkZqaHKbuaHcIj+ZYN1I2f31Y85/pfr2PQQLHbGr+3441wOYkEHht9nHhmZHWlOOZ0Q==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/sprite": "5.3.3",
-        "@pixi/ticker": "5.3.3"
-      }
-    },
-    "@pixi/sprite-tiling": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/sprite-tiling/-/sprite-tiling-5.3.3.tgz",
-      "integrity": "sha512-+Xk9AUh82rpArtrnZkw+9aJchrmHZ8QkpjsPRJcgPFHx3WEfABIkT6QEoYbRKiYH34OgO7ZOUXy9hcGPHnxjvw==",
-      "requires": {
-        "@pixi/constants": "5.3.3",
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/sprite": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/spritesheet": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/spritesheet/-/spritesheet-5.3.3.tgz",
-      "integrity": "sha512-pTkOCTL8jsmyAguCgcbz03UPYu+3buRkgua1g/vGyeoZBN2eJ04iSXdB0pfPrsPisxkvThGHyU23UqEDYVtXRQ==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/loaders": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/text": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/text/-/text-5.3.3.tgz",
-      "integrity": "sha512-juinZC2yFXnzucWWxSdty9nfIIOAq2WA8DD2k40YL+7Y5L52/ggkgnokeQ2lrTb1BvTfx6YVNlvAsKonUek0Og==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/sprite": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/text-bitmap": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/text-bitmap/-/text-bitmap-5.3.3.tgz",
-      "integrity": "sha512-QRRdEAFBwmRctp8PCPii5WUPM57T1I3r/EwyTvFCCDubOYOZu4aX/iFpCKZMl5GIphDFaGp8mNvbl+BwjUmBCA==",
-      "requires": {
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/loaders": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/mesh": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/text": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
-    "@pixi/ticker": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/ticker/-/ticker-5.3.3.tgz",
-      "integrity": "sha512-p5F/dwJGwfZWUg5cCPqOnEx5iYGW+huQlZZtrTKKd1KoVehFsrzHeRBOEp4d584jsOmBf7fjJaUTyzsFn0YtOQ==",
-      "requires": {
-        "@pixi/settings": "5.3.3"
-      }
-    },
-    "@pixi/utils": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/@pixi/utils/-/utils-5.3.3.tgz",
-      "integrity": "sha512-GDP2h1Mph9Uei4zmJjzDK6GZ5S9O2A09VySVfWyKgWwP3SQ/Ss0bGYm4sE6+u1NMSz1WCrLgu66H82XuXs2Cbg==",
-      "requires": {
-        "@pixi/constants": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "earcut": "^2.1.5",
-        "eventemitter3": "^3.1.0",
-        "url": "^0.11.0"
-      },
-      "dependencies": {
-        "eventemitter3": {
-          "version": "3.1.2",
-          "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
-          "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
-        }
-      }
-    },
     "@protobufjs/aspromise": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
@@ -3823,9 +3473,9 @@
       "dev": true
     },
     "astral-regex": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
-      "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
+      "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==",
       "dev": true
     },
     "async": {
@@ -4928,13 +4578,12 @@
       }
     },
     "cids": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/cids/-/cids-1.0.2.tgz",
-      "integrity": "sha512-ohCcYyEHh0Z5Hl+O1IML4kt6Kx5GPho1ybxtqK4zyk6DeV5CvOLoT/mqDh0cgKcAvsls3vcVa9HjZc7RQr3geA==",
+      "version": "1.1.4",
+      "resolved": "https://registry.npmjs.org/cids/-/cids-1.1.4.tgz",
+      "integrity": "sha512-mo0IWZKcaQZsret8cP39MzDnPVT9NhhQEVaIKwWnBFaLtj2slTFckYMnbk15ptewNkb22qRBLfuBK+qiWYW/Mg==",
       "requires": {
-        "class-is": "^1.1.0",
         "multibase": "^3.0.1",
-        "multicodec": "^2.0.1",
+        "multicodec": "^2.1.0",
         "multihashes": "^3.0.1",
         "uint8arrays": "^1.1.0"
       }
@@ -5514,9 +5163,9 @@
       }
     },
     "core-js": {
-      "version": "3.8.0",
-      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.0.tgz",
-      "integrity": "sha512-W2VYNB0nwQQE7tKS7HzXd7r2y/y2SVJl4ga6oH/dnaLFzM0o2lB2P3zCkWj5Wc/zyMYjtgd5Hmhk0ObkQFZOIA=="
+      "version": "3.8.1",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.8.1.tgz",
+      "integrity": "sha512-9Id2xHY1W7m8hCl8NkhQn5CufmF/WuR30BTRewvCXc1aZd3kMECwNZ69ndLbekKfakw9Rf2Xyc+QR6E7Gg+obg=="
     },
     "core-js-compat": {
       "version": "3.7.0",
@@ -6621,11 +6270,6 @@
         "stream-shift": "^1.0.0"
       }
     },
-    "earcut": {
-      "version": "2.2.2",
-      "resolved": "https://registry.npmjs.org/earcut/-/earcut-2.2.2.tgz",
-      "integrity": "sha512-eZoZPPJcUHnfRZ0PjLvx2qBordSiO8ofC3vt+qACLM95u+4DovnbYNpQtJh0DNsWj8RnxrQytD4WA8gj5cRIaQ=="
-    },
     "easy-stack": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.1.tgz",
@@ -6783,9 +6427,9 @@
           "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
         },
         "ws": {
-          "version": "7.4.0",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz",
-          "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ=="
+          "version": "7.4.1",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz",
+          "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ=="
         }
       }
     },
@@ -6954,11 +6598,6 @@
         "is-symbol": "^1.0.2"
       }
     },
-    "es6-promise-polyfill": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/es6-promise-polyfill/-/es6-promise-polyfill-1.2.0.tgz",
-      "integrity": "sha1-84kl8jyz4+jObNqP93T867sJDN4="
-    },
     "escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
@@ -6981,13 +6620,13 @@
       "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
     },
     "eslint": {
-      "version": "7.14.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.14.0.tgz",
-      "integrity": "sha512-5YubdnPXrlrYAFCKybPuHIAH++PINe1pmKNc5wQRB9HSbqIK1ywAnntE3Wwua4giKu0bjligf1gLF6qxMGOYRA==",
+      "version": "7.16.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.16.0.tgz",
+      "integrity": "sha512-iVWPS785RuDA4dWuhhgXTNrGxHHK3a8HLSMBgbbU59ruJDubUraXN8N5rn7kb8tG6sjg74eE0RA3YWT51eusEw==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.0.0",
-        "@eslint/eslintrc": "^0.2.1",
+        "@eslint/eslintrc": "^0.2.2",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
@@ -6997,10 +6636,10 @@
         "eslint-scope": "^5.1.1",
         "eslint-utils": "^2.1.0",
         "eslint-visitor-keys": "^2.0.0",
-        "espree": "^7.3.0",
+        "espree": "^7.3.1",
         "esquery": "^1.2.0",
         "esutils": "^2.0.2",
-        "file-entry-cache": "^5.0.1",
+        "file-entry-cache": "^6.0.0",
         "functional-red-black-tree": "^1.0.1",
         "glob-parent": "^5.0.0",
         "globals": "^12.1.0",
@@ -7020,7 +6659,7 @@
         "semver": "^7.2.1",
         "strip-ansi": "^6.0.0",
         "strip-json-comments": "^3.1.0",
-        "table": "^5.2.3",
+        "table": "^6.0.4",
         "text-table": "^0.2.0",
         "v8-compile-cache": "^2.0.3"
       },
@@ -7086,15 +6725,24 @@
           "dev": true
         },
         "import-fresh": {
-          "version": "3.2.2",
-          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.2.tgz",
-          "integrity": "sha512-cTPNrlvJT6twpYy+YmKUKrTSjWFs3bjYjAhCwm+z4EOCubZxAuO+hHpRN64TqjEaYSHs7tJAE0w1CKMGmsG/lw==",
+          "version": "3.3.0",
+          "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
+          "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
           "dev": true,
           "requires": {
             "parent-module": "^1.0.0",
             "resolve-from": "^4.0.0"
           }
         },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
         "resolve-from": {
           "version": "4.0.0",
           "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
@@ -7102,10 +6750,13 @@
           "dev": true
         },
         "semver": {
-          "version": "7.3.2",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
-          "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
-          "dev": true
+          "version": "7.3.4",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+          "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
         },
         "shebang-command": {
           "version": "2.0.0",
@@ -7139,6 +6790,12 @@
           "requires": {
             "isexe": "^2.0.0"
           }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+          "dev": true
         }
       }
     },
@@ -7165,30 +6822,48 @@
       }
     },
     "eslint-plugin-prettier": {
-      "version": "3.1.4",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz",
-      "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==",
+      "version": "3.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.3.0.tgz",
+      "integrity": "sha512-tMTwO8iUWlSRZIwS9k7/E4vrTsfvsrcM5p1eftyuqWH25nKsz/o6/54I7jwQ/3zobISyC7wMy9ZsFwgTxOcOpQ==",
       "dev": true,
       "requires": {
         "prettier-linter-helpers": "^1.0.0"
       }
     },
     "eslint-plugin-vue": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.1.0.tgz",
-      "integrity": "sha512-9dW7kj8/d2IkDdgNpvIhJdJ3XzU3x4PThXYMzWt49taktYnGyrTY6/bXCYZ/VtQKU9kXPntPrZ41+8Pw0Nxblg==",
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-7.3.0.tgz",
+      "integrity": "sha512-4rc9xrZgwT4aLz3XE6lrHu+FZtDLWennYvtzVvvS81kW9c65U4DUzQQWAFjDCgCFvN6HYWxi7ueEtxZVSB+f0g==",
       "dev": true,
       "requires": {
         "eslint-utils": "^2.1.0",
         "natural-compare": "^1.4.0",
         "semver": "^7.3.2",
-        "vue-eslint-parser": "^7.1.1"
+        "vue-eslint-parser": "^7.3.0"
       },
       "dependencies": {
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "dev": true,
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
         "semver": {
-          "version": "7.3.2",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
-          "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==",
+          "version": "7.3.4",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+          "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
           "dev": true
         }
       }
@@ -7201,25 +6876,6 @@
       "requires": {
         "esrecurse": "^4.3.0",
         "estraverse": "^4.1.1"
-      },
-      "dependencies": {
-        "esrecurse": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
-          "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
-          "dev": true,
-          "requires": {
-            "estraverse": "^5.2.0"
-          },
-          "dependencies": {
-            "estraverse": {
-              "version": "5.2.0",
-              "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.2.0.tgz",
-              "integrity": "sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==",
-              "dev": true
-            }
-          }
-        }
       }
     },
     "eslint-utils": {
@@ -7238,13 +6894,13 @@
       "dev": true
     },
     "espree": {
-      "version": "7.3.0",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.0.tgz",
-      "integrity": "sha512-dksIWsvKCixn1yrEXO8UosNSxaDoSYpq9reEjZSbHLpT5hpaCAKTLBwq0RHtLrIr+c0ByiYzWT8KTMRzoRCNlw==",
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-7.3.1.tgz",
+      "integrity": "sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==",
       "dev": true,
       "requires": {
         "acorn": "^7.4.0",
-        "acorn-jsx": "^5.2.0",
+        "acorn-jsx": "^5.3.1",
         "eslint-visitor-keys": "^1.3.0"
       },
       "dependencies": {
@@ -7705,12 +7361,12 @@
       }
     },
     "file-entry-cache": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
-      "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.0.tgz",
+      "integrity": "sha512-fqoO76jZ3ZnYrXLDRxBR1YvOvc0k844kcOg40bgsPrE25LAb/PDqTY+ho64Xh2c8ZXgIKldchCFHczG2UVRcWA==",
       "dev": true,
       "requires": {
-        "flat-cache": "^2.0.1"
+        "flat-cache": "^3.0.4"
       }
     },
     "file-loader": {
@@ -7836,20 +7492,19 @@
       }
     },
     "flat-cache": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
-      "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
+      "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
       "dev": true,
       "requires": {
-        "flatted": "^2.0.0",
-        "rimraf": "2.6.3",
-        "write": "1.0.3"
+        "flatted": "^3.1.0",
+        "rimraf": "^3.0.2"
       },
       "dependencies": {
         "rimraf": {
-          "version": "2.6.3",
-          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
-          "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+          "version": "3.0.2",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
+          "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
           "dev": true,
           "requires": {
             "glob": "^7.1.3"
@@ -7863,9 +7518,9 @@
       "integrity": "sha512-4zPxDyhCyiN2wIAtSLI6gc82/EjqZc1onI4Mz/l0pWrAlsSfYH/2ZIcU+e3oA2wDwbzIWNKwa23F8rh6+DRWkw=="
     },
     "flatted": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz",
-      "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.1.0.tgz",
+      "integrity": "sha512-tW+UkmtNg/jv9CSofAKvgVcO7c2URjhTdW1ZTkcAritblu8tajiYy7YisnIflEwtKssCtOxpnBRoCB7iap0/TA==",
       "dev": true
     },
     "flush-write-stream": {
@@ -8591,11 +8246,11 @@
       "dev": true
     },
     "global-dirs": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.0.1.tgz",
-      "integrity": "sha512-5HqUqdhkEovj2Of/ms3IeS/EekcO54ytHRLV4PEY2rhRwrHXLQjeVEES0Lhka0xwNDtGYn58wyC4s5+MHsOO6A==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-2.1.0.tgz",
+      "integrity": "sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==",
       "requires": {
-        "ini": "^1.3.5"
+        "ini": "1.3.7"
       }
     },
     "globals": {
@@ -9129,7 +8784,8 @@
     "human-signals": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
-      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw=="
+      "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
+      "dev": true
     },
     "iconv-lite": {
       "version": "0.4.24",
@@ -9257,9 +8913,9 @@
       "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
     },
     "ini": {
-      "version": "1.3.5",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
-      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
+      "version": "1.3.7",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz",
+      "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ=="
     },
     "inquirer": {
       "version": "7.3.3",
@@ -9516,22 +9172,38 @@
       "dev": true
     },
     "ipfs": {
-      "version": "0.52.2",
-      "resolved": "https://registry.npmjs.org/ipfs/-/ipfs-0.52.2.tgz",
-      "integrity": "sha512-2OZe6HyHGzSfdv55RFuw89n43zj+hPGLfmsz0h2LL4OH7ERtQVCH/5foDEoV6NJsXnBnps8w6adCtyrZeze9IQ==",
+      "version": "0.52.3",
+      "resolved": "https://registry.npmjs.org/ipfs/-/ipfs-0.52.3.tgz",
+      "integrity": "sha512-zCd2Ziq1GYDJizXdoAj5nof325i3mx2kzOhG6E+xdEK6FcK6kQwKendaBlQHwTbzHLqLI7ITxsepQzFWNopI2g==",
       "requires": {
         "debug": "^4.1.1",
-        "ipfs-cli": "^0.2.2",
-        "ipfs-core": "^0.3.0",
+        "ipfs-cli": "^0.2.3",
+        "ipfs-core": "^0.3.1",
         "ipfs-repo": "^7.0.0",
         "semver": "^7.3.2",
         "update-notifier": "^5.0.0"
       },
       "dependencies": {
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
         "semver": {
-          "version": "7.3.2",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
-          "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
+          "version": "7.3.4",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+          "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
         }
       }
     },
@@ -9569,24 +9241,22 @@
       }
     },
     "ipfs-cli": {
-      "version": "0.2.2",
-      "resolved": "https://registry.npmjs.org/ipfs-cli/-/ipfs-cli-0.2.2.tgz",
-      "integrity": "sha512-9DhIdTd8P/uvBv+IdhGjHEl2lpeXm8x2sj30PLddBHFo9PHOWUfqwo7FYHYIzn6MiakL0XWph4HAKX9Jw0iHJA==",
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/ipfs-cli/-/ipfs-cli-0.2.3.tgz",
+      "integrity": "sha512-3DGUh/V9INVPG5dv0bT1DQpjVM5diKEVrVYSMtk/h5enVPbNHTZ+Dz4zOwjRsob5QQNkdVQWdHnhCcRHNyWFCA==",
       "requires": {
         "bignumber.js": "^9.0.0",
         "byteman": "^1.3.5",
         "cid-tool": "^1.0.0",
         "cids": "^1.0.0",
         "debug": "^4.1.1",
-        "dlv": "^1.1.3",
         "err-code": "^2.0.3",
-        "execa": "^4.0.3",
+        "execa": "^5.0.0",
         "get-folder-size": "^2.0.1",
-        "ipfs-core": "^0.3.0",
-        "ipfs-core-utils": "^0.5.3",
-        "ipfs-http-client": "^48.1.2",
-        "ipfs-http-gateway": "^0.1.3",
-        "ipfs-http-server": "^0.1.3",
+        "ipfs-core": "^0.3.1",
+        "ipfs-core-utils": "^0.5.4",
+        "ipfs-daemon": "^0.3.2",
+        "ipfs-http-client": "^48.1.3",
         "ipfs-repo": "^7.0.0",
         "ipfs-utils": "^5.0.0",
         "ipld-dag-cbor": "^0.17.0",
@@ -9597,12 +9267,7 @@
         "it-glob": "0.0.10",
         "it-pipe": "^1.1.0",
         "jsondiffpatch": "^0.4.1",
-        "just-safe-set": "^2.1.0",
-        "libp2p": "^0.29.3",
         "libp2p-crypto": "^0.18.0",
-        "libp2p-delegated-content-routing": "^0.8.0",
-        "libp2p-delegated-peer-routing": "^0.8.0",
-        "libp2p-webrtc-star": "^0.20.1",
         "mafmt": "^8.0.0",
         "multiaddr": "^8.0.0",
         "multiaddr-to-uri": "^6.0.0",
@@ -9612,8 +9277,6 @@
         "peer-id": "^0.14.1",
         "pretty-bytes": "^5.4.1",
         "progress": "^2.0.3",
-        "prom-client": "^12.0.0",
-        "prometheus-gc-stats": "^0.6.0",
         "stream-to-it": "^0.2.2",
         "streaming-iterables": "^5.0.2",
         "uint8arrays": "^1.1.0",
@@ -9657,28 +9320,30 @@
           }
         },
         "execa": {
-          "version": "4.1.0",
-          "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
-          "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz",
+          "integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==",
           "requires": {
-            "cross-spawn": "^7.0.0",
-            "get-stream": "^5.0.0",
-            "human-signals": "^1.1.1",
+            "cross-spawn": "^7.0.3",
+            "get-stream": "^6.0.0",
+            "human-signals": "^2.1.0",
             "is-stream": "^2.0.0",
             "merge-stream": "^2.0.0",
-            "npm-run-path": "^4.0.0",
-            "onetime": "^5.1.0",
-            "signal-exit": "^3.0.2",
+            "npm-run-path": "^4.0.1",
+            "onetime": "^5.1.2",
+            "signal-exit": "^3.0.3",
             "strip-final-newline": "^2.0.0"
           }
         },
         "get-stream": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
-          "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
-          "requires": {
-            "pump": "^3.0.0"
-          }
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz",
+          "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg=="
+        },
+        "human-signals": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
+          "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
         },
         "is-stream": {
           "version": "2.0.0",
@@ -9743,9 +9408,9 @@
           "integrity": "sha512-hsRUr4FFrvhhRH12wOdfs38Gy7k2FFzB9qgN9v3aLykRq0dRcdcpz5C9FxdS2NuhOrI/628b/KSTJ3rwHysYSg=="
         },
         "yargs": {
-          "version": "16.1.1",
-          "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.1.1.tgz",
-          "integrity": "sha512-hAD1RcFP/wfgfxgMVswPE+z3tlPFtxG8/yWUrG2i17sTWGCGqWnxKcLTF4cUKDUK8fzokwsmO9H0TDkRbMHy8w==",
+          "version": "16.2.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+          "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
           "requires": {
             "cliui": "^7.0.2",
             "escalade": "^3.1.1",
@@ -9764,9 +9429,9 @@
       }
     },
     "ipfs-core": {
-      "version": "0.3.0",
-      "resolved": "https://registry.npmjs.org/ipfs-core/-/ipfs-core-0.3.0.tgz",
-      "integrity": "sha512-uBcYGsIM8lb8dixDvZ09OrMM5nBsvMQX9tUFS3+oo24JRhGKMWtDVV3umn26mXygobdQfGCTZFqjVMxoLssVEA==",
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/ipfs-core/-/ipfs-core-0.3.1.tgz",
+      "integrity": "sha512-d94i8Bvhm+0a38rZG2q7EcQXcVT4cTkjCZAu7ZZ4HOWyB0EevqrxH6D7VK3zv6fe+iOC6iv4qrB+Wtt1pE6NVw==",
       "requires": {
         "array-shuffle": "^1.0.1",
         "bignumber.js": "^9.0.0",
@@ -9784,11 +9449,11 @@
         "interface-datastore": "^2.0.0",
         "ipfs-bitswap": "^4.0.0",
         "ipfs-block-service": "^0.18.0",
-        "ipfs-core-utils": "^0.5.3",
+        "ipfs-core-utils": "^0.5.4",
         "ipfs-repo": "^7.0.0",
         "ipfs-unixfs": "^2.0.3",
         "ipfs-unixfs-exporter": "^3.0.4",
-        "ipfs-unixfs-importer": "^4.0.0",
+        "ipfs-unixfs-importer": "^5.0.0",
         "ipfs-utils": "^5.0.0",
         "ipld": "^0.28.0",
         "ipld-block": "^0.11.0",
@@ -9824,7 +9489,6 @@
         "multicodec": "^2.0.1",
         "multihashing-async": "^2.0.1",
         "native-abort-controller": "~0.0.3",
-        "p-defer": "^3.0.0",
         "p-queue": "^6.6.1",
         "parse-duration": "^0.4.4",
         "peer-id": "^0.14.1",
@@ -9833,9 +9497,9 @@
       }
     },
     "ipfs-core-utils": {
-      "version": "0.5.3",
-      "resolved": "https://registry.npmjs.org/ipfs-core-utils/-/ipfs-core-utils-0.5.3.tgz",
-      "integrity": "sha512-JuJz+sp+9+g7U5j0+M6+biBnVtbJnlRNuBrqku/RcwoH4IIMTX99PctGGyo8AjCo5ZK+j0om1Pp2cWTZrlSdAQ==",
+      "version": "0.5.4",
+      "resolved": "https://registry.npmjs.org/ipfs-core-utils/-/ipfs-core-utils-0.5.4.tgz",
+      "integrity": "sha512-V+OHCkqf/263jHU0Fc9Rx/uDuwlz3PHxl3qu6a5ka/mNi6gucbFuI53jWsevCrOOY9giWMLB29RINGmCV5dFeQ==",
       "requires": {
         "any-signal": "^2.0.0",
         "blob-to-it": "^1.0.1",
@@ -9853,17 +9517,39 @@
         "uint8arrays": "^1.1.0"
       }
     },
+    "ipfs-daemon": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/ipfs-daemon/-/ipfs-daemon-0.3.2.tgz",
+      "integrity": "sha512-MBpwB0zpYU17/ZZ4jGMGNvOHx6SYOOZyTfViw+dy/P3JZmeTZBzhPJQOZ0vwwnJI7OIwWscEakJWV4q4c6hrJw==",
+      "requires": {
+        "debug": "^4.1.1",
+        "dlv": "^1.1.3",
+        "ipfs-core": "^0.3.1",
+        "ipfs-http-client": "^48.1.3",
+        "ipfs-http-gateway": "^0.1.4",
+        "ipfs-http-server": "^0.1.4",
+        "ipfs-utils": "^5.0.0",
+        "just-safe-set": "^2.1.0",
+        "libp2p": "^0.29.3",
+        "libp2p-delegated-content-routing": "^0.8.0",
+        "libp2p-delegated-peer-routing": "^0.8.0",
+        "libp2p-webrtc-star": "^0.20.1",
+        "multiaddr": "^8.0.0",
+        "prom-client": "^12.0.0",
+        "prometheus-gc-stats": "^0.6.0"
+      }
+    },
     "ipfs-http-client": {
-      "version": "48.1.2",
-      "resolved": "https://registry.npmjs.org/ipfs-http-client/-/ipfs-http-client-48.1.2.tgz",
-      "integrity": "sha512-eeqHhjYUgPNBKxkS29xYS7Mtc9JxzLKI9Bua2nphB5vG1l6W2hjDTntfVl4ddY07XqZogDu6yTL3UsFj0WJFeg==",
+      "version": "48.1.3",
+      "resolved": "https://registry.npmjs.org/ipfs-http-client/-/ipfs-http-client-48.1.3.tgz",
+      "integrity": "sha512-+JV4cdMaTvYN3vd4r6+mcVxV3LkJXzc4kn2ToVbObpVpdqmG34ePf1KlvFF8A9gjcel84WpiP5xCEV/IrisPBA==",
       "requires": {
         "any-signal": "^2.0.0",
         "bignumber.js": "^9.0.0",
         "cids": "^1.0.0",
         "debug": "^4.1.1",
         "form-data": "^3.0.0",
-        "ipfs-core-utils": "^0.5.3",
+        "ipfs-core-utils": "^0.5.4",
         "ipfs-utils": "^5.0.0",
         "ipld-block": "^0.11.0",
         "ipld-dag-cbor": "^0.17.0",
@@ -9898,9 +9584,9 @@
       }
     },
     "ipfs-http-gateway": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/ipfs-http-gateway/-/ipfs-http-gateway-0.1.3.tgz",
-      "integrity": "sha512-SwBRSvwwXxlYEUBlDOBngmKFifnCFjs7HM90mgJnRjahDZzGV8YKAZpVLys0szLybz+pqGKK7LxSo7+ALS2hKQ==",
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/ipfs-http-gateway/-/ipfs-http-gateway-0.1.4.tgz",
+      "integrity": "sha512-/WuCFC5k31DiIIplGatyJnMmJ74YLnv12xU5DR1rr3E7abKLdyyvaca4cQz3iz2hFcTKvnD3+rRelbXH785JiA==",
       "requires": {
         "@hapi/ammo": "^5.0.1",
         "@hapi/boom": "^9.1.0",
@@ -9908,7 +9594,7 @@
         "cids": "^1.0.0",
         "debug": "^4.1.1",
         "hapi-pino": "^8.3.0",
-        "ipfs-core-utils": "^0.5.3",
+        "ipfs-core-utils": "^0.5.4",
         "ipfs-http-response": "^0.6.0",
         "is-ipfs": "^2.0.0",
         "it-last": "^1.0.4",
@@ -9944,9 +9630,9 @@
       }
     },
     "ipfs-http-server": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/ipfs-http-server/-/ipfs-http-server-0.1.3.tgz",
-      "integrity": "sha512-Hn7mEgfifHSVL1DFO1mIIytYiOW3Zlav+t6yQjdU+mgTzyH/4C7vwbz7V6ib5IfShROrfmeE6ahkt4IvEb9wxA==",
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/ipfs-http-server/-/ipfs-http-server-0.1.4.tgz",
+      "integrity": "sha512-EyGqwvYpOJHIW6eJ5te2UjjMA073JwabL7oNfCvITFb5ZcRKd76+ox0TDSHlkKUeWN8JP7T/00wYRj+8km2Oyg==",
       "requires": {
         "@hapi/boom": "^9.1.0",
         "@hapi/content": "^5.0.2",
@@ -9956,8 +9642,8 @@
         "dlv": "^1.1.3",
         "err-code": "^2.0.3",
         "hapi-pino": "^8.3.0",
-        "ipfs-core-utils": "^0.5.3",
-        "ipfs-http-gateway": "^0.1.3",
+        "ipfs-core-utils": "^0.5.4",
+        "ipfs-http-gateway": "^0.1.4",
         "ipfs-unixfs": "^2.0.3",
         "ipld-dag-pb": "^0.20.0",
         "it-all": "^1.0.4",
@@ -10121,6 +9807,13 @@
         "protons": "^2.0.0",
         "uint8arrays": "^1.0.0",
         "varint": "^5.0.0"
+      },
+      "dependencies": {
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+        }
       }
     },
     "ipfs-unixfs": {
@@ -10147,15 +9840,15 @@
       }
     },
     "ipfs-unixfs-importer": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-4.0.0.tgz",
-      "integrity": "sha512-ybTcgjNBaB6azQz8jJYESweATJFoc6D+Xo8USM0GahRx9xlFS+4qjnmGbC6H9RcFFt81amcP/P1zX9v83wo3cA==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/ipfs-unixfs-importer/-/ipfs-unixfs-importer-5.0.0.tgz",
+      "integrity": "sha512-bvdnCXwwCj72w/FQ7o6XcvrcbCUgXrruK0UZOfhl/mf44Nv0DWyn1Y4hQF/u63rJvYLQdAMlqniAAtFQpHQhcg==",
       "requires": {
         "bl": "^4.0.0",
         "err-code": "^2.0.0",
         "hamt-sharding": "^1.0.0",
         "ipfs-unixfs": "^2.0.4",
-        "ipfs-utils": "^4.0.0",
+        "ipfs-utils": "^5.0.0",
         "ipld-dag-pb": "^0.20.0",
         "it-all": "^1.0.1",
         "it-batch": "^1.0.3",
@@ -10167,89 +9860,11 @@
         "uint8arrays": "^1.1.0"
       },
       "dependencies": {
-        "buffer": {
-          "version": "6.0.3",
-          "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
-          "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
-          "requires": {
-            "base64-js": "^1.3.1",
-            "ieee754": "^1.2.1"
-          }
-        },
-        "fs-extra": {
-          "version": "9.0.1",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
-          "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
-          "requires": {
-            "at-least-node": "^1.0.0",
-            "graceful-fs": "^4.2.0",
-            "jsonfile": "^6.0.1",
-            "universalify": "^1.0.0"
-          }
-        },
-        "ieee754": {
-          "version": "1.2.1",
-          "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-          "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="
-        },
-        "ipfs-utils": {
-          "version": "4.0.1",
-          "resolved": "https://registry.npmjs.org/ipfs-utils/-/ipfs-utils-4.0.1.tgz",
-          "integrity": "sha512-6mg+S1sbjj+Ff+uoHOhVeC4myfV2tb2sHcdYwfpJ4ZcBo9WfdxSMnWFLiC5bIqByyJuN/g5aWgz3ozjKDzND1Q==",
-          "requires": {
-            "@achingbrain/electron-fetch": "^1.7.2",
-            "abort-controller": "^3.0.0",
-            "any-signal": "^2.1.0",
-            "buffer": "^6.0.1",
-            "err-code": "^2.0.0",
-            "fs-extra": "^9.0.1",
-            "is-electron": "^2.2.0",
-            "iso-url": "^1.0.0",
-            "it-glob": "0.0.10",
-            "merge-options": "^2.0.0",
-            "nanoid": "^3.1.3",
-            "native-abort-controller": "0.0.3",
-            "native-fetch": "^2.0.0",
-            "node-fetch": "^2.6.0",
-            "stream-to-it": "^0.2.0"
-          },
-          "dependencies": {
-            "merge-options": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-2.0.0.tgz",
-              "integrity": "sha512-S7xYIeWHl2ZUKF7SDeBhGg6rfv5bKxVBdk95s/I7wVF8d+hjLSztJ/B271cnUiF6CAFduEQ5Zn3HYwAjT16DlQ==",
-              "requires": {
-                "is-plain-obj": "^2.0.0"
-              }
-            }
-          }
-        },
         "is-plain-obj": {
           "version": "2.1.0",
           "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz",
           "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA=="
         },
-        "iso-url": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/iso-url/-/iso-url-1.0.0.tgz",
-          "integrity": "sha512-n/MsHgKOoHcFrhsxfbM3aaSdUujoFrrZ3537p3RW80AL7axL36acCseoMwIW4tNOl0n0SnkzNyVh4bREwmHoPQ=="
-        },
-        "jsonfile": {
-          "version": "6.1.0",
-          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
-          "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
-          "requires": {
-            "graceful-fs": "^4.1.6",
-            "universalify": "^2.0.0"
-          },
-          "dependencies": {
-            "universalify": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-              "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
-            }
-          }
-        },
         "merge-options": {
           "version": "3.0.4",
           "resolved": "https://registry.npmjs.org/merge-options/-/merge-options-3.0.4.tgz",
@@ -10257,11 +9872,6 @@
           "requires": {
             "is-plain-obj": "^2.1.0"
           }
-        },
-        "universalify": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
-          "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
         }
       }
     },
@@ -10802,11 +10412,6 @@
       "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
       "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
     },
-    "ismobilejs": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ismobilejs/-/ismobilejs-1.1.1.tgz",
-      "integrity": "sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw=="
-    },
     "iso-constants": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/iso-constants/-/iso-constants-0.1.2.tgz",
@@ -10967,6 +10572,13 @@
         "bl": "^4.0.2",
         "buffer": "^5.5.0",
         "varint": "^5.0.0"
+      },
+      "dependencies": {
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+        }
       }
     },
     "it-map": {
@@ -11102,9 +10714,9 @@
       },
       "dependencies": {
         "ws": {
-          "version": "7.4.0",
-          "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.0.tgz",
-          "integrity": "sha512-kyFwXuV/5ymf+IXhS6f0+eAFvydbaBW3zjpT6hUdAh/hbVjTIB5EHBGi0bPoCLSK2wcuz3BrEkB9LrYv1Nm4NQ=="
+          "version": "7.4.1",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz",
+          "integrity": "sha512-pTsP8UAfhy3sk1lSk/O/s4tjD0CRwvMnzvwr4OKGX7ZvqZtUyx4KIJB5JWbkykPoc55tixMGgTNoh3k4FkNGFQ=="
         }
       }
     },
@@ -11566,9 +11178,9 @@
       }
     },
     "libp2p": {
-      "version": "0.29.3",
-      "resolved": "https://registry.npmjs.org/libp2p/-/libp2p-0.29.3.tgz",
-      "integrity": "sha512-voILMLwpDqe/KafqaeH7CsmMNtOagV7ln6vNl0/2Lgq4zyY+vCmlzULRaStSagU+9V0QWoSoPmIgQdZ/Ydelhw==",
+      "version": "0.29.4",
+      "resolved": "https://registry.npmjs.org/libp2p/-/libp2p-0.29.4.tgz",
+      "integrity": "sha512-RACD3rvhgBTcLDtILwN8lE2z3GV5OCR1Se/wQ9UPYArSImsoikKjGQMvW0vZl9W3adUqmJOUs7CJWTUvdTAOpw==",
       "requires": {
         "abort-controller": "^3.0.0",
         "aggregate-error": "^3.0.1",
@@ -11743,6 +11355,11 @@
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
           "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
+        },
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
         }
       }
     },
@@ -11944,9 +11561,9 @@
       }
     },
     "libp2p-kad-dht": {
-      "version": "0.20.1",
-      "resolved": "https://registry.npmjs.org/libp2p-kad-dht/-/libp2p-kad-dht-0.20.1.tgz",
-      "integrity": "sha512-khffe6L6O6oU53LO8BrI3bULH4i6FLibvFEyV+7FAPXnFYhTKHa9TsIifkL/MEAfLI0hI9QN4NwMf0DpOLMvDA==",
+      "version": "0.20.4",
+      "resolved": "https://registry.npmjs.org/libp2p-kad-dht/-/libp2p-kad-dht-0.20.4.tgz",
+      "integrity": "sha512-7v4+3bdcoGUyR/8Y5G/Ok9UyhuqghpXFZq5VpW3oph5WtR348snTaBTPkI/8xkQmBxvLIAMxuomp7cMrQaTUyw==",
       "requires": {
         "abort-controller": "^3.0.0",
         "async": "^2.6.2",
@@ -12014,6 +11631,11 @@
           "requires": {
             "aggregate-error": "^3.0.0"
           }
+        },
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
         }
       }
     },
@@ -12061,6 +11683,13 @@
         "it-pipe": "^1.0.1",
         "it-pushable": "^1.3.1",
         "varint": "^5.0.0"
+      },
+      "dependencies": {
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+        }
       }
     },
     "libp2p-noise": {
@@ -12164,125 +11793,45 @@
       }
     },
     "libp2p-webrtc-star": {
-      "version": "0.20.1",
-      "resolved": "https://registry.npmjs.org/libp2p-webrtc-star/-/libp2p-webrtc-star-0.20.1.tgz",
-      "integrity": "sha512-VQNL24A3rN1/9U0fTO8MqUx3+6d99iz/HvPI3p+IzHb6MgBe7er+rgbvRep7uheZ2894IxiJI848Vs0ZNypn2w==",
+      "version": "0.20.5",
+      "resolved": "https://registry.npmjs.org/libp2p-webrtc-star/-/libp2p-webrtc-star-0.20.5.tgz",
+      "integrity": "sha512-Tny1+q0EY192WgrkNCV7360ifI3RXjMoao91qwLhNwx7ArsqVMzrZvBnK3MTMmYQaGE1W0n/CLlw/Nn344iv2Q==",
       "requires": {
         "@hapi/hapi": "^20.0.0",
-        "@hapi/inert": "^6.0.2",
+        "@hapi/inert": "^6.0.3",
         "abortable-iterator": "^3.0.0",
         "class-is": "^1.1.0",
-        "debug": "^4.1.1",
-        "err-code": "^2.0.0",
-        "ipfs-utils": "^3.0.0",
-        "it-pipe": "^1.0.1",
-        "libp2p-utils": "^0.2.0",
+        "debug": "^4.2.0",
+        "err-code": "^2.0.3",
+        "ipfs-utils": "^5.0.0",
+        "it-pipe": "^1.1.0",
+        "libp2p-utils": "^0.2.1",
         "libp2p-webrtc-peer": "^10.0.1",
         "mafmt": "^8.0.0",
         "menoetius": "0.0.2",
-        "minimist": "^1.2.0",
+        "minimist": "^1.2.5",
         "multiaddr": "^8.0.0",
         "p-defer": "^3.0.0",
-        "peer-id": "^0.14.0",
+        "peer-id": "^0.14.2",
         "prom-client": "^12.0.0",
         "socket.io": "^2.3.0",
         "socket.io-client": "^2.3.0",
         "stream-to-it": "^0.2.2",
-        "streaming-iterables": "^5.0.2"
+        "streaming-iterables": "^5.0.3"
       },
       "dependencies": {
-        "any-signal": {
-          "version": "1.2.0",
-          "resolved": "https://registry.npmjs.org/any-signal/-/any-signal-1.2.0.tgz",
-          "integrity": "sha512-Cl08k4xItix3jvu4cxO/dt2rQ6iUAjO66pTyRMub+WL1VXeAyZydCpD8GqWTPKfdL28U0R0UucmQVsUsBnvCmQ==",
-          "requires": {
-            "abort-controller": "^3.0.0"
-          }
-        },
-        "fs-extra": {
-          "version": "9.0.1",
-          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz",
-          "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==",
-          "requires": {
-            "at-least-node": "^1.0.0",
-            "graceful-fs": "^4.2.0",
-            "jsonfile": "^6.0.1",
-            "universalify": "^1.0.0"
-          }
-        },
-        "ipfs-utils": {
-          "version": "3.0.0",
-          "resolved": "https://registry.npmjs.org/ipfs-utils/-/ipfs-utils-3.0.0.tgz",
-          "integrity": "sha512-qahDc+fghrM57sbySr2TeWjaVR/RH/YEB/hvdAjiTbjESeD87qZawrXwj+19Q2LtGmFGusKNLo5wExeuI5ZfDQ==",
-          "requires": {
-            "abort-controller": "^3.0.0",
-            "any-signal": "^1.1.0",
-            "buffer": "^5.6.0",
-            "err-code": "^2.0.0",
-            "fs-extra": "^9.0.1",
-            "is-electron": "^2.2.0",
-            "iso-url": "^0.4.7",
-            "it-glob": "0.0.8",
-            "merge-options": "^2.0.0",
-            "nanoid": "^3.1.3",
-            "node-fetch": "^2.6.0",
-            "stream-to-it": "^0.2.0"
-          }
-        },
-        "it-glob": {
-          "version": "0.0.8",
-          "resolved": "https://registry.npmjs.org/it-glob/-/it-glob-0.0.8.tgz",
-          "integrity": "sha512-PmIAgb64aJPM6wwT1UTlNDAJnNgdGrvr0vRr3AYCngcUuq1KaAovuz0dQAmUkaXudDG3EQzc7OttuLW9DaL3YQ==",
-          "requires": {
-            "fs-extra": "^8.1.0",
-            "minimatch": "^3.0.4"
-          },
-          "dependencies": {
-            "fs-extra": {
-              "version": "8.1.0",
-              "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
-              "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
-              "requires": {
-                "graceful-fs": "^4.2.0",
-                "jsonfile": "^4.0.0",
-                "universalify": "^0.1.0"
-              }
-            },
-            "jsonfile": {
-              "version": "4.0.0",
-              "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
-              "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
-              "requires": {
-                "graceful-fs": "^4.1.6"
-              }
-            },
-            "universalify": {
-              "version": "0.1.2",
-              "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
-              "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
-            }
-          }
-        },
-        "jsonfile": {
-          "version": "6.1.0",
-          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
-          "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+        "debug": {
+          "version": "4.3.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz",
+          "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==",
           "requires": {
-            "graceful-fs": "^4.1.6",
-            "universalify": "^2.0.0"
-          },
-          "dependencies": {
-            "universalify": {
-              "version": "2.0.0",
-              "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz",
-              "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
-            }
+            "ms": "2.1.2"
           }
         },
-        "universalify": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz",
-          "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug=="
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
         }
       }
     },
@@ -12558,9 +12107,9 @@
       }
     },
     "marked": {
-      "version": "1.2.5",
-      "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.5.tgz",
-      "integrity": "sha512-2AlqgYnVPOc9WDyWu7S5DJaEZsfk6dNh/neatQ3IHUW4QLutM/VPSH9lG7bif+XjFWc9K9XR3QvR+fXuECmfdA=="
+      "version": "1.2.7",
+      "resolved": "https://registry.npmjs.org/marked/-/marked-1.2.7.tgz",
+      "integrity": "sha512-No11hFYcXr/zkBvL6qFmAp1z6BKY3zqLMHny/JN/ey+al7qwCM2+CMBL9BOgqMxZU36fz4cCWfn2poWIf7QRXA=="
     },
     "md5.js": {
       "version": "1.3.5",
@@ -12774,11 +12323,6 @@
         }
       }
     },
-    "mini-signals": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/mini-signals/-/mini-signals-1.2.0.tgz",
-      "integrity": "sha1-RbCAE8X65RokqhqTXNMXye1yHXQ="
-    },
     "minimalistic-assert": {
       "version": "1.0.1",
       "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -12948,9 +12492,9 @@
       "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
     },
     "multiaddr": {
-      "version": "8.1.1",
-      "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-8.1.1.tgz",
-      "integrity": "sha512-Dyur7rWX44MlgKIqVA2dYPOZx/UwG60PVSffJ5S17uo6Pu31lftJXShMEfPtUDGHnyALAOWOuC3X/iPhDtw4Vg==",
+      "version": "8.1.2",
+      "resolved": "https://registry.npmjs.org/multiaddr/-/multiaddr-8.1.2.tgz",
+      "integrity": "sha512-r13IzW8+Sv9zab9Gt8RPMIN2WkptIPq99EpAzg4IbJ/zTELhiEwXWr9bAmEatSCI4j/LSA6ESJzvz95JZ+ZYXQ==",
       "requires": {
         "cids": "^1.0.0",
         "class-is": "^1.1.0",
@@ -12960,6 +12504,13 @@
         "multibase": "^3.0.0",
         "uint8arrays": "^1.1.0",
         "varint": "^5.0.0"
+      },
+      "dependencies": {
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+        }
       }
     },
     "multiaddr-to-uri": {
@@ -12996,23 +12547,12 @@
       "dev": true
     },
     "multicodec": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-2.0.1.tgz",
-      "integrity": "sha512-YDYeWn9iGa76hOHAyyZa0kbt3tr5FLg1ZXUHrZUJltjnxxdbTIbHnxWLd2zTcMOjdT3QyO+Xs4bQgJUcC2RWUA==",
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/multicodec/-/multicodec-2.1.0.tgz",
+      "integrity": "sha512-7AYpK/avswOWvnqQ9/jOkQCS7Fp4aKxw5ojvn5gyK2VQTZz3YVXeLMzoIZDBy745JSfJMXkTS0ptnHci5Mt1mA==",
       "requires": {
-        "uint8arrays": "1.0.0",
-        "varint": "^5.0.0"
-      },
-      "dependencies": {
-        "uint8arrays": {
-          "version": "1.0.0",
-          "resolved": "https://registry.npmjs.org/uint8arrays/-/uint8arrays-1.0.0.tgz",
-          "integrity": "sha512-14tqEVujDREW7YwonSZZwLvo7aFDfX7b6ubvM/U7XvZol+CC/LbhaX/550VlWmhddAL9Wou1sxp0Of3tGqXigg==",
-          "requires": {
-            "multibase": "^3.0.0",
-            "web-encoding": "^1.0.2"
-          }
-        }
+        "uint8arrays": "1.1.0",
+        "varint": "^6.0.0"
       }
     },
     "multihashes": {
@@ -13023,13 +12563,6 @@
         "multibase": "^3.1.0",
         "uint8arrays": "^1.0.0",
         "varint": "^6.0.0"
-      },
-      "dependencies": {
-        "varint": {
-          "version": "6.0.0",
-          "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
-          "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="
-        }
       }
     },
     "multihashing-async": {
@@ -13094,9 +12627,9 @@
       "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ=="
     },
     "nanoid": {
-      "version": "3.1.18",
-      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.18.tgz",
-      "integrity": "sha512-rndlDjbbHbcV3xi+R2fpJ+PbGMdfBxz5v1fATIQFq0DP64FsicQdwnKLy47K4kZHdRpmQXtz24eGsxQqamzYTA=="
+      "version": "3.1.20",
+      "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz",
+      "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw=="
     },
     "nanomatch": {
       "version": "1.2.13",
@@ -13367,7 +12900,8 @@
     "object-assign": {
       "version": "4.1.1",
       "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
-      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+      "dev": true
     },
     "object-component": {
       "version": "0.0.3",
@@ -13899,11 +13433,6 @@
         "lines-and-columns": "^1.1.6"
       }
     },
-    "parse-uri": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/parse-uri/-/parse-uri-1.0.3.tgz",
-      "integrity": "sha512-upMnGxNcm+45So85HoguwZTVZI9u11i36DdxJfGF2HYWS2eh3TIx7+/tTi7qrEq15qzGkVhsKjesau+kCk48pA=="
-    },
     "parse5": {
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
@@ -14091,9 +13620,9 @@
       }
     },
     "pino": {
-      "version": "6.7.0",
-      "resolved": "https://registry.npmjs.org/pino/-/pino-6.7.0.tgz",
-      "integrity": "sha512-vPXJ4P9rWCwzlTJt+f0Ni4THc3DWyt8iDDCO4edQ8narTu6hnpzdXu8FqeSJCGndl1W6lfbYQUQihUO54y66Lw==",
+      "version": "6.8.0",
+      "resolved": "https://registry.npmjs.org/pino/-/pino-6.8.0.tgz",
+      "integrity": "sha512-nxq+6Jr7m0cMjYFBoTRw3bco14omZ/SQCheAHz9GVwdkbUrzKhgT+gSI/ql2Mnsca0QQKgpB/ACWhjxE4JsX3Q==",
       "requires": {
         "fast-redact": "^3.0.0",
         "fast-safe-stringify": "^2.0.7",
@@ -14181,47 +13710,6 @@
       "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-2.5.0.tgz",
       "integrity": "sha512-wXqbqSrIhE58TdrxxlfLwU9eDhrzppQDvGhBEr1gYbzzM4KKo3Y63gSjiDXRKLVS2UOXdPNR2v+KnQgNrs+xUg=="
     },
-    "pixi.js": {
-      "version": "5.3.3",
-      "resolved": "https://registry.npmjs.org/pixi.js/-/pixi.js-5.3.3.tgz",
-      "integrity": "sha512-uFQOXXyPMAVVayDebSFBS1AFfPT6QYNuz9Vu11yI2/k1DAef/rbYoJpSMM6SeB6dezDJPtIAaXXNxdaYzbe+kg==",
-      "requires": {
-        "@pixi/accessibility": "5.3.3",
-        "@pixi/app": "5.3.3",
-        "@pixi/constants": "5.3.3",
-        "@pixi/core": "5.3.3",
-        "@pixi/display": "5.3.3",
-        "@pixi/extract": "5.3.3",
-        "@pixi/filter-alpha": "5.3.3",
-        "@pixi/filter-blur": "5.3.3",
-        "@pixi/filter-color-matrix": "5.3.3",
-        "@pixi/filter-displacement": "5.3.3",
-        "@pixi/filter-fxaa": "5.3.3",
-        "@pixi/filter-noise": "5.3.3",
-        "@pixi/graphics": "5.3.3",
-        "@pixi/interaction": "5.3.3",
-        "@pixi/loaders": "5.3.3",
-        "@pixi/math": "5.3.3",
-        "@pixi/mesh": "5.3.3",
-        "@pixi/mesh-extras": "5.3.3",
-        "@pixi/mixin-cache-as-bitmap": "5.3.3",
-        "@pixi/mixin-get-child-by-name": "5.3.3",
-        "@pixi/mixin-get-global-position": "5.3.3",
-        "@pixi/particles": "5.3.3",
-        "@pixi/polyfill": "5.3.3",
-        "@pixi/prepare": "5.3.3",
-        "@pixi/runner": "5.3.3",
-        "@pixi/settings": "5.3.3",
-        "@pixi/sprite": "5.3.3",
-        "@pixi/sprite-animated": "5.3.3",
-        "@pixi/sprite-tiling": "5.3.3",
-        "@pixi/spritesheet": "5.3.3",
-        "@pixi/text": "5.3.3",
-        "@pixi/text-bitmap": "5.3.3",
-        "@pixi/ticker": "5.3.3",
-        "@pixi/utils": "5.3.3"
-      }
-    },
     "pkg-dir": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz",
@@ -15063,9 +14551,9 @@
       },
       "dependencies": {
         "@types/node": {
-          "version": "13.13.33",
-          "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.33.tgz",
-          "integrity": "sha512-1B3GM1yuYsFyEvBb+ljBqWBOylsWDYioZ5wpu8AhXdIhq20neXS7eaSC8GkwHE0yQYGiOIV43lMsgRYTgKZefQ=="
+          "version": "13.13.36",
+          "resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.36.tgz",
+          "integrity": "sha512-ctzZJ+XsmHQwe3xp07gFUq4JxBaRSYzKHPgblR76//UanGST7vfFNF0+ty5eEbgTqsENopzoDK090xlha9dccQ=="
         }
       }
     },
@@ -15083,6 +14571,13 @@
         "signed-varint": "^2.0.1",
         "uint8arrays": "^1.0.0",
         "varint": "^5.0.0"
+      },
+      "dependencies": {
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+        }
       }
     },
     "proxy-addr": {
@@ -15203,7 +14698,8 @@
     "querystring": {
       "version": "0.2.0",
       "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
-      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA="
+      "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+      "dev": true
     },
     "querystring-es3": {
       "version": "0.2.1",
@@ -15384,9 +14880,9 @@
       },
       "dependencies": {
         "ms": {
-          "version": "2.1.2",
-          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+          "version": "2.1.3",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+          "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="
         }
       }
     },
@@ -15677,15 +15173,6 @@
       "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
       "dev": true
     },
-    "resource-loader": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/resource-loader/-/resource-loader-3.0.1.tgz",
-      "integrity": "sha512-fBuCRbEHdLCI1eglzQhUv9Rrdcmqkydr1r6uHE2cYHvRBrcLXeSmbE/qI/urFt8rPr/IGxir3BUwM5kUK8XoyA==",
-      "requires": {
-        "mini-signals": "^1.2.0",
-        "parse-uri": "^1.0.0"
-      }
-    },
     "responselike": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
@@ -16098,6 +15585,13 @@
       "integrity": "sha1-UKmYnafJjCxh2tEZvJdHDvhSgSk=",
       "requires": {
         "varint": "~5.0.0"
+      },
+      "dependencies": {
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+        }
       }
     },
     "simple-swizzle": {
@@ -16118,14 +15612,14 @@
       }
     },
     "sinon": {
-      "version": "9.2.1",
-      "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz",
-      "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==",
+      "version": "9.2.2",
+      "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.2.tgz",
+      "integrity": "sha512-9Owi+RisvCZpB0bdOVFfL314I6I4YoRlz6Isi4+fr8q8YQsDPoCe5UnmNtKHRThX3negz2bXHWIuiPa42vM8EQ==",
       "requires": {
         "@sinonjs/commons": "^1.8.1",
         "@sinonjs/fake-timers": "^6.0.1",
         "@sinonjs/formatio": "^5.0.1",
-        "@sinonjs/samsam": "^5.2.0",
+        "@sinonjs/samsam": "^5.3.0",
         "diff": "^4.0.2",
         "nise": "^4.0.4",
         "supports-color": "^7.1.0"
@@ -16153,14 +15647,40 @@
       "dev": true
     },
     "slice-ansi": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
-      "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz",
+      "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==",
       "dev": true,
       "requires": {
-        "ansi-styles": "^3.2.0",
-        "astral-regex": "^1.0.0",
-        "is-fullwidth-code-point": "^2.0.0"
+        "ansi-styles": "^4.0.0",
+        "astral-regex": "^2.0.0",
+        "is-fullwidth-code-point": "^3.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        }
       }
     },
     "snapdragon": {
@@ -16506,6 +16026,11 @@
         "is-plain-obj": "^1.0.0"
       }
     },
+    "sortablejs": {
+      "version": "1.10.2",
+      "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
+      "integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
+    },
     "source-list-map": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -16990,43 +16515,15 @@
       }
     },
     "table": {
-      "version": "5.4.6",
-      "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz",
-      "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==",
+      "version": "6.0.4",
+      "resolved": "https://registry.npmjs.org/table/-/table-6.0.4.tgz",
+      "integrity": "sha512-sBT4xRLdALd+NFBvwOz8bw4b15htyythha+q+DVZqy2RS08PPC8O2sZFgJYEY7bJvbCFKccs+WIZ/cd+xxTWCw==",
       "dev": true,
       "requires": {
-        "ajv": "^6.10.2",
-        "lodash": "^4.17.14",
-        "slice-ansi": "^2.1.0",
-        "string-width": "^3.0.0"
-      },
-      "dependencies": {
-        "emoji-regex": {
-          "version": "7.0.3",
-          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
-          "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
-          "dev": true
-        },
-        "string-width": {
-          "version": "3.1.0",
-          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
-          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
-          "dev": true,
-          "requires": {
-            "emoji-regex": "^7.0.1",
-            "is-fullwidth-code-point": "^2.0.0",
-            "strip-ansi": "^5.1.0"
-          }
-        },
-        "strip-ansi": {
-          "version": "5.2.0",
-          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
-          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
-          "dev": true,
-          "requires": {
-            "ansi-regex": "^4.1.0"
-          }
-        }
+        "ajv": "^6.12.4",
+        "lodash": "^4.17.20",
+        "slice-ansi": "^4.0.0",
+        "string-width": "^4.2.0"
       }
     },
     "tapable": {
@@ -17643,10 +17140,21 @@
             "ci-info": "^2.0.0"
           }
         },
+        "lru-cache": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
+          "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+          "requires": {
+            "yallist": "^4.0.0"
+          }
+        },
         "semver": {
-          "version": "7.3.2",
-          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz",
-          "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ=="
+          "version": "7.3.4",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz",
+          "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==",
+          "requires": {
+            "lru-cache": "^6.0.0"
+          }
         },
         "supports-color": {
           "version": "7.2.0",
@@ -17655,6 +17163,11 @@
           "requires": {
             "has-flag": "^4.0.0"
           }
+        },
+        "yallist": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
+          "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
         }
       }
     },
@@ -17691,6 +17204,7 @@
       "version": "0.11.0",
       "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
       "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+      "dev": true,
       "requires": {
         "punycode": "1.3.2",
         "querystring": "0.2.0"
@@ -17699,7 +17213,8 @@
         "punycode": {
           "version": "1.3.2",
           "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
-          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0="
+          "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+          "dev": true
         }
       }
     },
@@ -17828,9 +17343,9 @@
       }
     },
     "varint": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
-      "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/varint/-/varint-6.0.0.tgz",
+      "integrity": "sha512-cXEIW6cfr15lFv563k4GuVuW/fiwjknytD37jIOLSdSWuOI6WnO/oKwmP2FQTU2l01LP8/M5TSAJpzUaGe3uWg=="
     },
     "varint-decoder": {
       "version": "1.0.0",
@@ -17838,6 +17353,13 @@
       "integrity": "sha512-JkOvdztASWGUAsXshCFHrB9f6AgR2Q8W08CEyJ+43b1qtFocmI8Sp1R/M0E/hDOY2FzVIqk63tOYLgDYWuJ7IQ==",
       "requires": {
         "varint": "^5.0.0"
+      },
+      "dependencies": {
+        "varint": {
+          "version": "5.0.2",
+          "resolved": "https://registry.npmjs.org/varint/-/varint-5.0.2.tgz",
+          "integrity": "sha512-lKxKYG6H03yCZUpAGOPOsMcGxd1RHCu1iKvEHYDPmTyq2HueGhD73ssNBqqQWfvYs04G9iUFRvmAVLW20Jw6ow=="
+        }
       }
     },
     "vary": {
@@ -17875,9 +17397,9 @@
       "integrity": "sha512-uhmLFETqPPNyuLLbsKz6ioJ4q7AZHzD8ZVFNATNyICSZouqP2Sz0rotWQC8UNBF6VGSCs5abnKJoStA6JbCbfg=="
     },
     "vue-draggable-resizable": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/vue-draggable-resizable/-/vue-draggable-resizable-2.2.0.tgz",
-      "integrity": "sha512-KjVyzg0OtLsyVhnwD/6NozJkLMD3li41QB/aJIJUr3VS75Gn32UPOWidLvhwsbkwNQcKajXW9QCV1aTrN6MY8w=="
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/vue-draggable-resizable/-/vue-draggable-resizable-2.3.0.tgz",
+      "integrity": "sha512-77CLRj1TPwB30pwsjOf3pkd1UzYanCdKXbqhILJ0Oo5QQl50lvBfyQCXxMFzwWwTc3sbBbQH3FfWSV+BkoSElA=="
     },
     "vue-emoji-picker": {
       "version": "1.0.1",
@@ -17885,9 +17407,9 @@
       "integrity": "sha512-phisHAaSg+7xnpi7xlOxFGD46npaQXCLit2T6nAHMlEcFNT1ZUqu/NO3P5FDp6RgjP7o4ueduktnxk9ul0IS9Q=="
     },
     "vue-eslint-parser": {
-      "version": "7.1.1",
-      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.1.1.tgz",
-      "integrity": "sha512-8FdXi0gieEwh1IprIBafpiJWcApwrU+l2FEj8c1HtHFdNXMd0+2jUSjBVmcQYohf/E72irwAXEXLga6TQcB3FA==",
+      "version": "7.3.0",
+      "resolved": "https://registry.npmjs.org/vue-eslint-parser/-/vue-eslint-parser-7.3.0.tgz",
+      "integrity": "sha512-n5PJKZbyspD0+8LnaZgpEvNCrjQx1DyDHw8JdWwoxhhC+yRip4TAvSDpXGf9SWX6b0umeB5aR61gwUo6NVvFxw==",
       "dev": true,
       "requires": {
         "debug": "^4.1.1",
@@ -18035,6 +17557,11 @@
         }
       }
     },
+    "vue-swatches": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/vue-swatches/-/vue-swatches-2.1.0.tgz",
+      "integrity": "sha512-JbSomg1penZvgHL24blA3PDgji7LPVGGSFlMo7F+jYVcxooemadI3gkMwFJVIPMikG5g160Mq+Lbph/lqFjzzw=="
+    },
     "vue-template-compiler": {
       "version": "2.6.12",
       "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.12.tgz",
@@ -18051,6 +17578,14 @@
       "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
       "dev": true
     },
+    "vuedraggable": {
+      "version": "2.24.3",
+      "resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
+      "integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
+      "requires": {
+        "sortablejs": "1.10.2"
+      }
+    },
     "vuex": {
       "version": "3.6.0",
       "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.6.0.tgz",
@@ -18211,9 +17746,9 @@
       }
     },
     "web-encoding": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/web-encoding/-/web-encoding-1.0.4.tgz",
-      "integrity": "sha512-DcXs2lbVPzuJmn2kuDEwul2oZg7p4YMa5J2f0YzsOBHaAnBYGPNUB/rJ74DTjTKpw7F0+lSsVM8sFHE2UyBixg=="
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/web-encoding/-/web-encoding-1.0.6.tgz",
+      "integrity": "sha512-26wEnRPEFAc5d5lmH1Q/DuvWEYsRF1D2alX2jlKpdmqv7cj+BbANL7Xlcl9r4s72Eg9kItZa9RWVbBMC9dMv4w=="
     },
     "webpack": {
       "version": "4.44.2",
@@ -18754,15 +18289,6 @@
       "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
       "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
     },
-    "write": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
-      "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
-      "dev": true,
-      "requires": {
-        "mkdirp": "^0.5.1"
-      }
-    },
     "write-file-atomic": {
       "version": "3.0.3",
       "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz",
diff --git a/app/package.json b/app/package.json
index 3e86fb645c9bc54c7d4a7d056a16b9dec1b304ea..212b8d78fd4e275777bcc603cb4731a530966c23 100644
--- a/app/package.json
+++ b/app/package.json
@@ -1,6 +1,6 @@
 {
   "name": "nodenogg.in",
-  "version": "0.1.38",
+  "version": "0.1.47",
   "private": true,
   "scripts": {
     "serve": "vue-cli-service serve",
@@ -9,16 +9,17 @@
     "lint:fix": "vue-cli-service lint --fix"
   },
   "dependencies": {
-    "core-js": "^3.8.0",
+    "core-js": "^3.8.1",
     "file-loader": "^6.2.0",
-    "ipfs": "^0.52.2",
-    "marked": "^1.2.5",
-    "pixi.js": "^5.3.3",
+    "ipfs": "^0.52.3",
+    "marked": "^1.2.7",
     "pouchdb": "^7.2.2",
     "vue": "^2.6.12",
-    "vue-draggable-resizable": "^2.2.0",
+    "vue-draggable-resizable": "^2.3.0",
     "vue-emoji-picker": "^1.0.1",
     "vue-router": "^3.4.9",
+    "vue-swatches": "^2.1.0",
+    "vuedraggable": "^2.24.3",
     "vuex": "^3.6.0"
   },
   "devDependencies": {
@@ -29,9 +30,9 @@
     "@vue/cli-service": "^4.5.9",
     "@vue/eslint-config-prettier": "^6.0.0",
     "babel-eslint": "^10.0.3",
-    "eslint": "^7.14.0",
-    "eslint-plugin-prettier": "^3.1.4",
-    "eslint-plugin-vue": "^7.0.0",
+    "eslint": "^7.16.0",
+    "eslint-plugin-prettier": "^3.3.0",
+    "eslint-plugin-vue": "^7.3.0",
     "prettier": "^2.2.1",
     "vue-template-compiler": "^2.6.12"
   }
diff --git a/app/src/components/CardsLayer.vue b/app/src/components/CardsLayer.vue
index 0ec9a4d63e9c405825d9554ff23883cbfe6da9a2..b0f9d105a08d8955de2ea5edb3cd51420d20b03d 100644
--- a/app/src/components/CardsLayer.vue
+++ b/app/src/components/CardsLayer.vue
@@ -1,65 +1,206 @@
 <template>
-  <div class="grid">
-    <div v-for="(nodes, index) in nodes_filtered" v-bind:key="index">
-      <form class="nodes">
-        <template v-if="nodes.read_mode == false">
-          <textarea
-            @focus="editTrue(true)"
-            @blur="editTrue(false)"
-            autofocus
-            v-model="nodes.node_text"
-            @input="editNode"
-            :id="nodes.node_id"
-            ref="nodetext"
-            placeholder="Type your thoughts and ideas here! (auto saved every keystroke)"
-          ></textarea>
-        </template>
-        <template v-else>
-          <p
-            :id="nodes.node_id"
-            :inner-html.prop="nodes.node_text | marked"
-          ></p>
-        </template>
-        <div class="btn-row">
-          <SvgButton
-            buttonClass="nodes"
-            @click.prevent="deleteFlag(nodes.node_id)"
-          />
-          <SvgButton2
-            buttonClass="nodes"
-            @click.prevent="readFlag(nodes.node_id, nodes.read_mode)"
-          />
+  <div>
+    <draggable
+      id="dragger"
+      class="grid"
+      name="grid"
+      @start="drag = true"
+      @end="drag = false"
+      @update="nodePositionIndex"
+    >
+      <div v-for="(value, index) in configPositions" v-bind:key="index">
+        <div v-for="(nodes, index) in $options.myArray" v-bind:key="index">
+          <form
+            class="nodes cell"
+            :style="{
+              backgroundColor: nodes.color,
+            }"
+            v-if="nodes.node_id == value.node_id"
+          >
+            <template v-if="nodes.read_mode == false">
+              <textarea
+                @focus="editTrue(true)"
+                @blur="editTrue(false)"
+                autofocus
+                v-focus
+                v-model="nodes.node_text"
+                @input="editNode"
+                :id="nodes.node_id"
+                ref="nodetext"
+                placeholder="Type your thoughts and ideas here! (auto saved every keystroke)"
+              ></textarea>
+            </template>
+            <template v-else>
+              <p
+                :id="nodes.node_id"
+                :inner-html.prop="nodes.node_text | marked"
+              ></p>
+            </template>
+            <div class="btn-row">
+              <SvgButton
+                buttonClass="nodes"
+                @click.prevent="deleteFlag(nodes.node_id), updateNodes()"
+              />
+              <SvgButton2
+                buttonClass="nodes"
+                @click.prevent="
+                  readFlag(nodes.node_id, nodes.read_mode), updateNodes()
+                "
+              />
+              <v-swatches
+                v-model="color"
+                @input="chooseColor(color, nodes.node_id)"
+                :swatches="swatches"
+                :shapes="shapes"
+                show-border
+                show-fallback
+                fallback-input-type="color"
+              >
+                <SvgButton3 buttonClass="nodes" @click.prevent slot="trigger" />
+              </v-swatches>
+            </div>
+
+            <div class="allemoji">
+              <div
+                class="eachemoji"
+                v-for="(emojis, index) in configEmoji"
+                :key="index"
+              >
+                <template v-if="emojis.node_id == nodes.node_id">{{
+                  emojis.emoji_text
+                }}</template>
+              </div>
+            </div>
+          </form>
         </div>
+      </div>
 
-        <div class="allemoji">
-          <div
-            class="eachemoji"
-            v-for="(emojis, index) in configEmoji"
-            :key="index"
-          >
-            <template v-if="emojis.node_id == nodes.node_id">{{
-              emojis.emoji_text
-            }}</template>
+      <div
+        v-for="(othernodes, index) in othernodes_filtered"
+        v-bind:key="index.nodeid"
+      >
+        <div
+          class="othernodes cell"
+          :style="{
+            backgroundColor: othernodes.color,
+          }"
+        >
+          <p :inner-html.prop="othernodes.node_text | marked"></p>
+
+          <div class="eeee">
+            <input :value="othernodes.node_id" name="id" readonly hidden />
+            <input
+              id="emojifield"
+              class="regular-input"
+              v-model="input"
+              readonly
+            />
+
+            <emoji-picker @emoji="append" :search="search">
+              <div
+                class="emoji-invoker"
+                slot="emoji-invoker"
+                slot-scope="{ events: { click: clickEvent } }"
+                @click.stop="clickEvent"
+              >
+                <svg
+                  height="24"
+                  viewBox="0 0 24 24"
+                  width="24"
+                  xmlns="http://www.w3.org/2000/svg"
+                >
+                  <path d="M0 0h24v24H0z" fill="none" />
+                  <path
+                    d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"
+                  />
+                </svg>
+              </div>
+              <div slot="emoji-picker" slot-scope="{ emojis, insert, display }">
+                <div
+                  class="emoji-picker"
+                  :style="{ top: display.y + 'px', left: display.x + 'px' }"
+                >
+                  <div class="emoji-picker__search">
+                    <input type="text" v-model="search" />
+                  </div>
+                  <div>
+                    <div
+                      v-for="(emojiGroup, category) in emojis"
+                      :key="category"
+                    >
+                      <h5>{{ category }}</h5>
+                      <div class="emojis">
+                        <span
+                          v-for="(emoji, emojiName) in emojiGroup"
+                          :key="emojiName"
+                          @click="insert(emoji), sentReact(othernodes.node_id)"
+                          :title="emojiName"
+                          >{{ emoji }}</span
+                        >
+                      </div>
+                    </div>
+                  </div>
+                </div>
+              </div>
+            </emoji-picker>
+
+            <div class="allemoji">
+              <div
+                class="eachemoji"
+                v-for="(emojis, index) in configEmoji"
+                :key="index"
+              >
+                <p v-if="othernodes.node_id == emojis.node_id">
+                  {{ emojis.emoji_text }}
+                </p>
+              </div>
+            </div>
           </div>
         </div>
-      </form>
-    </div>
+      </div>
+    </draggable>
   </div>
 </template>
 
 <script>
 import { mapState } from 'vuex'
 import marked from 'marked'
+import draggable from 'vuedraggable'
+import EmojiPicker from 'vue-emoji-picker'
 import SvgButton from '@/components/SvgButton'
 import SvgButton2 from '@/components/SvgButton2'
+import SvgButton3 from '@/components/SvgButton3'
+import VSwatches from 'vue-swatches'
+import 'vue-swatches/dist/vue-swatches.css'
+
 var readmode
+var nodeid
+//var nodesort
+var emojitext
 
 export default {
   name: 'CardsLayer',
 
+  props: {
+    added: Boolean,
+  },
   data: function () {
     return {
+      color: '#9bc2d8',
+      shapes: 'circles',
+      // swatches: [{ color: '#F493A7', showBorder: true }],
+      swatches: [
+        ['#EB5757', '#F2994A', '#F2C94C'],
+        ['#219653', '#27AE60', '#6FCF97'],
+        ['#2F80ED', '#2D9CDB', '#56CCF2'],
+        ['#9B51E0', '#BB6BD9', '#E9B7FC'],
+      ],
       localreadmode: false,
+      myArray: null,
+      update: false,
+      input: '',
+      search: '',
+      orders: this.configPositions,
     }
   },
 
@@ -68,6 +209,7 @@ export default {
   },
   computed: {
     ...mapState({
+      otherNodes: (state) => state.otherNodes,
       myNodes: (state) => state.myNodes,
       configPositions: (state) => state.configPositions,
       configEmoji: (state) => state.configEmoji,
@@ -78,16 +220,97 @@ export default {
         return nodes.deleted == false
       })
     },
+    othernodes_filtered: function () {
+      return this.otherNodes.filter((othernodes) => {
+        return othernodes.deleted == false
+      })
+    },
   },
 
   // this is to stop sync chasing bug
-  myArray: null,
+
   mounted() {
     //access the custom option using $options
-    this.$options.myArray = this.nodes_filtered
+    const unwatch = this.$watch('nodes_filtered', (value) => {
+      this.$options.myArray = this.nodes_filtered
+
+      this.$forceUpdate()
+      // ignore falsy values
+      if (!value) return
+
+      // stop watching when nodes_filtered[] is not empty
+      if (value && value.length) unwatch()
+
+      // process value here
+    })
+  },
+
+  watch: {
+    added: {
+      deep: true,
+
+      handler() {
+        setTimeout(this.loadData, 200)
+      },
+    },
+    update: {
+      deep: true,
+
+      handler() {
+        setTimeout(this.loadData, 200)
+      },
+    },
   },
 
   methods: {
+    nodePositionIndex() {
+      // var i
+      // var j
+      // var dragger = document.getElementById('dragger')
+      // // console.log(dragger.childNodes.length)
+      // for (i = 0; i < dragger.childNodes.length; i++) {
+      //   var count = i
+      //   for (j = 0; j < Object.keys(this.configPositions).length; j++) {
+      //     if (dragger.childNodes[i].firstChild != 'undefined') {
+      //       if (
+      //         dragger.childNodes[i].firstChild[0].id ==
+      //         this.configPositions[j].node_id
+      //       ) {
+      //         nodeid = this.configPositions[j].node_id
+      //         nodesort = count
+      //         this.$store.dispatch('sortNode', { nodeid, nodesort })
+      //       }
+      //     }
+      //     //  console.log(nodesort)
+      //   }
+      // }
+    },
+    chooseColor(color, nodeid) {
+      this.$store.dispatch('colorNode', { nodeid, color })
+      this.$options.myArray = this.nodes_filtered
+    },
+
+    append(emoji) {
+      this.input += emoji
+    },
+    sentReact(e) {
+      emojitext = this.input
+      nodeid = e
+
+      this.$store.dispatch('addEmoji', {
+        nodeid,
+        emojitext,
+      })
+
+      this.input = ''
+    },
+    updateNodes() {
+      this.update = !this.update
+    },
+    loadData() {
+      this.$options.myArray = this.nodes_filtered
+      this.$forceUpdate()
+    },
     editNode(e) {
       var nodeid = e.target.id
       var nodetext = e.target.value
@@ -99,7 +322,6 @@ export default {
     },
 
     deleteFlag(e) {
-      e = this.nodeid
       if (confirm('Confirm discard?')) {
         this.$store.dispatch('deleteFlag', { e })
       } else {
@@ -121,19 +343,47 @@ export default {
   components: {
     SvgButton,
     SvgButton2,
+    SvgButton3,
+    VSwatches,
+    EmojiPicker,
+    draggable,
   },
 }
 </script>
 
 <style lang="css" scoped>
-.grid {
+/* .grid {
   display: flex;
   flex-wrap: wrap;
+} */
+
+.grid {
+  display: grid;
+  /* grid-template-columns: repeat(3, 350px); */
+  /* grid-template-rows: repeat(3, 350px); */
+  grid-gap: 0.2em;
+}
+
+.grid-move {
+  transition: all 0.3s;
 }
+
 .nodes {
+  padding: 0.5em 0.5em;
   min-width: 343px;
-  max-width: 343px;
+  /* max-width: 343px; */
   border: 2px dashed black;
+  /* background-color: rgb(155, 194, 216); */
+  margin-top: 1em;
+  margin-left: 0.5em;
+  margin-right: 0.5em;
+}
+
+.othernodes {
+  padding: 0.5em 0.5em;
+  min-width: 343px;
+  /* max-width: 343px; */
+  border: 2px solid black;
   background-color: rgb(155, 194, 216);
   margin-top: 1em;
   margin-left: 0.5em;
@@ -167,8 +417,7 @@ textarea {
   display: flex;
   justify-content: center;
   flex-wrap: wrap;
-  padding: 0 15px;
-  border-radius: 4px;
+  padding: 0 25px;
 }
 
 .allemoji {
@@ -183,6 +432,97 @@ textarea {
   margin: 0em;
 }
 
+input {
+  display: none;
+}
+
+.allemoji {
+  font-size: 2em;
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(0, auto));
+
+  /* float: left; */
+}
+
+.eachemoji p {
+  margin: 0em;
+}
+
+.emoji-invoker {
+  top: -0.5rem;
+  right: 0.5rem;
+  width: 1.5rem;
+  height: 2.5rem;
+  /* transform: scale(1.6); */
+  /* margin: 0em 0em 1em 0em; */
+  /* border-radius: 50%; */
+  cursor: pointer;
+  transition: all 0.8s;
+}
+.emoji-invoker:hover > svg {
+  fill: #84949b;
+
+  /* transform: scale(1.5); */
+}
+.emoji-invoker > svg {
+  fill: #b1c6d0;
+  margin-top: 10px;
+  margin-left: 0.2em;
+  transform: scale(1.5);
+}
+
+.emoji-picker {
+  transform: scale(1.2);
+  z-index: 1;
+  font-family: Montserrat;
+  border: 1px solid #ccc;
+  width: 18rem;
+  height: 20rem;
+  overflow: scroll;
+  padding: 1rem;
+  box-sizing: border-box;
+  border-radius: 0.5rem;
+  background: #fff;
+  box-shadow: 1px 1px 8px #c7dbe6;
+  margin-top: 3em;
+}
+.emoji-picker__search {
+  display: flex;
+}
+.emoji-picker__search > input {
+  flex: 1;
+  border-radius: 10rem;
+  border: 1px solid #ccc;
+  padding: 0.5rem 1rem;
+  outline: none;
+}
+.emoji-picker h5 {
+  margin-top: 0;
+  margin-bottom: 0;
+  color: #b1b1b1;
+  text-transform: uppercase;
+  font-size: 0.8rem;
+  cursor: default;
+}
+.emoji-picker .emojis {
+  display: flex;
+  flex-wrap: wrap;
+  justify-content: space-between;
+}
+.emoji-picker .emojis:after {
+  content: '';
+  flex: auto;
+}
+.emoji-picker .emojis span {
+  padding: 0.2rem;
+  cursor: pointer;
+  border-radius: 5px;
+}
+.emoji-picker .emojis span:hover {
+  background: #ececec;
+  cursor: pointer;
+}
+
 @media only screen and (max-width: 600px) {
   .readmode >>> a {
     font-size: 2em;
@@ -190,4 +530,18 @@ textarea {
     padding-right: 0.5em;
   }
 }
+
+@media (min-width: 700px) {
+  .grid {
+    grid-template-columns: repeat(2, 1fr);
+  }
+}
+
+@media (min-width: 1100px) {
+  .grid {
+    grid-template-columns: repeat(3, 1fr);
+    margin: 0 auto;
+    max-width: 1100px;
+  }
+}
 </style>
diff --git a/app/src/components/CardsLayerOld.vue b/app/src/components/CardsLayerOld.vue
new file mode 100644
index 0000000000000000000000000000000000000000..df9bd254de869c92ea3822146a9ccf0cbc134de4
--- /dev/null
+++ b/app/src/components/CardsLayerOld.vue
@@ -0,0 +1,235 @@
+<template>
+  <div class="grid">
+    <div v-for="(nodes, index) in $options.myArray" v-bind:key="index">
+      <form class="nodes">
+        <template v-if="nodes.read_mode == false">
+          <textarea
+            @focus="editTrue(true)"
+            @blur="editTrue(false)"
+            autofocus
+            v-model="nodes.node_text"
+            @input="editNode"
+            :id="nodes.node_id"
+            ref="nodetext"
+            placeholder="Type your thoughts and ideas here! (auto saved every keystroke)"
+          ></textarea>
+        </template>
+        <template v-else>
+          <p
+            :id="nodes.node_id"
+            :inner-html.prop="nodes.node_text | marked"
+          ></p>
+        </template>
+        <div class="btn-row">
+          <SvgButton
+            buttonClass="nodes"
+            @click.prevent="deleteFlag(nodes.node_id), updateNodes()"
+          />
+          <SvgButton2
+            buttonClass="nodes"
+            @click.prevent="
+              readFlag(nodes.node_id, nodes.read_mode), updateNodes()
+            "
+          />
+        </div>
+
+        <div class="allemoji">
+          <div
+            class="eachemoji"
+            v-for="(emojis, index) in configEmoji"
+            :key="index"
+          >
+            <template v-if="emojis.node_id == nodes.node_id">{{
+              emojis.emoji_text
+            }}</template>
+          </div>
+        </div>
+      </form>
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import marked from 'marked'
+
+import SvgButton from '@/components/SvgButton'
+import SvgButton2 from '@/components/SvgButton2'
+var readmode
+
+export default {
+  name: 'CardsLayer',
+
+  props: {
+    added: Boolean,
+  },
+  data: function () {
+    return {
+      localreadmode: false,
+      myArray: null,
+      update: false,
+    }
+  },
+
+  filters: {
+    marked: marked,
+  },
+  computed: {
+    ...mapState({
+      myNodes: (state) => state.myNodes,
+      configPositions: (state) => state.configPositions,
+      configEmoji: (state) => state.configEmoji,
+    }),
+
+    nodes_filtered: function () {
+      return this.myNodes.filter((nodes) => {
+        return nodes.deleted == false
+      })
+    },
+  },
+
+  // this is to stop sync chasing bug
+
+  mounted() {
+    //access the custom option using $options
+    const unwatch = this.$watch('nodes_filtered', (value) => {
+      this.$options.myArray = this.nodes_filtered
+
+      this.$forceUpdate()
+      // ignore falsy values
+      if (!value) return
+
+      // stop watching when nodes_filtered[] is not empty
+      if (value && value.length) unwatch()
+
+      // process value here
+    })
+  },
+
+  watch: {
+    added: {
+      deep: true,
+
+      handler() {
+        setTimeout(this.loadData, 200)
+      },
+    },
+    update: {
+      deep: true,
+
+      handler() {
+        setTimeout(this.loadData, 200)
+      },
+    },
+  },
+
+  methods: {
+    updateNodes() {
+      this.update = !this.update
+    },
+    loadData() {
+      this.$options.myArray = this.nodes_filtered
+      this.$forceUpdate()
+    },
+    editNode(e) {
+      var nodeid = e.target.id
+      var nodetext = e.target.value
+      this.$store.dispatch('editNode', { nodeid, nodetext })
+    },
+
+    editTrue(e) {
+      this.$emit('edit-true', e)
+    },
+
+    deleteFlag(e) {
+      if (confirm('Confirm discard?')) {
+        this.$store.dispatch('deleteFlag', { e })
+      } else {
+        // nothing happens
+      }
+    },
+    readFlag(e, f) {
+      readmode = f
+      readmode = !readmode
+      this.$store.dispatch('readFlag', { e, readmode })
+
+      if (readmode == true) {
+        this.mode = 'Read'
+      } else {
+        this.mode = 'Edit'
+      }
+    },
+  },
+  components: {
+    SvgButton,
+    SvgButton2,
+  },
+}
+</script>
+
+<style lang="css" scoped>
+.grid {
+  display: flex;
+  flex-wrap: wrap;
+}
+.nodes {
+  min-width: 343px;
+  max-width: 343px;
+  border: 2px dashed black;
+  background-color: rgb(155, 194, 216);
+  margin-top: 1em;
+  margin-left: 0.5em;
+  margin-right: 0.5em;
+}
+
+.readmode {
+  margin-top: 1em;
+  margin-left: 1em;
+  padding-right: 1em;
+}
+
+textarea {
+  width: 100%;
+  height: 175px;
+  resize: none;
+  font-size: 18px;
+  box-sizing: border-box;
+  font-family: 'Inter var', Helvetica, sans-serif;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+  border: none;
+  outline: none;
+  background-color: rgb(187, 227, 255);
+  scrollbar-color: yellow rgb(187, 227, 255);
+}
+.btn-row {
+  position: relative;
+  margin-bottom: 5px;
+  display: flex;
+  justify-content: center;
+  flex-wrap: wrap;
+  padding: 0 15px;
+  border-radius: 4px;
+}
+
+.allemoji {
+  font-size: 2em;
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(0, auto));
+
+  /* float: left; */
+}
+
+.eachemoji p {
+  margin: 0em;
+}
+
+@media only screen and (max-width: 600px) {
+  .readmode >>> a {
+    font-size: 2em;
+    word-break: break-all;
+    padding-right: 0.5em;
+  }
+}
+</style>
diff --git a/app/src/components/ConnectionsLayer.vue b/app/src/components/ConnectionsLayer.vue
index 2addb63c675feb4d4a8d584b56b107ed31ca3086..f801d947ecdd1250d454856524021e63f8fa9d47 100644
--- a/app/src/components/ConnectionsLayer.vue
+++ b/app/src/components/ConnectionsLayer.vue
@@ -1,12 +1,84 @@
 <template>
-  <div class="connections">
-    <canvas ref="pixi" id="pixi"></canvas>
+  <div>
+    <!-- view box same width as canvas -->
+    <!-- falls off edge -->
+    <svg id="connections" viewBox="0 0 2000 2000">
+      <g v-for="(value, index) in positions_filtered" v-bind:key="index">
+        <!-- still empty divs -->
+        <g v-for="(nodes, index) in nodes_filtered" v-bind:key="index">
+          <template v-if="toolmode == 'connect'">
+            <circle
+              v-if="nodes.node_id == value.node_id"
+              :cx="value.x_pos + value.width"
+              :cy="value.y_pos + value.height / 4"
+              r="15"
+              width="30"
+              height="30"
+              @mousedown.prevent="
+                buttonPress(nodes.node_id, value.x_pos, value.y_pos)
+              "
+              @mouseup.prevent="
+                buttonUp(nodes.node_id, value.x_pos, value.y_pos)
+              "
+            />
+          </template>
+          <g v-for="(lines, index) in configConnections" v-bind:key="index">
+            <line
+              v-if="lines.start_id == value.node_id"
+              :x1="lines.x_pos_start + value.width"
+              :y1="lines.y_pos_start + value.height / 4"
+              :x2="lines.x_pos_end"
+              :y2="lines.y_pos_end + value.height / 4"
+              style="stroke: rgb(255, 0, 0); stroke-width: 5"
+            />
+          </g>
+        </g>
+      </g>
+
+      <g
+        v-for="(others, index) in otherpositions_filtered"
+        v-bind:key="'o' + index"
+      >
+        <g v-for="(othernodes, index) in otherNodes" v-bind:key="index">
+          <template v-if="toolmode == 'connect'">
+            <circle
+              v-if="othernodes.node_id == others.node_id"
+              :cx="others.x_pos + others.width"
+              :cy="others.y_pos + others.height / 4"
+              r="15"
+              width="30"
+              height="30"
+              @mousedown.prevent="
+                buttonPress(othernodes.node_id, others.x_pos, others.y_pos)
+              "
+              @mouseup.prevent="
+                buttonUp(othernodes.node_id, others.x_pos, others.y_pos)
+              "
+            />
+          </template>
+
+          <g
+            v-for="(otherlines, index) in configConnections"
+            v-bind:key="index"
+          >
+            <line
+              v-if="otherlines.start_id == others.node_id"
+              :x1="otherlines.x_pos_start + others.width"
+              :y1="otherlines.y_pos_start + others.height / 4"
+              :x2="otherlines.x_pos_end"
+              :y2="otherlines.y_pos_end + others.height / 4"
+              style="stroke: rgb(255, 0, 0); stroke-width: 5"
+            />
+          </g>
+        </g>
+      </g>
+    </svg>
   </div>
 </template>
 
 <script>
 import { mapState } from 'vuex'
-import * as PIXI from 'pixi.js'
+
 //var initialMoveTo
 //var id
 var fromnode
@@ -15,296 +87,151 @@ var xposstart
 var yposstart
 var xposend
 var yposend
-var endState = false
+var connectmode = false
+let newLine
+
+let drawing = false
 
 export default {
   name: 'ConnectionsLayer',
 
   data() {
     return {
-      //  localtoolstate: this.toolmode,
+      id: Number,
+      x: Number,
+      y: Number,
     }
   },
-  computed: mapState({
-    configConnections: (state) => state.configConnections,
-    configPositions: (state) => state.configPositions,
-    myNodes: (state) => state.myNodes,
-    otherNodes: (state) => state.otherNodes,
-    toolmode: (state) => state.ui.mode,
-    // connectionstate: (state) => state.connectionstate,
-  }),
+  computed: {
+    ...mapState({
+      configConnections: (state) => state.configConnections,
+      configPositions: (state) => state.configPositions,
+      myNodes: (state) => state.myNodes,
+      otherNodes: (state) => state.otherNodes,
+      toolmode: (state) => state.ui.mode,
+      // connectionstate: (state) => state.connectionstate,
+    }),
+
+    nodes_filtered: function () {
+      return this.myNodes.filter((nodes) => {
+        return nodes.deleted == false
+      })
+    },
 
-  watch: {
-    configConnections: {
-      deep: true,
+    positions_filtered: function () {
+      return this.configPositions.filter((positions) => {
+        return this.myNodes.some((node) => {
+          return positions.node_id == node.node_id
+        })
+      })
+    },
 
-      handler() {
-        this.connectionsDraw()
-      },
+    otherpositions_filtered: function () {
+      return this.configPositions.filter((otherpositions) => {
+        return this.otherNodes.some((node) => {
+          return otherpositions.node_id == node.node_id
+        })
+      })
     },
+  },
+
+  watch: {
     toolmode: {
       handler() {
         this.toolState()
       },
     },
   },
-
   methods: {
     toolState() {
       if (this.toolmode == 'connect') {
-        this.buttonsDraw()
+        connectmode = true
       } else {
-        this.connectionsDraw()
+        connectmode = false
       }
     },
+    // this should only fire if toolmode = connect
+    buttonPress(id, x, y) {
+      if (connectmode == true) {
+        drawing = true
+        this.id = id
+        this.x = x
+        this.y = y
+
+        newLine = document.createElementNS('http://www.w3.org/2000/svg', 'line')
+
+        const pt = document.getElementById('connections').createSVGPoint()
+        pt.x = event.clientX
+        pt.y = event.clientY
+        const svgP = pt.matrixTransform(
+          document.getElementById('connections').getScreenCTM().inverse()
+        )
 
-    makeConnection(id, xpos, ypos) {
-      if (endState == false) {
-        fromnode = id
-        xposstart = xpos
-        yposstart = ypos
-
-        //count = 1
-        // this.$store.dispatch('connectionState', true)
-      } else if (endState == true) {
-        tonode = id
-        xposend = xpos
-        yposend = ypos
+        newLine.setAttribute('stroke', 'red')
+        newLine.setAttribute('stroke-width', '5')
+        newLine.setAttribute('x1', svgP.x)
+        newLine.setAttribute('y1', svgP.y)
+        newLine.setAttribute('x2', svgP.x)
+        newLine.setAttribute('y2', svgP.y)
 
-        // count = 0
-        //  this.$store.dispatch('connectionState', false)
-        // console.log(fromnode, tonode, xposstart, yposstart, xposend, yposend)
-        this.$store.dispatch('makeConnect', {
-          fromnode,
-          tonode,
-          xposstart,
-          yposstart,
-          xposend,
-          yposend,
-        })
-        endState = false
+        document.getElementById('connections').appendChild(newLine)
       }
     },
-    buttonsDraw() {
-      var i
-      var j
-      //var n = 1
-      var ref = this
-      var buttonMap = {}
-      var buttonMapOther = {}
-
-      this.canvas = this.$refs.pixi
-      const stage = this.PIXIApp.stage
-      //const allButtons = new PIXI.Container()
-
-      for (i = 0; i < Object.keys(this.myNodes).length; i++) {
-        buttonMap[i] = new PIXI.Graphics()
-        // console.log(buttonMap[i])
-        for (j = 0; j < Object.keys(this.configPositions).length; j++) {
-          if (
-            this.configPositions[j].node_id == this.myNodes[i].node_id &&
-            this.myNodes[i].deleted == false
-          ) {
-            buttonMap[i].name = this.myNodes[i].node_id
-            // console.log(button_one.name)
-            buttonMap[i].lineStyle(1)
-            buttonMap[i].beginFill(0xcab6ff, 1)
-            // x, y, radius
-
-            buttonMap[i].drawCircle(
-              this.configPositions[j].x_pos + this.configPositions[j].width,
-              this.configPositions[j].y_pos +
-                this.configPositions[j].height / 2,
-              15
-            )
-            buttonMap[i].endFill()
-            // names it the last one only?
-          }
-          //  allButtons.addChild(buttonMap[i])
-          //  stage.addChild(allButtons)
-          stage.addChild(buttonMap[i])
-          // Opt-in to interactivity
-          buttonMap[i].interactive = true
-          // Shows hand cursor
-          buttonMap[i].buttonMode = true
-        }
-
-        buttonMap[i]
-          .on('pointerdown', onDragStart)
-          .on('pointerdown', start)
-          .on('pointerup', onDragEnd)
-          .on('pointerup', finish)
-          .on('pointerupoutside', onDragEndOutside)
-          .on('pointermove', onDragMove)
-      }
-
-      for (i = 0; i < Object.keys(this.otherNodes).length; i++) {
-        buttonMapOther[i] = new PIXI.Graphics()
-        // console.log(buttonMap[i])
-        for (j = 0; j < Object.keys(this.configPositions).length; j++) {
-          if (this.configPositions[j].node_id == this.otherNodes[i].node_id) {
-            buttonMapOther[i].name = this.otherNodes[i].node_id
-            // console.log(button_one.name)
-            buttonMapOther[i].lineStyle(1)
-            buttonMapOther[i].beginFill(0xcab6ff, 1)
-            // x, y, radius
-
-            buttonMapOther[i].drawCircle(
-              this.configPositions[j].x_pos + this.configPositions[j].width,
-              this.configPositions[j].y_pos +
-                this.configPositions[j].height / 2,
-              15
-            )
-            buttonMapOther[i].endFill()
-            // names it the last one only?
-          }
-          stage.addChild(buttonMapOther[i])
-
-          // Opt-in to interactivity
-          buttonMapOther[i].interactive = true
-          // Shows hand cursor
-          buttonMapOther[i].buttonMode = true
-        }
-
-        buttonMapOther[i]
-          .on('pointerdown', onDragStart)
-          .on('pointerdown', start)
-          .on('pointerup', finish)
-          .on('pointerup', onDragEnd)
-          .on('pointerupoutside', onDragEndOutside)
-          .on('pointermove', onDragMove)
-      }
-
-      let line = new PIXI.Graphics()
-      var initialMoveTo
-      let lines = []
-
-      function start(event) {
-        // console.log(this.getChildByName)
-        this.id = this.name
-        ref.makeConnection(this.id, event.data.global.x, event.data.global.y)
-      }
-
-      function finish(event) {
-        this.id = this.name
-        if (this.id != fromnode) {
-          endState = true
-          ref.makeConnection(this.id, event.data.global.x, event.data.global.y)
-        } else {
-          endState = false
-        }
-      }
-
-      function onDragStart(event) {
-        this.dragging = true
-        // returns on the last one in the loop
-        // console.log(button_one.name)
-        let mouseX = event.data.global.x
-        let mouseY = event.data.global.y
 
-        initialMoveTo = [mouseX, mouseY]
-
-        line.lineStyle(8, 0xcab6ff)
-        line.moveTo(mouseX, mouseY)
-
-        lines = [line].concat(lines)
-
-        stage.addChild(line)
-      }
-
-      function onDragEnd() {
-        //endState = true
-        this.dragging = false
-        stage.removeChild(line)
-      }
-
-      function onDragEndOutside() {
-        stage.removeChild(line)
-        // console.log('outside')
-        // console.log(this.name)
-        // console.log(fromnode)
-        // if (this.name != fromnode) {
-        //   console.log('diff')
-        //   endState = true
-        //   this.dragging = false
-        //   stage.removeChild(line)
-        //   this.finish()
-        // }
-        // } else {
-        //   endState = false
-        //   this.dragging = false
-        //   stage.removeChild(line)
-        // }
-      }
-
-      function onDragMove(event) {
-        if (this.dragging) {
-          let mouseX = event.data.global.x
-          let mouseY = event.data.global.y
-          lines[0].clear()
-          lines[0].lineStyle(8, 0xcab6ff)
-          lines[0].moveTo(initialMoveTo[0], initialMoveTo[1])
-          lines[0].lineTo(mouseX, mouseY)
-        }
-      }
+    buttonUp(id, x, y) {
+      drawing = false
+      document.getElementById('connections').removeChild(newLine)
+      fromnode = this.id
+      xposstart = this.x
+      yposstart = this.y
+      tonode = id
+      xposend = x
+      yposend = y
+
+      this.$store.dispatch('makeConnect', {
+        fromnode,
+        tonode,
+        xposstart,
+        yposstart,
+        xposend,
+        yposend,
+      })
     },
+  },
+}
 
-    connectionsDraw() {
-      var i
-      //  var j
-      this.canvas = this.$refs.pixi
-      const stage = this.PIXIApp.stage
-      let graphics = new PIXI.Graphics()
-      //let line = new PIXI.Graphics()
-
-      graphics.lineStyle(8, 0xcab6ff)
-      // move the lines to start and end pos based on if to_node == node_id
-      // or from_id == node_id
-      //start_id == node_id
-      // this will put them in the same place as buttons
-
-      //     for (i = 0; i < Object.keys(this.otherNodes).length; i++) {
-
-      // for (j = 0; j < Object.keys(this.configPositions).length; j++) {
-      //   if (this.configConnections[j].start_id == this.otherNodes[i].node_id) {
-
-      // for (j = 0; j < Object.keys(this.otherNodes).length; j++) {
-      for (i = 0; i < Object.keys(this.configConnections).length; i++) {
-        //start
-
-        graphics.moveTo(
-          this.configConnections[i].x_pos_start,
-          this.configConnections[i].y_pos_start
-        )
+function onMouseMove() {
+  //Add code here
+  if (drawing) {
+    // const pt = document.getElementById('connections').createSVGPoint()
+    // pt.x = event.clientX
+    // pt.y = event.clientY
+    // const svgP = pt.matrixTransform(
+    //   document.getElementById('connections').getScreenCTM().inverse()
+    // )
+
+    newLine.setAttribute('x2', event.clientX)
+    newLine.setAttribute('y2', event.clientY)
+  }
+}
+function onMouseUp() {
+  if (drawing) {
+    document.getElementById('connections').removeChild(newLine)
+  }
+}
 
-        //end
-        graphics.lineTo(
-          this.configConnections[i].x_pos_end,
-          this.configConnections[i].y_pos_end
-        )
-      }
-      //  }
-      for (var l = stage.children.length - 1; l >= 0; l--) {
-        stage.removeChild(stage.children[l])
-      }
+function setup() {
+  document.addEventListener('mousemove', onMouseMove)
+  document.addEventListener('mouseup', onMouseUp)
+}
 
-      stage.addChild(graphics)
-      if (this.toolmode == 'connect') {
-        this.buttonsDraw()
-      }
-    },
-  },
-  mounted() {
-    const canvas = this.$refs.pixi
-    this.PIXIApp = new PIXI.Application({
-      width: 3000,
-      height: 3000,
-      antialias: true,
-      transparent: true,
-      view: canvas,
-    })
+window.onload = () => setup()
+</script>
 
-    this.connectionsDraw()
-  },
+<style scoped>
+circle {
+  fill: rgb(187, 227, 255);
+  stroke: black;
+  stroke-width: 2;
 }
-</script>
+</style>
diff --git a/app/src/components/ListLayer.vue b/app/src/components/ListLayer.vue
index fe48288b8423c4d65ae45150dafc2fac89b64fcd..a7623d0232c39381df125a9f9c00e8350e955881 100644
--- a/app/src/components/ListLayer.vue
+++ b/app/src/components/ListLayer.vue
@@ -1,7 +1,12 @@
 <template>
   <div>
-    <div v-for="(nodes, index) in nodes_filtered" v-bind:key="index">
-      <form class="nodes">
+    <div v-for="(nodes, index) in $options.myArray" v-bind:key="index">
+      <form
+        class="nodes"
+        :style="{
+          backgroundColor: nodes.color,
+        }"
+      >
         <template v-if="nodes.read_mode == false">
           <textarea
             @focus="editTrue(true)"
@@ -10,6 +15,8 @@
             v-model="nodes.node_text"
             @input="editNode"
             :id="nodes.node_id"
+            v-focus
+            ref="textentry"
             placeholder="Type your thoughts and ideas here! (auto saved every keystroke)"
           ></textarea>
           <p class="info">*markdown supported &amp; autosaves</p>
@@ -24,12 +31,25 @@
         <div class="btn-row">
           <SvgButton
             buttonClass="nodes"
-            @click.prevent="deleteFlag(nodes.node_id)"
+            @click.prevent="deleteFlag(nodes.node_id), updateNodes()"
           />
           <SvgButton2
             buttonClass="nodes"
-            @click.prevent="readFlag(nodes.node_id, nodes.read_mode)"
+            @click.prevent="
+              readFlag(nodes.node_id, nodes.read_mode), updateNodes()
+            "
           />
+          <v-swatches
+            v-model="color"
+            @input="chooseColor(color, nodes.node_id)"
+            :swatches="swatches"
+            :shapes="shapes"
+            show-border
+            show-fallback
+            fallback-input-type="color"
+          >
+            <SvgButton3 buttonClass="nodes" @click.prevent slot="trigger" />
+          </v-swatches>
         </div>
 
         <div class="allemoji">
@@ -53,14 +73,32 @@ import { mapState } from 'vuex'
 import marked from 'marked'
 import SvgButton from '@/components/SvgButton'
 import SvgButton2 from '@/components/SvgButton2'
+import SvgButton3 from '@/components/SvgButton3'
+import VSwatches from 'vue-swatches'
+import 'vue-swatches/dist/vue-swatches.css'
 
 var readmode
 export default {
   name: 'ListLayer',
 
+  props: {
+    added: Boolean,
+  },
+
   data: function () {
     return {
+      color: '#9bc2d8',
+      shapes: 'circles',
+      // swatches: [{ color: '#F493A7', showBorder: true }],
+      swatches: [
+        ['#EB5757', '#F2994A', '#F2C94C'],
+        ['#219653', '#27AE60', '#6FCF97'],
+        ['#2F80ED', '#2D9CDB', '#56CCF2'],
+        ['#9B51E0', '#BB6BD9', '#E9B7FC'],
+      ],
       localreadmode: false,
+      myArray: null,
+      update: false,
     }
   },
 
@@ -73,6 +111,7 @@ export default {
       myNodes: (state) => state.myNodes,
       configPositions: (state) => state.configPositions,
       configEmoji: (state) => state.configEmoji,
+      // toolmode: (state) => state.ui.mode,
     }),
 
     nodes_filtered: function () {
@@ -82,14 +121,52 @@ export default {
     },
   },
 
-  // this is to stop sync chasing bug
-  myArray: null,
   mounted() {
-    //access the custom option using $options
-    this.$options.myArray = this.nodes_filtered
+    setTimeout(this.loadData, 500)
+
+    const unwatch = this.$watch('nodes_filtered', (value) => {
+      this.$options.myArray = this.nodes_filtered
+      this.$forceUpdate()
+      // this.focusInput()
+      // ignore falsy values
+      if (!value) return
+
+      // stop watching when nodes_filtered[] is not empty
+      if (value && value.length) unwatch()
+
+      // process value here
+    })
+  },
+
+  watch: {
+    added: {
+      deep: true,
+
+      handler() {
+        setTimeout(this.loadData, 200)
+      },
+    },
+    update: {
+      deep: true,
+
+      handler() {
+        setTimeout(this.loadData, 200)
+      },
+    },
   },
 
   methods: {
+    chooseColor(color, nodeid) {
+      this.$store.dispatch('colorNode', { nodeid, color })
+      this.$options.myArray = this.nodes_filtered
+    },
+    updateNodes() {
+      this.update = !this.update
+    },
+    loadData() {
+      this.$options.myArray = this.nodes_filtered
+      this.$forceUpdate()
+    },
     editNode(e) {
       var nodeid = e.target.id
       var nodetext = e.target.value
@@ -122,6 +199,8 @@ export default {
   components: {
     SvgButton,
     SvgButton2,
+    SvgButton3,
+    VSwatches,
   },
 }
 </script>
diff --git a/app/src/components/ModesCard.vue b/app/src/components/ModesCard.vue
index 3404884b80e7f6f3028d5a0af3b18e7eee91161e..837ae03fbb489cb5ebf843c2127e637331a0dbeb 100644
--- a/app/src/components/ModesCard.vue
+++ b/app/src/components/ModesCard.vue
@@ -1,6 +1,6 @@
 <template>
   <div>
-    <div v-show="tipsplease" class="nodes welcome">
+    <div v-show="showtipsstate" class="nodes welcome">
       <img src="https://alpha.nodenogg.in/files/collect.png" />
 
       <p>
@@ -101,7 +101,7 @@ import SvgButton from '@/components/SvgButton'
 export default {
   data: function () {
     return {
-      tipsplease: true,
+      // showtipsstate: null,
     }
   },
 
@@ -113,13 +113,13 @@ export default {
   },
 
   computed: mapState({
-    hidetipsstate: (state) => state.hidetipsstate,
+    showtipsstate: (state) => state.showtipsstate,
   }),
 
   methods: {
     hideTips() {
-      this.tipsplease = false
-      //  this.hidetipsstate = false
+      var e = false
+      this.$store.dispatch('showTipsstate', e)
     },
   },
   components: {
diff --git a/app/src/components/ModesCardorg.vue b/app/src/components/ModesCardorg.vue
index 11fbaae021693d17fd5c5516632a045fdf9e5078..ad17bd4afeba8b89234aa720757edaea370a4637 100644
--- a/app/src/components/ModesCardorg.vue
+++ b/app/src/components/ModesCardorg.vue
@@ -1,5 +1,5 @@
 <template>
-  <div v-show="tipsplease">
+  <div v-show="showtipsstate">
     <draggable
       class="innernode"
       :w="450"
@@ -169,7 +169,7 @@
         <SvgButton @click="hideTips()" />
       </div>
     </draggable>
-    <div v-show="!tipsplease"></div>
+    <div v-show="!showtipsstate"></div>
   </div>
 </template>
 
@@ -182,7 +182,7 @@ import draggable from '@/experimental/Draggable'
 export default {
   data: function () {
     return {
-      tipsplease: true,
+      // showtipsstate: true,
     }
   },
 
@@ -194,14 +194,14 @@ export default {
   },
 
   computed: mapState({
-    hidetipsstate: (state) => state.hidetipsstate,
+    showtipsstate: (state) => state.showtipsstate,
     scale: (state) => state.ui.scale,
   }),
 
   methods: {
     hideTips() {
-      this.tipsplease = false
-      //  this.hidetipsstate = false
+      var e = false
+      this.$store.dispatch('showTipsstate', e)
     },
   },
   components: {
diff --git a/app/src/components/Navigation.vue b/app/src/components/Navigation.vue
index e14f17d7b5d25f2b42fe0143f50867f313aec6ed..971eada1d98b985af98d3e2171d88290dbabf915 100644
--- a/app/src/components/Navigation.vue
+++ b/app/src/components/Navigation.vue
@@ -1,8 +1,10 @@
 <template>
   <nav class="navigation">
-    <router-link v-for="route in routes" :key="route.name" :to="route.path">{{
-      route.name
-    }}</router-link>
+    <router-link v-for="route in routes" :key="route.name" :to="route.path">
+      <div v-if="route.path != '/nitpicky'">
+        {{ route.name }}
+      </div></router-link
+    >
   </nav>
 </template>
 
diff --git a/app/src/components/NodesLayer.vue b/app/src/components/NodesLayer.vue
index 308d863465b1af38e296de7b2b0e073e07061fad..377cdb3ab4b75030895f31006cfce00e553adba6 100644
--- a/app/src/components/NodesLayer.vue
+++ b/app/src/components/NodesLayer.vue
@@ -12,7 +12,7 @@
             :y="value.y_pos"
             :z="value.z_index"
             :scale="scale"
-            @activated="onActivated(nodes.node_id)"
+            @activated="onActivated(nodes.node_id, value.z_index)"
             :draggable="false"
             :resizable="false"
             @dragging="onDrag"
@@ -20,12 +20,11 @@
             @dragstop="onDragstop"
             @resizestop="onResizestop"
             :drag-cancel="'.drag-cancel'"
-            style="
-              border: 2px dashed black;
-              background-color: rgb(155, 194, 216);
-            "
-            :min-width="200"
-            :min-height="220"
+            :style="{
+              border: border,
+              backgroundColor: nodes.color,
+            }"
+            ref="node"
           >
             <form class="nodes">
               <template v-if="nodes.read_mode == false">
@@ -34,6 +33,7 @@
                   @blur="editTrue(false)"
                   autofocus
                   v-model="nodes.node_text"
+                  v-focus
                   @input="editNode"
                   :id="nodes.node_id"
                   placeholder="Type your thoughts and ideas here! (auto saved every keystroke)"
@@ -90,25 +90,26 @@
             :y="value.y_pos"
             :z="value.z_index"
             :scale="scale"
-            @activated="onActivated(nodes.node_id)"
+            @activated="onActivated(nodes.node_id, value.z_index)"
             @dragging="onDrag"
             @resizing="onResize"
             @dragstop="onDragstop"
             @resizestop="onResizestop"
             :drag-cancel="'.drag-cancel'"
-            style="
-              border: 2px dashed black;
-              background-color: rgb(155, 194, 216);
-            "
-            :min-width="200"
-            :min-height="220"
+            :style="{
+              border: border,
+              backgroundColor: nodes.color,
+            }"
+            ref="node"
           >
             <form class="nodes">
               <template v-if="nodes.read_mode == false">
                 <textarea
+                  class="drag-cancel"
                   @focus="editTrue(true)"
                   @blur="editTrue(false)"
                   autofocus
+                  v-focus
                   v-model="nodes.node_text"
                   @input="editNode"
                   :id="nodes.node_id"
@@ -132,6 +133,21 @@
                     buttonClass="nodes"
                     @click.prevent="readFlag(nodes.node_id, nodes.read_mode)"
                   />
+                  <v-swatches
+                    v-model="color"
+                    @input="chooseColor(color, nodes.node_id)"
+                    :swatches="swatches"
+                    :shapes="shapes"
+                    show-border
+                    show-fallback
+                    fallback-input-type="color"
+                  >
+                    <SvgButton3
+                      buttonClass="nodes"
+                      @click.prevent
+                      slot="trigger"
+                    />
+                  </v-swatches>
                 </div>
               </template>
 
@@ -159,7 +175,10 @@ import { mapState } from 'vuex'
 import marked from 'marked'
 import SvgButton from '@/components/SvgButton'
 import SvgButton2 from '@/components/SvgButton2'
+import SvgButton3 from '@/components/SvgButton3'
 import draggable from '@/experimental/Draggable'
+import VSwatches from 'vue-swatches'
+import 'vue-swatches/dist/vue-swatches.css'
 
 var readmode
 
@@ -168,31 +187,46 @@ export default {
 
   data() {
     return {
+      border: '2px dashed black',
+      color: '#9bc2d8',
+      shapes: 'circles',
+
+      // swatches: [{ color: '#F493A7', showBorder: true }],
+      swatches: [
+        ['#EB5757', '#F2994A', '#F2C94C'],
+        ['#219653', '#27AE60', '#6FCF97'],
+        ['#2F80ED', '#2D9CDB', '#56CCF2'],
+        ['#9B51E0', '#BB6BD9', '#E9B7FC'],
+      ],
+
       pickupz: 1,
       localreadmode: false,
       mode: '',
       nodeid: String,
-      // firstload: true,
+      myArray: null,
+      positionsArray: null,
     }
   },
 
+  props: {
+    added: Boolean,
+  },
+
   filters: {
     marked: marked,
   },
 
   // FIXME: how do we know how to focus on the newest node ?
   // FIXME: Tab between them would also be good
-  // var delay = 100
-  // var input
-  // mounted() {
-  //   setTimeout(this.setFocus, delay)
-  //   input = this.$refs.nodetext
-  //   // console.log(input)
-  // },
-  // method
-  // setFocus() {
-  //   this.$refs.nodetext.focus()
-  // },
+  watch: {
+    added: {
+      deep: true,
+
+      handler() {
+        setTimeout(this.loadData, 200)
+      },
+    },
+  },
 
   computed: {
     ...mapState({
@@ -206,10 +240,13 @@ export default {
 
     nodes_filtered: function () {
       return this.myNodes.filter((nodes) => {
+        // backwards compatablity fix
+        if (nodes.color == undefined || '') {
+          nodes.color = '#A4C2D6'
+        }
         return nodes.deleted == false
       })
     },
-    // this is not working correctly as dragging around moves wrong things
     positions_filtered: function () {
       return this.configPositions.filter((positions) => {
         return this.myNodes.some((node) => {
@@ -219,32 +256,85 @@ export default {
     },
   },
   // this is to stop sync chasing bug
-  myArray: null,
-  positionsArray: null,
-  // NOTE: ok as created here but NOT if this is the first view to load
-  created() {
-    //access the custom option using $options
-    this.$options.myArray = this.nodes_filtered
-    this.$options.positionsArray = this.positions_filtered
+
+  mounted() {
+    setTimeout(this.loadData, 500)
+
+    const unwatch = this.$watch('nodes_filtered', (value) => {
+      this.$options.myArray = this.nodes_filtered
+      // this.$options.positionsArray = this.positions_filtered
+      this.$forceUpdate()
+      // ignore falsy values
+      if (!value) return
+
+      // stop watching when nodes_filtered[] is not empty
+      if (value && value.length) unwatch()
+
+      // process value here
+    })
+
+    const unwatchtwo = this.$watch('positions_filtered', (value) => {
+      // this.$options.myArray = this.nodes_filtered
+      this.$options.positionsArray = this.positions_filtered
+      this.$forceUpdate()
+      // ignore falsy values
+      if (!value) return
+
+      // stop watching when nodes_filtered[] is not empty
+      if (value && value.length) unwatchtwo()
+
+      // process value here
+    })
   },
 
   updated() {
     this.$options.positionsArray = this.positions_filtered
 
     if (this.toolmode == 'addNode') {
-      this.$options.myArray = this.nodes_filtered
+      setTimeout(this.loadData, 300)
+      // this.$options.myArray = this.nodes_filtered
       this.$store.commit('ui/setMode', 'select')
     }
   },
 
   methods: {
-    onActivated(e) {
-      this.nodeid = e
+    chooseColor(color, nodeid) {
+      this.$store.dispatch('colorNode', { nodeid, color })
+      this.$options.myArray = this.nodes_filtered
+    },
+
+    loadData() {
+      this.$options.myArray = this.nodes_filtered
+      this.$options.positionsArray = this.positions_filtered
+      this.$forceUpdate()
+    },
+
+    onActivated(id, zindex) {
+      this.zindex = zindex
+      this.nodeid = id
       var i
+      var zindexes = []
+
       for (i = 0; i < Object.keys(this.configPositions).length; i++) {
+        zindexes.push(this.configPositions[i].z_index)
         if (this.configPositions[i].node_id == this.nodeid) {
           this.width = this.configPositions[i].width
           this.height = this.configPositions[i].height
+          this.zindex = this.configPositions[i].z_index
+        }
+        // console.log(zindexes)
+      }
+      var topZ = Math.max(...zindexes)
+
+      for (i = 0; i < Object.keys(this.configPositions).length; i++) {
+        if (topZ > 2147483640) {
+          this.configPositions[i].z_index = 0
+        }
+
+        if (this.configPositions[i].node_id == this.nodeid) {
+          this.width = this.configPositions[i].width
+          this.height = this.configPositions[i].height
+          this.configPositions[i].z_index = topZ + 1
         }
       }
     },
@@ -254,19 +344,27 @@ export default {
       this.width = width
       this.height = height
     },
-    onResizestop(x, y, width, height, zindex) {
+    onResizestop(x, y, width, height) {
+      // var nodecontentHeight = document.getElementById(this.nodeid).clientHeight
+
       var localnodeid = this.nodeid
-      zindex = this.pickupz
+      var zindex
       var i
+
       for (i = 0; i < Object.keys(this.configPositions).length; i++) {
         if (this.configPositions[i].node_id == this.nodeid) {
           this.width = this.configPositions[i].width
           this.height = this.configPositions[i].height
-          this.pickupz = this.configPositions[i].z_index
+          zindex = this.configPositions[i].z_index
         }
       }
       this.width = width
       this.height = height
+
+      // if (nodecontentHeight > this.height) {
+      //   height = nodecontentHeight + 150
+      // }
+
       this.$store.dispatch('movePos', {
         localnodeid,
         x,
@@ -280,18 +378,24 @@ export default {
       this.localx = x
       this.localy = y
     },
-    onDragstop(x, y, width, height, zindex) {
+    onDragstop(x, y, width, height) {
+      var nodecontentHeight = document.getElementById(this.nodeid).clientHeight
+
       var localnodeid = this.nodeid
-      zindex = this.pickupz
+      var zindex
       width = this.width
       height = this.height
       var i
+
+      if (nodecontentHeight > this.height) {
+        this.height = nodecontentHeight + 150
+      }
       // FIXME: What is this for loop doing ??
       for (i = 0; i < Object.keys(this.configPositions).length; i++) {
         if (this.configPositions[i].node_id == this.nodeid) {
           this.localx = this.configPositions[i].x_pos
           this.localy = this.configPositions[i].y_pos
-          this.pickupz = this.configPositions[i].z_index
+          zindex = this.configPositions[i].z_index
         }
       }
       this.$store.dispatch('movePos', {
@@ -320,6 +424,7 @@ export default {
           })
         }
       }
+      this.$options.myArray = this.nodes_filtered
     },
 
     editTrue(e) {
@@ -357,6 +462,8 @@ export default {
     draggable,
     SvgButton,
     SvgButton2,
+    SvgButton3,
+    VSwatches,
   },
 }
 </script>
@@ -369,6 +476,8 @@ export default {
 
 .vdr {
   padding: 0 0.5em;
+  min-width: 260px;
+  min-height: 265px;
 }
 
 .info {
diff --git a/app/src/components/OffLine.vue b/app/src/components/OffLine.vue
deleted file mode 100644
index 2ab43f55dedb832d479e010886c085bf01b7d318..0000000000000000000000000000000000000000
--- a/app/src/components/OffLine.vue
+++ /dev/null
@@ -1,72 +0,0 @@
-// FIXME: Everything below is OLD code
-
-<template>
-  <div class="yourdata" name="anchorName">
-    <div v-for="value in myNodes" v-bind:key="value.node_id">
-      <textarea
-        v-if="nodeid == value.node_id"
-        @focus="editTrue(true)"
-        @blur="editTrue(false)"
-        autofocus
-        @input="editNode"
-        v-model="value.node_text"
-        :id="nodeid"
-        class="drag-cancel"
-        ref="nodetext"
-        placeholder="Idea goes here!"
-      ></textarea>
-    </div>
-
-    <div class="btn-row">
-      <BaseButton buttonClass="danger" @click="deleteFlag()">Delete</BaseButton>
-    </div>
-  </div>
-</template>
-
-<script>
-import { mapState } from 'vuex'
-
-export default {
-  name: 'OffLine',
-  computed: mapState({
-    myNodes: (state) => state.myNodes,
-  }),
-
-  props: {
-    nodeid: String,
-  },
-
-  methods: {
-    addDoc() {
-      this.$store.dispatch('addDoc')
-      this.$emit('edit-mode')
-    },
-    editTrue(e) {
-      this.$emit('edit-true', e)
-      //// console.log(e)
-    },
-
-    editNode(e) {
-      var nodeid = e.target.id
-      var nodetext = e.target.value
-      this.$store.dispatch('editNode', { nodeid, nodetext })
-    },
-
-    deleteFlag(e) {
-      e = this.nodeid
-      this.$store.dispatch('deleteFlag', { e })
-    },
-  },
-}
-</script>
-
-<style lang="css" scoped>
-h3 {
-  margin-top: 1em;
-}
-
-.data p {
-  white-space: pre-wrap;
-  line-height: 1em;
-}
-</style>
diff --git a/app/src/components/OtherCardslayer.vue b/app/src/components/OtherCardslayer.vue
index 711d1bc4904b785231bac1c526cdee79b43f83c7..36b2859c02c4985c700dfcbb86e5e8a2769cc7fc 100644
--- a/app/src/components/OtherCardslayer.vue
+++ b/app/src/components/OtherCardslayer.vue
@@ -1,82 +1,88 @@
 <template>
   <div class="grid">
-    <div v-for="(nodes, index) in othernodes_filtered" v-bind:key="index">
-      <div class="nodes">
-        <p :inner-html.prop="nodes.node_text | marked"></p>
+   
+      <div v-for="(nodes, index) in othernodes_filtered" v-bind:key="index">
+        <div class="nodes">
+          <p :inner-html.prop="nodes.node_text | marked"></p>
 
-        <div class="eeee">
-          <input :value="nodes.node_id" name="id" readonly hidden />
-          <input
-            id="emojifield"
-            class="regular-input"
-            v-model="input"
-            readonly
-          />
+          <div class="eeee">
+            <input :value="nodes.node_id" name="id" readonly hidden />
+            <input
+              id="emojifield"
+              class="regular-input"
+              v-model="input"
+              readonly
+            />
 
-          <emoji-picker @emoji="append" :search="search">
-            <div
-              class="emoji-invoker"
-              slot="emoji-invoker"
-              slot-scope="{ events: { click: clickEvent } }"
-              @click.stop="clickEvent"
-            >
-              <svg
-                height="24"
-                viewBox="0 0 24 24"
-                width="24"
-                xmlns="http://www.w3.org/2000/svg"
-              >
-                <path d="M0 0h24v24H0z" fill="none" />
-                <path
-                  d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"
-                />
-              </svg>
-            </div>
-            <div slot="emoji-picker" slot-scope="{ emojis, insert, display }">
+            <emoji-picker @emoji="append" :search="search">
               <div
-                class="emoji-picker"
-                :style="{ top: display.y + 'px', left: display.x + 'px' }"
+                class="emoji-invoker"
+                slot="emoji-invoker"
+                slot-scope="{ events: { click: clickEvent } }"
+                @click.stop="clickEvent"
               >
-                <div class="emoji-picker__search">
-                  <input type="text" v-model="search" />
-                </div>
-                <div>
-                  <div v-for="(emojiGroup, category) in emojis" :key="category">
-                    <h5>{{ category }}</h5>
-                    <div class="emojis">
-                      <span
-                        v-for="(emoji, emojiName) in emojiGroup"
-                        :key="emojiName"
-                        @click="insert(emoji), sentReact(nodes.node_id)"
-                        :title="emojiName"
-                        >{{ emoji }}</span
-                      >
+                <svg
+                  height="24"
+                  viewBox="0 0 24 24"
+                  width="24"
+                  xmlns="http://www.w3.org/2000/svg"
+                >
+                  <path d="M0 0h24v24H0z" fill="none" />
+                  <path
+                    d="M11.99 2C6.47 2 2 6.48 2 12s4.47 10 9.99 10C17.52 22 22 17.52 22 12S17.52 2 11.99 2zM12 20c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3.5-9c.83 0 1.5-.67 1.5-1.5S16.33 8 15.5 8 14 8.67 14 9.5s.67 1.5 1.5 1.5zm-7 0c.83 0 1.5-.67 1.5-1.5S9.33 8 8.5 8 7 8.67 7 9.5 7.67 11 8.5 11zm3.5 6.5c2.33 0 4.31-1.46 5.11-3.5H6.89c.8 2.04 2.78 3.5 5.11 3.5z"
+                  />
+                </svg>
+              </div>
+              <div slot="emoji-picker" slot-scope="{ emojis, insert, display }">
+                <div
+                  class="emoji-picker"
+                  :style="{ top: display.y + 'px', left: display.x + 'px' }"
+                >
+                  <div class="emoji-picker__search">
+                    <input type="text" v-model="search" />
+                  </div>
+                  <div>
+                    <div
+                      v-for="(emojiGroup, category) in emojis"
+                      :key="category"
+                    >
+                      <h5>{{ category }}</h5>
+                      <div class="emojis">
+                        <span
+                          v-for="(emoji, emojiName) in emojiGroup"
+                          :key="emojiName"
+                          @click="insert(emoji), sentReact(nodes.node_id)"
+                          :title="emojiName"
+                          >{{ emoji }}</span
+                        >
+                      </div>
                     </div>
                   </div>
                 </div>
               </div>
-            </div>
-          </emoji-picker>
+            </emoji-picker>
 
-          <div class="allemoji">
-            <div
-              class="eachemoji"
-              v-for="(emojis, index) in configEmoji"
-              :key="index"
-            >
-              <p v-if="nodes.node_id == emojis.node_id">
-                {{ emojis.emoji_text }}
-              </p>
+            <div class="allemoji">
+              <div
+                class="eachemoji"
+                v-for="(emojis, index) in configEmoji"
+                :key="index"
+              >
+                <p v-if="nodes.node_id == emojis.node_id">
+                  {{ emojis.emoji_text }}
+                </p>
+              </div>
             </div>
           </div>
         </div>
       </div>
-    </div>
+  
   </div>
 </template>
 
 <script>
 import { mapState } from 'vuex'
+
 import EmojiPicker from 'vue-emoji-picker'
 import marked from 'marked'
 
@@ -88,6 +94,7 @@ export default {
 
   components: {
     EmojiPicker,
+
   },
 
   data: function () {
diff --git a/app/src/components/OtherNodeslayer.vue b/app/src/components/OtherNodeslayer.vue
index 4bea445da702a2829518cf5375cd45b30aae21f5..89676ce40887689e527204956ce5ed98a8e208bc 100644
--- a/app/src/components/OtherNodeslayer.vue
+++ b/app/src/components/OtherNodeslayer.vue
@@ -11,17 +11,17 @@
             :y="value.y_pos"
             :z="value.z_index"
             :scale="scale"
-            @activated="onActivated(nodes.node_id)"
+            @activated="onActivated(nodes.node_id, value.z_index)"
             :draggable="false"
             :resizable="false"
             @dragging="onDrag"
             @resizing="onResize"
             @dragstop="onDragstop"
             @resizestop="onResizestop"
-            style="
-              border: 2px solid black;
-              background-color: rgb(205, 234, 255);
-            "
+            :style="{
+              border: border,
+              backgroundColor: nodes.color,
+            }"
             :min-width="200"
             :min-height="220"
           >
@@ -122,15 +122,15 @@
             :y="value.y_pos"
             :z="value.z_index"
             :scale="scale"
-            @activated="onActivated(nodes.node_id)"
+            @activated="onActivated(nodes.node_id, value.z_index)"
             @dragging="onDrag"
             @resizing="onResize"
             @dragstop="onDragstop"
             @resizestop="onResizestop"
-            style="
-              border: 2px solid black;
-              background-color: rgb(205, 234, 255);
-            "
+            :style="{
+              border: border,
+              backgroundColor: nodes.color,
+            }"
             :min-width="200"
             :min-height="220"
           >
@@ -236,10 +236,13 @@ export default {
 
   data() {
     return {
+      border: '2px solid black',
+      color: '#CDEAFF',
       input: '',
       search: '',
       pickupz: 1,
       nodeid: String,
+      positionsArray: null,
     }
   },
 
@@ -259,6 +262,10 @@ export default {
 
     othernodes_filtered: function () {
       return this.otherNodes.filter((nodes) => {
+        // backwards compatablity fix
+        if (nodes.color == undefined || '') {
+          nodes.color = '#A4C2D6'
+        }
         return nodes.deleted == false
       })
     },
@@ -272,11 +279,35 @@ export default {
     },
   },
 
-  positionsArray: null,
-  // NOTE: ok as created here but NOT if this is the first view to load
-  created() {
+  mounted() {
     //access the custom option using $options
-    this.$options.positionsArray = this.positions_filtered
+    setTimeout(this.loadData, 500)
+
+    const unwatch = this.$watch('othernodes_filtered', (value) => {
+      this.$options.myArray = this.othernodes_filtered
+      // this.$options.positionsArray = this.positions_filtered
+      this.$forceUpdate()
+      // ignore falsy values
+      if (!value) return
+
+      // stop watching when nodes_filtered[] is not empty
+      if (value && value.length) unwatch()
+
+      // process value here
+    })
+
+    const unwatchtwo = this.$watch('positions_filtered', (value) => {
+      // this.$options.myArray = this.nodes_filtered
+      this.$options.positionsArray = this.positions_filtered
+      this.$forceUpdate()
+      // ignore falsy values
+      if (!value) return
+
+      // stop watching when nodes_filtered[] is not empty
+      if (value && value.length) unwatchtwo()
+
+      // process value here
+    })
   },
 
   updated() {
@@ -284,14 +315,34 @@ export default {
   },
 
   methods: {
-    onActivated(e) {
-      this.nodeid = e
+    loadData() {
+      this.$options.positionsArray = this.positions_filtered
+      this.$forceUpdate()
+    },
+    onActivated(id, zindex) {
+      this.zindex = zindex
+      this.nodeid = id
       var i
+      var zindexes = []
       for (i = 0; i < Object.keys(this.configPositions).length; i++) {
+        zindexes.push(this.configPositions[i].z_index)
+        if (this.configPositions[i].node_id == this.nodeid) {
+          this.width = this.configPositions[i].width
+          this.height = this.configPositions[i].height
+          this.zindex = this.configPositions[i].z_index
+        }
+      }
+      var topZ = Math.max(...zindexes)
+
+      for (i = 0; i < Object.keys(this.configPositions).length; i++) {
+        if (topZ > 2147483640) {
+          this.configPositions[i].z_index = 0
+        }
+
         if (this.configPositions[i].node_id == this.nodeid) {
           this.width = this.configPositions[i].width
           this.height = this.configPositions[i].height
-          this.pickupz = this.configPositions[i].z_index
+          this.configPositions[i].z_index = topZ + 1
         }
       }
     },
@@ -301,15 +352,15 @@ export default {
       this.width = width
       this.height = height
     },
-    onResizestop(x, y, width, height, zindex) {
+    onResizestop(x, y, width, height) {
       var localnodeid = this.nodeid
-      zindex = this.pickupz
+      var zindex
       var i
       for (i = 0; i < Object.keys(this.configPositions).length; i++) {
         if (this.configPositions[i].node_id == this.nodeid) {
           this.width = this.configPositions[i].width
           this.height = this.configPositions[i].height
-          this.pickupz = this.configPositions[i].z_index
+          zindex = this.configPositions[i].z_index
         }
       }
       this.width = width
@@ -327,9 +378,9 @@ export default {
       this.localx = x
       this.localy = y
     },
-    onDragstop(x, y, width, height, zindex) {
+    onDragstop(x, y, width, height) {
       var localnodeid = this.nodeid
-      zindex = this.pickupz
+      var zindex
       width = this.width
       height = this.height
       var i
@@ -337,7 +388,7 @@ export default {
         if (this.configPositions[i].node_id == this.nodeid) {
           this.localx = this.configPositions[i].x_pos
           this.localy = this.configPositions[i].y_pos
-          this.pickupz = this.configPositions[i].z_index
+          zindex = this.configPositions[i].z_index
         }
       }
       this.$store.dispatch('movePos', {
@@ -366,6 +417,7 @@ export default {
           })
         }
       }
+      this.$options.myArray = this.othernodes_filtered
     },
     append(emoji) {
       this.input += emoji
@@ -445,7 +497,7 @@ h3 {
   /* transform: scale(1.5); */
 }
 .emoji-invoker > svg {
-  fill: #b1c6d0;
+  fill: #4e4e4e;
   margin-top: 10px;
   margin-left: 0.2em;
   transform: scale(1.5);
@@ -479,7 +531,7 @@ h3 {
 .emoji-picker h5 {
   margin-top: 0;
   margin-bottom: 0;
-  color: #b1b1b1;
+  color: #5c5c5c;
   text-transform: uppercase;
   font-size: 0.8rem;
   cursor: default;
diff --git a/app/src/components/SvgButton.vue b/app/src/components/SvgButton.vue
index 5543dee6c310a59859a0a91ab331527e98be523b..c3c6694f0c58964aeef6b7372f08f9a14a1c599e 100644
--- a/app/src/components/SvgButton.vue
+++ b/app/src/components/SvgButton.vue
@@ -56,7 +56,7 @@ button {
 }
 
 button.nodes {
-  background-color: rgb(155, 194, 216);
+  background-color: rgba(255, 255, 255, 0);
 }
 
 .z {
diff --git a/app/src/components/SvgButton2.vue b/app/src/components/SvgButton2.vue
index 164bbfee99d050d4ce14e4f613b3c268e602bb0c..63343d53625d6aa2d0d1d80de0b806dcd1f4548b 100644
--- a/app/src/components/SvgButton2.vue
+++ b/app/src/components/SvgButton2.vue
@@ -38,7 +38,7 @@ button {
 }
 
 button.nodes {
-  background-color: rgb(155, 194, 216);
+  background-color: rgba(255, 255, 255, 0);
 }
 
 .a {
diff --git a/app/src/components/SvgButton3.vue b/app/src/components/SvgButton3.vue
new file mode 100644
index 0000000000000000000000000000000000000000..2274cc096289f5ccfa626867663cebacbb12dc57
--- /dev/null
+++ b/app/src/components/SvgButton3.vue
@@ -0,0 +1,80 @@
+<template>
+  <div>
+    <button v-on="$listeners" class="button" :class="buttonClass">
+      <svg xmlns="http://www.w3.org/2000/svg" width="50" viewBox="0 0 194 178">
+        <g transform="translate(-1340.934 -573.185)">
+          <g transform="translate(16 57)">
+            <path
+              class="a"
+              d="M1370.346,606.448C1250.818,701.656,1237.2,715.157,1237.2,715.157l-12.18,28.185,32.968-8.841,132.15-102.707Z"
+              transform="translate(103 -49)"
+            />
+            <path
+              class="a"
+              d="M0,0H47a8,8,0,0,1,8,8V35a0,0,0,0,1,0,0H0a0,0,0,0,1,0,0V0A0,0,0,0,1,0,0Z"
+              transform="translate(1484.229 527.185) rotate(50)"
+            />
+          </g>
+          <path
+            class="b"
+            d="M1278.245,681.651c-43.206,34.469-41.047,33.506-41.047,33.506l-12.18,28.185,32.968-8.841,57.042-46.029Z"
+            transform="translate(122 -12)"
+          />
+          <path
+            class="c"
+            d="M1370.346,606.448C1250.818,701.656,1237.2,715.157,1237.2,715.157l36.986-31.527,41.706,6.236,42.508-33.315,31.739-24.758Z"
+            transform="translate(122 -12)"
+          />
+          <path
+            class="d"
+            d="M1370.346,606.448C1250.818,701.656,1237.2,715.157,1237.2,715.157l-12.18,28.185,32.968-8.841,132.15-102.707Z"
+            transform="translate(122 -12)"
+          />
+          <path
+            d="M10,0H46a9,9,0,0,1,9,9V35a0,0,0,0,1,0,0H0a0,0,0,0,1,0,0V10A10,10,0,0,1,10,0Z"
+            transform="translate(1498.229 573.185) rotate(50)"
+          />
+        </g>
+      </svg>
+    </button>
+  </div>
+</template>
+
+<script>
+export default {
+  props: {
+    buttonClass: {
+      type: String,
+    },
+  },
+}
+</script>
+
+<style lang="css" scoped>
+button {
+  background-color: #6fcf97;
+  touch-action: manipulation;
+  border: none;
+  outline: none;
+  cursor: pointer;
+}
+
+button.nodes {
+  background-color: rgba(255, 255, 255, 0);
+}
+
+.a {
+  fill: #4f4f4f;
+}
+.b {
+  fill: #2d9cdb;
+}
+.c {
+  fill: #fff;
+}
+.d {
+  fill: none;
+  stroke: #000;
+  stroke-width: 7px;
+}
+</style>
diff --git a/app/src/components/TipsLayer.vue b/app/src/components/TipsLayer.vue
index 25cefb91103e174592eab9555314a8d5ab61c493..32bdf51fc5088e11928c5974a11614c99bbeaff7 100644
--- a/app/src/components/TipsLayer.vue
+++ b/app/src/components/TipsLayer.vue
@@ -1,13 +1,13 @@
 <template>
   <div ref="nodes" class="node">
-    <div v-show="tipsplease">
+    <div v-show="showtipsstate">
       <draggable
         class="innernode"
         :w="250"
         :h="225"
         :x="540"
         :y="15"
-        :z="1"
+        :z="0"
         :scale="scale"
         :draggable="true"
         :resizable="false"
@@ -21,7 +21,7 @@
       </draggable>
     </div>
 
-    <div v-show="!tipsplease"></div>
+    <div v-show="!showtipsstate"></div>
   </div>
 </template>
 
@@ -35,10 +35,11 @@ export default {
     return {
       nodetext:
         '## Shortcuts 🐢 -> 🐰 \n **n** to create new nodes. </br> **c** create connections </br> **a** or **s** select &amp; move nodes. </br> **m** pan and zoom canvas',
-      tipsplease: true,
+      // showtipsstate: true,
     }
   },
   computed: mapState({
+    showtipsstate: (state) => state.showtipsstate,
     scale: (state) => state.ui.scale,
   }),
   filters: {
@@ -47,7 +48,8 @@ export default {
 
   methods: {
     hideTips() {
-      this.tipsplease = false
+      var e = false
+      this.$store.dispatch('showTipsstate', e)
     },
   },
   components: {
diff --git a/app/src/components/UploadLayer.vue b/app/src/components/UploadLayer.vue
index 980bb6bdce6174a423bb5ffc583c3cfd66c7ee91..61bf9ada025851c187a8b12e1e84eccf3cd65982 100644
--- a/app/src/components/UploadLayer.vue
+++ b/app/src/components/UploadLayer.vue
@@ -1,30 +1,185 @@
 <template>
-  <div class="ipfsupload">
-    <form>
-      <input
-        id="file"
-        class="fileInput"
-        type="file"
-        name="fileInput"
-        ref="fileInput"
-        @change="onFileSelected"
-      />
-
-      <textarea id="ipfshash" v-model="copytext"></textarea>
-      <div class="btn-row">
-        <button v-on:click.prevent="copyDone()" id="copyme" hidden>Copy</button>
-      </div>
-    </form>
+  <div v-if="this.currentroute.name == 'Organise'">
+    <div class="ipfsupload dropORG" id="dropContainer">
+      <form>
+        <input
+          id="file"
+          class="fileInput"
+          type="file"
+          name="fileInput"
+          ref="fileInput"
+          @change="onFileSelected"
+        />
+        <!--  -->
+        <p>Drop media here to upload.</p>
+        <svg
+          class="icon"
+          xmlns="http://www.w3.org/2000/svg"
+          width="50"
+          height="50"
+        >
+          <g>
+            <circle cx="6.5" cy="30.5" r="5.5" fill="grey" />
+            <circle cx="40.5" cy="30.5" r="5.5" fill="grey" />
+            <circle cx="17.5" cy="27.5" r="8.5" fill="grey" />
+            <circle cx="28.5" cy="25.5" r="10.5" fill="grey" />
+            <rect
+              fill-rule="evenodd"
+              clip-rule="evenodd"
+              x="6"
+              y="31"
+              width="35"
+              height="5"
+              fill="grey"
+            />
+            <circle
+              cx="9.5"
+              cy="25.5"
+              r="4.5"
+              fill="white"
+              stroke="grey"
+              stroke-width="2"
+            />
+            <circle
+              cx="43.5"
+              cy="25.5"
+              r="4.5"
+              fill="white"
+              stroke="grey"
+              stroke-width="2"
+            />
+            <circle
+              cx="20.5"
+              cy="22.5"
+              r="7.5"
+              fill="white"
+              stroke="grey"
+              stroke-width="2"
+            />
+            <circle
+              cx="31.5"
+              cy="20.5"
+              r="9.5"
+              fill="white"
+              stroke="grey"
+              stroke-width="2"
+            />
+            <rect x="9" y="23" width="35" height="6" fill="white" />
+            <rect x="9" y="23" width="12" height="5" fill="white" />
+            <rect x="18" y="21" width="9" height="6" fill="white" />
+            <rect x="17" y="17" width="21" height="5" fill="white" />
+            <rect x="21" y="18" width="10" height="4" fill="white" />
+            <path
+              d="M30.5303 15.4697C30.2374 15.1768 29.7626 15.1768 29.4697 15.4697L24.6967 20.2426C24.4038 20.5355 24.4038 21.0104 24.6967 21.3033C24.9896 21.5962 25.4645 21.5962 25.7574 21.3033L30 17.0607L34.2426 21.3033C34.5355 21.5962 35.0104 21.5962 35.3033 21.3033C35.5962 21.0104 35.5962 20.5355 35.3033 20.2426L30.5303 15.4697ZM30.75 28L30.75 16L29.25 16L29.25 28L30.75 28Z"
+              fill="grey"
+            />
+          </g>
+        </svg>
+        <textarea id="ipfshash" v-model="copytext"></textarea>
+        <div class="btn-row">
+          <button v-on:click.prevent="copyDone()" id="copyme" hidden>
+            Copy
+          </button>
+        </div>
+      </form>
+    </div>
+  </div>
+  <div v-else>
+    <div class="ipfsupload dropList" id="dropContainer">
+      <form>
+        <input
+          id="file"
+          class="fileInput"
+          type="file"
+          name="fileInput"
+          ref="fileInput"
+          @change="onFileSelected"
+        />
+        <!--  -->
+        <p>Drop media here to upload.</p>
+        <svg
+          class="icon"
+          xmlns="http://www.w3.org/2000/svg"
+          width="50"
+          height="50"
+        >
+          <g>
+            <circle cx="6.5" cy="30.5" r="5.5" fill="grey" />
+            <circle cx="40.5" cy="30.5" r="5.5" fill="grey" />
+            <circle cx="17.5" cy="27.5" r="8.5" fill="grey" />
+            <circle cx="28.5" cy="25.5" r="10.5" fill="grey" />
+            <rect
+              fill-rule="evenodd"
+              clip-rule="evenodd"
+              x="6"
+              y="31"
+              width="35"
+              height="5"
+              fill="grey"
+            />
+            <circle
+              cx="9.5"
+              cy="25.5"
+              r="4.5"
+              fill="white"
+              stroke="grey"
+              stroke-width="2"
+            />
+            <circle
+              cx="43.5"
+              cy="25.5"
+              r="4.5"
+              fill="white"
+              stroke="grey"
+              stroke-width="2"
+            />
+            <circle
+              cx="20.5"
+              cy="22.5"
+              r="7.5"
+              fill="white"
+              stroke="grey"
+              stroke-width="2"
+            />
+            <circle
+              cx="31.5"
+              cy="20.5"
+              r="9.5"
+              fill="white"
+              stroke="grey"
+              stroke-width="2"
+            />
+            <rect x="9" y="23" width="35" height="6" fill="white" />
+            <rect x="9" y="23" width="12" height="5" fill="white" />
+            <rect x="18" y="21" width="9" height="6" fill="white" />
+            <rect x="17" y="17" width="21" height="5" fill="white" />
+            <rect x="21" y="18" width="10" height="4" fill="white" />
+            <path
+              d="M30.5303 15.4697C30.2374 15.1768 29.7626 15.1768 29.4697 15.4697L24.6967 20.2426C24.4038 20.5355 24.4038 21.0104 24.6967 21.3033C24.9896 21.5962 25.4645 21.5962 25.7574 21.3033L30 17.0607L34.2426 21.3033C34.5355 21.5962 35.0104 21.5962 35.3033 21.3033C35.5962 21.0104 35.5962 20.5355 35.3033 20.2426L30.5303 15.4697ZM30.75 28L30.75 16L29.25 16L29.25 28L30.75 28Z"
+              fill="grey"
+            />
+          </g>
+        </svg>
+        <textarea id="ipfshash" v-model="copytext"></textarea>
+        <div class="btn-row">
+          <button v-on:click.prevent="copyDone()" id="copyme" hidden>
+            Copy
+          </button>
+        </div>
+      </form>
+    </div>
   </div>
 </template>
 
 <script>
 import VueIpfs from 'ipfs'
+import Router from '@/router'
 const ipfs = VueIpfs.create()
 var node
 var output
 var path = 'ready'
 var copytext = ''
+let dropArea
 
 //const fileContents = []
 
@@ -38,6 +193,7 @@ export default {
   },
   data: function () {
     return {
+      currentroute: Router.currentRoute,
       status: 'Connecting to IPFS...',
       // id: '',
       // agentVersion: '',
@@ -48,8 +204,16 @@ export default {
       copytext: copytext,
     }
   },
+
+  // computed: {
+  //   ...mapState({
+  //     myNodes: (state) => state.myNodes,
+  //   }),
+  // },
+
   mounted: function () {
     this.getIpfsNodeInfo()
+    setTimeout(this.dropReady, 300)
   },
 
   watch: {
@@ -69,12 +233,77 @@ export default {
     },
   },
   methods: {
+    dropReady() {
+      dropArea = document.getElementById('dropContainer')
+      ;['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
+        dropArea.addEventListener(eventName, this.preventDefaults, false)
+      })
+      ;['dragenter', 'dragover'].forEach((eventName) => {
+        dropArea.addEventListener(eventName, overState)
+      })
+      ;['dragleave', 'dragend', 'drop'].forEach((eventName) => {
+        dropArea.addEventListener(eventName, leaveState)
+      })
+      ;['dragenter', 'dragover'].forEach((eventName) => {
+        dropArea.addEventListener(eventName, overStateList)
+      })
+      ;['dragleave', 'dragend', 'drop'].forEach((eventName) => {
+        dropArea.addEventListener(eventName, leaveStateList)
+      })
+
+      dropArea.addEventListener('drop', this.handleDrop, false)
+
+      function overStateList() {
+        if (document.getElementsByClassName('dropList')[0] != undefined) {
+          document.getElementsByClassName('dropList')[0].className =
+            'ipfsupload dropList dragover'
+        }
+      }
+
+      function leaveStateList() {
+        if (document.getElementsByClassName('dropList')[0] != undefined) {
+          document.getElementsByClassName('dropList')[0].className =
+            'ipfsupload dropList'
+        }
+      }
+
+      function overState() {
+        if (document.getElementsByClassName('dropORG')[0] != undefined) {
+          document.getElementsByClassName('dropORG')[0].className =
+            'ipfsupload dropORG dragover'
+        }
+      }
+
+      function leaveState() {
+        if (document.getElementsByClassName('dropORG')[0] != undefined) {
+          document.getElementsByClassName('dropORG')[0].className =
+            'ipfsupload dropORG'
+        }
+      }
+    },
+    preventDefaults(e) {
+      e.preventDefault()
+      e.stopPropagation()
+    },
+
+    handleDrop(e) {
+      let dt = e.dataTransfer
+      let files = dt.files
+      this.handleFiles(files)
+    },
+
+    handleFiles(files) {
+      // console.log(files)
+      this.dropIPFS(files)
+
+      // ;[...files].forEach(this.dropIPFS(files))
+    },
+
     async getIpfsNodeInfo() {
       try {
         // Await for ipfs node instance.
         node = await ipfs
 
-        // console.log(node)
         // Call ipfs `id` method.
         // Returns the identity of the Peer.
         //  const { agentVersion, id } = await node.id()
@@ -97,7 +326,19 @@ export default {
     async saveIPFS() {
       try {
         this.fileContents = await node.add(this.selectedFile)
-        this.getIPFS()
+        this.getIPFS(this.selectedFile.type)
+      } catch (err) {
+        // Set error status text.
+        this.status = `Error: ${err}`
+        console.log(this.status)
+      }
+    },
+
+    async dropIPFS(files) {
+      try {
+        this.fileContents = await node.add(files)
+
+        this.getIPFS(files[0].type)
       } catch (err) {
         // Set error status text.
         this.status = `Error: ${err}`
@@ -105,12 +346,12 @@ export default {
       }
     },
 
-    async getIPFS() {
+    async getIPFS(type) {
       try {
         for await (const newfile of node.get(this.fileContents.path)) {
           // console.log(newfile.path)
           this.path = newfile.path
-          this.copyClipBoard(this.path)
+          this.copyClipBoard(this.path, type)
         }
       } catch (err) {
         // Set error status text.
@@ -119,15 +360,32 @@ export default {
       }
     },
 
-    copyClipBoard(e) {
-      this.copytext = '![](https://ipfs.io/ipfs/' + e + ')'
-      //this.copyready = true
-      // setTimeout(this.copyClick, 1000)
+    copyClipBoard(e, type) {
+      // console.log(type)
+      switch (true) {
+        case type.includes('image/'):
+          this.copytext = '![](https://cloudflare-ipfs.com/ipfs/' + e + ')'
+          break
+        case type.includes('audio/'):
+          this.copytext =
+            '<audio src="https://cloudflare-ipfs.com/ipfs/' +
+            e +
+            '" controls></audio>'
+          break
+        case type.includes('video/'):
+          this.copytext =
+            '<video src="https://ipfs.infura.io/ipfs/' +
+            e +
+            '" controls></video>'
+          break
+        default:
+          this.copytext = 'https://cloudflare-ipfs.com/ipfs/' + e
+      }
     },
 
-    // copyClick() {
-    //   document.getElementById('copyme').click()
-    // },
+    copyClick() {
+      document.getElementById('copyme').click()
+    },
 
     copyDone() {
       var copyHash = document.getElementById('ipfshash')
@@ -135,7 +393,7 @@ export default {
 
       copyHash.setSelectionRange(0, 99999) /*For mobile devices*/
       document.execCommand('copy')
-      this.$emit('upload-added')
+      // this.$emit('upload-added')
       this.$emit('copy-done')
     },
   },
@@ -143,13 +401,52 @@ export default {
 </script>
 
 <style lang="css" scoped>
+.icon {
+  margin-top: -1.5em;
+  margin-left: 4.5em;
+}
 .fileInput {
   display: none;
 }
 
+#dropContainer {
+  border: 1px solid rgb(180, 180, 180);
+  height: 100px;
+  margin: 1em;
+}
+
+.dropList {
+  padding: 1em;
+  background-color: white;
+}
+.dropORG {
+  margin: 0em;
+  position: fixed;
+  bottom: 0em;
+  left: 27em;
+  padding: 1em;
+  display: flex;
+  flex-wrap: wrap;
+  align-items: center;
+  justify-content: space-between;
+  border: 1px solid rgb(180, 180, 180);
+  border-radius: 20px;
+  height: 100px;
+  background-color: white;
+  outline: 2px dashed rgb(180, 180, 180);
+  outline-offset: -10px;
+}
+
+.dragover {
+  outline: 2px dashed black;
+  outline-offset: -10px;
+  background-color: rgb(180, 180, 180);
+}
+
 textarea {
   position: absolute;
-  top: 0px;
+  top: 10px;
+  left: 0em;
   height: 0px;
   width: 0px;
   padding: 0px;
diff --git a/app/src/components/old/ConnectionsLayer.vue b/app/src/components/old/ConnectionsLayer.vue
new file mode 100644
index 0000000000000000000000000000000000000000..2addb63c675feb4d4a8d584b56b107ed31ca3086
--- /dev/null
+++ b/app/src/components/old/ConnectionsLayer.vue
@@ -0,0 +1,310 @@
+<template>
+  <div class="connections">
+    <canvas ref="pixi" id="pixi"></canvas>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import * as PIXI from 'pixi.js'
+//var initialMoveTo
+//var id
+var fromnode
+var tonode
+var xposstart
+var yposstart
+var xposend
+var yposend
+var endState = false
+
+export default {
+  name: 'ConnectionsLayer',
+
+  data() {
+    return {
+      //  localtoolstate: this.toolmode,
+    }
+  },
+  computed: mapState({
+    configConnections: (state) => state.configConnections,
+    configPositions: (state) => state.configPositions,
+    myNodes: (state) => state.myNodes,
+    otherNodes: (state) => state.otherNodes,
+    toolmode: (state) => state.ui.mode,
+    // connectionstate: (state) => state.connectionstate,
+  }),
+
+  watch: {
+    configConnections: {
+      deep: true,
+
+      handler() {
+        this.connectionsDraw()
+      },
+    },
+    toolmode: {
+      handler() {
+        this.toolState()
+      },
+    },
+  },
+
+  methods: {
+    toolState() {
+      if (this.toolmode == 'connect') {
+        this.buttonsDraw()
+      } else {
+        this.connectionsDraw()
+      }
+    },
+
+    makeConnection(id, xpos, ypos) {
+      if (endState == false) {
+        fromnode = id
+        xposstart = xpos
+        yposstart = ypos
+
+        //count = 1
+        // this.$store.dispatch('connectionState', true)
+      } else if (endState == true) {
+        tonode = id
+        xposend = xpos
+        yposend = ypos
+
+        // count = 0
+        //  this.$store.dispatch('connectionState', false)
+        // console.log(fromnode, tonode, xposstart, yposstart, xposend, yposend)
+        this.$store.dispatch('makeConnect', {
+          fromnode,
+          tonode,
+          xposstart,
+          yposstart,
+          xposend,
+          yposend,
+        })
+        endState = false
+      }
+    },
+    buttonsDraw() {
+      var i
+      var j
+      //var n = 1
+      var ref = this
+      var buttonMap = {}
+      var buttonMapOther = {}
+
+      this.canvas = this.$refs.pixi
+      const stage = this.PIXIApp.stage
+      //const allButtons = new PIXI.Container()
+
+      for (i = 0; i < Object.keys(this.myNodes).length; i++) {
+        buttonMap[i] = new PIXI.Graphics()
+        // console.log(buttonMap[i])
+        for (j = 0; j < Object.keys(this.configPositions).length; j++) {
+          if (
+            this.configPositions[j].node_id == this.myNodes[i].node_id &&
+            this.myNodes[i].deleted == false
+          ) {
+            buttonMap[i].name = this.myNodes[i].node_id
+            // console.log(button_one.name)
+            buttonMap[i].lineStyle(1)
+            buttonMap[i].beginFill(0xcab6ff, 1)
+            // x, y, radius
+
+            buttonMap[i].drawCircle(
+              this.configPositions[j].x_pos + this.configPositions[j].width,
+              this.configPositions[j].y_pos +
+                this.configPositions[j].height / 2,
+              15
+            )
+            buttonMap[i].endFill()
+            // names it the last one only?
+          }
+          //  allButtons.addChild(buttonMap[i])
+          //  stage.addChild(allButtons)
+          stage.addChild(buttonMap[i])
+          // Opt-in to interactivity
+          buttonMap[i].interactive = true
+          // Shows hand cursor
+          buttonMap[i].buttonMode = true
+        }
+
+        buttonMap[i]
+          .on('pointerdown', onDragStart)
+          .on('pointerdown', start)
+          .on('pointerup', onDragEnd)
+          .on('pointerup', finish)
+          .on('pointerupoutside', onDragEndOutside)
+          .on('pointermove', onDragMove)
+      }
+
+      for (i = 0; i < Object.keys(this.otherNodes).length; i++) {
+        buttonMapOther[i] = new PIXI.Graphics()
+        // console.log(buttonMap[i])
+        for (j = 0; j < Object.keys(this.configPositions).length; j++) {
+          if (this.configPositions[j].node_id == this.otherNodes[i].node_id) {
+            buttonMapOther[i].name = this.otherNodes[i].node_id
+            // console.log(button_one.name)
+            buttonMapOther[i].lineStyle(1)
+            buttonMapOther[i].beginFill(0xcab6ff, 1)
+            // x, y, radius
+
+            buttonMapOther[i].drawCircle(
+              this.configPositions[j].x_pos + this.configPositions[j].width,
+              this.configPositions[j].y_pos +
+                this.configPositions[j].height / 2,
+              15
+            )
+            buttonMapOther[i].endFill()
+            // names it the last one only?
+          }
+          stage.addChild(buttonMapOther[i])
+
+          // Opt-in to interactivity
+          buttonMapOther[i].interactive = true
+          // Shows hand cursor
+          buttonMapOther[i].buttonMode = true
+        }
+
+        buttonMapOther[i]
+          .on('pointerdown', onDragStart)
+          .on('pointerdown', start)
+          .on('pointerup', finish)
+          .on('pointerup', onDragEnd)
+          .on('pointerupoutside', onDragEndOutside)
+          .on('pointermove', onDragMove)
+      }
+
+      let line = new PIXI.Graphics()
+      var initialMoveTo
+      let lines = []
+
+      function start(event) {
+        // console.log(this.getChildByName)
+        this.id = this.name
+        ref.makeConnection(this.id, event.data.global.x, event.data.global.y)
+      }
+
+      function finish(event) {
+        this.id = this.name
+        if (this.id != fromnode) {
+          endState = true
+          ref.makeConnection(this.id, event.data.global.x, event.data.global.y)
+        } else {
+          endState = false
+        }
+      }
+
+      function onDragStart(event) {
+        this.dragging = true
+        // returns on the last one in the loop
+        // console.log(button_one.name)
+        let mouseX = event.data.global.x
+        let mouseY = event.data.global.y
+
+        initialMoveTo = [mouseX, mouseY]
+
+        line.lineStyle(8, 0xcab6ff)
+        line.moveTo(mouseX, mouseY)
+
+        lines = [line].concat(lines)
+
+        stage.addChild(line)
+      }
+
+      function onDragEnd() {
+        //endState = true
+        this.dragging = false
+        stage.removeChild(line)
+      }
+
+      function onDragEndOutside() {
+        stage.removeChild(line)
+        // console.log('outside')
+        // console.log(this.name)
+        // console.log(fromnode)
+        // if (this.name != fromnode) {
+        //   console.log('diff')
+        //   endState = true
+        //   this.dragging = false
+        //   stage.removeChild(line)
+        //   this.finish()
+        // }
+        // } else {
+        //   endState = false
+        //   this.dragging = false
+        //   stage.removeChild(line)
+        // }
+      }
+
+      function onDragMove(event) {
+        if (this.dragging) {
+          let mouseX = event.data.global.x
+          let mouseY = event.data.global.y
+          lines[0].clear()
+          lines[0].lineStyle(8, 0xcab6ff)
+          lines[0].moveTo(initialMoveTo[0], initialMoveTo[1])
+          lines[0].lineTo(mouseX, mouseY)
+        }
+      }
+    },
+
+    connectionsDraw() {
+      var i
+      //  var j
+      this.canvas = this.$refs.pixi
+      const stage = this.PIXIApp.stage
+      let graphics = new PIXI.Graphics()
+      //let line = new PIXI.Graphics()
+
+      graphics.lineStyle(8, 0xcab6ff)
+      // move the lines to start and end pos based on if to_node == node_id
+      // or from_id == node_id
+      //start_id == node_id
+      // this will put them in the same place as buttons
+
+      //     for (i = 0; i < Object.keys(this.otherNodes).length; i++) {
+
+      // for (j = 0; j < Object.keys(this.configPositions).length; j++) {
+      //   if (this.configConnections[j].start_id == this.otherNodes[i].node_id) {
+
+      // for (j = 0; j < Object.keys(this.otherNodes).length; j++) {
+      for (i = 0; i < Object.keys(this.configConnections).length; i++) {
+        //start
+
+        graphics.moveTo(
+          this.configConnections[i].x_pos_start,
+          this.configConnections[i].y_pos_start
+        )
+
+        //end
+        graphics.lineTo(
+          this.configConnections[i].x_pos_end,
+          this.configConnections[i].y_pos_end
+        )
+      }
+      //  }
+      for (var l = stage.children.length - 1; l >= 0; l--) {
+        stage.removeChild(stage.children[l])
+      }
+
+      stage.addChild(graphics)
+      if (this.toolmode == 'connect') {
+        this.buttonsDraw()
+      }
+    },
+  },
+  mounted() {
+    const canvas = this.$refs.pixi
+    this.PIXIApp = new PIXI.Application({
+      width: 3000,
+      height: 3000,
+      antialias: true,
+      transparent: true,
+      view: canvas,
+    })
+
+    this.connectionsDraw()
+  },
+}
+</script>
diff --git a/app/src/components/old/OffLine.vue b/app/src/components/old/OffLine.vue
new file mode 100644
index 0000000000000000000000000000000000000000..c8b0803ed65105a88f20e60855caee55f62399b3
--- /dev/null
+++ b/app/src/components/old/OffLine.vue
@@ -0,0 +1,100 @@
+// FIXME: Everything below is OLD code
+
+<template>
+  <div class="yourdata" name="anchorName">
+    <div v-for="(nodes, index) in $options.myArray" v-bind:key="index">
+      <textarea
+        @focus="editTrue(true)"
+        @blur="editTrue(false)"
+        autofocus
+        @input="editNode"
+        v-model="nodes.node_text"
+        :id="nodes.node_id"
+        class="drag-cancel"
+        ref="nodetext"
+        placeholder="Type your thoughts and ideas here! (will sync to couchdb when back online)"
+      ></textarea>
+    </div>
+
+    <div class="btn-row">
+      <BaseButton
+        buttonClass="danger"
+        @click.prevent="deleteFlag(nodes.node_id)"
+        >Discard</BaseButton
+      >
+    </div>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+
+export default {
+  name: 'OffLine',
+
+  data() {
+    return {
+      nodeid: String,
+      myArray: null,
+    }
+  },
+  computed: {
+    ...mapState({
+      myNodes: (state) => state.myNodes,
+    }),
+
+    nodes_filtered: function () {
+      return this.myNodes.filter((nodes) => {
+        return nodes.deleted == false
+      })
+    },
+  },
+
+  mounted() {
+    setTimeout(this.loadData, 500)
+  },
+
+  methods: {
+    loadData() {
+      this.$options.myArray = this.nodes_filtered
+      // this.$options.positionsArray = this.positions_filtered
+      this.$forceUpdate()
+    },
+    // addNode() {
+    //   // console.log('add called')
+    //   this.$store.dispatch('addNode')
+    //   this.added = !this.added
+    // },
+    editTrue(e) {
+      this.$emit('edit-true', e)
+      //// console.log(e)
+    },
+
+    editNode(e) {
+      var nodeid = e.target.id
+      var nodetext = e.target.value
+      this.$store.dispatch('editNode', { nodeid, nodetext })
+    },
+
+    deleteFlag(e) {
+      if (confirm('Confirm discard?')) {
+        this.$store.dispatch('deleteFlag', { e })
+        this.$options.myArray = this.nodes_filtered
+      } else {
+        // nothing happens
+      }
+    },
+  },
+}
+</script>
+
+<style lang="css" scoped>
+h3 {
+  margin-top: 1em;
+}
+
+.data p {
+  white-space: pre-wrap;
+  line-height: 1em;
+}
+</style>
diff --git a/app/src/experimental/ModeToolbar.vue b/app/src/experimental/ModeToolbar.vue
index 103cefcc4b224859e46a67766eed2ce8961fe575..d345bf1a5e10dd60f59066a8e074d128fa79051b 100644
--- a/app/src/experimental/ModeToolbar.vue
+++ b/app/src/experimental/ModeToolbar.vue
@@ -12,20 +12,17 @@
       />
     </button>
 
-    <p>{{ clientid }} / {{ microcosm }}</p>
+    <!-- <p>{{ clientid }} / {{ microcosm }}</p> -->
   </nav>
 </template>
 
 <script>
-var serverUrl = 'https://nodenogg.in'
 import { mapState, mapGetters } from 'vuex'
 
 import * as allModes from '@/experimental/modes'
 
 export default {
   mounted() {
-    window.addEventListener('online', this.handleConnection)
-    window.addEventListener('offline', this.handleConnection)
     this.clientid = localStorage.myNNClient
     this.microcosm = localStorage.mylastMicrocosm
   },
@@ -49,7 +46,8 @@ export default {
         }
       }
       if (mode == 'addNode') {
-        this.$store.dispatch('addNode')
+        this.$emit('add-node')
+        // this.$store.dispatch('addNode')
       }
       if (mode == 'upload') {
         this.$emit('upload-added')
@@ -82,38 +80,6 @@ export default {
         process.env.VUE_APP_HTTP + '://' + process.env.VUE_APP_URL + '/'
       )
     },
-
-    handleConnection: function () {
-      var ref = this
-      if (navigator.onLine) {
-        this.isReachable(this.getServerUrl()).then(function (online) {
-          if (online) {
-            // handle online status
-            console.log('online')
-            location.reload()
-          } else {
-            console.log('no connectivity')
-          }
-        })
-      } else {
-        // handle offline status
-        console.log('offline')
-        ref.$emit('offline-triggered')
-      }
-    },
-    isReachable: function (url) {
-      // This should pick up a CORS error but it doesnt seem to //
-      return fetch(url, { method: 'HEAD', mode: 'no-cors' })
-        .then(function (resp) {
-          return resp && (resp.ok || resp.type === 'opaque')
-        })
-        .catch(function (err) {
-          console.warn('[conn test failure]:', err)
-        })
-    },
-    getServerUrl: function () {
-      return serverUrl || window.location.origin
-    },
   },
   data() {
     return {
diff --git a/app/src/experimental/uiStore.js b/app/src/experimental/uiStore.js
index 74f1963e5749fb896e548134dc4325d2285d8bd5..d3d7b7659434bb832b73499898262ffe00075843 100644
--- a/app/src/experimental/uiStore.js
+++ b/app/src/experimental/uiStore.js
@@ -18,7 +18,7 @@ const store = {
       nodes: [],
     },
     mode: 'select',
-    tipshidden: false,
+
     scale: 1,
     translation: {
       x: 0,
diff --git a/app/src/main.js b/app/src/main.js
index c554968c7b97471887d03525aa0a3a4a18b544ee..db32d0b022ccdb632ba6b5db0bf1ed546a4ff345 100644
--- a/app/src/main.js
+++ b/app/src/main.js
@@ -17,6 +17,15 @@ Vue.component('Icon', Icon)
 
 Vue.config.productionTip = false
 
+// Register a global custom directive called `v-focus`
+Vue.directive('focus', {
+  // When the bound element is inserted into the DOM...
+  inserted: function (el) {
+    // Focus the element
+    el.focus()
+  },
+})
+
 new Vue({
   router,
   store,
diff --git a/app/src/router/index.js b/app/src/router/index.js
index d715684b206d916237f104df50553d7f6757f227..069ce11e292c7e6808f833316d99681546d9d2ed 100644
--- a/app/src/router/index.js
+++ b/app/src/router/index.js
@@ -7,6 +7,7 @@ import Discarded from '../views/Discarded.vue'
 import Leave from '../views/Leave.vue'
 import About from '../views/About.vue'
 import NotFound from '../views/NotFound.vue'
+import NitPicky from '../views/NitPicky.vue'
 //import store from '../store'
 // import Oldhome from '../views/Oldhome'
 //import Test from '../views/Test'
@@ -46,6 +47,11 @@ export const routes = [
     name: 'About',
     component: About,
   },
+  {
+    path: '/nitpicky',
+    name: 'NitPicky',
+    component: NitPicky,
+  },
 
   {
     // catches 404 errors
diff --git a/app/src/store/index.js b/app/src/store/index.js
index 0b1f75efaaf5419807e5f3c57316d229b42ca519..1bdc2bafed4fd5f31d9c755be21f1b32bc4bf43a 100644
--- a/app/src/store/index.js
+++ b/app/src/store/index.js
@@ -40,7 +40,7 @@ var remote =
 const store = new Vuex.Store({
   state: {
     shortcutstate: false,
-    hidetipsstate: true,
+    showtipsstate: true,
     //  connectionstate: false,
     version: process.env.VUE_APP_VERSION,
     localnodeid: '',
@@ -69,6 +69,18 @@ const store = new Vuex.Store({
     configEmoji: [
       //{}
     ],
+    configRemote: [
+      // {
+      // protocol: 'https://',
+      // couchusername: 'something',
+      // couchpassword: 'passcouch',
+      // couchurl: 'domain.com',
+      // },
+      //{ https://,
+      // couchusername
+      // couchpassword
+      // couchURL}
+    ],
   },
   mutations: {
     CREATE_MICROCOSM(state, doc) {
@@ -82,16 +94,31 @@ const store = new Vuex.Store({
         } else {
           microcosm = doc
         }
+
         pouchdb = new PouchDB(microcosm)
-        remote =
-          process.env.VUE_APP_COUCH_HTTP +
-          '://' +
-          process.env.VUE_APP_COUCH_USER +
-          ':' +
-          process.env.VUE_APP_COUCH_PASS +
-          process.env.VUE_APP_COUCH_URL +
-          microcosm +
-          '/'
+        if (state.configRemote && state.configRemote.length > 0) {
+          remote =
+            state.configRemote[0].protocol +
+            state.configRemote[0].couchusername +
+            ':' +
+            state.configRemote[0].couchpassword +
+            '@' +
+            state.configRemote[0].couchurl +
+            '/' +
+            microcosm +
+            '/'
+        } else {
+          remote =
+            process.env.VUE_APP_COUCH_HTTP +
+            '://' +
+            process.env.VUE_APP_COUCH_USER +
+            ':' +
+            process.env.VUE_APP_COUCH_PASS +
+            process.env.VUE_APP_COUCH_URL +
+            microcosm +
+            '/'
+        }
+
         store.dispatch('syncDB')
       })
     },
@@ -136,6 +163,7 @@ const store = new Vuex.Store({
               node_id: state.allNodes[i].doc.nodes[j].node_id,
               node_text: state.allNodes[i].doc.nodes[j].node_text,
               deleted: state.allNodes[i].doc.nodes[j].deleted,
+              color: state.allNodes[i].doc.nodes[j].color,
             }
 
             state.otherNodes.push(newNode)
@@ -186,7 +214,7 @@ const store = new Vuex.Store({
                   // this shouldn't need to be here though
                   node_id: startup,
                   node_text:
-                    '## Welcome \n This node was automatically by the system as a workaround for an iOS and URL routing bug, just ignore for now please \n ## 🤦🏻‍♂️',
+                    '## Welcome \n This node was automatically created by the system as a workaround for an iOS and URL routing bug, just ignore for now please \n ## 🤦🏻‍♂️',
                   node_owner: state.myclient,
                   content_type: 'sheet',
                   // NOTE: the first node is also hidden due to a position not being created
@@ -386,94 +414,131 @@ const store = new Vuex.Store({
       state.shortcutstate = e
     },
 
-    // CONNECTION_STATE(state, e) {
-    //   state.connectionstate = e
-    // },
+    SHOWTIPS_STATE(state, e) {
+      state.showtipsstate = e
+    },
+
+    UPDATE_REMOTE(state, e) {
+      state.configRemote = [
+        {
+          protocol: e.protocol,
+          couchusername: e.couchusername,
+          couchpassword: e.couchpassword,
+          couchurl: e.couchurl,
+        },
+      ]
+    },
 
     ADD_NODE(state) {
+      var i
+      var zindex
+      var totalNodes = []
+      for (i = 0; i < Object.keys(state.allNodes).length; i++) {
+        if (
+          state.allNodes[i].id != state.global_pos_name &&
+          state.allNodes[i].id != state.global_emoji_name &&
+          state.allNodes[i].id != state.global_con_name //&&
+          //
+        ) {
+          // console.log(state.allNodes[i].doc.nodes.length)
+          totalNodes.push(state.allNodes[i].doc.nodes.length)
+        }
+      }
+      const reducer = (accumulator, currentValue) => accumulator + currentValue
+      if (totalNodes && totalNodes.length > 0) {
+        zindex = totalNodes.reduce(reducer)
+      } else {
+        zindex = 1
+      }
+
       var uniqueid =
         Math.random().toString(36).substring(2, 15) +
         Math.random().toString(36).substring(2, 15)
       state.localnodeid = uniqueid
-
-      pouchdb.get(state.myclient).then(function (doc) {
-        doc.nodes.push({
-          node_id: uniqueid,
-          node_text: '',
-          node_owner: state.myclient,
-          content_type: 'sheet',
-          deleted: false,
-          read_mode: false,
-        })
-
-        return pouchdb
-          .put({
-            _id: state.myclient,
-            _rev: doc._rev,
-            _attachments: doc._attachments,
-            nodes: doc.nodes,
+      if (state.microcosm == 'firstvisit') {
+        console.log('not allowed on this microcosm')
+      } else {
+        pouchdb.get(state.myclient).then(function (doc) {
+          doc.nodes.push({
+            node_id: uniqueid,
+            node_text: '',
+            node_owner: state.myclient,
+            content_type: 'sheet',
+            deleted: false,
+            read_mode: false,
+            color: '#9bc2d8',
           })
-          .then(function () {
-            return pouchdb.get(state.myclient).then(function (doc) {
-              state.myNodes = doc.nodes
-              var end = Object.keys(state.myNodes).length - 1
-              const newNode = {
-                nodeid: state.myNodes[end].id,
-                nodetext: state.myNodes[end].text,
-                //  content_type: state.notes[end].content_type
+
+          return pouchdb
+            .put({
+              _id: state.myclient,
+              _rev: doc._rev,
+              _attachments: doc._attachments,
+              nodes: doc.nodes,
+            })
+            .then(function () {
+              return pouchdb.get(state.myclient).then(function (doc) {
+                state.myNodes = doc.nodes
+                var end = Object.keys(state.myNodes).length - 1
+                const newNode = {
+                  nodeid: state.myNodes[end].id,
+                  nodetext: state.myNodes[end].text,
+                  //  content_type: state.notes[end].content_type
+                }
+                state.activeNode = newNode
+              })
+            })
+            .catch(function (err) {
+              if (err.status == 404) {
+                // pouchdb.put({  })
               }
-              state.activeNode = newNode
             })
-          })
-          .catch(function (err) {
-            if (err.status == 404) {
-              // pouchdb.put({  })
+        })
+        pouchdb.get(state.global_pos_name).then(function (doc) {
+          //console.log(doc.positions[doc.positions.length - 1].z_index)
+          var i
+          localxpos = 50
+          localypos = 50
+          for (i = 0; i < Object.keys(doc.positions).length; i++) {
+            if (doc.positions[i].x_pos == 50) {
+              localxpos = 70
+              localypos = 70
+            }
+            if (doc.positions[i].x_pos == 70) {
+              localxpos = 90
+              localypos = 90
+            }
+            if (doc.positions[i].x_pos == 90) {
+              localxpos = 110
+              localypos = 110
+            }
+            if (doc.positions[i].x_pos == 110) {
+              localxpos = 50
+              localypos = 50
             }
-          })
-      })
-      pouchdb.get(state.global_pos_name).then(function (doc) {
-        //console.log(doc.positions[doc.positions.length - 1].z_index)
-        var i
-        localxpos = 50
-        localypos = 50
-        for (i = 0; i < Object.keys(doc.positions).length; i++) {
-          if (doc.positions[i].x_pos == 50) {
-            localxpos = 70
-            localypos = 70
-          }
-          if (doc.positions[i].x_pos == 70) {
-            localxpos = 90
-            localypos = 90
-          }
-          if (doc.positions[i].x_pos == 90) {
-            localxpos = 110
-            localypos = 110
-          }
-          if (doc.positions[i].x_pos == 110) {
-            localxpos = 50
-            localypos = 50
           }
-        }
 
-        doc.positions.push({
-          node_id: uniqueid,
-          x_pos: localxpos,
-          y_pos: localypos,
-          width: 200,
-          height: 370,
-          z_index: 10,
-          read_mode: false,
-        })
-        return pouchdb
-          .put({
-            _id: state.global_pos_name,
-            _rev: doc._rev,
-            positions: doc.positions,
+          doc.positions.push({
+            node_id: uniqueid,
+            x_pos: localxpos,
+            y_pos: localypos,
+            width: 200,
+            height: 370,
+            z_index: zindex,
+            read_mode: false,
+            node_sort: 0,
           })
-          .catch(function (err) {
-            console.log(err)
-          })
-      })
+          return pouchdb
+            .put({
+              _id: state.global_pos_name,
+              _rev: doc._rev,
+              positions: doc.positions,
+            })
+            .catch(function (err) {
+              console.log(err)
+            })
+        })
+      }
     },
 
     EDIT_NODE(state, e) {
@@ -510,6 +575,40 @@ const store = new Vuex.Store({
         })
     },
 
+    COLOR_NODE(state, e) {
+      //   console.log(e)
+      var i
+      for (i = 0; i < Object.keys(state.myNodes).length; i++) {
+        if (e.nodeid == state.myNodes[i].node_id) {
+          state.myNodes[i].color = e.color
+        }
+      }
+      pouchdb
+        .get(state.myclient)
+        .then(function (doc) {
+          // put the store into pouchdb
+
+          return pouchdb.bulkDocs([
+            {
+              _id: state.myclient,
+              _rev: doc._rev,
+              _attachments: doc._attachments,
+              nodes: state.myNodes,
+            },
+          ])
+        })
+        .then(function () {
+          return pouchdb.get(state.myclient).then(function (doc) {
+            state.myNodes = doc.nodes
+          })
+        })
+        .catch(function (err) {
+          if (err.status == 404) {
+            // pouchdb.put({  })
+          }
+        })
+    },
+
     DELETE_FLAG(state, e) {
       var i
       for (i = 0; i < Object.keys(state.myNodes).length; i++) {
@@ -607,6 +706,38 @@ const store = new Vuex.Store({
         })
     },
 
+    SORT_NODE(state, e) {
+      var i
+      for (i = 0; i < Object.keys(state.configPositions).length; i++) {
+        if (e.nodeid == state.configPositions[i].node_id) {
+          state.configPositions[i].node_sort = e.nodesort
+        }
+      }
+      pouchdb
+        .get(state.global_pos_name)
+        .then(function (doc) {
+          //  // console.log(doc)
+          // put the store into pouchdb
+          return pouchdb.bulkDocs([
+            {
+              _id: state.global_pos_name,
+              _rev: doc._rev,
+              positions: state.configPositions,
+            },
+          ])
+        })
+        .then(function () {
+          return pouchdb.get(state.global_pos_name).then(function (doc) {
+            state.configPositions = doc.positions
+          })
+        })
+        .catch(function (err) {
+          if (err.status == 404) {
+            // pouchdb.put({  })
+          }
+        })
+    },
+
     LEGACY_READ_FLAG(state, e) {
       var i
       // console.log(e.e)
@@ -743,6 +874,9 @@ const store = new Vuex.Store({
       commit('MOVE_POS', nodeid, xpos, ypos, width, height, zindex)
     },
 
+    sortNode: ({ commit }, e) => {
+      commit('SORT_NODE', e)
+    },
     updateConnect: ({ commit }, fromnode, xposstart, yposstart) => {
       commit('UPDATE_CONNECT', fromnode, xposstart, yposstart)
     },
@@ -766,6 +900,22 @@ const store = new Vuex.Store({
       commit('EDIT_NODE', { nodeid, nodetext })
     },
 
+    colorNode: ({ commit }, { nodeid, color }) => {
+      commit('COLOR_NODE', { nodeid, color })
+    },
+
+    updateRemote: (
+      { commit },
+      { protocol, couchusername, couchpassword, couchurl }
+    ) => {
+      commit('UPDATE_REMOTE', {
+        protocol,
+        couchusername,
+        couchpassword,
+        couchurl,
+      })
+    },
+
     makeConnect: (
       { commit },
       { fromnode, tonode, xposstart, yposstart, yposend, xposend }
@@ -783,6 +933,10 @@ const store = new Vuex.Store({
       commit('SHORTCUT_STATE', e)
     },
 
+    showTipsstate: ({ commit }, e) => {
+      commit('SHOWTIPS_STATE', e)
+    },
+
     // connectionState: ({ commit }, e) => {
     //   commit('CONNECTION_STATE', e)
     // },
diff --git a/app/src/views/About.vue b/app/src/views/About.vue
index dd6f338d8ad17b9559e50f865bf9da514df37f57..4c958dafd77a962ff1a9ae75eca0228f976937e8 100644
--- a/app/src/views/About.vue
+++ b/app/src/views/About.vue
@@ -7,9 +7,10 @@
       concepts
     </p>
     <p>
-      Made by Adam Procter and Toby Milner-Gulland.
+      Made by Adam Procter.
       <em>
-        (+ many helpers (Mathew Parker, im looking at you) &amp;
+        (+ many helpers (Toby Milner-Gulland &amp; Mathew Parker, I'm looking at
+        you) &amp;
         <a href="https://patreon.com/procterbot">supporters</a>)
       </em>
     </p>
diff --git a/app/src/views/Cards.vue b/app/src/views/Cards.vue
index 13ad2aea68c06eb603f0437435f733d479ff2058..74de959beade158c721dd477b1e5a3f73a6dee55 100644
--- a/app/src/views/Cards.vue
+++ b/app/src/views/Cards.vue
@@ -2,50 +2,49 @@
   <div id="listwrapper">
     <div v-if="clientset">
       <h1 class="mobile">All nodes - card view</h1>
+      <h2 class="danger">Positions not saved</h2>
+      <CardsLayer @edit-true="(e) => editTrue(e)" :added="added" />
 
-      <CardsLayer @editTrue="(e) => editTrue(e)" />
+      <!-- <OtherCardslayer /> -->
 
-      <OtherCardslayer />
-
-      <div class="btn-row">
-        <!-- <BaseButton class="new" buttonClass="action" @click="addNode()"
+      <!-- <BaseButton class="new" buttonClass="action" @click="addNode()"
             >Create Node</BaseButton
           > -->
 
-        <svg
-          xmlns="http://www.w3.org/2000/svg"
-          width="80"
-          viewBox="0 0 143 106"
-          class="icon"
-          @click="addNode()"
-        >
-          <g transform="translate(-1345 -843)">
-            <g class="a" transform="translate(1345 865)">
-              <rect class="d" width="127" height="84" />
-              <rect class="e" x="0.5" y="0.5" width="126" height="83" />
-            </g>
-            <g class="b" transform="translate(1361 843)">
-              <rect class="d" width="127" height="84" />
-              <rect class="e" x="3.5" y="3.5" width="120" height="77" />
-            </g>
-            <line class="c" x2="41" transform="translate(1406.5 884.5)" />
-            <line class="c" y2="41" transform="translate(1426.5 863.5)" />
+      <svg
+        xmlns="http://www.w3.org/2000/svg"
+        width="80"
+        viewBox="0 0 143 106"
+        class="icon"
+        @click="addNode()"
+      >
+        <g transform="translate(-1345 -843)">
+          <g class="a" transform="translate(1345 865)">
+            <rect class="d" width="127" height="84" />
+            <rect class="e" x="0.5" y="0.5" width="126" height="83" />
+          </g>
+          <g class="b" transform="translate(1361 843)">
+            <rect class="d" width="127" height="84" />
+            <rect class="e" x="3.5" y="3.5" width="120" height="77" />
           </g>
-        </svg>
-
-        <UploadLayer
-          v-bind:uploadready="uploadready"
-          v-bind:copyready="copyready"
-          @upload-added="uploadAdded()"
-          @copy-done="copyDone()"
-        />
+          <line class="c" x2="41" transform="translate(1406.5 884.5)" />
+          <line class="c" y2="41" transform="translate(1426.5 863.5)" />
+        </g>
+      </svg>
+      <div class="btn-row">
+        <BaseButton class="new" buttonClass="action" @click="uploadAdded()"
+          >Upload</BaseButton
+        >
+        <BaseButton class="new" buttonClass="action" @click="copyDone()"
+          >Get Upload</BaseButton
+        >
       </div>
-      <BaseButton class="new" buttonClass="action" @click="uploadAdded()"
-        >Upload</BaseButton
-      >
-      <BaseButton class="new" buttonClass="action" @click="copyDone()"
-        >Get Upload</BaseButton
-      >
+      <UploadLayer
+        v-bind:uploadready="uploadready"
+        v-bind:copyready="copyready"
+        @upload-added="uploadAdded()"
+        @copy-done="copyDone()"
+      />
     </div>
 
     <div v-else>
@@ -56,9 +55,10 @@
 
 <script>
 import CardsLayer from '@/components/CardsLayer'
-import OtherCardslayer from '@/components/OtherCardslayer'
+// import OtherCardslayer from '@/components/OtherCardslayer'
 import OnBoard from '@/components/OnBoard'
 import UploadLayer from '@/components/UploadLayer'
+
 import { mapState } from 'vuex'
 
 import { shortcutsMixin } from '@/components/mixins/shortcutsMixin.js'
@@ -72,15 +72,10 @@ export default {
       clientset: false,
       uploadready: false,
       copyready: false,
+      added: true,
     }
   },
 
-  props: {
-    nodeid: String,
-    nodetext: String,
-    deleted: Boolean,
-  },
-
   computed: {
     ...mapState({
       myNodes: (state) => state.myNodes,
@@ -114,6 +109,7 @@ export default {
 
     addNode() {
       this.$store.dispatch('addNode')
+      this.added = !this.added
     },
 
     editTrue(e) {
@@ -133,7 +129,7 @@ export default {
   },
   components: {
     CardsLayer,
-    OtherCardslayer,
+    // OtherCardslayer,
     UploadLayer,
     OnBoard,
   },
@@ -141,6 +137,9 @@ export default {
 </script>
 
 <style lang="css" scoped>
+.danger {
+  color: red;
+}
 .mobile {
   margin-left: 1em;
   font-size: 1em;
@@ -149,6 +148,10 @@ export default {
   margin-bottom: 1em;
 }
 
+.btn-row {
+  margin-left: 1em;
+}
+
 .example {
   width: 30px;
 }
diff --git a/app/src/views/Collect.vue b/app/src/views/Collect.vue
index c20497054c6e7c963f8ab955a469a2bcff94b9ba..702557f0598728eb9303745d06b3acd103568989 100644
--- a/app/src/views/Collect.vue
+++ b/app/src/views/Collect.vue
@@ -3,12 +3,8 @@
     <div v-if="clientset">
       <div id="listwrapper">
         <ModesCard />
-        <ListLayer @edit-true="(e) => editTrue(e)" />
+        <ListLayer @edit-true="(e) => editTrue(e)" :added="added" />
         <div class="btn-row">
-          <!-- <BaseButton class="new" buttonClass="action" @click="addNode()"
-            >Create Node</BaseButton
-          > -->
-
           <svg
             xmlns="http://www.w3.org/2000/svg"
             width="80"
@@ -78,15 +74,10 @@ export default {
       clientset: false,
       uploadready: false,
       copyready: false,
+      added: true,
     }
   },
 
-  props: {
-    nodeid: String,
-    nodetext: String,
-    deleted: Boolean,
-  },
-
   computed: {
     ...mapState({
       myNodes: (state) => state.myNodes,
@@ -103,8 +94,7 @@ export default {
   },
 
   mounted() {
-    var e = false
-    this.$store.dispatch('shortcutState', e)
+    setTimeout(this.loadShortcut, 1000)
   },
 
   beforeDestroy() {
@@ -114,12 +104,19 @@ export default {
   },
 
   methods: {
+    loadShortcut() {
+      var e = false
+      this.$store.dispatch('shortcutState', e)
+    },
+
     clientAdded() {
       this.clientset = !this.clientset
     },
 
     addNode() {
+      // console.log('add called')
       this.$store.dispatch('addNode')
+      this.added = !this.added
     },
 
     editTrue(e) {
diff --git a/app/src/views/NitPicky.vue b/app/src/views/NitPicky.vue
new file mode 100644
index 0000000000000000000000000000000000000000..ae544c35462ae4cc6aa74e83d2d7278daff82592
--- /dev/null
+++ b/app/src/views/NitPicky.vue
@@ -0,0 +1,84 @@
+<template>
+  <div>
+    <h1>Admin</h1>
+    <p>Access to some objects to test redirect of CouchDB and credentails</p>
+
+    <div v-for="(value, index) in configRemote" v-bind:key="index">
+      {{ value.protocol }}{{ value.couchusername }}:{{ value.couchpassword }}@{{
+        value.couchurl
+      }}
+    </div>
+    <form>
+      <input
+        type="text"
+        v-model="protocol"
+        placeholder="https://"
+        autocorrect="off"
+        autocapitalize="none"
+      />
+      <input
+        type="text"
+        v-model="couchusername"
+        placeholder="couch admin username"
+        autocorrect="off"
+        autocapitalize="none"
+      />
+      <input
+        type="text"
+        v-model="couchpassword"
+        placeholder="couch admin password"
+        autocorrect="off"
+        autocapitalize="none"
+      />
+      <input
+        type="text"
+        v-model="couchurl"
+        placeholder="youcouch.com"
+        autocorrect="off"
+        autocapitalize="none"
+      />
+
+      <button
+        @click.prevent="
+          updateRemote(protocol, couchusername, couchpassword, couchurl)
+        "
+      >
+        Change Credentials
+      </button>
+    </form>
+  </div>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+
+export default {
+  name: 'NitPicky',
+
+  data: function () {
+    return {
+      protocol: '',
+      couchusername: '',
+      couchpassword: '',
+      couchurl: '',
+    }
+  },
+  computed: mapState({
+    configRemote: (state) => state.configRemote,
+  }),
+
+  methods: {
+    updateRemote(protocol, couchusername, couchpassword, couchurl) {
+      // console.log(protocol, couchusername, couchpassword, couchurl)
+      this.$store.dispatch('updateRemote', {
+        protocol,
+        couchusername,
+        couchpassword,
+        couchurl,
+      })
+    },
+  },
+}
+</script>
+
+<style lang="css" scoped></style>
diff --git a/app/src/views/Organise.vue b/app/src/views/Organise.vue
index 77df0612a1242d2c68da39e199adfe0761627281..0df4a9eec5b683ccee82d841435af4145a34388d 100644
--- a/app/src/views/Organise.vue
+++ b/app/src/views/Organise.vue
@@ -1,87 +1,59 @@
 <template>
   <div>
-    <div class="offline" v-if="clientset && offline">
-      <div ref="container" class="wrapper" v-bind:style="modeContainerStyle">
-        <h2>Offline</h2>
-        <p>
-          nodenogg.in appears to be offline, which means you cant see other data
-          at this stage, as it maybe out of date. Once you reconnect. Your data
-          will sync and the main views will reappear. This maybe down to you or
-          maybe us. If you think it's us let us know.
-        </p>
-        <OffLine
-          v-for="value in myNodes"
-          v-bind:key="value.node_id"
-          v-bind:nodeid="value.node_id"
-          v-bind:nodetext="value.node_text"
-          @edit-true="(e) => editTrue(e)"
-        />
-        <ModeToolbar
-          @offline-triggered="offlineTriggered()"
-          @online-triggered="onlineTriggered()"
-        />
-        <ViewToolbar />
-
-        <!-- <OnBoard v-else @clientAdded="clientAdded()" /> -->
-      </div>
-    </div>
-
-    <div class="online" v-else>
-      <div ref="container" class="wrapper" v-bind:style="modeContainerStyle">
-        <PanZoomContainer
-          v-bind:width="width"
-          v-bind:height="height"
-          v-bind:scale="scale"
-          v-bind:translation="translation"
-        >
-          <div v-if="clientset">
-            <OtherNodeslayer />
-            <NodesLayer @edit-true="(e) => editTrue(e)" />
-            <TipsLayer />
-            <ModeCardorg />
-            <!-- <ConnectionsLayer /> -->
-          </div>
-
-          <div v-else>
-            <OtherNodeslayer />
-            <NodesLayer @edit-true="(e) => editTrue(e)" />
-            <OnBoard
-              @client-added="clientAdded()"
-              @edit-true="(e) => editTrue(e)"
-            />
-            <!-- <ConnectionsLayer /> -->
-          </div>
-          <ScribbleLayer v-bind:drawready="drawready"></ScribbleLayer>
-        </PanZoomContainer>
-        <!-- <ToolBar /> -->
-        <ModeToolbar
-          @offline-triggered="offlineTriggered()"
-          @online-triggered="onlineTriggered()"
-          @upload-added="uploadAdded()"
-          @copy-done="copyDone()"
-          @draw-on="drawOn()"
-          @draw-off="drawOff()"
-        />
-        <ViewToolbar />
-        <UploadLayer
-          v-bind:uploadready="uploadready"
-          v-bind:copyready="copyready"
-          @upload-added="uploadAdded()"
-          @copy-done="copyDone()"
-        />
-      </div>
+    <div ref="container" class="wrapper" v-bind:style="modeContainerStyle">
+      <PanZoomContainer
+        v-bind:width="width"
+        v-bind:height="height"
+        v-bind:scale="scale"
+        v-bind:translation="translation"
+      >
+        <div v-if="clientset">
+          <OtherNodeslayer />
+          <NodesLayer @edit-true="(e) => editTrue(e)" :added="added" />
+          <TipsLayer />
+          <ModeCardorg />
+          <ConnectionsLayer />
+        </div>
+
+        <div v-else>
+          <OtherNodeslayer />
+          <NodesLayer @edit-true="(e) => editTrue(e)" :added="added" />
+          <OnBoard
+            @client-added="clientAdded()"
+            @edit-true="(e) => editTrue(e)"
+          />
+          <ConnectionsLayer />
+        </div>
+        <!-- <ScribbleLayer v-bind:drawready="drawready"></ScribbleLayer> -->
+      </PanZoomContainer>
+      <!-- <ToolBar /> -->
+
+      <ModeToolbar
+        @upload-added="uploadAdded()"
+        @copy-done="copyDone()"
+        @draw-on="drawOn()"
+        @draw-off="drawOff()"
+        @add-node="addNode()"
+      />
+      <ViewToolbar />
+      <UploadLayer
+        class="orgupload"
+        v-bind:uploadready="uploadready"
+        v-bind:copyready="copyready"
+        @upload-added="uploadAdded()"
+        @copy-done="copyDone()"
+      />
     </div>
   </div>
 </template>
 
 <script>
 import PanZoomContainer from '@/experimental/PanZoomContainer'
-// import ConnectionsLayer from '@/components/ConnectionsLayer'
+import ConnectionsLayer from '@/components/ConnectionsLayer'
 import NodesLayer from '@/components/NodesLayer'
-import OffLine from '@/components/OffLine'
 
 // import ToolBar from '@/components/ToolBar'
-import ScribbleLayer from '@/components/ScribbleLayer'
+//import ScribbleLayer from '@/components/ScribbleLayer'
 import UploadLayer from '@/components/UploadLayer'
 import OtherNodeslayer from '@/components/OtherNodeslayer.vue'
 import OnBoard from '@/components/OnBoard.vue'
@@ -94,7 +66,7 @@ import { shortcutsMixin } from '@/components/mixins/shortcutsMixin.js'
 import { mapGetters, mapState } from 'vuex'
 
 export default {
-  name: 'Home',
+  name: 'Organise',
   mixins: [shortcutsMixin],
   data: function () {
     return {
@@ -104,10 +76,12 @@ export default {
       height: 2000,
       clientset: false,
       // listview: false,
-      offline: false,
+      added: true,
+
       uploadready: false,
       copyready: false,
       drawready: false,
+
       // shortcutstate: false,
     }
   },
@@ -136,9 +110,9 @@ export default {
     }),
   },
   mounted() {
-    var e = false
     window.addEventListener('resize', this.handleResize)
     this.handleResize()
+    var e = false
     this.$store.dispatch('shortcutState', e)
   },
 
@@ -192,17 +166,11 @@ export default {
     // This is here to support the shortcuts
     addNode() {
       this.$store.dispatch('addNode')
+      this.added = !this.added
     },
     selectMode(mode) {
       this.$store.commit('ui/setMode', mode)
     },
-
-    offlineTriggered() {
-      this.offline = true
-    },
-    onlineTriggered() {
-      this.offline = false
-    },
   },
   components: {
     ModeToolbar,
@@ -212,12 +180,12 @@ export default {
     // SelectionLayer,
     NodesLayer,
     OtherNodeslayer,
-    // ConnectionsLayer,
+    ConnectionsLayer,
     OnBoard,
     // ToolBar,
-    OffLine,
+
     UploadLayer,
-    ScribbleLayer,
+    // ScribbleLayer,
     TipsLayer,
     ModeCardorg,
   },
@@ -231,4 +199,29 @@ export default {
   margin: 0px;
   position: relative;
 }
+.orgupload {
+}
+
+.a {
+  fill: #333;
+  stroke: #707070;
+}
+.b {
+  fill: #fff;
+  stroke: #333;
+}
+.b,
+.c {
+  stroke-width: 7px;
+}
+.c,
+.e {
+  fill: none;
+}
+.c {
+  stroke: #2d9cdb;
+}
+.d {
+  stroke: none;
+}
 </style>