diff --git a/package-lock.json b/package-lock.json
index 7b956bf..3f02893 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,43 +1,47 @@
 {
   "name": "gas-fire",
-  "version": "1.1.1",
+  "version": "2.0.0",
   "lockfileVersion": 2,
   "requires": true,
   "packages": {
     "": {
       "name": "gas-fire",
-      "version": "1.1.1",
+      "version": "2.0.0",
       "license": "MIT",
       "workspaces": [
         "client",
         "server"
       ],
       "dependencies": {
-        "@babel/preset-react": "^7.23.3",
         "@emotion/react": "^11.11.1",
         "@emotion/styled": "^11.11.0",
         "@mui/material": "^5.14.17",
-        "gas-types-detailed": "^1.1.2",
-        "gas-webpack-plugin": "^2.5.0",
         "materialize-css": "^1.0.0-rc.2",
+        "papaparse": "^5.4.1",
         "react": "^18.2.0",
-        "react-dom": "^18.2.0"
+        "react-dom": "^18.2.0",
+        "tabulator-tables": "^4.9.3"
       },
       "devDependencies": {
         "@babel/core": "^7.23.3",
         "@babel/preset-env": "^7.23.3",
+        "@babel/preset-react": "^7.23.3",
         "@effortlessmotion/dynamic-cdn-webpack-plugin": "^5.0.1",
         "@effortlessmotion/html-webpack-inline-source-plugin": "^1.0.3",
         "@google/clasp": "^2.4.2",
         "@types/google-apps-script": "^1.0.77",
         "@types/materialize-css": "^1.0.14",
+        "@types/papaparse": "^5.3.11",
         "@types/react": "^18.0.14",
         "@types/react-dom": "^18.2.15",
+        "@types/tabulator-tables": "^4.9.3",
         "babel-loader": "^9.1.3",
         "copy-webpack-plugin": "^11.0.0",
         "cross-env": "^7.0.3",
         "css-loader": "^6.8.1",
         "gas-client": "^1.1.1",
+        "gas-types-detailed": "^1.1.2",
+        "gas-webpack-plugin": "^2.5.0",
         "html-webpack-plugin": "^5.5.3",
         "module-to-cdn": "^3.1.5",
         "style-loader": "^3.3.3",
@@ -53,6 +57,7 @@
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
       "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+      "dev": true,
       "dependencies": {
         "@jridgewell/gen-mapping": "^0.3.0",
         "@jridgewell/trace-mapping": "^0.3.9"
@@ -133,6 +138,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz",
       "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==",
+      "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
@@ -141,6 +147,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz",
       "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==",
+      "dev": true,
       "dependencies": {
         "@ampproject/remapping": "^2.2.0",
         "@babel/code-frame": "^7.22.13",
@@ -169,12 +176,14 @@
     "node_modules/@babel/core/node_modules/convert-source-map": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
-      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
+      "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+      "dev": true
     },
     "node_modules/@babel/generator": {
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz",
       "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==",
+      "dev": true,
       "dependencies": {
         "@babel/types": "^7.23.3",
         "@jridgewell/gen-mapping": "^0.3.2",
@@ -189,6 +198,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
       "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+      "dev": true,
       "dependencies": {
         "@babel/types": "^7.22.5"
       },
@@ -212,6 +222,7 @@
       "version": "7.22.15",
       "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
       "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
+      "dev": true,
       "dependencies": {
         "@babel/compat-data": "^7.22.9",
         "@babel/helper-validator-option": "^7.22.15",
@@ -227,6 +238,7 @@
       "version": "5.1.1",
       "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
       "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+      "dev": true,
       "dependencies": {
         "yallist": "^3.0.2"
       }
@@ -234,7 +246,8 @@
     "node_modules/@babel/helper-compilation-targets/node_modules/yallist": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+      "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+      "dev": true
     },
     "node_modules/@babel/helper-create-class-features-plugin": {
       "version": "7.22.15",
@@ -296,6 +309,7 @@
       "version": "7.22.20",
       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
       "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+      "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
@@ -304,6 +318,7 @@
       "version": "7.23.0",
       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
       "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+      "dev": true,
       "dependencies": {
         "@babel/template": "^7.22.15",
         "@babel/types": "^7.23.0"
@@ -316,6 +331,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
       "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+      "dev": true,
       "dependencies": {
         "@babel/types": "^7.22.5"
       },
@@ -350,6 +366,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
       "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+      "dev": true,
       "dependencies": {
         "@babel/helper-environment-visitor": "^7.22.20",
         "@babel/helper-module-imports": "^7.22.15",
@@ -380,6 +397,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
       "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+      "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
@@ -422,6 +440,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
       "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+      "dev": true,
       "dependencies": {
         "@babel/types": "^7.22.5"
       },
@@ -445,6 +464,7 @@
       "version": "7.22.6",
       "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
       "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+      "dev": true,
       "dependencies": {
         "@babel/types": "^7.22.5"
       },
@@ -472,6 +492,7 @@
       "version": "7.22.15",
       "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
       "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
+      "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
@@ -494,6 +515,7 @@
       "version": "7.23.2",
       "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz",
       "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==",
+      "dev": true,
       "dependencies": {
         "@babel/template": "^7.22.15",
         "@babel/traverse": "^7.23.2",
@@ -576,6 +598,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz",
       "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==",
+      "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
       },
@@ -764,6 +787,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz",
       "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==",
+      "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
       },
@@ -1498,6 +1522,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz",
       "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==",
+      "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5"
       },
@@ -1512,6 +1537,7 @@
       "version": "7.22.15",
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz",
       "integrity": "sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==",
+      "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
         "@babel/helper-module-imports": "^7.22.15",
@@ -1530,6 +1556,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz",
       "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==",
+      "dev": true,
       "dependencies": {
         "@babel/plugin-transform-react-jsx": "^7.22.5"
       },
@@ -1544,6 +1571,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz",
       "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==",
+      "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -1837,6 +1865,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz",
       "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==",
+      "dev": true,
       "dependencies": {
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-validator-option": "^7.22.15",
@@ -1873,6 +1902,7 @@
       "version": "7.22.15",
       "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
       "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+      "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.22.13",
         "@babel/parser": "^7.22.15",
@@ -1886,6 +1916,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz",
       "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==",
+      "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.22.13",
         "@babel/generator": "^7.23.3",
@@ -2526,6 +2557,7 @@
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
       "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+      "dev": true,
       "dependencies": {
         "@jridgewell/set-array": "^1.0.1",
         "@jridgewell/sourcemap-codec": "^1.4.10",
@@ -2539,6 +2571,7 @@
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
       "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+      "dev": true,
       "engines": {
         "node": ">=6.0.0"
       }
@@ -2547,6 +2580,7 @@
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
       "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "dev": true,
       "engines": {
         "node": ">=6.0.0"
       }
@@ -2564,12 +2598,14 @@
     "node_modules/@jridgewell/sourcemap-codec": {
       "version": "1.4.15",
       "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
-      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+      "dev": true
     },
     "node_modules/@jridgewell/trace-mapping": {
       "version": "0.3.19",
       "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
       "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+      "dev": true,
       "dependencies": {
         "@jridgewell/resolve-uri": "^3.1.0",
         "@jridgewell/sourcemap-codec": "^1.4.14"
@@ -2971,6 +3007,15 @@
       "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
       "dev": true
     },
+    "node_modules/@types/papaparse": {
+      "version": "5.3.11",
+      "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.11.tgz",
+      "integrity": "sha512-ISil0lMkpRDrBTKRPnUgVb5IqxWwj19gWBrX/ROk3pbkkslBN3URa713r/BSfAUj+w9gTPg3S3f45aMToVfh1w==",
+      "dev": true,
+      "dependencies": {
+        "@types/node": "*"
+      }
+    },
     "node_modules/@types/parse-json": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
@@ -3028,6 +3073,12 @@
       "integrity": "sha512-m04Om5Gz6kbjUwAQ7XJJQ30OdEFsSmAVsvn4NYwcTRyMVpKKa1aPuESw1n2CxS5fYkOQv3nHgDKeNa8e76fUkw==",
       "dev": true
     },
+    "node_modules/@types/tabulator-tables": {
+      "version": "4.9.4",
+      "resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-4.9.4.tgz",
+      "integrity": "sha512-yx8lZb15X+RP5a0ih6Fw5AaD/1m62+35ULMcm3TxQaheiH76lyBr2Zs20Wf7KNWsIGy1nwMmbjkCt6vjMczJQQ==",
+      "dev": true
+    },
     "node_modules/@webassemblyjs/ast": {
       "version": "1.11.6",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@@ -3569,7 +3620,8 @@
     "node_modules/balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "dev": true
     },
     "node_modules/base64-js": {
       "version": "1.5.1",
@@ -3652,6 +3704,7 @@
       "version": "4.22.1",
       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
       "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+      "dev": true,
       "funding": [
         {
           "type": "opencollective",
@@ -3778,6 +3831,7 @@
       "version": "1.0.30001561",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz",
       "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==",
+      "dev": true,
       "funding": [
         {
           "type": "opencollective",
@@ -4351,6 +4405,7 @@
       "version": "4.3.3",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
       "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+      "dev": true,
       "dependencies": {
         "ms": "2.1.2"
       },
@@ -4393,7 +4448,8 @@
     "node_modules/deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
+      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+      "dev": true
     },
     "node_modules/defaults": {
       "version": "1.0.3",
@@ -4562,7 +4618,8 @@
     "node_modules/electron-to-chromium": {
       "version": "1.4.581",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.581.tgz",
-      "integrity": "sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw=="
+      "integrity": "sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==",
+      "dev": true
     },
     "node_modules/emoji-regex": {
       "version": "8.0.0",
@@ -4631,6 +4688,7 @@
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
       "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true,
       "engines": {
         "node": ">=6"
       }
@@ -4647,6 +4705,7 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
       "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+      "dev": true,
       "dependencies": {
         "esprima": "^4.0.1",
         "estraverse": "^5.2.0",
@@ -4668,6 +4727,7 @@
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
       "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
       "engines": {
         "node": ">=4.0"
       }
@@ -4676,6 +4736,7 @@
       "version": "0.6.1",
       "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
       "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+      "dev": true,
       "optional": true,
       "engines": {
         "node": ">=0.10.0"
@@ -4698,6 +4759,7 @@
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
       "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true,
       "bin": {
         "esparse": "bin/esparse.js",
         "esvalidate": "bin/esvalidate.js"
@@ -4710,6 +4772,7 @@
       "version": "5.8.4",
       "resolved": "https://registry.npmjs.org/esprima-next/-/esprima-next-5.8.4.tgz",
       "integrity": "sha512-8nYVZ4ioIH4Msjb/XmhnBdz5WRRBaYqevKa1cv9nGJdCehMbzZCPNEEnqfLCZVetUVrUPEcb5IYyu1GG4hFqgg==",
+      "dev": true,
       "bin": {
         "esparse": "bin/esparse.js",
         "esvalidate": "bin/esvalidate.js"
@@ -4752,6 +4815,7 @@
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
       "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -4825,7 +4889,8 @@
     "node_modules/fast-levenshtein": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
+      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+      "dev": true
     },
     "node_modules/fast-text-encoding": {
       "version": "1.0.6",
@@ -5092,6 +5157,7 @@
       "version": "2.5.1",
       "resolved": "https://registry.npmjs.org/gas-entry-generator/-/gas-entry-generator-2.5.1.tgz",
       "integrity": "sha512-grd9Qvbm8AgyoDlUCKsbLpPVBFQm+Giv/7xmcINLSQfCELIxg6Cb/C2bOYfqZFjWhsGYwU2ZrWy3mt2XtWjHKA==",
+      "dev": true,
       "dependencies": {
         "escodegen": "2.0.0",
         "esprima-next": "^5.8.3",
@@ -5102,6 +5168,7 @@
       "version": "5.3.0",
       "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
       "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+      "dev": true,
       "engines": {
         "node": ">=4.0"
       }
@@ -5109,12 +5176,14 @@
     "node_modules/gas-types-detailed": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/gas-types-detailed/-/gas-types-detailed-1.1.2.tgz",
-      "integrity": "sha512-QqGcuS6Ikuvq8JpxcfZpEuygx8+COzmQYBYpcx6icEbXylCGNhyVcZb1xNnREWrU1PLg5luMvcpSXEUZJYMCbA=="
+      "integrity": "sha512-QqGcuS6Ikuvq8JpxcfZpEuygx8+COzmQYBYpcx6icEbXylCGNhyVcZb1xNnREWrU1PLg5luMvcpSXEUZJYMCbA==",
+      "dev": true
     },
     "node_modules/gas-webpack-plugin": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/gas-webpack-plugin/-/gas-webpack-plugin-2.5.0.tgz",
       "integrity": "sha512-qk5lOacJYY9Hqa2X/VTys+MfsYZawraGbmQRyQ34qak8BN/kHBxXt2Bav+sJ+Bf4bYRZc/Z7gKrNiAr1OWGmAA==",
+      "dev": true,
       "dependencies": {
         "gas-entry-generator": "2.5.1",
         "minimatch": "^7.4.2",
@@ -5126,6 +5195,7 @@
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
       "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+      "dev": true,
       "dependencies": {
         "balanced-match": "^1.0.0"
       }
@@ -5134,6 +5204,7 @@
       "version": "7.4.6",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz",
       "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==",
+      "dev": true,
       "dependencies": {
         "brace-expansion": "^2.0.1"
       },
@@ -5177,6 +5248,7 @@
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
       "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true,
       "engines": {
         "node": ">=6.9.0"
       }
@@ -5233,6 +5305,7 @@
       "version": "11.12.0",
       "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
       "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true,
       "engines": {
         "node": ">=4"
       }
@@ -6048,6 +6121,7 @@
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
       "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "dev": true,
       "bin": {
         "jsesc": "bin/jsesc"
       },
@@ -6085,6 +6159,7 @@
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
       "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true,
       "bin": {
         "json5": "lib/cli.js"
       },
@@ -6147,6 +6222,7 @@
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
       "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+      "dev": true,
       "dependencies": {
         "prelude-ls": "~1.1.2",
         "type-check": "~0.3.2"
@@ -6392,7 +6468,8 @@
     "node_modules/ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
     },
     "node_modules/multimatch": {
       "version": "5.0.0",
@@ -6485,7 +6562,8 @@
     "node_modules/node-releases": {
       "version": "2.0.13",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
-      "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
+      "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+      "dev": true
     },
     "node_modules/normalize-newline": {
       "version": "4.1.0",
@@ -6627,6 +6705,7 @@
       "version": "0.8.3",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
       "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "dev": true,
       "dependencies": {
         "deep-is": "~0.1.3",
         "fast-levenshtein": "~2.0.6",
@@ -6846,6 +6925,11 @@
         "node": ">=6"
       }
     },
+    "node_modules/papaparse": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz",
+      "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw=="
+    },
     "node_modules/param-case": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
@@ -6928,7 +7012,8 @@
     "node_modules/picocolors": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "dev": true
     },
     "node_modules/picomatch": {
       "version": "2.3.1",
@@ -7116,6 +7201,7 @@
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
       "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+      "dev": true,
       "engines": {
         "node": ">= 0.8.0"
       }
@@ -7725,6 +7811,7 @@
       "version": "6.3.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
       "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true,
       "bin": {
         "semver": "bin/semver.js"
       }
@@ -7816,6 +7903,7 @@
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
       "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true,
       "engines": {
         "node": ">=8"
       }
@@ -8088,6 +8176,11 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
+    "node_modules/tabulator-tables": {
+      "version": "4.9.3",
+      "resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-4.9.3.tgz",
+      "integrity": "sha512-iwwQqAEGGxlgrBpcmJJvMJrfjGLcCXOB3AOb/DGkXqBy1YKoYA36hIl7qXGp6Jo8dSkzFAlDT6pKLZgyhs9OnQ=="
+    },
     "node_modules/tapable": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -8291,6 +8384,7 @@
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
       "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+      "dev": true,
       "dependencies": {
         "prelude-ls": "~1.1.2"
       },
@@ -8377,6 +8471,7 @@
       "version": "1.0.13",
       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
       "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+      "dev": true,
       "funding": [
         {
           "type": "opencollective",
@@ -8605,6 +8700,7 @@
       "version": "3.2.3",
       "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
       "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+      "dev": true,
       "engines": {
         "node": ">=10.13.0"
       }
@@ -8644,6 +8740,7 @@
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
       "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+      "dev": true,
       "engines": {
         "node": ">=0.10.0"
       }
@@ -8686,6 +8783,7 @@
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.1.tgz",
       "integrity": "sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==",
+      "dev": true,
       "requires": {
         "@jridgewell/gen-mapping": "^0.3.0",
         "@jridgewell/trace-mapping": "^0.3.9"
@@ -8749,12 +8847,14 @@
     "@babel/compat-data": {
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.23.3.tgz",
-      "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ=="
+      "integrity": "sha512-BmR4bWbDIoFJmJ9z2cZ8Gmm2MXgEDgjdWgpKmKWUt54UGFJdlj31ECtbaDvCG/qVdG3AQ1SfpZEs01lUFbzLOQ==",
+      "dev": true
     },
     "@babel/core": {
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.23.3.tgz",
       "integrity": "sha512-Jg+msLuNuCJDyBvFv5+OKOUjWMZgd85bKjbICd3zWrKAo+bJ49HJufi7CQE0q0uR8NGyO6xkCACScNqyjHSZew==",
+      "dev": true,
       "requires": {
         "@ampproject/remapping": "^2.2.0",
         "@babel/code-frame": "^7.22.13",
@@ -8776,7 +8876,8 @@
         "convert-source-map": {
           "version": "2.0.0",
           "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
-          "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="
+          "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
+          "dev": true
         }
       }
     },
@@ -8784,6 +8885,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.3.tgz",
       "integrity": "sha512-keeZWAV4LU3tW0qRi19HRpabC/ilM0HRBBzf9/k8FFiG4KVpiv0FIy4hHfLfFQZNhziCTPTmd59zoyv6DNISzg==",
+      "dev": true,
       "requires": {
         "@babel/types": "^7.23.3",
         "@jridgewell/gen-mapping": "^0.3.2",
@@ -8795,6 +8897,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz",
       "integrity": "sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==",
+      "dev": true,
       "requires": {
         "@babel/types": "^7.22.5"
       }
@@ -8812,6 +8915,7 @@
       "version": "7.22.15",
       "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz",
       "integrity": "sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw==",
+      "dev": true,
       "requires": {
         "@babel/compat-data": "^7.22.9",
         "@babel/helper-validator-option": "^7.22.15",
@@ -8824,6 +8928,7 @@
           "version": "5.1.1",
           "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
           "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
+          "dev": true,
           "requires": {
             "yallist": "^3.0.2"
           }
@@ -8831,7 +8936,8 @@
         "yallist": {
           "version": "3.1.1",
           "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
-          "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
+          "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
+          "dev": true
         }
       }
     },
@@ -8879,12 +8985,14 @@
     "@babel/helper-environment-visitor": {
       "version": "7.22.20",
       "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz",
-      "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA=="
+      "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==",
+      "dev": true
     },
     "@babel/helper-function-name": {
       "version": "7.23.0",
       "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz",
       "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==",
+      "dev": true,
       "requires": {
         "@babel/template": "^7.22.15",
         "@babel/types": "^7.23.0"
@@ -8894,6 +9002,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz",
       "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==",
+      "dev": true,
       "requires": {
         "@babel/types": "^7.22.5"
       }
@@ -8919,6 +9028,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz",
       "integrity": "sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==",
+      "dev": true,
       "requires": {
         "@babel/helper-environment-visitor": "^7.22.20",
         "@babel/helper-module-imports": "^7.22.15",
@@ -8939,7 +9049,8 @@
     "@babel/helper-plugin-utils": {
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz",
-      "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg=="
+      "integrity": "sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==",
+      "dev": true
     },
     "@babel/helper-remap-async-to-generator": {
       "version": "7.22.20",
@@ -8967,6 +9078,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz",
       "integrity": "sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==",
+      "dev": true,
       "requires": {
         "@babel/types": "^7.22.5"
       }
@@ -8984,6 +9096,7 @@
       "version": "7.22.6",
       "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz",
       "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==",
+      "dev": true,
       "requires": {
         "@babel/types": "^7.22.5"
       }
@@ -9001,7 +9114,8 @@
     "@babel/helper-validator-option": {
       "version": "7.22.15",
       "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz",
-      "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA=="
+      "integrity": "sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA==",
+      "dev": true
     },
     "@babel/helper-wrap-function": {
       "version": "7.22.20",
@@ -9018,6 +9132,7 @@
       "version": "7.23.2",
       "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.23.2.tgz",
       "integrity": "sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ==",
+      "dev": true,
       "requires": {
         "@babel/template": "^7.22.15",
         "@babel/traverse": "^7.23.2",
@@ -9083,7 +9198,8 @@
     "@babel/parser": {
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.3.tgz",
-      "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw=="
+      "integrity": "sha512-uVsWNvlVsIninV2prNz/3lHCb+5CJ+e+IUBfbjToAHODtfGYLfCFuY4AU7TskI+dAKk+njsPiBjq1gKTvZOBaw==",
+      "dev": true
     },
     "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
       "version": "7.23.3",
@@ -9207,6 +9323,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz",
       "integrity": "sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==",
+      "dev": true,
       "requires": {
         "@babel/helper-plugin-utils": "^7.22.5"
       }
@@ -9677,6 +9794,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz",
       "integrity": "sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw==",
+      "dev": true,
       "requires": {
         "@babel/helper-plugin-utils": "^7.22.5"
       }
@@ -9685,6 +9803,7 @@
       "version": "7.22.15",
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz",
       "integrity": "sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA==",
+      "dev": true,
       "requires": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
         "@babel/helper-module-imports": "^7.22.15",
@@ -9697,6 +9816,7 @@
       "version": "7.22.5",
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz",
       "integrity": "sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A==",
+      "dev": true,
       "requires": {
         "@babel/plugin-transform-react-jsx": "^7.22.5"
       }
@@ -9705,6 +9825,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz",
       "integrity": "sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ==",
+      "dev": true,
       "requires": {
         "@babel/helper-annotate-as-pure": "^7.22.5",
         "@babel/helper-plugin-utils": "^7.22.5"
@@ -9917,6 +10038,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.23.3.tgz",
       "integrity": "sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w==",
+      "dev": true,
       "requires": {
         "@babel/helper-plugin-utils": "^7.22.5",
         "@babel/helper-validator-option": "^7.22.15",
@@ -9944,6 +10066,7 @@
       "version": "7.22.15",
       "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz",
       "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==",
+      "dev": true,
       "requires": {
         "@babel/code-frame": "^7.22.13",
         "@babel/parser": "^7.22.15",
@@ -9954,6 +10077,7 @@
       "version": "7.23.3",
       "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.3.tgz",
       "integrity": "sha512-+K0yF1/9yR0oHdE0StHuEj3uTPzwwbrLGfNOndVJVV2TqA5+j3oljJUb4nmB954FLGjNem976+B+eDuLIjesiQ==",
+      "dev": true,
       "requires": {
         "@babel/code-frame": "^7.22.13",
         "@babel/generator": "^7.23.3",
@@ -10428,6 +10552,7 @@
       "version": "0.3.3",
       "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz",
       "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==",
+      "dev": true,
       "requires": {
         "@jridgewell/set-array": "^1.0.1",
         "@jridgewell/sourcemap-codec": "^1.4.10",
@@ -10437,12 +10562,14 @@
     "@jridgewell/resolve-uri": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz",
-      "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA=="
+      "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==",
+      "dev": true
     },
     "@jridgewell/set-array": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
-      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
+      "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
+      "dev": true
     },
     "@jridgewell/source-map": {
       "version": "0.3.5",
@@ -10457,12 +10584,14 @@
     "@jridgewell/sourcemap-codec": {
       "version": "1.4.15",
       "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz",
-      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="
+      "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==",
+      "dev": true
     },
     "@jridgewell/trace-mapping": {
       "version": "0.3.19",
       "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz",
       "integrity": "sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw==",
+      "dev": true,
       "requires": {
         "@jridgewell/resolve-uri": "^3.1.0",
         "@jridgewell/sourcemap-codec": "^1.4.14"
@@ -10713,6 +10842,15 @@
       "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==",
       "dev": true
     },
+    "@types/papaparse": {
+      "version": "5.3.11",
+      "resolved": "https://registry.npmjs.org/@types/papaparse/-/papaparse-5.3.11.tgz",
+      "integrity": "sha512-ISil0lMkpRDrBTKRPnUgVb5IqxWwj19gWBrX/ROk3pbkkslBN3URa713r/BSfAUj+w9gTPg3S3f45aMToVfh1w==",
+      "dev": true,
+      "requires": {
+        "@types/node": "*"
+      }
+    },
     "@types/parse-json": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
@@ -10770,6 +10908,12 @@
       "integrity": "sha512-m04Om5Gz6kbjUwAQ7XJJQ30OdEFsSmAVsvn4NYwcTRyMVpKKa1aPuESw1n2CxS5fYkOQv3nHgDKeNa8e76fUkw==",
       "dev": true
     },
+    "@types/tabulator-tables": {
+      "version": "4.9.4",
+      "resolved": "https://registry.npmjs.org/@types/tabulator-tables/-/tabulator-tables-4.9.4.tgz",
+      "integrity": "sha512-yx8lZb15X+RP5a0ih6Fw5AaD/1m62+35ULMcm3TxQaheiH76lyBr2Zs20Wf7KNWsIGy1nwMmbjkCt6vjMczJQQ==",
+      "dev": true
+    },
     "@webassemblyjs/ast": {
       "version": "1.11.6",
       "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz",
@@ -11190,7 +11334,8 @@
     "balanced-match": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+      "dev": true
     },
     "base64-js": {
       "version": "1.5.1",
@@ -11250,6 +11395,7 @@
       "version": "4.22.1",
       "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.22.1.tgz",
       "integrity": "sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==",
+      "dev": true,
       "requires": {
         "caniuse-lite": "^1.0.30001541",
         "electron-to-chromium": "^1.4.535",
@@ -11329,7 +11475,8 @@
     "caniuse-lite": {
       "version": "1.0.30001561",
       "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz",
-      "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw=="
+      "integrity": "sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw==",
+      "dev": true
     },
     "cash-dom": {
       "version": "8.1.5",
@@ -11730,6 +11877,7 @@
       "version": "4.3.3",
       "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz",
       "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==",
+      "dev": true,
       "requires": {
         "ms": "2.1.2"
       }
@@ -11754,7 +11902,8 @@
     "deep-is": {
       "version": "0.1.4",
       "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
-      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
+      "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+      "dev": true
     },
     "defaults": {
       "version": "1.0.3",
@@ -11890,7 +12039,8 @@
     "electron-to-chromium": {
       "version": "1.4.581",
       "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.581.tgz",
-      "integrity": "sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw=="
+      "integrity": "sha512-6uhqWBIapTJUxgPTCHH9sqdbxIMPt7oXl0VcAL1kOtlU6aECdcMncCrX5Z7sHQ/invtrC9jUQUef7+HhO8vVFw==",
+      "dev": true
     },
     "emoji-regex": {
       "version": "8.0.0",
@@ -11946,7 +12096,8 @@
     "escalade": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw=="
+      "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+      "dev": true
     },
     "escape-string-regexp": {
       "version": "1.0.5",
@@ -11957,6 +12108,7 @@
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz",
       "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==",
+      "dev": true,
       "requires": {
         "esprima": "^4.0.1",
         "estraverse": "^5.2.0",
@@ -11968,12 +12120,14 @@
         "estraverse": {
           "version": "5.3.0",
           "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
+          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+          "dev": true
         },
         "source-map": {
           "version": "0.6.1",
           "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
           "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+          "dev": true,
           "optional": true
         }
       }
@@ -11991,12 +12145,14 @@
     "esprima": {
       "version": "4.0.1",
       "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="
+      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+      "dev": true
     },
     "esprima-next": {
       "version": "5.8.4",
       "resolved": "https://registry.npmjs.org/esprima-next/-/esprima-next-5.8.4.tgz",
-      "integrity": "sha512-8nYVZ4ioIH4Msjb/XmhnBdz5WRRBaYqevKa1cv9nGJdCehMbzZCPNEEnqfLCZVetUVrUPEcb5IYyu1GG4hFqgg=="
+      "integrity": "sha512-8nYVZ4ioIH4Msjb/XmhnBdz5WRRBaYqevKa1cv9nGJdCehMbzZCPNEEnqfLCZVetUVrUPEcb5IYyu1GG4hFqgg==",
+      "dev": true
     },
     "esrecurse": {
       "version": "4.3.0",
@@ -12024,7 +12180,8 @@
     "esutils": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="
+      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+      "dev": true
     },
     "event-target-shim": {
       "version": "5.0.1",
@@ -12083,7 +12240,8 @@
     "fast-levenshtein": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
-      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw=="
+      "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+      "dev": true
     },
     "fast-text-encoding": {
       "version": "1.0.6",
@@ -12265,6 +12423,7 @@
       "version": "2.5.1",
       "resolved": "https://registry.npmjs.org/gas-entry-generator/-/gas-entry-generator-2.5.1.tgz",
       "integrity": "sha512-grd9Qvbm8AgyoDlUCKsbLpPVBFQm+Giv/7xmcINLSQfCELIxg6Cb/C2bOYfqZFjWhsGYwU2ZrWy3mt2XtWjHKA==",
+      "dev": true,
       "requires": {
         "escodegen": "2.0.0",
         "esprima-next": "^5.8.3",
@@ -12274,19 +12433,22 @@
         "estraverse": {
           "version": "5.3.0",
           "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="
+          "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+          "dev": true
         }
       }
     },
     "gas-types-detailed": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/gas-types-detailed/-/gas-types-detailed-1.1.2.tgz",
-      "integrity": "sha512-QqGcuS6Ikuvq8JpxcfZpEuygx8+COzmQYBYpcx6icEbXylCGNhyVcZb1xNnREWrU1PLg5luMvcpSXEUZJYMCbA=="
+      "integrity": "sha512-QqGcuS6Ikuvq8JpxcfZpEuygx8+COzmQYBYpcx6icEbXylCGNhyVcZb1xNnREWrU1PLg5luMvcpSXEUZJYMCbA==",
+      "dev": true
     },
     "gas-webpack-plugin": {
       "version": "2.5.0",
       "resolved": "https://registry.npmjs.org/gas-webpack-plugin/-/gas-webpack-plugin-2.5.0.tgz",
       "integrity": "sha512-qk5lOacJYY9Hqa2X/VTys+MfsYZawraGbmQRyQ34qak8BN/kHBxXt2Bav+sJ+Bf4bYRZc/Z7gKrNiAr1OWGmAA==",
+      "dev": true,
       "requires": {
         "gas-entry-generator": "2.5.1",
         "minimatch": "^7.4.2",
@@ -12298,6 +12460,7 @@
           "version": "2.0.1",
           "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
           "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+          "dev": true,
           "requires": {
             "balanced-match": "^1.0.0"
           }
@@ -12306,6 +12469,7 @@
           "version": "7.4.6",
           "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz",
           "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==",
+          "dev": true,
           "requires": {
             "brace-expansion": "^2.0.1"
           }
@@ -12338,7 +12502,8 @@
     "gensync": {
       "version": "1.0.0-beta.2",
       "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
-      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="
+      "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
+      "dev": true
     },
     "get-intrinsic": {
       "version": "1.2.2",
@@ -12379,7 +12544,8 @@
     "globals": {
       "version": "11.12.0",
       "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
-      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="
+      "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+      "dev": true
     },
     "globby": {
       "version": "13.2.2",
@@ -12959,7 +13125,8 @@
     "jsesc": {
       "version": "2.5.2",
       "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
-      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA=="
+      "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+      "dev": true
     },
     "json-bigint": {
       "version": "1.0.0",
@@ -12990,7 +13157,8 @@
     "json5": {
       "version": "2.2.3",
       "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
-      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="
+      "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
+      "dev": true
     },
     "jsonfile": {
       "version": "6.1.0",
@@ -13042,6 +13210,7 @@
       "version": "0.3.0",
       "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
       "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==",
+      "dev": true,
       "requires": {
         "prelude-ls": "~1.1.2",
         "type-check": "~0.3.2"
@@ -13223,7 +13392,8 @@
     "ms": {
       "version": "2.1.2",
       "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+      "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+      "dev": true
     },
     "multimatch": {
       "version": "5.0.0",
@@ -13284,7 +13454,8 @@
     "node-releases": {
       "version": "2.0.13",
       "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.13.tgz",
-      "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ=="
+      "integrity": "sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==",
+      "dev": true
     },
     "normalize-newline": {
       "version": "4.1.0",
@@ -13383,6 +13554,7 @@
       "version": "0.8.3",
       "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz",
       "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==",
+      "dev": true,
       "requires": {
         "deep-is": "~0.1.3",
         "fast-levenshtein": "~2.0.6",
@@ -13531,6 +13703,11 @@
       "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
       "dev": true
     },
+    "papaparse": {
+      "version": "5.4.1",
+      "resolved": "https://registry.npmjs.org/papaparse/-/papaparse-5.4.1.tgz",
+      "integrity": "sha512-HipMsgJkZu8br23pW15uvo6sib6wne/4woLZPlFf3rpDyMe9ywEXUsuD7+6K9PRkJlVT51j/sCOYDKGGS3ZJrw=="
+    },
     "param-case": {
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz",
@@ -13595,7 +13772,8 @@
     "picocolors": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
-      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="
+      "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
+      "dev": true
     },
     "picomatch": {
       "version": "2.3.1",
@@ -13717,7 +13895,8 @@
     "prelude-ls": {
       "version": "1.1.2",
       "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
-      "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w=="
+      "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==",
+      "dev": true
     },
     "prepend-http": {
       "version": "3.0.1",
@@ -14166,7 +14345,8 @@
     "semver": {
       "version": "6.3.1",
       "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
-      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="
+      "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
+      "dev": true
     },
     "serialize-javascript": {
       "version": "6.0.1",
@@ -14239,7 +14419,8 @@
     "slash": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
+      "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+      "dev": true
     },
     "slice-ansi": {
       "version": "5.0.0",
@@ -14431,6 +14612,11 @@
       "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
       "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
     },
+    "tabulator-tables": {
+      "version": "4.9.3",
+      "resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-4.9.3.tgz",
+      "integrity": "sha512-iwwQqAEGGxlgrBpcmJJvMJrfjGLcCXOB3AOb/DGkXqBy1YKoYA36hIl7qXGp6Jo8dSkzFAlDT6pKLZgyhs9OnQ=="
+    },
     "tapable": {
       "version": "2.2.1",
       "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz",
@@ -14569,6 +14755,7 @@
       "version": "0.3.2",
       "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
       "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==",
+      "dev": true,
       "requires": {
         "prelude-ls": "~1.1.2"
       }
@@ -14624,6 +14811,7 @@
       "version": "1.0.13",
       "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
       "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
+      "dev": true,
       "requires": {
         "escalade": "^3.1.1",
         "picocolors": "^1.0.0"
@@ -14782,7 +14970,8 @@
     "webpack-sources": {
       "version": "3.2.3",
       "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz",
-      "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w=="
+      "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==",
+      "dev": true
     },
     "whatwg-url": {
       "version": "5.0.0",
@@ -14812,7 +15001,8 @@
     "word-wrap": {
       "version": "1.2.5",
       "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
-      "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="
+      "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+      "dev": true
     },
     "wrappy": {
       "version": "1.0.2",
diff --git a/package.json b/package.json
index 9d02634..ba6c158 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "gas-fire",
-  "version": "1.1.1",
+  "version": "2.0.0",
   "author": "Melle Dijkstra",
   "description": "Google App Script utilities to automate the FIRE google sheet",
   "license": "MIT",
@@ -23,31 +23,35 @@
     "start": "npm run deploy:dev && npm run serve"
   },
   "dependencies": {
-    "@babel/preset-react": "^7.23.3",
     "@emotion/react": "^11.11.1",
     "@emotion/styled": "^11.11.0",
     "@mui/material": "^5.14.17",
-    "gas-types-detailed": "^1.1.2",
-    "gas-webpack-plugin": "^2.5.0",
     "materialize-css": "^1.0.0-rc.2",
+    "papaparse": "^5.4.1",
     "react": "^18.2.0",
-    "react-dom": "^18.2.0"
+    "react-dom": "^18.2.0",
+    "tabulator-tables": "^4.9.3"
   },
   "devDependencies": {
     "@babel/core": "^7.23.3",
     "@babel/preset-env": "^7.23.3",
+    "@babel/preset-react": "^7.23.3",
     "@effortlessmotion/dynamic-cdn-webpack-plugin": "^5.0.1",
     "@effortlessmotion/html-webpack-inline-source-plugin": "^1.0.3",
     "@google/clasp": "^2.4.2",
     "@types/google-apps-script": "^1.0.77",
     "@types/materialize-css": "^1.0.14",
+    "@types/papaparse": "^5.3.11",
     "@types/react": "^18.0.14",
     "@types/react-dom": "^18.2.15",
+    "@types/tabulator-tables": "^4.9.3",
     "babel-loader": "^9.1.3",
     "copy-webpack-plugin": "^11.0.0",
     "cross-env": "^7.0.3",
     "css-loader": "^6.8.1",
     "gas-client": "^1.1.1",
+    "gas-types-detailed": "^1.1.2",
+    "gas-webpack-plugin": "^2.5.0",
     "html-webpack-plugin": "^5.5.3",
     "module-to-cdn": "^3.1.5",
     "style-loader": "^3.3.3",
diff --git a/src/client/import-dialog/components/App.tsx b/src/client/import-dialog/components/App.tsx
index c123985..46203d2 100644
--- a/src/client/import-dialog/components/App.tsx
+++ b/src/client/import-dialog/components/App.tsx
@@ -3,8 +3,11 @@ import { serverFunctions } from '../../utils/serverFunctions';
 import { StrategyOption, Table } from '../../../server/types';
 import { isAllowedFile } from './utils';
 import M from 'materialize-css';
+import Tabulator from 'tabulator-tables';
+import Papa from 'papaparse';
 
-// import materialize css as it is needed for the Form
+// import css from external packages
+import 'tabulator-tables/dist/css/tabulator.min.css';
 import 'materialize-css/dist/css/materialize.min.css';
 
 export const App = () => {
@@ -15,22 +18,15 @@ export const App = () => {
     useState<StrategyOption>(null);
   const [statusText, setStatusText] = useState<string>('-');
 
-  const tabulatorRef = useRef<unknown>();
-  const fileRef = useRef<HTMLInputElement>();
+  const tabulatorRef = useRef<Tabulator>();
+  const tabulatorContainer = useRef<HTMLDivElement>(null);
 
+  const [importFile, setImportFile] = useState<File>(null);
+
+  // This useEffect is here to initialize some parts of the webpage
   useEffect(() => {
     M.FormSelect.init(document.querySelectorAll('select'));
 
-    // @ts-ignore
-    tabulatorRef.current = new Tabulator('#import-table', {
-      autoColumns: true,
-      // layout: "fitColumns",
-      autoColumnsDefinitions: (definitions) => {
-        definitions.forEach((definition) => (definition['headerSort'] = false));
-        return definitions;
-      },
-    });
-
     serverFunctions
       .getStrategyOptions()
       .then((serverStrategyOptions) => {
@@ -39,10 +35,20 @@ export const App = () => {
       .catch(onFailure);
   }, []);
 
+  useEffect(() => {
+    tabulatorRef.current = new Tabulator(tabulatorContainer.current, {
+      autoColumns: true,
+      layout: 'fitColumns',
+      autoColumnsDefinitions: (definitions) => {
+        definitions.forEach((definition) => (definition['headerSort'] = false));
+        return definitions;
+      },
+    });
+  }, [tabulatorContainer.current]);
+
   const onSuccess = (response) => {
     if ('data' in response) setTableData(csvToJson(response.data));
     setStatusText(`Action successful! ${response.message}`);
-    // @ts-ignore
     google.script.host.close();
   };
 
@@ -55,49 +61,29 @@ export const App = () => {
       .catch(onFailure);
   };
 
-  const getFile = () => {
-    if (fileRef?.current?.files.length < 1) return;
-    return fileRef.current.files[0];
-  };
-
   const onParseError = (error) => {
     console.error(error);
     alert(`Parsing error: ${error}`);
   };
 
-  function handleOnFileSelect() {
-    const file = getFile();
-    if (!file || !isAllowedFile(file.type)) return;
-    triggerPreview();
-  }
-
   const handleFormSubmit = (event: React.FormEvent) => {
     event.preventDefault();
-    const file = getFile();
-    if (!file || !isAllowedFile(file.type)) return;
-    // UPDATE WITH CORRECT TYPES / PACKAGE
-    // @ts-ignore
-    Papa.parse(file, {
+    if (!importFile || !isAllowedFile(importFile.type)) return;
+    Papa.parse<string[]>(importFile, {
       complete: (result) => submitDataToServer(result.data, selectedStrategy),
       error: onParseError,
     });
   };
 
   const triggerPreview = () => {
-    const fileInput = getFile();
-
-    if (!selectedStrategy || !fileInput) {
+    if (!selectedStrategy || !importFile) {
       setStatusText('File and strategy need to be set to generate preview!');
       return;
     }
 
-    // UPDATE WITH CORRECT TYPES / PACKAGE
-    // @ts-ignore
     tabulatorRef?.current?.clearData();
     setStatusText('Data is being processed...');
-    // UPDATE WITH CORRECT TYPES / PACKAGE
-    // @ts-ignore
-    Papa.parse(fileInput, {
+    Papa.parse<string[]>(importFile, {
       complete: (result) => generatePreview(result.data, selectedStrategy),
       error: onParseError,
     });
@@ -112,7 +98,8 @@ export const App = () => {
 
   const onGeneratePreviewSuccess = ({ result, newBalance }) => {
     console.log('received from server', { result, newBalance });
-    setStatusText(`Your new balance: ${newBalance}`);
+    // setStatusText(`Your new balance: ${newBalance}`);
+    setStatusText('Import preview set');
     setPreview(result);
   };
 
@@ -129,8 +116,6 @@ export const App = () => {
 
   const setTableData = (data) => {
     try {
-      // UPDATE WITH CORRECT TYPES / PACKAGE
-      // @ts-ignore
       tabulatorRef.current.setData(data);
     } catch (error) {
       alert(`Could not set table data (error: ${error})`);
@@ -153,10 +138,12 @@ export const App = () => {
                 <span>Select File</span>
                 <input
                   required
-                  ref={fileRef}
                   id="csvFiles"
                   type="file"
-                  onChange={handleOnFileSelect}
+                  onChange={(event) => {
+                    setImportFile(event.target.files[0]);
+                    triggerPreview();
+                  }}
                   accept="text/csv"
                   name="csvFiles"
                 />
@@ -211,7 +198,7 @@ export const App = () => {
 
       <div className="row">
         <h5>Preview data</h5>
-        <div id="import-table"></div>
+        <div ref={tabulatorContainer}></div>
       </div>
     </>
   );
diff --git a/src/client/import-dialog/index.html b/src/client/import-dialog/index.html
index bab0333..3a50281 100644
--- a/src/client/import-dialog/index.html
+++ b/src/client/import-dialog/index.html
@@ -2,27 +2,10 @@
 <html>
   <head>
     <base target="_top" />
-    <!-- Tabulator is used to generate tables -->
-    <link
-      href="https://unpkg.com/tabulator-tables@4.9.3/dist/css/tabulator.min.css"
-      rel="stylesheet"
-    />
   </head>
-
   <body>
     <section id="index">
       <!-- bundled js and css will get inlined here during build -->
     </section>
-    <!-- Papa parse is used to parse CSV on the client side in Javascript [window.Papa] -->
-    <script
-      src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/5.3.0/papaparse.min.js"
-      integrity="sha512-rKFvwjvE4liWPlFnvH4ZhRDfNZ9FOpdkD/BU5gAIA3VS3vOQrQ5BjKgbO3kxebKhHdHcNUHLqxQYSoxee9UwgA=="
-      crossorigin="anonymous"
-    ></script>
-    <!-- Tabulator is used to generate tables on the client side [window.Tabulator] -->
-    <script
-      type="text/javascript"
-      src="https://unpkg.com/tabulator-tables@4.9.3/dist/js/tabulator.min.js"
-    ></script>
   </body>
 </html>
diff --git a/src/client/index.d.ts b/src/client/index.d.ts
new file mode 100644
index 0000000..04c16ef
--- /dev/null
+++ b/src/client/index.d.ts
@@ -0,0 +1,14 @@
+declare module 'tabulator-tables' {
+  export = Tabulator;
+}
+
+declare namespace google.script.host {
+  const origin: string;
+  function close(): void;
+  function setHeight(height: number): void;
+  function setWidth(height: number): void;
+}
+
+declare namespace google.script.host.editor {
+  function focus(): void;
+}
diff --git a/webpack.config.js b/webpack.config.js
index 97b0097..fbfe389 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -198,6 +198,21 @@ const DynamicCdnWebpackPluginConfig = {
           version: packageVersion,
           url: `https://cdnjs.cloudflare.com/ajax/libs/materialize/${packageVersion}/js/materialize.min.js`,
         };
+      case 'tabulator-tables':
+        return {
+          name: packageName,
+          var: 'Tabulator',
+          version: packageVersion,
+          url: `https://unpkg.com/tabulator-tables@${packageVersion}/dist/js/tabulator.min.js`,
+        };
+      case 'papaparse': {
+        return {
+          name: packageName,
+          var: 'Papa',
+          version: packageVersion,
+          url: `https://unpkg.com/papaparse@${packageVersion}/papaparse.min.js`,
+        };
+      }
       // externalize gas-client to keep bundle size even smaller
       case 'gas-client':
         return {