diff --git a/frontend/README.md b/frontend/README.md
index 58beeaccd87e230076cab531b8f418f40b6d1aeb..b87cb00449efa5b6131f56b7e45cc63eddf37373 100644
--- a/frontend/README.md
+++ b/frontend/README.md
@@ -9,10 +9,10 @@ In the project directory, you can run:
 ### `npm start`
 
 Runs the app in the development mode.\
-Open [http://localhost:3000](http://localhost:3000) to view it in your browser.
+Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
 
-The page will reload when you make changes.\
-You may also see any lint errors in the console.
+The page will reload if you make edits.\
+You will also see any lint errors in the console.
 
 ### `npm test`
 
@@ -31,40 +31,16 @@ See the section about [deployment](https://facebook.github.io/create-react-app/d
 
 ### `npm run eject`
 
-**Note: this is a one-way operation. Once you `eject`, you can't go back!**
+**Note: this is a one-way operation. Once you `eject`, you can’t go back!**
 
-If you aren't satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
+If you aren’t satisfied with the build tool and configuration choices, you can `eject` at any time. This command will remove the single build dependency from your project.
 
-Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you're on your own.
+Instead, it will copy all the configuration files and the transitive dependencies (webpack, Babel, ESLint, etc) right into your project so you have full control over them. All of the commands except `eject` will still work, but they will point to the copied scripts so you can tweak them. At this point you’re on your own.
 
-You don't have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn't feel obligated to use this feature. However we understand that this tool wouldn't be useful if you couldn't customize it when you are ready for it.
+You don’t have to ever use `eject`. The curated feature set is suitable for small and middle deployments, and you shouldn’t feel obligated to use this feature. However we understand that this tool wouldn’t be useful if you couldn’t customize it when you are ready for it.
 
 ## Learn More
 
 You can learn more in the [Create React App documentation](https://facebook.github.io/create-react-app/docs/getting-started).
 
 To learn React, check out the [React documentation](https://reactjs.org/).
-
-### Code Splitting
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/code-splitting](https://facebook.github.io/create-react-app/docs/code-splitting)
-
-### Analyzing the Bundle Size
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size](https://facebook.github.io/create-react-app/docs/analyzing-the-bundle-size)
-
-### Making a Progressive Web App
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app](https://facebook.github.io/create-react-app/docs/making-a-progressive-web-app)
-
-### Advanced Configuration
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/advanced-configuration](https://facebook.github.io/create-react-app/docs/advanced-configuration)
-
-### Deployment
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/deployment](https://facebook.github.io/create-react-app/docs/deployment)
-
-### `npm run build` fails to minify
-
-This section has moved here: [https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify](https://facebook.github.io/create-react-app/docs/troubleshooting#npm-run-build-fails-to-minify)
diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 9d8c48303823a7c7911706a076a4ac4f60c0302e..0b093b4c20e49cedbc672f4ab62da1bd120f4a71 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -8,13 +8,23 @@
       "name": "frontend",
       "version": "0.1.0",
       "dependencies": {
+        "@clientio/rappid": "file:rappid.tgz",
         "@testing-library/jest-dom": "^5.16.5",
         "@testing-library/react": "^13.4.0",
         "@testing-library/user-event": "^13.5.0",
+        "@types/jest": "^27.5.2",
+        "@types/node": "^16.18.12",
+        "@types/react": "^18.0.27",
+        "@types/react-dom": "^18.0.10",
         "react": "^18.2.0",
         "react-dom": "^18.2.0",
         "react-scripts": "5.0.1",
+        "typescript": "^4.9.5",
         "web-vitals": "^2.1.4"
+      },
+      "devDependencies": {
+        "@types/backbone": "^1.4.15",
+        "@types/jquery": "^3.5.16"
       }
     },
     "node_modules/@adobe/css-tools": {
@@ -1854,6 +1864,27 @@
       "resolved": "https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
       "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="
     },
+    "node_modules/@clientio/rappid": {
+      "name": "rappid",
+      "version": "3.6.3",
+      "resolved": "file:rappid.tgz",
+      "integrity": "sha512-uqPqhJ8H+4HOCRZrRXWxSnBy2W9BoPolCmNpvi3YpBt51wVgUSIqNbRrj0KToMRmuU80UqBaYWpaDDMMXb5BIA==",
+      "license": "SEE LICENSE IN LICENSE.txt",
+      "dependencies": {
+        "@types/backbone": "~1.4.13",
+        "@types/dagre": "~0.7.44",
+        "@types/graphlib": "~2.1.8",
+        "@types/jquery": "~3.5.5",
+        "@types/lodash": "~4.14.170",
+        "backbone": "~1.4.1",
+        "canvg-rappid": "~1.0.3",
+        "dagre": "~0.8.5",
+        "graphlib": "~2.1.8",
+        "jointjs": "~3.6.4",
+        "jquery": "~3.6.0",
+        "lodash": "~4.17.21"
+      }
+    },
     "node_modules/@csstools/normalize.css": {
       "version": "12.0.0",
       "resolved": "https://registry.npmmirror.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz",
@@ -2417,25 +2448,6 @@
         "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
       }
     },
-    "node_modules/@jest/expect-utils": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/@jest/expect-utils/-/expect-utils-29.4.2.tgz",
-      "integrity": "sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==",
-      "dependencies": {
-        "jest-get-type": "^29.4.2"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@jest/expect-utils/node_modules/jest-get-type": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.4.2.tgz",
-      "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==",
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
     "node_modules/@jest/fake-timers": {
       "version": "27.5.1",
       "resolved": "https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
@@ -3483,6 +3495,15 @@
         "@babel/types": "^7.3.0"
       }
     },
+    "node_modules/@types/backbone": {
+      "version": "1.4.15",
+      "resolved": "https://registry.npmmirror.com/@types/backbone/-/backbone-1.4.15.tgz",
+      "integrity": "sha512-WWeKtYlsIMtDyLbbhkb96taJMEbfQBnuz7yw1u0pkphCOtksemoWhIXhK74VRCY9hbjnsH3rsJu2uUiFtnsEYg==",
+      "dependencies": {
+        "@types/jquery": "*",
+        "@types/underscore": "*"
+      }
+    },
     "node_modules/@types/body-parser": {
       "version": "1.19.2",
       "resolved": "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.2.tgz",
@@ -3517,6 +3538,11 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/dagre": {
+      "version": "0.7.48",
+      "resolved": "https://registry.npmmirror.com/@types/dagre/-/dagre-0.7.48.tgz",
+      "integrity": "sha512-rF3yXSwHIrDxEkN6edCE4TXknb5YSEpiXfLaspw1I08grC49ZFuAVGOQCmZGIuLUGoFgcqGlUFBL/XrpgYpQgw=="
+    },
     "node_modules/@types/eslint": {
       "version": "8.21.0",
       "resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-8.21.0.tgz",
@@ -3569,6 +3595,11 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmmirror.com/@types/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-8nbbyD3zABRA9ePoBgAl2ym8cIwKQXTfv1gaIRTdY99yEOCaHfmjBeRp+BIemS8NtOqoWK7mfzWxjNrxLK3T5w=="
+    },
     "node_modules/@types/html-minifier-terser": {
       "version": "6.1.0",
       "resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@@ -3604,230 +3635,20 @@
       }
     },
     "node_modules/@types/jest": {
-      "version": "29.4.0",
-      "resolved": "https://registry.npmmirror.com/@types/jest/-/jest-29.4.0.tgz",
-      "integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==",
-      "dependencies": {
-        "expect": "^29.0.0",
-        "pretty-format": "^29.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/@jest/schemas": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.4.2.tgz",
-      "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==",
-      "dependencies": {
-        "@sinclair/typebox": "^0.25.16"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/@jest/types": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/@jest/types/-/types-29.4.2.tgz",
-      "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==",
-      "dependencies": {
-        "@jest/schemas": "^29.4.2",
-        "@types/istanbul-lib-coverage": "^2.0.0",
-        "@types/istanbul-reports": "^3.0.0",
-        "@types/node": "*",
-        "@types/yargs": "^17.0.8",
-        "chalk": "^4.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/@sinclair/typebox": {
-      "version": "0.25.21",
-      "resolved": "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.25.21.tgz",
-      "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g=="
-    },
-    "node_modules/@types/jest/node_modules/@types/yargs": {
-      "version": "17.0.22",
-      "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.22.tgz",
-      "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==",
-      "dependencies": {
-        "@types/yargs-parser": "*"
-      }
-    },
-    "node_modules/@types/jest/node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@types/jest/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@types/jest/node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
-    },
-    "node_modules/@types/jest/node_modules/diff-sequences": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.4.2.tgz",
-      "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw==",
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/expect": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/expect/-/expect-29.4.2.tgz",
-      "integrity": "sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==",
-      "dependencies": {
-        "@jest/expect-utils": "^29.4.2",
-        "jest-get-type": "^29.4.2",
-        "jest-matcher-utils": "^29.4.2",
-        "jest-message-util": "^29.4.2",
-        "jest-util": "^29.4.2"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/@types/jest/node_modules/jest-diff": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/jest-diff/-/jest-diff-29.4.2.tgz",
-      "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==",
+      "version": "27.5.2",
+      "resolved": "https://registry.npmmirror.com/@types/jest/-/jest-27.5.2.tgz",
+      "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==",
       "dependencies": {
-        "chalk": "^4.0.0",
-        "diff-sequences": "^29.4.2",
-        "jest-get-type": "^29.4.2",
-        "pretty-format": "^29.4.2"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/jest-get-type": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.4.2.tgz",
-      "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg==",
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
+        "jest-matcher-utils": "^27.0.0",
+        "pretty-format": "^27.0.0"
       }
     },
-    "node_modules/@types/jest/node_modules/jest-matcher-utils": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz",
-      "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==",
+    "node_modules/@types/jquery": {
+      "version": "3.5.16",
+      "resolved": "https://registry.npmmirror.com/@types/jquery/-/jquery-3.5.16.tgz",
+      "integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==",
       "dependencies": {
-        "chalk": "^4.0.0",
-        "jest-diff": "^29.4.2",
-        "jest-get-type": "^29.4.2",
-        "pretty-format": "^29.4.2"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/jest-message-util": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-29.4.2.tgz",
-      "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==",
-      "dependencies": {
-        "@babel/code-frame": "^7.12.13",
-        "@jest/types": "^29.4.2",
-        "@types/stack-utils": "^2.0.0",
-        "chalk": "^4.0.0",
-        "graceful-fs": "^4.2.9",
-        "micromatch": "^4.0.4",
-        "pretty-format": "^29.4.2",
-        "slash": "^3.0.0",
-        "stack-utils": "^2.0.3"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/jest-util": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/jest-util/-/jest-util-29.4.2.tgz",
-      "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==",
-      "dependencies": {
-        "@jest/types": "^29.4.2",
-        "@types/node": "*",
-        "chalk": "^4.0.0",
-        "ci-info": "^3.2.0",
-        "graceful-fs": "^4.2.9",
-        "picomatch": "^2.2.3"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/pretty-format": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-29.4.2.tgz",
-      "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==",
-      "dependencies": {
-        "@jest/schemas": "^29.4.2",
-        "ansi-styles": "^5.0.0",
-        "react-is": "^18.0.0"
-      },
-      "engines": {
-        "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
-      }
-    },
-    "node_modules/@types/jest/node_modules/pretty-format/node_modules/ansi-styles": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz",
-      "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/@types/jest/node_modules/react-is": {
-      "version": "18.2.0",
-      "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz",
-      "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
-    },
-    "node_modules/@types/jest/node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
+        "@types/sizzle": "*"
       }
     },
     "node_modules/@types/json-schema": {
@@ -3840,15 +3661,20 @@
       "resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz",
       "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
     },
+    "node_modules/@types/lodash": {
+      "version": "4.14.191",
+      "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.191.tgz",
+      "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
+    },
     "node_modules/@types/mime": {
       "version": "3.0.1",
       "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-3.0.1.tgz",
       "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
     },
     "node_modules/@types/node": {
-      "version": "18.13.0",
-      "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.13.0.tgz",
-      "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg=="
+      "version": "16.18.12",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-16.18.12.tgz",
+      "integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw=="
     },
     "node_modules/@types/parse-json": {
       "version": "4.0.0",
@@ -3938,6 +3764,11 @@
         "@types/node": "*"
       }
     },
+    "node_modules/@types/sizzle": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/@types/sizzle/-/sizzle-2.3.3.tgz",
+      "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ=="
+    },
     "node_modules/@types/sockjs": {
       "version": "0.3.33",
       "resolved": "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.33.tgz",
@@ -3964,6 +3795,11 @@
       "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.2.tgz",
       "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg=="
     },
+    "node_modules/@types/underscore": {
+      "version": "1.11.4",
+      "resolved": "https://registry.npmmirror.com/@types/underscore/-/underscore-1.11.4.tgz",
+      "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg=="
+    },
     "node_modules/@types/ws": {
       "version": "8.5.4",
       "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.5.4.tgz",
@@ -4984,6 +4820,14 @@
         "babel-plugin-transform-react-remove-prop-types": "^0.4.24"
       }
     },
+    "node_modules/backbone": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/backbone/-/backbone-1.4.1.tgz",
+      "integrity": "sha512-ADy1ztN074YkWbHi8ojJVFe3vAanO/lrzMGZWUClIP7oDD/Pjy2vrASraUP+2EVCfIiTtCW4FChVow01XneivA==",
+      "dependencies": {
+        "underscore": ">=1.8.3"
+      }
+    },
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -5229,6 +5073,15 @@
       "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz",
       "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w=="
     },
+    "node_modules/canvg-rappid": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/canvg-rappid/-/canvg-rappid-1.0.3.tgz",
+      "integrity": "sha512-Eje+Ckt/EZmVGuYYM/bgKz8C92AtjuYQoy4aafA4Zl9i995bfCTybdBt4T6kSUzguV5V1IY/wSvYKmmuqDJjUw==",
+      "dependencies": {
+        "rgbcolor": "0.0.4",
+        "stackblur": "^1.0.0"
+      }
+    },
     "node_modules/case-sensitive-paths-webpack-plugin": {
       "version": "2.4.0",
       "resolved": "https://registry.npmmirror.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
@@ -5952,6 +5805,15 @@
       "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.1.tgz",
       "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
     },
+    "node_modules/dagre": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmmirror.com/dagre/-/dagre-0.8.5.tgz",
+      "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
+      "dependencies": {
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      }
+    },
     "node_modules/damerau-levenshtein": {
       "version": "1.0.8",
       "resolved": "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -8008,6 +7870,14 @@
       "resolved": "https://registry.npmmirror.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
       "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ=="
     },
+    "node_modules/graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmmirror.com/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
+      "dependencies": {
+        "lodash": "^4.17.15"
+      }
+    },
     "node_modules/gzip-size": {
       "version": "6.0.0",
       "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz",
@@ -10715,6 +10585,23 @@
         "node": ">=10"
       }
     },
+    "node_modules/jointjs": {
+      "version": "3.6.5",
+      "resolved": "https://registry.npmmirror.com/jointjs/-/jointjs-3.6.5.tgz",
+      "integrity": "sha512-TvTMDDcZPvIisMNnr0/pJpi2mc2bSkVDFC+3nFopxP/7oWXZnhKJtXGBIwWEVtKwWzQgGW3NeMGiqjSe7mZtFw==",
+      "dependencies": {
+        "backbone": "~1.4.1",
+        "dagre": "~0.8.5",
+        "graphlib": "~2.1.8",
+        "jquery": "~3.6.1",
+        "lodash": "~4.17.21"
+      }
+    },
+    "node_modules/jquery": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmmirror.com/jquery/-/jquery-3.6.3.tgz",
+      "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg=="
+    },
     "node_modules/js-sdsl": {
       "version": "4.3.0",
       "resolved": "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.3.0.tgz",
@@ -13666,6 +13553,14 @@
         "node": ">=0.10.0"
       }
     },
+    "node_modules/rgbcolor": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmmirror.com/rgbcolor/-/rgbcolor-0.0.4.tgz",
+      "integrity": "sha512-fG8I3S9oe435NsIa3bAcavWhr0ioN+m5qRfjidB1vn5rU2D69Ain0N0aiTtXggZJnsV7Fo/poCI0NnkkhtcRgw==",
+      "engines": {
+        "node": ">= 0.8.15"
+      }
+    },
     "node_modules/rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
@@ -14213,6 +14108,11 @@
         "node": ">=8"
       }
     },
+    "node_modules/stackblur": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/stackblur/-/stackblur-1.0.0.tgz",
+      "integrity": "sha512-K92JX8alrs0pTox5U2arVBqB8tJmak9dh9i4Xausy94TnnGMdLfTn7P2Dp/NOzlmxvEs7lDzeryo8YqOy0BHRQ=="
+    },
     "node_modules/stackframe": {
       "version": "1.3.4",
       "resolved": "https://registry.npmmirror.com/stackframe/-/stackframe-1.3.4.tgz",
@@ -14904,7 +14804,6 @@
       "version": "4.9.5",
       "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz",
       "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "peer": true,
       "bin": {
         "tsc": "bin/tsc",
         "tsserver": "bin/tsserver"
@@ -14924,6 +14823,11 @@
         "which-boxed-primitive": "^1.0.2"
       }
     },
+    "node_modules/underscore": {
+      "version": "1.13.6",
+      "resolved": "https://registry.npmmirror.com/underscore/-/underscore-1.13.6.tgz",
+      "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
+    },
     "node_modules/unicode-canonical-property-names-ecmascript": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
@@ -17236,6 +17140,24 @@
       "resolved": "https://registry.npmmirror.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz",
       "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw=="
     },
+    "@clientio/rappid": {
+      "version": "file:rappid.tgz",
+      "integrity": "sha512-uqPqhJ8H+4HOCRZrRXWxSnBy2W9BoPolCmNpvi3YpBt51wVgUSIqNbRrj0KToMRmuU80UqBaYWpaDDMMXb5BIA==",
+      "requires": {
+        "@types/backbone": "~1.4.13",
+        "@types/dagre": "~0.7.44",
+        "@types/graphlib": "~2.1.8",
+        "@types/jquery": "~3.5.5",
+        "@types/lodash": "~4.14.170",
+        "backbone": "~1.4.1",
+        "canvg-rappid": "~1.0.3",
+        "dagre": "~0.8.5",
+        "graphlib": "~2.1.8",
+        "jointjs": "~3.6.4",
+        "jquery": "~3.6.0",
+        "lodash": "~4.17.21"
+      }
+    },
     "@csstools/normalize.css": {
       "version": "12.0.0",
       "resolved": "https://registry.npmmirror.com/@csstools/normalize.css/-/normalize.css-12.0.0.tgz",
@@ -17632,21 +17554,6 @@
         "jest-mock": "^27.5.1"
       }
     },
-    "@jest/expect-utils": {
-      "version": "29.4.2",
-      "resolved": "https://registry.npmmirror.com/@jest/expect-utils/-/expect-utils-29.4.2.tgz",
-      "integrity": "sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA==",
-      "requires": {
-        "jest-get-type": "^29.4.2"
-      },
-      "dependencies": {
-        "jest-get-type": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.4.2.tgz",
-          "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg=="
-        }
-      }
-    },
     "@jest/fake-timers": {
       "version": "27.5.1",
       "resolved": "https://registry.npmmirror.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz",
@@ -18435,6 +18342,15 @@
         "@babel/types": "^7.3.0"
       }
     },
+    "@types/backbone": {
+      "version": "1.4.15",
+      "resolved": "https://registry.npmmirror.com/@types/backbone/-/backbone-1.4.15.tgz",
+      "integrity": "sha512-WWeKtYlsIMtDyLbbhkb96taJMEbfQBnuz7yw1u0pkphCOtksemoWhIXhK74VRCY9hbjnsH3rsJu2uUiFtnsEYg==",
+      "requires": {
+        "@types/jquery": "*",
+        "@types/underscore": "*"
+      }
+    },
     "@types/body-parser": {
       "version": "1.19.2",
       "resolved": "https://registry.npmmirror.com/@types/body-parser/-/body-parser-1.19.2.tgz",
@@ -18469,6 +18385,11 @@
         "@types/node": "*"
       }
     },
+    "@types/dagre": {
+      "version": "0.7.48",
+      "resolved": "https://registry.npmmirror.com/@types/dagre/-/dagre-0.7.48.tgz",
+      "integrity": "sha512-rF3yXSwHIrDxEkN6edCE4TXknb5YSEpiXfLaspw1I08grC49ZFuAVGOQCmZGIuLUGoFgcqGlUFBL/XrpgYpQgw=="
+    },
     "@types/eslint": {
       "version": "8.21.0",
       "resolved": "https://registry.npmmirror.com/@types/eslint/-/eslint-8.21.0.tgz",
@@ -18521,6 +18442,11 @@
         "@types/node": "*"
       }
     },
+    "@types/graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmmirror.com/@types/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-8nbbyD3zABRA9ePoBgAl2ym8cIwKQXTfv1gaIRTdY99yEOCaHfmjBeRp+BIemS8NtOqoWK7mfzWxjNrxLK3T5w=="
+    },
     "@types/html-minifier-terser": {
       "version": "6.1.0",
       "resolved": "https://registry.npmmirror.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz",
@@ -18556,186 +18482,20 @@
       }
     },
     "@types/jest": {
-      "version": "29.4.0",
-      "resolved": "https://registry.npmmirror.com/@types/jest/-/jest-29.4.0.tgz",
-      "integrity": "sha512-VaywcGQ9tPorCX/Jkkni7RWGFfI11whqzs8dvxF41P17Z+z872thvEvlIbznjPJ02kl1HMX3LmLOonsj2n7HeQ==",
+      "version": "27.5.2",
+      "resolved": "https://registry.npmmirror.com/@types/jest/-/jest-27.5.2.tgz",
+      "integrity": "sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA==",
       "requires": {
-        "expect": "^29.0.0",
-        "pretty-format": "^29.0.0"
-      },
-      "dependencies": {
-        "@jest/schemas": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/@jest/schemas/-/schemas-29.4.2.tgz",
-          "integrity": "sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g==",
-          "requires": {
-            "@sinclair/typebox": "^0.25.16"
-          }
-        },
-        "@jest/types": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/@jest/types/-/types-29.4.2.tgz",
-          "integrity": "sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw==",
-          "requires": {
-            "@jest/schemas": "^29.4.2",
-            "@types/istanbul-lib-coverage": "^2.0.0",
-            "@types/istanbul-reports": "^3.0.0",
-            "@types/node": "*",
-            "@types/yargs": "^17.0.8",
-            "chalk": "^4.0.0"
-          }
-        },
-        "@sinclair/typebox": {
-          "version": "0.25.21",
-          "resolved": "https://registry.npmmirror.com/@sinclair/typebox/-/typebox-0.25.21.tgz",
-          "integrity": "sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g=="
-        },
-        "@types/yargs": {
-          "version": "17.0.22",
-          "resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-17.0.22.tgz",
-          "integrity": "sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g==",
-          "requires": {
-            "@types/yargs-parser": "*"
-          }
-        },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
-          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
-          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
-        },
-        "diff-sequences": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/diff-sequences/-/diff-sequences-29.4.2.tgz",
-          "integrity": "sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw=="
-        },
-        "expect": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/expect/-/expect-29.4.2.tgz",
-          "integrity": "sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ==",
-          "requires": {
-            "@jest/expect-utils": "^29.4.2",
-            "jest-get-type": "^29.4.2",
-            "jest-matcher-utils": "^29.4.2",
-            "jest-message-util": "^29.4.2",
-            "jest-util": "^29.4.2"
-          }
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
-          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
-        },
-        "jest-diff": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/jest-diff/-/jest-diff-29.4.2.tgz",
-          "integrity": "sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g==",
-          "requires": {
-            "chalk": "^4.0.0",
-            "diff-sequences": "^29.4.2",
-            "jest-get-type": "^29.4.2",
-            "pretty-format": "^29.4.2"
-          }
-        },
-        "jest-get-type": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/jest-get-type/-/jest-get-type-29.4.2.tgz",
-          "integrity": "sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg=="
-        },
-        "jest-matcher-utils": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz",
-          "integrity": "sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg==",
-          "requires": {
-            "chalk": "^4.0.0",
-            "jest-diff": "^29.4.2",
-            "jest-get-type": "^29.4.2",
-            "pretty-format": "^29.4.2"
-          }
-        },
-        "jest-message-util": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/jest-message-util/-/jest-message-util-29.4.2.tgz",
-          "integrity": "sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g==",
-          "requires": {
-            "@babel/code-frame": "^7.12.13",
-            "@jest/types": "^29.4.2",
-            "@types/stack-utils": "^2.0.0",
-            "chalk": "^4.0.0",
-            "graceful-fs": "^4.2.9",
-            "micromatch": "^4.0.4",
-            "pretty-format": "^29.4.2",
-            "slash": "^3.0.0",
-            "stack-utils": "^2.0.3"
-          }
-        },
-        "jest-util": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/jest-util/-/jest-util-29.4.2.tgz",
-          "integrity": "sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g==",
-          "requires": {
-            "@jest/types": "^29.4.2",
-            "@types/node": "*",
-            "chalk": "^4.0.0",
-            "ci-info": "^3.2.0",
-            "graceful-fs": "^4.2.9",
-            "picomatch": "^2.2.3"
-          }
-        },
-        "pretty-format": {
-          "version": "29.4.2",
-          "resolved": "https://registry.npmmirror.com/pretty-format/-/pretty-format-29.4.2.tgz",
-          "integrity": "sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg==",
-          "requires": {
-            "@jest/schemas": "^29.4.2",
-            "ansi-styles": "^5.0.0",
-            "react-is": "^18.0.0"
-          },
-          "dependencies": {
-            "ansi-styles": {
-              "version": "5.2.0",
-              "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-5.2.0.tgz",
-              "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="
-            }
-          }
-        },
-        "react-is": {
-          "version": "18.2.0",
-          "resolved": "https://registry.npmmirror.com/react-is/-/react-is-18.2.0.tgz",
-          "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        }
+        "jest-matcher-utils": "^27.0.0",
+        "pretty-format": "^27.0.0"
+      }
+    },
+    "@types/jquery": {
+      "version": "3.5.16",
+      "resolved": "https://registry.npmmirror.com/@types/jquery/-/jquery-3.5.16.tgz",
+      "integrity": "sha512-bsI7y4ZgeMkmpG9OM710RRzDFp+w4P1RGiIt30C1mSBT+ExCleeh4HObwgArnDFELmRrOpXgSYN9VF1hj+f1lw==",
+      "requires": {
+        "@types/sizzle": "*"
       }
     },
     "@types/json-schema": {
@@ -18748,15 +18508,20 @@
       "resolved": "https://registry.npmmirror.com/@types/json5/-/json5-0.0.29.tgz",
       "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
     },
+    "@types/lodash": {
+      "version": "4.14.191",
+      "resolved": "https://registry.npmmirror.com/@types/lodash/-/lodash-4.14.191.tgz",
+      "integrity": "sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ=="
+    },
     "@types/mime": {
       "version": "3.0.1",
       "resolved": "https://registry.npmmirror.com/@types/mime/-/mime-3.0.1.tgz",
       "integrity": "sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA=="
     },
     "@types/node": {
-      "version": "18.13.0",
-      "resolved": "https://registry.npmmirror.com/@types/node/-/node-18.13.0.tgz",
-      "integrity": "sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg=="
+      "version": "16.18.12",
+      "resolved": "https://registry.npmmirror.com/@types/node/-/node-16.18.12.tgz",
+      "integrity": "sha512-vzLe5NaNMjIE3mcddFVGlAXN1LEWueUsMsOJWaT6wWMJGyljHAWHznqfnKUQWGzu7TLPrGvWdNAsvQYW+C0xtw=="
     },
     "@types/parse-json": {
       "version": "4.0.0",
@@ -18846,6 +18611,11 @@
         "@types/node": "*"
       }
     },
+    "@types/sizzle": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmmirror.com/@types/sizzle/-/sizzle-2.3.3.tgz",
+      "integrity": "sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ=="
+    },
     "@types/sockjs": {
       "version": "0.3.33",
       "resolved": "https://registry.npmmirror.com/@types/sockjs/-/sockjs-0.3.33.tgz",
@@ -18872,6 +18642,11 @@
       "resolved": "https://registry.npmmirror.com/@types/trusted-types/-/trusted-types-2.0.2.tgz",
       "integrity": "sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg=="
     },
+    "@types/underscore": {
+      "version": "1.11.4",
+      "resolved": "https://registry.npmmirror.com/@types/underscore/-/underscore-1.11.4.tgz",
+      "integrity": "sha512-uO4CD2ELOjw8tasUrAhvnn2W4A0ZECOvMjCivJr4gA9pGgjv+qxKWY9GLTMVEK8ej85BxQOocUyE7hImmSQYcg=="
+    },
     "@types/ws": {
       "version": "8.5.4",
       "resolved": "https://registry.npmmirror.com/@types/ws/-/ws-8.5.4.tgz",
@@ -19675,6 +19450,14 @@
         "babel-plugin-transform-react-remove-prop-types": "^0.4.24"
       }
     },
+    "backbone": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmmirror.com/backbone/-/backbone-1.4.1.tgz",
+      "integrity": "sha512-ADy1ztN074YkWbHi8ojJVFe3vAanO/lrzMGZWUClIP7oDD/Pjy2vrASraUP+2EVCfIiTtCW4FChVow01XneivA==",
+      "requires": {
+        "underscore": ">=1.8.3"
+      }
+    },
     "balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -19879,6 +19662,15 @@
       "resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz",
       "integrity": "sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w=="
     },
+    "canvg-rappid": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmmirror.com/canvg-rappid/-/canvg-rappid-1.0.3.tgz",
+      "integrity": "sha512-Eje+Ckt/EZmVGuYYM/bgKz8C92AtjuYQoy4aafA4Zl9i995bfCTybdBt4T6kSUzguV5V1IY/wSvYKmmuqDJjUw==",
+      "requires": {
+        "rgbcolor": "0.0.4",
+        "stackblur": "^1.0.0"
+      }
+    },
     "case-sensitive-paths-webpack-plugin": {
       "version": "2.4.0",
       "resolved": "https://registry.npmmirror.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz",
@@ -20432,6 +20224,15 @@
       "resolved": "https://registry.npmmirror.com/csstype/-/csstype-3.1.1.tgz",
       "integrity": "sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw=="
     },
+    "dagre": {
+      "version": "0.8.5",
+      "resolved": "https://registry.npmmirror.com/dagre/-/dagre-0.8.5.tgz",
+      "integrity": "sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==",
+      "requires": {
+        "graphlib": "^2.1.8",
+        "lodash": "^4.17.15"
+      }
+    },
     "damerau-levenshtein": {
       "version": "1.0.8",
       "resolved": "https://registry.npmmirror.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz",
@@ -22041,6 +21842,14 @@
       "resolved": "https://registry.npmmirror.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
       "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ=="
     },
+    "graphlib": {
+      "version": "2.1.8",
+      "resolved": "https://registry.npmmirror.com/graphlib/-/graphlib-2.1.8.tgz",
+      "integrity": "sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==",
+      "requires": {
+        "lodash": "^4.17.15"
+      }
+    },
     "gzip-size": {
       "version": "6.0.0",
       "resolved": "https://registry.npmmirror.com/gzip-size/-/gzip-size-6.0.0.tgz",
@@ -24145,6 +23954,23 @@
         }
       }
     },
+    "jointjs": {
+      "version": "3.6.5",
+      "resolved": "https://registry.npmmirror.com/jointjs/-/jointjs-3.6.5.tgz",
+      "integrity": "sha512-TvTMDDcZPvIisMNnr0/pJpi2mc2bSkVDFC+3nFopxP/7oWXZnhKJtXGBIwWEVtKwWzQgGW3NeMGiqjSe7mZtFw==",
+      "requires": {
+        "backbone": "~1.4.1",
+        "dagre": "~0.8.5",
+        "graphlib": "~2.1.8",
+        "jquery": "~3.6.1",
+        "lodash": "~4.17.21"
+      }
+    },
+    "jquery": {
+      "version": "3.6.3",
+      "resolved": "https://registry.npmmirror.com/jquery/-/jquery-3.6.3.tgz",
+      "integrity": "sha512-bZ5Sy3YzKo9Fyc8wH2iIQK4JImJ6R0GWI9kL1/k7Z91ZBNgkRXE6U0JfHIizZbort8ZunhSI3jw9I6253ahKfg=="
+    },
     "js-sdsl": {
       "version": "4.3.0",
       "resolved": "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.3.0.tgz",
@@ -26267,6 +26093,11 @@
       "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.0.4.tgz",
       "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
     },
+    "rgbcolor": {
+      "version": "0.0.4",
+      "resolved": "https://registry.npmmirror.com/rgbcolor/-/rgbcolor-0.0.4.tgz",
+      "integrity": "sha512-fG8I3S9oe435NsIa3bAcavWhr0ioN+m5qRfjidB1vn5rU2D69Ain0N0aiTtXggZJnsV7Fo/poCI0NnkkhtcRgw=="
+    },
     "rimraf": {
       "version": "3.0.2",
       "resolved": "https://registry.npmmirror.com/rimraf/-/rimraf-3.0.2.tgz",
@@ -26711,6 +26542,11 @@
         }
       }
     },
+    "stackblur": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmmirror.com/stackblur/-/stackblur-1.0.0.tgz",
+      "integrity": "sha512-K92JX8alrs0pTox5U2arVBqB8tJmak9dh9i4Xausy94TnnGMdLfTn7P2Dp/NOzlmxvEs7lDzeryo8YqOy0BHRQ=="
+    },
     "stackframe": {
       "version": "1.3.4",
       "resolved": "https://registry.npmmirror.com/stackframe/-/stackframe-1.3.4.tgz",
@@ -27259,8 +27095,7 @@
     "typescript": {
       "version": "4.9.5",
       "resolved": "https://registry.npmmirror.com/typescript/-/typescript-4.9.5.tgz",
-      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
-      "peer": true
+      "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g=="
     },
     "unbox-primitive": {
       "version": "1.0.2",
@@ -27273,6 +27108,11 @@
         "which-boxed-primitive": "^1.0.2"
       }
     },
+    "underscore": {
+      "version": "1.13.6",
+      "resolved": "https://registry.npmmirror.com/underscore/-/underscore-1.13.6.tgz",
+      "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A=="
+    },
     "unicode-canonical-property-names-ecmascript": {
       "version": "2.0.0",
       "resolved": "https://registry.npmmirror.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index 149bb8e9ed9226fab7d50e325dbcd4518f08c2e7..4d14a28e2505284c99c96c2f7cc3c5479844d8e8 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -3,12 +3,18 @@
   "version": "0.1.0",
   "private": true,
   "dependencies": {
+    "@clientio/rappid": "file:rappid.tgz",
     "@testing-library/jest-dom": "^5.16.5",
     "@testing-library/react": "^13.4.0",
     "@testing-library/user-event": "^13.5.0",
+    "@types/jest": "^27.5.2",
+    "@types/node": "^16.18.12",
+    "@types/react": "^18.0.27",
+    "@types/react-dom": "^18.0.10",
     "react": "^18.2.0",
     "react-dom": "^18.2.0",
     "react-scripts": "5.0.1",
+    "typescript": "^4.9.5",
     "web-vitals": "^2.1.4"
   },
   "scripts": {
@@ -34,5 +40,9 @@
       "last 1 firefox version",
       "last 1 safari version"
     ]
+  },
+  "devDependencies": {
+    "@types/backbone": "^1.4.15",
+    "@types/jquery": "^3.5.16"
   }
 }
diff --git a/frontend/rappid.tgz b/frontend/rappid.tgz
new file mode 100644
index 0000000000000000000000000000000000000000..f48ae7800d9b358aa3fc812bb0ee90933ac8abfb
Binary files /dev/null and b/frontend/rappid.tgz differ
diff --git a/frontend/src/App.js b/frontend/src/App.js
deleted file mode 100644
index 37845757234ccb68531c10cf7a2ffc589c47e342..0000000000000000000000000000000000000000
--- a/frontend/src/App.js
+++ /dev/null
@@ -1,25 +0,0 @@
-import logo from './logo.svg';
-import './App.css';
-
-function App() {
-  return (
-    <div className="App">
-      <header className="App-header">
-        <img src={logo} className="App-logo" alt="logo" />
-        <p>
-          Edit <code>src/App.js</code> and save to reload.
-        </p>
-        <a
-          className="App-link"
-          href="https://reactjs.org"
-          target="_blank"
-          rel="noopener noreferrer"
-        >
-          Learn React
-        </a>
-      </header>
-    </div>
-  );
-}
-
-export default App;
diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx
new file mode 100644
index 0000000000000000000000000000000000000000..4939f83368c3a7b811e043a8d34415a3a46fd5aa
--- /dev/null
+++ b/frontend/src/App.tsx
@@ -0,0 +1,80 @@
+import React, { useEffect, useRef } from 'react';
+import { dia, shapes, ui } from '@clientio/rappid';
+import './styles/App.css'; 
+
+function App() {
+    const canvas: any = useRef(null);
+
+    useEffect(() => {
+        const graph = new dia.Graph({}, { cellNamespace: shapes });
+        const paper = new dia.Paper({
+            model: graph,
+            background: {
+                color: '#F8F9FA',
+            },
+            frozen: true,
+            async: true,
+            sorting: dia.Paper.sorting.APPROX,
+            cellViewNamespace: shapes
+        });
+
+        const scroller = new ui.PaperScroller({
+            paper,
+            autoResizePaper: true,
+            cursor: 'grab'
+        });
+
+        canvas.current.appendChild(scroller.el);
+        scroller.render().center();
+
+        const rect = new shapes.standard.Rectangle({
+            position: { x: 100, y: 100 },
+            size: { width: 100, height: 50 },
+            attrs: {
+                label: {
+                    text: 'Hello World'
+                }
+            }
+        });
+
+        graph.addCell(rect);
+        paper.unfreeze();
+
+        return () => {
+            scroller.remove();
+            paper.remove();
+        };
+
+  }, []);
+
+  return (
+    //   <head>
+    //     <meta charset="utf-8">
+    //     <link rel="stylesheet" href="../../build/package/rappid.css" />
+    //   <link rel="stylesheet" href="./style.css" />
+    //   </head>
+    // <body>
+    //   <div class="toolbar-container"></div>
+    //   <div class="stencil-container"></div>
+    //   <div class="paper-container"></div>
+    //   <div class="inspector-container"></div>
+  
+    //   {/* <!-- JointJS+ dependencies: --> */}
+    //   <script src="../../node_modules/jquery/dist/jquery.js"></script>
+    //   <script src="../../node_modules/lodash/lodash.js"></script>
+    //   <script src="../../node_modules/backbone/backbone.js"></script>
+    //   <script src="../../node_modules/graphlib/dist/graphlib.core.js"></script>
+    //   <script src="../../node_modules/dagre/dist/dagre.core.js"></script>
+  
+    //   <script src="../../build/package/rappid.js"></script>
+    //   <script src="./index.js"></script>
+    // </body>
+    <body>
+        <div className="canvas" ref={canvas}/>
+
+    </body>
+    
+  );
+}
+
+export default App;
diff --git a/frontend/src/index.js b/frontend/src/index.tsx
similarity index 70%
rename from frontend/src/index.js
rename to frontend/src/index.tsx
index d563c0fb10ba0e42724b21286eb546ee4e5734fc..745cc26f470525204c7ad79187721f012daeda74 100644
--- a/frontend/src/index.js
+++ b/frontend/src/index.tsx
@@ -1,10 +1,12 @@
 import React from 'react';
 import ReactDOM from 'react-dom/client';
-import './index.css';
+import './styles/index.css';
 import App from './App';
-import reportWebVitals from './reportWebVitals';
+import reportWebVitals from './scripts/reportWebVitals';
 
-const root = ReactDOM.createRoot(document.getElementById('root'));
+const root = ReactDOM.createRoot(
+  document.getElementById('root') as HTMLElement
+);
 root.render(
   <React.StrictMode>
     <App />
diff --git a/frontend/src/react-app-env.d.ts b/frontend/src/react-app-env.d.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6431bc5fc6b2c932dfe5d0418fc667b86c18b9fc
--- /dev/null
+++ b/frontend/src/react-app-env.d.ts
@@ -0,0 +1 @@
+/// <reference types="react-scripts" />
diff --git a/frontend/src/reportWebVitals.js b/frontend/src/scripts/reportWebVitals.ts
similarity index 75%
rename from frontend/src/reportWebVitals.js
rename to frontend/src/scripts/reportWebVitals.ts
index 5253d3ad9e6be6690549cb255f5952337b02401d..49a2a16e0fbc7636ee16bf907257a5282b856493 100644
--- a/frontend/src/reportWebVitals.js
+++ b/frontend/src/scripts/reportWebVitals.ts
@@ -1,4 +1,6 @@
-const reportWebVitals = onPerfEntry => {
+import { ReportHandler } from 'web-vitals';
+
+const reportWebVitals = (onPerfEntry?: ReportHandler) => {
   if (onPerfEntry && onPerfEntry instanceof Function) {
     import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
       getCLS(onPerfEntry);
diff --git a/frontend/src/logo.svg b/frontend/src/static/logo.svg
similarity index 100%
rename from frontend/src/logo.svg
rename to frontend/src/static/logo.svg
diff --git a/frontend/src/App.css b/frontend/src/styles/App.css
similarity index 73%
rename from frontend/src/App.css
rename to frontend/src/styles/App.css
index 74b5e053450a48a6bdb4d71aad648e7af821975c..03c5fb420e1650397ed17ee1718323244682e65b 100644
--- a/frontend/src/App.css
+++ b/frontend/src/styles/App.css
@@ -1,4 +1,20 @@
-.App {
+@import "~@clientio/rappid/rappid.css";
+
+#root {
+    height: 100vh;
+    width: 100vw;
+}
+
+.canvas {
+    width: 100%;
+    height: 100%;
+}
+
+.joint-paper {
+    border: 1px solid #A0A0A0;
+}
+
+/* .App {
   text-align: center;
 }
 
@@ -35,4 +51,4 @@
   to {
     transform: rotate(360deg);
   }
-}
+} */
diff --git a/frontend/src/index.css b/frontend/src/styles/index.css
similarity index 100%
rename from frontend/src/index.css
rename to frontend/src/styles/index.css
diff --git a/frontend/src/App.test.js b/frontend/src/tests/App.test.tsx
similarity index 80%
rename from frontend/src/App.test.js
rename to frontend/src/tests/App.test.tsx
index 1f03afeece5ac28064fa3c73a29215037465f789..59f2994d756f0899463ac4ce69e6ad412c9f5d64 100644
--- a/frontend/src/App.test.js
+++ b/frontend/src/tests/App.test.tsx
@@ -1,5 +1,6 @@
+import React from 'react';
 import { render, screen } from '@testing-library/react';
-import App from './App';
+import App from '../App';
 
 test('renders learn react link', () => {
   render(<App />);
diff --git a/frontend/src/setupTests.js b/frontend/src/tests/setupTests.ts
similarity index 100%
rename from frontend/src/setupTests.js
rename to frontend/src/tests/setupTests.ts
diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json
new file mode 100644
index 0000000000000000000000000000000000000000..f4892ea2bfae2947ccf59ce7cf27efc3adeedde2
--- /dev/null
+++ b/frontend/tsconfig.json
@@ -0,0 +1,26 @@
+{
+  "compilerOptions": {
+    "target": "es5",
+    "lib": [
+      "dom",
+      "dom.iterable",
+      "esnext"
+    ],
+    "allowJs": true,
+    "skipLibCheck": true,
+    "esModuleInterop": true,
+    "allowSyntheticDefaultImports": true,
+    "strict": true,
+    "forceConsistentCasingInFileNames": true,
+    "noFallthroughCasesInSwitch": true,
+    "module": "esnext",
+    "moduleResolution": "node",
+    "resolveJsonModule": true,
+    "isolatedModules": true,
+    "noEmit": true,
+    "jsx": "react"
+  },
+  "include": [
+    "src", "../index.js"
+  ]
+}