diff --git a/client/package-lock.json b/client/package-lock.json
index 3996951..483d6ec 100644
--- a/client/package-lock.json
+++ b/client/package-lock.json
@@ -927,9 +927,9 @@
"integrity": "sha512-6It2EVfGskxZCQhuykrfnALg7oVeiI6KclWSmGDqB0AiInVrTGB9Jp9i4/Ad21u9Jde/voVQz6eFX/eSg/UsPA=="
},
"@emotion/hash": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.7.2.tgz",
- "integrity": "sha512-RMtr1i6E8MXaBWwhXL3yeOU8JXRnz8GNxHvaUfVvwxokvayUY0zoBeWbKw1S9XkufmGEEdQd228pSZXFkAln8Q=="
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz",
+ "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow=="
},
"@hapi/address": {
"version": "2.0.0",
@@ -1182,95 +1182,97 @@
}
},
"@material-ui/core": {
- "version": "4.1.3",
- "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.1.3.tgz",
- "integrity": "sha512-cSrI3yZ2L1XVi5IyO0/dPGUq1FaDBKTL9ygDOlvojD6bGuD/Qu17dCFAD8/mHV4CPNQMJYUKLYyOmqtDYdEB9g==",
- "requires": {
- "@babel/runtime": "^7.2.0",
- "@material-ui/styles": "^4.1.2",
- "@material-ui/system": "^4.3.0",
- "@material-ui/types": "^4.1.1",
- "@material-ui/utils": "^4.1.0",
- "@types/react-transition-group": "^2.0.16",
- "clsx": "^1.0.2",
- "convert-css-length": "^2.0.0",
- "debounce": "^1.1.0",
- "deepmerge": "^3.0.0",
- "hoist-non-react-statics": "^3.2.1",
- "is-plain-object": "^3.0.0",
- "normalize-scroll-left": "^0.2.0",
- "popper.js": "^1.14.1",
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@material-ui/core/-/core-4.10.0.tgz",
+ "integrity": "sha512-yVlHe4b8AaoiTHhCOZeszHZ+T2iHU5DncdMGeNcQaaaO+q/Qrq0hxP3iFzTbgjRWnWwftEVQL668GRxcPJVRaQ==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/styles": "^4.10.0",
+ "@material-ui/system": "^4.9.14",
+ "@material-ui/types": "^5.1.0",
+ "@material-ui/utils": "^4.9.12",
+ "@types/react-transition-group": "^4.2.0",
+ "clsx": "^1.0.4",
+ "hoist-non-react-statics": "^3.3.2",
+ "popper.js": "^1.16.1-lts",
"prop-types": "^15.7.2",
- "react-event-listener": "^0.6.6",
- "react-transition-group": "^4.0.0",
- "warning": "^4.0.1"
+ "react-is": "^16.8.0",
+ "react-transition-group": "^4.4.0"
},
"dependencies": {
- "is-plain-object": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-3.0.0.tgz",
- "integrity": "sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==",
+ "hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"requires": {
- "isobject": "^4.0.0"
+ "react-is": "^16.7.0"
}
- },
- "isobject": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-4.0.0.tgz",
- "integrity": "sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA=="
}
}
},
+ "@material-ui/icons": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.9.1.tgz",
+ "integrity": "sha512-GBitL3oBWO0hzBhvA9KxqcowRUsA0qzwKkURyC8nppnC3fw54KPKZ+d4V1Eeg/UnDRSzDaI9nGCdel/eh9AQMg==",
+ "requires": {
+ "@babel/runtime": "^7.4.4"
+ }
+ },
"@material-ui/styles": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.1.2.tgz",
- "integrity": "sha512-IRwhGI3OzxMKIDXnYl/vi9FD/i5ZktVP2m/5PIf/HVdvhqUZGIzqR2OB/9f3W1hc+kKKExdOPlpZpVihIsJWkA==",
- "requires": {
- "@babel/runtime": "^7.2.0",
- "@emotion/hash": "^0.7.1",
- "@material-ui/types": "^4.1.1",
- "@material-ui/utils": "^4.1.0",
- "clsx": "^1.0.2",
+ "version": "4.10.0",
+ "resolved": "https://registry.npmjs.org/@material-ui/styles/-/styles-4.10.0.tgz",
+ "integrity": "sha512-XPwiVTpd3rlnbfrgtEJ1eJJdFCXZkHxy8TrdieaTvwxNYj42VnnCyFzxYeNW9Lhj4V1oD8YtQ6S5Gie7bZDf7Q==",
+ "requires": {
+ "@babel/runtime": "^7.4.4",
+ "@emotion/hash": "^0.8.0",
+ "@material-ui/types": "^5.1.0",
+ "@material-ui/utils": "^4.9.6",
+ "clsx": "^1.0.4",
"csstype": "^2.5.2",
- "deepmerge": "^3.0.0",
- "hoist-non-react-statics": "^3.2.1",
- "jss": "10.0.0-alpha.17",
- "jss-plugin-camel-case": "10.0.0-alpha.17",
- "jss-plugin-default-unit": "10.0.0-alpha.17",
- "jss-plugin-global": "10.0.0-alpha.17",
- "jss-plugin-nested": "10.0.0-alpha.17",
- "jss-plugin-props-sort": "10.0.0-alpha.17",
- "jss-plugin-rule-value-function": "10.0.0-alpha.17",
- "jss-plugin-vendor-prefixer": "10.0.0-alpha.17",
- "prop-types": "^15.7.2",
- "warning": "^4.0.1"
+ "hoist-non-react-statics": "^3.3.2",
+ "jss": "^10.0.3",
+ "jss-plugin-camel-case": "^10.0.3",
+ "jss-plugin-default-unit": "^10.0.3",
+ "jss-plugin-global": "^10.0.3",
+ "jss-plugin-nested": "^10.0.3",
+ "jss-plugin-props-sort": "^10.0.3",
+ "jss-plugin-rule-value-function": "^10.0.3",
+ "jss-plugin-vendor-prefixer": "^10.0.3",
+ "prop-types": "^15.7.2"
+ },
+ "dependencies": {
+ "hoist-non-react-statics": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
+ "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
+ "requires": {
+ "react-is": "^16.7.0"
+ }
+ }
}
},
"@material-ui/system": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.3.0.tgz",
- "integrity": "sha512-VQh3mWZSmzm1JR7Ci35AHKwOhhxHHMrBWCdP4mh7UAwSdjWBE6s2Y9Y0iJiqMoEsHP64vU3W1JpsW2AgkUeHsQ==",
+ "version": "4.9.14",
+ "resolved": "https://registry.npmjs.org/@material-ui/system/-/system-4.9.14.tgz",
+ "integrity": "sha512-oQbaqfSnNlEkXEziDcJDDIy8pbvwUmZXWNqlmIwDqr/ZdCK8FuV3f4nxikUh7hvClKV2gnQ9djh5CZFTHkZj3w==",
"requires": {
- "@babel/runtime": "^7.2.0",
- "deepmerge": "^3.0.0",
- "prop-types": "^15.7.2",
- "warning": "^4.0.1"
+ "@babel/runtime": "^7.4.4",
+ "@material-ui/utils": "^4.9.6",
+ "csstype": "^2.5.2",
+ "prop-types": "^15.7.2"
}
},
"@material-ui/types": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-4.1.1.tgz",
- "integrity": "sha512-AN+GZNXytX9yxGi0JOfxHrRTbhFybjUJ05rnsBVjcB+16e466Z0Xe5IxawuOayVZgTBNDxmPKo5j4V6OnMtaSQ==",
- "requires": {
- "@types/react": "*"
- }
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/@material-ui/types/-/types-5.1.0.tgz",
+ "integrity": "sha512-7cqRjrY50b8QzRSYyhSpx4WRw2YuO0KKIGQEVk5J8uoz2BanawykgZGoWEqKm7pVIbzFDN0SpPcVV4IhOFkl8A=="
},
"@material-ui/utils": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.1.0.tgz",
- "integrity": "sha512-muwmVU799tzPjzb+Q5E/CTDle0rXwkCAdvMVyU0BfbJhenkUsFmuYiCmbvMVOU1m6F1S5HWfXz8EP4pXwwAvrw==",
+ "version": "4.9.12",
+ "resolved": "https://registry.npmjs.org/@material-ui/utils/-/utils-4.9.12.tgz",
+ "integrity": "sha512-/0rgZPEOcZq5CFA4+4n6Q6zk7fi8skHhH2Bcra8R3epoJEYy5PL55LuMazPtPH1oKeRausDV/Omz4BbgFsn1HQ==",
"requires": {
- "@babel/runtime": "^7.2.0",
+ "@babel/runtime": "^7.4.4",
"prop-types": "^15.7.2",
"react-is": "^16.8.0"
}
@@ -1493,9 +1495,9 @@
"integrity": "sha512-Uy0PN4R5vgBUXFoJrKryf5aTk3kJ8Rv3PdlHjl6UaX+Cqp1QE0yPQ68MPXGrZOfG7gZVNDIJZYyot0B9ubXUrQ=="
},
"@types/prop-types": {
- "version": "15.7.1",
- "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.1.tgz",
- "integrity": "sha512-CFzn9idOEpHrgdw8JsoTkaDDyRWk1jrzIV8djzcgpq0y9tG4B4lFT+Nxh52DVpDXV+n4+NPNv7M1Dj5uMp6XFg=="
+ "version": "15.7.3",
+ "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.3.tgz",
+ "integrity": "sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw=="
},
"@types/q": {
"version": "1.5.2",
@@ -1503,18 +1505,18 @@
"integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw=="
},
"@types/react": {
- "version": "16.8.23",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-16.8.23.tgz",
- "integrity": "sha512-abkEOIeljniUN9qB5onp++g0EY38h7atnDHxwKUFz1r3VH1+yG1OKi2sNPTyObL40goBmfKFpdii2lEzwLX1cA==",
+ "version": "16.9.35",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-16.9.35.tgz",
+ "integrity": "sha512-q0n0SsWcGc8nDqH2GJfWQWUOmZSJhXV64CjVN5SvcNti3TdEaA3AH0D8DwNmMdzjMAC/78tB8nAZIlV8yTz+zQ==",
"requires": {
"@types/prop-types": "*",
"csstype": "^2.2.0"
}
},
"@types/react-transition-group": {
- "version": "2.9.2",
- "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-2.9.2.tgz",
- "integrity": "sha512-5Fv2DQNO+GpdPZcxp2x/OQG/H19A01WlmpjVD9cKvVFmoVLOZ9LvBgSWG6pSXIU4og5fgbvGPaCV5+VGkWAEHA==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.0.tgz",
+ "integrity": "sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w==",
"requires": {
"@types/react": "*"
}
@@ -3552,9 +3554,9 @@
}
},
"clsx": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.0.4.tgz",
- "integrity": "sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg=="
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.0.tgz",
+ "integrity": "sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA=="
},
"co": {
"version": "4.6.0",
@@ -3730,11 +3732,6 @@
"date-now": "^0.1.4"
}
},
- "console-polyfill": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/console-polyfill/-/console-polyfill-0.1.2.tgz",
- "integrity": "sha1-ls/tUcr3gYn2mVcubxgnHcN8DjA="
- },
"constants-browserify": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz",
@@ -3758,15 +3755,6 @@
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
"integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
},
- "convert-css-length": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/convert-css-length/-/convert-css-length-2.0.0.tgz",
- "integrity": "sha512-ygBgHNzImHJ/kjgqdzC0oaY2+EMID3s88/CZD2C9O1stM3PwsOwXzzlFTTkZy/bPZe0wjyt1UoYjilfunQGjlw==",
- "requires": {
- "console-polyfill": "^0.1.2",
- "parse-unit": "^1.0.1"
- }
- },
"convert-source-map": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
@@ -4034,12 +4022,27 @@
"integrity": "sha1-g4NCMMyfdMRX3lnuvRVD/uuDt+w="
},
"css-vendor": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.5.tgz",
- "integrity": "sha512-36w+4Cg0zqFIt5TAkaM3proB6XWh5kSGmbddRCPdrRLQiYNfHPTgaWPOlCrcuZIO0iAtrG+5wsHJZ6jj8AUULA==",
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz",
+ "integrity": "sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ==",
"requires": {
- "@babel/runtime": "^7.3.1",
+ "@babel/runtime": "^7.8.3",
"is-in-browser": "^1.0.2"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.9.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
+ "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.5",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+ "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
+ }
}
},
"css-what": {
@@ -4161,9 +4164,9 @@
}
},
"csstype": {
- "version": "2.6.5",
- "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.5.tgz",
- "integrity": "sha512-JsTaiksRsel5n7XwqPAfB0l3TFKdpjW/kgAELf9vrb5adGA7UCPLajKK5s3nFrcFm3Rkyp/Qkgl73ENc1UY3cA=="
+ "version": "2.6.10",
+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.10.tgz",
+ "integrity": "sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w=="
},
"cyclist": {
"version": "0.2.2",
@@ -4210,11 +4213,6 @@
"resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
"integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs="
},
- "debounce": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.0.tgz",
- "integrity": "sha512-mYtLl1xfZLi1m4RtQYlZgJUNQjl4ZxVnHzIR8nLLgi4q1YT8o/WM+MK/f8yfcc9s5Ir5zRaPZyZU6xs1Syoocg=="
- },
"debug": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
@@ -4243,11 +4241,6 @@
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
- "deepmerge": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz",
- "integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA=="
- },
"default-gateway": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz",
@@ -4462,11 +4455,27 @@
}
},
"dom-helpers": {
- "version": "3.4.0",
- "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
- "integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
+ "version": "5.1.4",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.1.4.tgz",
+ "integrity": "sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A==",
"requires": {
- "@babel/runtime": "^7.1.2"
+ "@babel/runtime": "^7.8.7",
+ "csstype": "^2.6.7"
+ },
+ "dependencies": {
+ "@babel/runtime": {
+ "version": "7.9.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
+ "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
+ "requires": {
+ "regenerator-runtime": "^0.13.4"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.13.5",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+ "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
+ }
}
},
"dom-serializer": {
@@ -7974,79 +7983,80 @@
}
},
"jss": {
- "version": "10.0.0-alpha.17",
- "resolved": "https://registry.npmjs.org/jss/-/jss-10.0.0-alpha.17.tgz",
- "integrity": "sha512-egGIUg+YRu0+U+XXlD0gmVtU/gW5sn7+qmDv7opwK5s8emZBE/VoN55X6CaMrAa0kLeGMldnI43KOWea6M9/mA==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/jss/-/jss-10.1.1.tgz",
+ "integrity": "sha512-Xz3qgRUFlxbWk1czCZibUJqhVPObrZHxY3FPsjCXhDld4NOj1BgM14Ir5hVm+Qr6OLqVljjGvoMcCdXNOAbdkQ==",
"requires": {
"@babel/runtime": "^7.3.1",
+ "csstype": "^2.6.5",
"is-in-browser": "^1.1.3",
"tiny-warning": "^1.0.2"
}
},
"jss-plugin-camel-case": {
- "version": "10.0.0-alpha.17",
- "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.0.0-alpha.17.tgz",
- "integrity": "sha512-aPY4kr6MwliH7KToLRzeSk1NxXUo9n7MQsAa0Hghwj01x9UnMkDkGAKENMKUtPjGkQZfiJpB9tTLFrSJ/6VrIQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/jss-plugin-camel-case/-/jss-plugin-camel-case-10.1.1.tgz",
+ "integrity": "sha512-MDIaw8FeD5uFz1seQBKz4pnvDLnj5vIKV5hXSVdMaAVq13xR6SVTVWkIV/keyTs5txxTvzGJ9hXoxgd1WTUlBw==",
"requires": {
"@babel/runtime": "^7.3.1",
"hyphenate-style-name": "^1.0.3",
- "jss": "10.0.0-alpha.17"
+ "jss": "10.1.1"
}
},
"jss-plugin-default-unit": {
- "version": "10.0.0-alpha.17",
- "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.0.0-alpha.17.tgz",
- "integrity": "sha512-KQgiXczvzJ9AlFdD8NS7FZLub0NSctSrCA9Yi/GqdsfJg4ZCriU4DzIybCZBHCi/INFGJmLIESYWSxnuhAzgSQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/jss-plugin-default-unit/-/jss-plugin-default-unit-10.1.1.tgz",
+ "integrity": "sha512-UkeVCA/b3QEA4k0nIKS4uWXDCNmV73WLHdh2oDGZZc3GsQtlOCuiH3EkB/qI60v2MiCq356/SYWsDXt21yjwdg==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.0.0-alpha.17"
+ "jss": "10.1.1"
}
},
"jss-plugin-global": {
- "version": "10.0.0-alpha.17",
- "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.0.0-alpha.17.tgz",
- "integrity": "sha512-WYxiwwI+CLk0ozW8loeceqXBAZXBMsLBEZeRwVf9WX+FljdJkGwVZpRCk6LBX4aXnqAGyKqCxIAIJ3KP2yBdEg==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/jss-plugin-global/-/jss-plugin-global-10.1.1.tgz",
+ "integrity": "sha512-VBG3wRyi3Z8S4kMhm8rZV6caYBegsk+QnQZSVmrWw6GVOT/Z4FA7eyMu5SdkorDlG/HVpHh91oFN56O4R9m2VA==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.0.0-alpha.17"
+ "jss": "10.1.1"
}
},
"jss-plugin-nested": {
- "version": "10.0.0-alpha.17",
- "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.0.0-alpha.17.tgz",
- "integrity": "sha512-onpFqv904KCujryf2t6IIV1/QoB7cSF7ojrd4UujcN5TPvYOvXF5bchi7jnHG5U0SLlRSDGMLJ9fhtoCknhEbw==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/jss-plugin-nested/-/jss-plugin-nested-10.1.1.tgz",
+ "integrity": "sha512-ozEu7ZBSVrMYxSDplPX3H82XHNQk2DQEJ9TEyo7OVTPJ1hEieqjDFiOQOxXEj9z3PMqkylnUbvWIZRDKCFYw5Q==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.0.0-alpha.17",
+ "jss": "10.1.1",
"tiny-warning": "^1.0.2"
}
},
"jss-plugin-props-sort": {
- "version": "10.0.0-alpha.17",
- "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.0.0-alpha.17.tgz",
- "integrity": "sha512-KnbyrxCbtQTqpDx2mSZU/r/E5QnDPIVfIxRi8K+W/q4gZpomBvqWC+xgvAk9hbpmA6QBoQaOilV8o12w2IZ6fg==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/jss-plugin-props-sort/-/jss-plugin-props-sort-10.1.1.tgz",
+ "integrity": "sha512-g/joK3eTDZB4pkqpZB38257yD4LXB0X15jxtZAGbUzcKAVUHPl9Jb47Y7lYmiGsShiV4YmQRqG1p2DHMYoK91g==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.0.0-alpha.17"
+ "jss": "10.1.1"
}
},
"jss-plugin-rule-value-function": {
- "version": "10.0.0-alpha.17",
- "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.0.0-alpha.17.tgz",
- "integrity": "sha512-8AuJB44Q+ehfkWVRi2XlRbUf6SrLmrHTa5EXd6dgQRCCRuvGmqX8Dl4fZvNeKRFjTLPZgzg9+31rqeOMhKa2vA==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.1.1.tgz",
+ "integrity": "sha512-ClV1lvJ3laU9la1CUzaDugEcwnpjPTuJ0yGy2YtcU+gG/w9HMInD5vEv7xKAz53Bk4WiJm5uLOElSEshHyhKNw==",
"requires": {
"@babel/runtime": "^7.3.1",
- "jss": "10.0.0-alpha.17"
+ "jss": "10.1.1"
}
},
"jss-plugin-vendor-prefixer": {
- "version": "10.0.0-alpha.17",
- "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.0.0-alpha.17.tgz",
- "integrity": "sha512-wDq9EL0QaoMGSGifPEBb+/SA9LBcqPEW0jpL9ht+Z2t+lV7NNz0j7uCEOuE6FvNWqHzUKTsiATs1rTHPkzNBEQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.1.1.tgz",
+ "integrity": "sha512-09MZpQ6onQrhaVSF6GHC4iYifQ7+4YC/tAP6D4ZWeZotvCMq1mHLqNKRIaqQ2lkgANjlEot2JnVi1ktu4+L4pw==",
"requires": {
"@babel/runtime": "^7.3.1",
- "css-vendor": "^2.0.1",
- "jss": "10.0.0-alpha.17"
+ "css-vendor": "^2.0.7",
+ "jss": "10.1.1"
}
},
"jsx-ast-utils": {
@@ -8814,11 +8824,6 @@
"resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
"integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI="
},
- "normalize-scroll-left": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/normalize-scroll-left/-/normalize-scroll-left-0.2.0.tgz",
- "integrity": "sha512-t5oCENZJl8TGusJKoCJm7+asaSsPuNmK6+iEjrZ5TyBj2f02brCRsd4c83hwtu+e5d4LCSBZ0uoDlMjBo+A8yA=="
- },
"normalize-url": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
@@ -9185,11 +9190,6 @@
"json-parse-better-errors": "^1.0.1"
}
},
- "parse-unit": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parse-unit/-/parse-unit-1.0.1.tgz",
- "integrity": "sha1-fhu21b7zh0wo45JSaiVBFwKR7s8="
- },
"parse5": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz",
@@ -9382,9 +9382,9 @@
}
},
"popper.js": {
- "version": "1.15.0",
- "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.15.0.tgz",
- "integrity": "sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA=="
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz",
+ "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ=="
},
"portfinder": {
"version": "1.0.20",
@@ -10592,16 +10592,6 @@
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-5.1.6.tgz",
"integrity": "sha512-X1Y+0jR47ImDVr54Ab6V9eGk0Hnu7fVWGeHQSOXHf/C2pF9c6uy3gef8QUeuUiWlNb0i08InPSE5a/KJzNzw1Q=="
},
- "react-event-listener": {
- "version": "0.6.6",
- "resolved": "https://registry.npmjs.org/react-event-listener/-/react-event-listener-0.6.6.tgz",
- "integrity": "sha512-+hCNqfy7o9wvO6UgjqFmBzARJS7qrNoda0VqzvOuioEpoEXKutiKuv92dSz6kP7rYLmyHPyYNLesi5t/aH1gfw==",
- "requires": {
- "@babel/runtime": "^7.2.0",
- "prop-types": "^15.6.0",
- "warning": "^4.0.1"
- }
- },
"react-is": {
"version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz",
@@ -10714,23 +10704,28 @@
}
},
"react-transition-group": {
- "version": "4.2.1",
- "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.2.1.tgz",
- "integrity": "sha512-IXrPr93VzCPupwm2O6n6C2kJIofJ/Rp5Ltihhm9UfE8lkuVX2ng/SUUl/oWjblybK9Fq2Io7LGa6maVqPB762Q==",
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.1.tgz",
+ "integrity": "sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==",
"requires": {
- "@babel/runtime": "^7.4.5",
- "dom-helpers": "^3.4.0",
+ "@babel/runtime": "^7.5.5",
+ "dom-helpers": "^5.0.1",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2"
},
"dependencies": {
"@babel/runtime": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.5.0.tgz",
- "integrity": "sha512-2xsuyZ0R0RBFwjgae5NpXk8FcfH4qovj5cEM5VEeB7KXnKqzaisIu2HSV/mCEISolJJuR4wkViUGYujA8MH9tw==",
+ "version": "7.9.6",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.6.tgz",
+ "integrity": "sha512-64AF1xY3OAkFHqOb9s4jpgk1Mm5vDZ4L3acHvAml+53nO1XbXLuDodsVpO4OIUsmemlUHMxNdYMNJmsvOwLrvQ==",
"requires": {
- "regenerator-runtime": "^0.13.2"
+ "regenerator-runtime": "^0.13.4"
}
+ },
+ "regenerator-runtime": {
+ "version": "0.13.5",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz",
+ "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA=="
}
}
},
@@ -12771,14 +12766,6 @@
"makeerror": "1.0.x"
}
},
- "warning": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz",
- "integrity": "sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==",
- "requires": {
- "loose-envify": "^1.0.0"
- }
- },
"watchpack": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
diff --git a/client/package.json b/client/package.json
index 481a54e..2c880d2 100644
--- a/client/package.json
+++ b/client/package.json
@@ -4,6 +4,7 @@
"private": true,
"dependencies": {
"@material-ui/core": "^4.1.3",
+ "@material-ui/icons": "^4.9.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-router-dom": "^5.0.1",
diff --git a/client/src/App.js b/client/src/App.js
index 276a05d..2bc94a9 100644
--- a/client/src/App.js
+++ b/client/src/App.js
@@ -6,6 +6,7 @@ import { theme } from "./themes/theme";
import LandingPage from "./pages/Landing";
import CreateGame from "./pages/create_game/CreateGame";
import GameIO from "./socket_io/GameIO";
+import GameLobby from "./pages/game_lobby/GameLobby";
import "./App.css";
@@ -24,6 +25,7 @@ function App() {
+
diff --git a/client/src/pages/common/common.css b/client/src/pages/common/common.css
index cd2b11a..6a6e25c 100644
--- a/client/src/pages/common/common.css
+++ b/client/src/pages/common/common.css
@@ -7,3 +7,11 @@
width: 75px;
background-color: limegreen;
}
+
+.grid-content {
+ padding: 25px;
+}
+
+.label {
+ padding-right: 8px;
+}
diff --git a/client/src/pages/create_game/CreateGame.js b/client/src/pages/create_game/CreateGame.js
index cf55ab8..72e577d 100644
--- a/client/src/pages/create_game/CreateGame.js
+++ b/client/src/pages/create_game/CreateGame.js
@@ -55,7 +55,7 @@ function CreateGame() {
onChange(event);
}}
value={matchID}
- placeholder="Enter Game ID"
+ placeholder="Enter Match ID"
/>
diff --git a/client/src/pages/game_lobby/GameLobby.css b/client/src/pages/game_lobby/GameLobby.css
new file mode 100644
index 0000000..e69de29
diff --git a/client/src/pages/game_lobby/GameLobby.js b/client/src/pages/game_lobby/GameLobby.js
new file mode 100644
index 0000000..8405240
--- /dev/null
+++ b/client/src/pages/game_lobby/GameLobby.js
@@ -0,0 +1,100 @@
+import React, { useState } from "react";
+import Button from "@material-ui/core/Button";
+import Container from "@material-ui/core/Container";
+import Grid from "@material-ui/core/Grid";
+import Typography from "@material-ui/core/Typography";
+
+import { copyToClipboard } from "../../utils/utils";
+import Header from "../common/Header";
+import TeamSelect from "./team_select/TeamSelect";
+import "../common/common.css";
+import "./GameLobby.css";
+
+const SPYMASTER_INDEX = 0;
+const FIELD_AGENT_INDEX = 1;
+
+function GameLobby() {
+ const currentUser = { sessionID: 1, firstName: "Tony" }; // dummy data of current user. sessionID will be generated from web socket in backend
+ const [matchID] = useState("ABCD"); // dummy match ID
+ const [canStartGame, setCanStartGame] = useState(false);
+
+ const isTeamReady = (team) => {
+ const spyMaster = team[SPYMASTER_INDEX];
+ const fieldAgents = team.slice(FIELD_AGENT_INDEX);
+
+ return spyMaster.player && fieldAgents.some((agent) => agent.player);
+ };
+
+ const onTeamSelect = (redTeam, blueTeam) => {
+ const isRedTeamReady = isTeamReady(redTeam);
+ const isBlueTeamReady = isTeamReady(blueTeam);
+
+ setCanStartGame(isRedTeamReady && isBlueTeamReady);
+ };
+
+ const startGame = () => {
+ if (canStartGame) {
+ // send list of players of each team to server and transition to game board
+ console.log("Game is starting...");
+ }
+ };
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Share Match ID:
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default GameLobby;
diff --git a/client/src/pages/game_lobby/team_select/TeamPresets.js b/client/src/pages/game_lobby/team_select/TeamPresets.js
new file mode 100644
index 0000000..360b037
--- /dev/null
+++ b/client/src/pages/game_lobby/team_select/TeamPresets.js
@@ -0,0 +1,29 @@
+export const TEAM_CODE = {
+ RED: "RED",
+ BLUE: "BLUE",
+};
+
+export const DEFAULT_TEAM_STATE = [
+ { role: "Spymaster", player: null },
+ { role: "Field Agent", player: null },
+ { role: "Field Agent", player: null },
+ { role: "Field Agent", player: null },
+];
+
+export const ACTION_TYPE = {
+ SET_PLAYER: "SET_PLAYER",
+ REMOVE_PLAYER: "REMOVE_PLAYER",
+};
+
+export const reducer = (state, action) => {
+ switch (action.type) {
+ case ACTION_TYPE.SET_PLAYER:
+ state[action.payload].player = action.player;
+ return state;
+ case ACTION_TYPE.REMOVE_PLAYER:
+ state[action.payload].player = null;
+ return state;
+ default:
+ return state;
+ }
+};
diff --git a/client/src/pages/game_lobby/team_select/TeamSelect.css b/client/src/pages/game_lobby/team_select/TeamSelect.css
new file mode 100644
index 0000000..1094221
--- /dev/null
+++ b/client/src/pages/game_lobby/team_select/TeamSelect.css
@@ -0,0 +1,11 @@
+.team {
+ padding: 25px;
+}
+
+#red-team {
+ color: red;
+}
+
+#blue-team {
+ color: blue;
+}
diff --git a/client/src/pages/game_lobby/team_select/TeamSelect.js b/client/src/pages/game_lobby/team_select/TeamSelect.js
new file mode 100644
index 0000000..209c184
--- /dev/null
+++ b/client/src/pages/game_lobby/team_select/TeamSelect.js
@@ -0,0 +1,132 @@
+import React, { useState, useEffect, useReducer } from "react";
+import Grid from "@material-ui/core/Grid";
+import List from "@material-ui/core/List";
+import ListItem from "@material-ui/core/ListItem";
+import ListItemText from "@material-ui/core/ListItemText";
+import ListItemSecondaryAction from "@material-ui/core/ListItemSecondaryAction";
+import Typography from "@material-ui/core/Typography";
+
+import {
+ TEAM_CODE,
+ ACTION_TYPE,
+ DEFAULT_TEAM_STATE,
+ reducer as teamReducer,
+} from "./TeamPresets";
+import { JoinRoleAction, LeaveRoleAction } from "./TeamSelectActions";
+import "./TeamSelect.css";
+
+const DEFAULT_RED_TEAM_STATE = JSON.parse(JSON.stringify(DEFAULT_TEAM_STATE));
+const DEFAULT_BLUE_TEAM_STATE = JSON.parse(JSON.stringify(DEFAULT_TEAM_STATE));
+
+const UNOCCUPIED_SPOT_NAME = "--";
+
+function TeamSelect(props) {
+ const [redTeam, redTeamDispatch] = useReducer(
+ teamReducer,
+ DEFAULT_RED_TEAM_STATE
+ );
+ const [blueTeam, blueTeamDispatch] = useReducer(
+ teamReducer,
+ DEFAULT_BLUE_TEAM_STATE
+ );
+ const [isRoleAssigned, setIsRoleAssigned] = useState(false);
+
+ useEffect(() => {
+ props.onChange(redTeam, blueTeam);
+ });
+
+ const joinRole = (teamCode, index) => {
+ const action = {
+ type: ACTION_TYPE.SET_PLAYER,
+ payload: index,
+ player: props.currentUser,
+ };
+
+ teamCode === TEAM_CODE.RED
+ ? redTeamDispatch(action)
+ : blueTeamDispatch(action);
+
+ setIsRoleAssigned(!isRoleAssigned);
+ };
+
+ const leaveRole = (teamCode, index) => {
+ const action = {
+ type: ACTION_TYPE.SET_PLAYER,
+ payload: index,
+ };
+
+ teamCode === TEAM_CODE.RED
+ ? redTeamDispatch(action)
+ : blueTeamDispatch(action);
+
+ setIsRoleAssigned(!isRoleAssigned);
+ };
+
+ const generateListItem = (teamCode) => {
+ const team = teamCode === TEAM_CODE.RED ? redTeam : blueTeam;
+ const generateActions = (spot, index) => {
+ return !spot.player ? (
+ !isRoleAssigned ? (
+
+ ) : null
+ ) : // show "Leave Role" action only if current user's session ID matches their own
+ props.currentUser.sessionID === spot.player.sessionID &&
+ isRoleAssigned ? (
+
+ ) : null;
+ };
+
+ return team.map((spot, index) => {
+ const uniquekey = teamCode + "-" + index;
+ return (
+
+
+ {spot.player ? spot.player.firstName : UNOCCUPIED_SPOT_NAME}
+
+
+ {generateActions(spot, index)}
+
+
+ );
+ });
+ };
+
+ return (
+
+
+
+
+
+ Red Team
+
+
+
+ {generateListItem(TEAM_CODE.RED)}
+
+
+
+
+
+
+
+ Blue Team
+
+
+
+ {generateListItem(TEAM_CODE.BLUE)}
+
+
+
+
+ );
+}
+
+export default TeamSelect;
diff --git a/client/src/pages/game_lobby/team_select/TeamSelectActions.js b/client/src/pages/game_lobby/team_select/TeamSelectActions.js
new file mode 100644
index 0000000..c7e1085
--- /dev/null
+++ b/client/src/pages/game_lobby/team_select/TeamSelectActions.js
@@ -0,0 +1,30 @@
+import React from "react";
+import AddCircle from "@material-ui/icons/AddCircle";
+import IconButton from "@material-ui/core/IconButton";
+import RemoveCircle from "@material-ui/icons/RemoveCircle";
+
+export const JoinRoleAction = ({ joinRole, teamCode, index }) => {
+ return (
+ {
+ joinRole(teamCode, index);
+ }}
+ edge="end"
+ >
+
+
+ );
+};
+
+export const LeaveRoleAction = ({ leaveRole, teamCode, index }) => {
+ return (
+ {
+ leaveRole(teamCode, index);
+ }}
+ edge="end"
+ >
+
+
+ );
+};
diff --git a/client/src/utils/utils.js b/client/src/utils/utils.js
new file mode 100644
index 0000000..a92c41f
--- /dev/null
+++ b/client/src/utils/utils.js
@@ -0,0 +1,9 @@
+export const copyToClipboard = (text) => {
+ // source: https://stackoverflow.com/questions/33855641/copy-output-of-a-javascript-variable-to-the-clipboard
+ let dummy = document.createElement("textarea");
+ document.body.appendChild(dummy);
+ dummy.value = text;
+ dummy.select();
+ document.execCommand("copy");
+ document.body.removeChild(dummy);
+};
diff --git a/server/app.js b/server/app.js
index e54fa48..a8dcc25 100644
--- a/server/app.js
+++ b/server/app.js
@@ -7,8 +7,6 @@ const logger = require("morgan");
const indexRouter = require("./routes/index");
const pingRouter = require("./routes/ping");
-const { mongoose } = require("./db/mongoose");
-
const { json, urlencoded } = express;
var app = express();
diff --git a/server/db/mongoose.js b/server/db/mongoose.js
index 31d1e5c..45b15b6 100644
--- a/server/db/mongoose.js
+++ b/server/db/mongoose.js
@@ -1,5 +1,9 @@
-const mongoose = require('mongoose');
+const mongoose = require("mongoose");
const url = process.env.MONGOLAB_URI;
-mongoose.connect(url, { useNewUrlParser: true, useCreateIndex: true, useUnifiedTopology: true});
-module.exports = { mongoose };
\ No newline at end of file
+mongoose.connect(url, {
+ useNewUrlParser: true,
+ useCreateIndex: true,
+ useUnifiedTopology: true,
+});
+module.exports = { mongoose };
diff --git a/server/engine/Board.js b/server/engine/Board.js
new file mode 100644
index 0000000..51c7774
--- /dev/null
+++ b/server/engine/Board.js
@@ -0,0 +1,77 @@
+const Words = require("./Words");
+const Card = require("./Card");
+const getMapCard = require("./getMapCard");
+const shuffle = require("./shuffle");
+
+class Board {
+ constructor() {
+ //new deck of words
+ this.deck = [...Words];
+ shuffle(this.deck);
+ this.deckLength = this.deck.length;
+ this.mapCard = [];
+ //drawed cards
+ this.cards = [];
+
+ this.redAgentNum = 0;
+ this.blueAgentNum = 0;
+
+ this.decideAgentNum();
+ this.generateNewRound();
+ }
+
+ generateNewRound() {
+ let selectedWords = [];
+ const remainCardsNum = 25;
+
+ if (this.deckLength < remainCardsNum) {
+ this.deck = [...Words];
+ shuffle(this.deck);
+ }
+ selectedWords = this.deck.splice(0, 25);
+ this.updateDeckLength();
+
+ this.cards = selectedWords.map(
+ (word, index) => new Card(word, this.mapCard[index])
+ );
+ }
+
+ updateDeckLength() {
+ this.deckLength = this.deck.length;
+ }
+
+ //getters
+ getCards() {
+ return this.cards;
+ }
+ getRedAgentNum() {
+ return this.redAgentNum;
+ }
+ getBlueAgentNum() {
+ return this.blueAgentNum;
+ }
+
+ setCard(selectedCard) {
+ //assume it pass the card
+ this.cards.forEach((card) => {
+ if (card === selectedCard) {
+ card.select();
+ return card.role;
+ }
+ });
+ }
+
+ decideAgentNum() {
+ const decision = Math.round(Math.random());
+ if (decision === 0) {
+ this.blueAgentNum = 9;
+ this.redAgentNum = 8;
+ } else {
+ this.blueAgentNum = 8;
+ this.redAgentNum = 9;
+ }
+ this.mapCard = getMapCard(decision);
+ }
+}
+
+module.exports = Board;
diff --git a/server/engine/Card.js b/server/engine/Card.js
new file mode 100644
index 0000000..039f895
--- /dev/null
+++ b/server/engine/Card.js
@@ -0,0 +1,17 @@
+class Card {
+ constructor(word, role) {
+ this.word = word;
+ this.role = role;
+ this.selected = false;
+ }
+
+ select() {
+ if (this.selected) {
+ return false;
+ } else {
+ this.selected = true;
+ }
+ }
+}
+
+module.exports = Card;
diff --git a/server/engine/FieldAgent.js b/server/engine/FieldAgent.js
new file mode 100644
index 0000000..fd53902
--- /dev/null
+++ b/server/engine/FieldAgent.js
@@ -0,0 +1,12 @@
+class FieldAgent{
+ constructor(user, team) {
+ this.user = user;
+ this.team = team;
+ }
+
+ selectCard(card, board) {
+ return board.chooseCard(card);
+ }
+}
+
+module.exports = FieldAgent;
diff --git a/server/engine/Game.js b/server/engine/Game.js
new file mode 100644
index 0000000..84f223c
--- /dev/null
+++ b/server/engine/Game.js
@@ -0,0 +1,231 @@
+const Board = require("./Board");
+const { Team, TeamColor } = require("./Team");
+const FieldAgent = require("./FieldAgent");
+const SpyMaster = require("./SpyMaster");
+const GameTurns = require("./GameTurns");
+const PlayerRoles = require("./PlayerRoles");
+const WordRoles = require("./WordRoles");
+
+class Game {
+ constructor(matchId) {
+ this.matchId = matchId;
+
+ this.gameTurn = [GameTurns.BLUE_SPY_TURN, GameTurns.RED_SPY_TURN][
+ Math.round(Math.random())
+ ];
+
+ this.redTeam = new Team(TeamColor.RED);
+ this.blueTeam = new Team(TeamColor.BLUE);
+ this.redPoints = 0;
+ this.bluePoints = 0;
+ this.numGuessLeft = 0;
+ this.winner = null;
+
+ this.gameBoard = new Board();
+ }
+
+ //adders
+ addRedPoint() {
+ this.redPoints += 1;
+ }
+ addBluePoint() {
+ this.bluePoints += 1;
+ }
+
+ //reducers
+ reduceNumGuessLeft() {
+ this.numGuessLeft -= 1;
+ }
+
+ //getters
+ getMatchId() {
+ return this.machId;
+ }
+ getGameTurn() {
+ return this.gameTurn;
+ }
+ getRedTeam() {
+ return this.redTeam;
+ }
+ getBlueTeam() {
+ return this.blueTeam;
+ }
+ getRedPoints() {
+ return this.redPoints;
+ }
+ getBluePoints() {
+ return this.bluePoints;
+ }
+ getNumGuessLeft() {
+ return this.numGuessLeft;
+ }
+ getWinner() {
+ return this.winner;
+ }
+ getBoard() {
+ return this.gameBoard;
+ }
+ getGameState() {
+ return {
+ gameTurn: this.gameTurn,
+ redPoints: this.redPoints,
+ bluePoints: this.bluePoints,
+ // gameBoard: this.gameBoard,
+ numGuessLeft: this.numGuessLeft,
+ };
+ }
+
+ //setters
+ setGameTurn(turn) {
+ this.gameTurn = turn;
+ }
+ setNumGuessLeft(num) {
+ this.numGuessLeft = num;
+ }
+ setWinner(team) {
+ this.winner = team;
+ }
+ setGamePoints(guess) {
+ switch (guess.role) {
+ case WordRoles.BLUE:
+ this.addBluePoint();
+ guess.select();
+ break;
+ case WordRoles.RED:
+ this.addRedPoint();
+ guess.select();
+ break;
+ case WordRoles.WHITE:
+ guess.select();
+ break;
+ case WordRoles.BLACK:
+ // guess.select();
+ this.setGameTurn(GameTurns.End);
+ break;
+ }
+ }
+
+ setRoles(players) {
+ players.forEach((player) => {
+ switch (player.role) {
+ case PlayerRoles.RED_FIELD_AGENT:
+ const newRedFieldAgent = new FieldAgent(player, TeamColor.RED);
+ this.redTeam.addPlayer(newRedFieldAgent);
+ this.redTeam.addFieldAgent(newRedFieldAgent);
+ break;
+ case PlayerRoles.BLUE_FIELD_AGENT:
+ const newBlueFieldAgent = new FieldAgent(player, TeamColor.BLUE);
+ this.redTeam.addPlayer(newBlueFieldAgent);
+ this.redTeam.addFieldAgent(newBlueFieldAgent);
+ break;
+ case PlayerRoles.RED_SPY_MASTER:
+ const newRedSpyMaster = new SpyMaster(player, TeamColor.RED);
+ this.redSpyMaster = newRedSpyMaster;
+ this.redTeam.addPlayer(newRedSpyMaster);
+ this.redTeam.setSpymaster(newRedSpyMaster);
+ break;
+ case PlayerRoles.BLUE_SPY_MASTER:
+ const newBlueSpyMaster = new SpyMaster(player, TeamColor.BLUE);
+ this.blueSpyMaster = newBlueSpyMaster;
+ this.blueTeam.addPlayer(newBlueSpyMaster);
+ this.blueTeam.setSpymaster(newBlueSpyMaster);
+ break;
+ }
+ });
+ }
+
+ nextGameTurn(info) {
+ const winner = this.checkIfWinning(info.guess);
+ if (winner) {
+ this.setGameTurn(GameTurns.End);
+ }
+ switch (this.gameTurn) {
+ case GameTurns.RED_SPY_TURN:
+ this.setNumGuessLeft(info.numGuess);
+ // this.redTeam.spymaster.setClue(info);
+ this.setGameTurn(GameTurns.RED_AGENT_TURN);
+ break;
+ case GameTurns.BLUE_SPY_TURN:
+ this.setNumGuessLeft(info.numGuess);
+ // this.blueTeam.spymaster.setClue(info);
+ this.setGameTurn(GameTurns.BLUE_AGENT_TURN);
+ break;
+ case GameTurns.RED_AGENT_TURN:
+ this.gameBoard.setCard(info.guess);
+ this.reduceNumGuessLeft();
+ this.setGamePoints(info.guess);
+
+ if (this.getNumGuessLeft() === 0) {
+ this.setGameTurn(GameTurns.BLUE_SPY_TURN);
+ }
+ break;
+ case GameTurns.BLUE_AGENT_TURN:
+ this.gameBoard.setCard(info.guess);
+ this.reduceNumGuessLeft();
+ this.setGamePoints(info.guess);
+
+ if (this.getNumGuessLeft() === 0) {
+ this.setGameTurn(GameTurns.RED_SPY_TURN);
+ }
+ break;
+ case GameTurns.End:
+ console.log("I'm in the end");
+ break;
+ }
+ }
+
+ checkIfWinning(info) {
+ if (
+ this.getGameTurn() === GameTurns.BLUE_AGENT_TURN ||
+ this.getGameTurn() === GameTurns.RED_AGENT_TURN
+ ) {
+ if (
+ info.role === WordRoles.BLACK &&
+ this.getGameTurn() === GameTurns.BLUE_AGENT_TURN
+ ) {
+ this.setWinner(this.getRedTeam());
+ return true;
+ }
+ if (
+ info.role === WordRoles.BLACK &&
+ this.getGameTurn() === GameTurns.RED_AGENT_TURN
+ ) {
+ this.setWinner(this.getBlueTeam());
+ return true;
+ }
+ if (this.getRedPoints() === this.gameBoard.getRedAgentNum()) {
+ this.setWinner(this.getRedTeam());
+ return true;
+ }
+ if (this.getBluePoints() === this.gameBoard.getBlueAgentNum()) {
+ this.setWinner(this.getBlueTeam());
+ return true;
+ }
+ }
+ return false;
+ }
+
+ stopGuess() {
+ switch (this.gameTurn) {
+ case GameTurns.BLUE_AGENT_TURN:
+ this.setNumGuessLeft = 0;
+ this.setGameTurn(GameTurns.RED_SPY_TURN);
+ break;
+ case GameTurns.RED_AGENT_TURN:
+ this.setNumGuessLeft = 0;
+ this.setGameTurn(GameTurns.BLUE_SPY_TURN);
+ break;
+ }
+ }
+ resetGame() {
+ this.bluePoints = 0;
+ this.redPoints = 0;
+ this.numGuessLeft = 0;
+ this.gameBoard.generateNewRound();
+ this.gameTurn = [GameTurns.BLUE_SPY_TURN, GameTurns.RED_SPY_TURN][
+ Math.round(Math.random())
+ ];
+ this.winner = null;
+ }
+}
+
diff --git a/server/engine/GameTurns.js b/server/engine/GameTurns.js
new file mode 100644
index 0000000..b80f7de
--- /dev/null
+++ b/server/engine/GameTurns.js
@@ -0,0 +1,9 @@
+const GameTurns = {
+ RED_AGENT_TURN: "Red agent's turn",
+ BLUE_AGENT_TURN:"Blue agent's turn",
+ RED_SPY_TURN: "Red spymaster's turn",
+ BLUE_SPY_TURN: "Blue spymaster's turn",
+ END: "End"
+}
+
+module.exports = GameTurns;
\ No newline at end of file
diff --git a/server/engine/PlayerRoles.js b/server/engine/PlayerRoles.js
new file mode 100644
index 0000000..4ce9428
--- /dev/null
+++ b/server/engine/PlayerRoles.js
@@ -0,0 +1,8 @@
+const PlayerRoles = {
+ RED_FIELD_AGENT: "RED FIELD AGENT",
+ BLUE_FIELD_AGENT: "BLUE FIELD AGENT",
+ RED_SPY_MASTER: "RED SPY MASTER",
+ BLUE_SPY_MASTER: "BLUE SPY MASTER",
+};
+
+module.exports = PlayerRoles;
diff --git a/server/engine/SpyMaster.js b/server/engine/SpyMaster.js
new file mode 100644
index 0000000..3d61ae8
--- /dev/null
+++ b/server/engine/SpyMaster.js
@@ -0,0 +1,23 @@
+class SpyMaster {
+ constructor(user, team) {
+ this.user = user;
+ this.team = team;
+ this.clue = {};
+ }
+
+ setClue(clue) {
+ //todo
+ //return moves?
+ this.clue = clue;
+ }
+
+ getClue() {
+ return this.clue;
+ }
+
+ deleteClue() {
+ this.clue = {};
+ }
+}
+
+module.exports = SpyMaster;
diff --git a/server/engine/Team.js b/server/engine/Team.js
new file mode 100644
index 0000000..2e8ceaf
--- /dev/null
+++ b/server/engine/Team.js
@@ -0,0 +1,38 @@
+class Team {
+ constructor(color) {
+ this.teamColor = color;
+ this.players = [];
+ this.fieldAgents = [];
+ this.spymaster = null;
+ }
+
+ addPlayer(player) {
+ this.players.push(player);
+ }
+
+ addFieldAgent(fieldAgent) {
+ this.fieldAgents.push(fieldAgent);
+ }
+
+ getFieldAgent() {
+ return this.fieldAgents;
+ }
+
+ getPlayers() {
+ return this.players;
+ }
+
+ getSpymaster() {
+ return this.spymaster;
+ }
+
+ setSpymaster(player) {
+ this.spymaster = player;
+ }
+}
+
+const TeamColor = {
+ RED: "RED",
+ BLUE: "BLUE",
+};
+module.exports = { Team, TeamColor };
diff --git a/server/engine/WordRoles.js b/server/engine/WordRoles.js
new file mode 100644
index 0000000..c8e8def
--- /dev/null
+++ b/server/engine/WordRoles.js
@@ -0,0 +1,8 @@
+const WordRoles = {
+ BLUE: "Blue Agent",
+ RED: "Red Agent",
+ WHITE: "Innocent Bystander",
+ BLACK: "Assassin",
+};
+
+module.exports = WordRoles;
diff --git a/server/engine/Words.js b/server/engine/Words.js
new file mode 100644
index 0000000..ff37d90
--- /dev/null
+++ b/server/engine/Words.js
@@ -0,0 +1,927 @@
+const Words = [
+ "account",
+ "achiever",
+ "acoustics",
+ "act",
+ "action",
+ "activity",
+ "actor",
+ "addition",
+ "adjustment",
+ "advertisement",
+ "advice",
+ "aftermath",
+ "afternoon",
+ "afterthought",
+ "agreement",
+ "air",
+ "airplane",
+ "airport",
+ "alarm",
+ "amount",
+ "amusement",
+ "anger",
+ "angle",
+ "animal",
+ "answer",
+ "ant",
+ "apparatus",
+ "apparel",
+ "apple",
+ "appliance",
+ "approval",
+ "arch",
+ "argument",
+ "arithmetic",
+ "arm",
+ "army",
+ "art",
+ "attack",
+ "attempt",
+ "attention",
+ "attraction",
+ "aunt",
+ "authority",
+ "babies",
+ "baby",
+ "back",
+ "badge",
+ "bag",
+ "bait",
+ "balance",
+ "ball",
+ "balloon",
+ "banana",
+ "band",
+ "base",
+ "baseball",
+ "basin",
+ "basket",
+ "basketball",
+ "bat",
+ "bath",
+ "battle",
+ "bead",
+ "beam",
+ "bean",
+ "bear",
+ "bears",
+ "beast",
+ "bed",
+ "bedroom",
+ "bee",
+ "beef",
+ "beetle",
+ "beggar",
+ "beginner",
+ "behavior",
+ "belief",
+ "bell",
+ "berry",
+ "bike",
+ "bird",
+ "birth",
+ "birthday",
+ "bit",
+ "bite",
+ "blade",
+ "blood",
+ "blow",
+ "board",
+ "boat",
+ "boats",
+ "body",
+ "bomb",
+ "bone",
+ "book",
+ "boot",
+ "border",
+ "bottle",
+ "boundary",
+ "box",
+ "boy",
+ "brain",
+ "brake",
+ "branch",
+ "brass",
+ "bread",
+ "breakfast",
+ "breath",
+ "brick",
+ "bridge",
+ "brother",
+ "brush",
+ "bubble",
+ "bucket",
+ "building",
+ "bulb",
+ "bun",
+ "burn",
+ "burst",
+ "bushes",
+ "business",
+ "butter",
+ "button",
+ "cabbage",
+ "cable",
+ "cactus",
+ "cake",
+ "calculator",
+ "calendar",
+ "camera",
+ "camp",
+ "can",
+ "cannon",
+ "canvas",
+ "cap",
+ "caption",
+ "car",
+ "card",
+ "care",
+ "carpenter",
+ "carriage",
+ "cart",
+ "cast",
+ "cat",
+ "cattle",
+ "cause",
+ "cave",
+ "celery",
+ "cellar",
+ "cemetery",
+ "cent",
+ "chain",
+ "chair",
+ "chalk",
+ "chance",
+ "change",
+ "channel",
+ "cheese",
+ "cherry",
+ "chess",
+ "chicken",
+ "children",
+ "chin",
+ "church",
+ "circle",
+ "clam",
+ "class",
+ "clock",
+ "cloth",
+ "cloud",
+ "clover",
+ "club",
+ "coach",
+ "coal",
+ "coast",
+ "coat",
+ "cobweb",
+ "coil",
+ "collar",
+ "color",
+ "comb",
+ "comfort",
+ "committee",
+ "company",
+ "comparison",
+ "competition",
+ "condition",
+ "connection",
+ "control",
+ "cook",
+ "copper",
+ "copy",
+ "cord",
+ "cork",
+ "corn",
+ "cough",
+ "country",
+ "cover",
+ "cow",
+ "crack",
+ "cracker",
+ "crate",
+ "crayon",
+ "cream",
+ "creator",
+ "creature",
+ "credit",
+ "crib",
+ "crime",
+ "crook",
+ "crow",
+ "crowd",
+ "crown",
+ "crush",
+ "cry",
+ "cub",
+ "cup",
+ "current",
+ "curtain",
+ "curve",
+ "cushion",
+ "dad",
+ "daughter",
+ "day",
+ "death",
+ "debt",
+ "decision",
+ "deer",
+ "degree",
+ "design",
+ "desire",
+ "desk",
+ "destruction",
+ "detail",
+ "development",
+ "digestion",
+ "dime",
+ "dinner",
+ "dinosaurs",
+ "direction",
+ "dirt",
+ "discovery",
+ "discussion",
+ "disease",
+ "disgust",
+ "distance",
+ "distribution",
+ "division",
+ "dock",
+ "doctor",
+ "dog",
+ "doll",
+ "donkey",
+ "door",
+ "downtown",
+ "drain",
+ "drawer",
+ "dress",
+ "drink",
+ "driving",
+ "drop",
+ "drug",
+ "drum",
+ "duck",
+ "dust",
+ "ear",
+ "earth",
+ "earthquake",
+ "edge",
+ "education",
+ "effect",
+ "egg",
+ "eggnog",
+ "elbow",
+ "end",
+ "engine",
+ "error",
+ "event",
+ "example",
+ "exchange",
+ "existence",
+ "expansion",
+ "experience",
+ "expert",
+ "eye",
+ "face",
+ "fact",
+ "fairies",
+ "fall",
+ "family",
+ "fan",
+ "fang",
+ "farm",
+ "farmer",
+ "father",
+ "faucet",
+ "fear",
+ "feast",
+ "feather",
+ "feeling",
+ "feet",
+ "fiction",
+ "field",
+ "fifth",
+ "fight",
+ "finger",
+ "fire",
+ "fireman",
+ "fish",
+ "flag",
+ "flame",
+ "flavor",
+ "flesh",
+ "flight",
+ "flock",
+ "floor",
+ "flower",
+ "fly",
+ "fog",
+ "fold",
+ "food",
+ "foot",
+ "force",
+ "fork",
+ "form",
+ "fowl",
+ "frame",
+ "friction",
+ "friend",
+ "frog",
+ "front",
+ "fruit",
+ "fuel",
+ "furniture",
+ "alley",
+ "game",
+ "garden",
+ "gate",
+ "geese",
+ "ghost",
+ "giants",
+ "giraffe",
+ "girl",
+ "glass",
+ "glove",
+ "glue",
+ "goat",
+ "gold",
+ "goldfish",
+ "good-bye",
+ "goose",
+ "government",
+ "governor",
+ "grade",
+ "grain",
+ "grandfather",
+ "grandmother",
+ "grape",
+ "grass",
+ "grip",
+ "ground",
+ "group",
+ "growth",
+ "guide",
+ "guitar",
+ "gun",
+ "hair",
+ "haircut",
+ "hall",
+ "hammer",
+ "hand",
+ "harbor",
+ "harmony",
+ "hat",
+ "hate",
+ "head",
+ "health",
+ "hearing",
+ "heart",
+ "heat",
+ "help",
+ "hen",
+ "hill",
+ "history",
+ "hobbies",
+ "hole",
+ "holiday",
+ "home",
+ "honey",
+ "hook",
+ "hope",
+ "horn",
+ "horse",
+ "hose",
+ "hospital",
+ "hot",
+ "hour",
+ "house",
+ "humor",
+ "hydrant",
+ "ice",
+ "icicle",
+ "idea",
+ "impulse",
+ "income",
+ "increase",
+ "industry",
+ "ink",
+ "insect",
+ "instrument",
+ "insurance",
+ "interest",
+ "invention",
+ "iron",
+ "island",
+ "jail",
+ "jam",
+ "jar",
+ "jeans",
+ "jelly",
+ "jellyfish",
+ "jewel",
+ "join",
+ "joke",
+ "journey",
+ "judge",
+ "juice",
+ "jump",
+ "kettle",
+ "key",
+ "kick",
+ "kiss",
+ "kite",
+ "kitten",
+ "knee",
+ "knife",
+ "knot",
+ "knowledge",
+ "laborer",
+ "lace",
+ "ladybug",
+ "lake",
+ "lamp",
+ "land",
+ "language",
+ "laugh",
+ "lawyer",
+ "lead",
+ "leaf",
+ "learning",
+ "leather",
+ "leg",
+ "letter",
+ "lettuce",
+ "level",
+ "library",
+ "lift",
+ "light",
+ "limit",
+ "line",
+ "linen",
+ "lip",
+ "liquid",
+ "list",
+ "lizard",
+ "loaf",
+ "lock",
+ "locket",
+ "look",
+ "loss",
+ "love",
+ "low",
+ "lumber",
+ "lunch",
+ "lunchroom",
+ "machine",
+ "magic",
+ "maid",
+ "mailbox",
+ "man",
+ "manager",
+ "map",
+ "marble",
+ "mark",
+ "market",
+ "mask",
+ "mass",
+ "match",
+ "meal",
+ "measure",
+ "meat",
+ "meeting",
+ "memory",
+ "men",
+ "metal",
+ "mice",
+ "middle",
+ "milk",
+ "mind",
+ "mine",
+ "minister",
+ "mint",
+ "minute",
+ "mist",
+ "mitten",
+ "mom",
+ "money",
+ "monkey",
+ "month",
+ "moon",
+ "morning",
+ "mother",
+ "motion",
+ "mountain",
+ "mouth",
+ "move",
+ "muscle",
+ "music",
+ "nail",
+ "name",
+ "nation",
+ "neck",
+ "need",
+ "needle",
+ "nerve",
+ "nest",
+ "net",
+ "news",
+ "night",
+ "noise",
+ "north",
+ "nose",
+ "note",
+ "notebook",
+ "number",
+ "nut",
+ "oatmeal",
+ "observation",
+ "ocean",
+ "offer",
+ "office",
+ "oil",
+ "operation",
+ "opinion",
+ "orange",
+ "order",
+ "organization",
+ "ornament",
+ "oven",
+ "owl",
+ "owner",
+ "page",
+ "pail",
+ "pain",
+ "paint",
+ "pan",
+ "pancake",
+ "paper",
+ "parcel",
+ "parent",
+ "park",
+ "part",
+ "partner",
+ "party",
+ "passenger",
+ "paste",
+ "patch",
+ "payment",
+ "peace",
+ "pear",
+ "pen",
+ "pencil",
+ "person",
+ "pest",
+ "pet",
+ "pickle",
+ "picture",
+ "pie",
+ "pig",
+ "pin",
+ "pipe",
+ "pizzas",
+ "place",
+ "plane",
+ "plant",
+ "plantation",
+ "plastic",
+ "plate",
+ "play",
+ "playground",
+ "pleasure",
+ "plot",
+ "plough",
+ "pocket",
+ "point",
+ "poison",
+ "police",
+ "polish",
+ "pollution",
+ "popcorn",
+ "porter",
+ "position",
+ "pot",
+ "potato",
+ "powder",
+ "power",
+ "price",
+ "print",
+ "prison",
+ "process",
+ "produce",
+ "profit",
+ "property",
+ "prose",
+ "protest",
+ "pull",
+ "pump",
+ "punishment",
+ "purpose",
+ "push",
+ "quarter",
+ "quartz",
+ "queen",
+ "question",
+ "quicksand",
+ "quiet",
+ "quill",
+ "quilt",
+ "quince",
+ "quiver",
+ "rabbit",
+ "rail",
+ "railway",
+ "rain",
+ "rainstorm",
+ "rake",
+ "range",
+ "rat",
+ "rate",
+ "ray",
+ "reaction",
+ "reading",
+ "reason",
+ "receipt",
+ "recess",
+ "record",
+ "regret",
+ "relation",
+ "religion",
+ "representative",
+ "request",
+ "respect",
+ "rest",
+ "reward",
+ "rhythm",
+ "rice",
+ "riddle",
+ "rifle",
+ "ring",
+ "river",
+ "road",
+ "robin",
+ "rock",
+ "rod",
+ "roll",
+ "roof",
+ "room",
+ "root",
+ "rose",
+ "route",
+ "rub",
+ "rule",
+ "run",
+ "sack",
+ "sail",
+ "salt",
+ "sand",
+ "scale",
+ "scarecrow",
+ "scarf",
+ "scene",
+ "scent",
+ "school",
+ "science",
+ "scissors",
+ "screw",
+ "sea",
+ "seashore",
+ "seat",
+ "secretary",
+ "seed",
+ "selection",
+ "self",
+ "sense",
+ "servant",
+ "shade",
+ "shake",
+ "shame",
+ "shape",
+ "sheep",
+ "sheet",
+ "shelf",
+ "ship",
+ "shirt",
+ "shock",
+ "shoe",
+ "shop",
+ "show",
+ "side",
+ "sidewalk",
+ "sign",
+ "silk",
+ "silver",
+ "sink",
+ "sister",
+ "size",
+ "skate",
+ "skin",
+ "skirt",
+ "sky",
+ "slave",
+ "sleep",
+ "sleet",
+ "slip",
+ "slope",
+ "smash",
+ "smell",
+ "smile",
+ "smoke",
+ "snail",
+ "snake",
+ "sneeze",
+ "snow",
+ "soap",
+ "society",
+ "sock",
+ "soda",
+ "sofa",
+ "son",
+ "song",
+ "sort",
+ "sound",
+ "soup",
+ "space",
+ "spade",
+ "spark",
+ "spiders",
+ "sponge",
+ "spoon",
+ "spot",
+ "spring",
+ "spy",
+ "square",
+ "squirrel",
+ "stage",
+ "stamp",
+ "star",
+ "start",
+ "statement",
+ "station",
+ "steam",
+ "steel",
+ "stem",
+ "step",
+ "stew",
+ "stick",
+ "stitch",
+ "stocking",
+ "stomach",
+ "stone",
+ "stop",
+ "store",
+ "story",
+ "stove",
+ "stranger",
+ "straw",
+ "stream",
+ "street",
+ "stretch",
+ "string",
+ "structure",
+ "substance",
+ "sugar",
+ "suggestion",
+ "suit",
+ "summer",
+ "sun",
+ "support",
+ "surprise",
+ "sweater",
+ "swim",
+ "swing",
+ "system",
+ "table",
+ "tail",
+ "talk",
+ "tank",
+ "taste",
+ "tax",
+ "teaching",
+ "team",
+ "teeth",
+ "temper",
+ "tendency",
+ "tent",
+ "territory",
+ "test",
+ "texture",
+ "theory",
+ "thing",
+ "thought",
+ "thread",
+ "thrill",
+ "throat",
+ "throne",
+ "thumb",
+ "thunder",
+ "ticket",
+ "tiger",
+ "time",
+ "tin",
+ "title",
+ "toad",
+ "toe",
+ "tomatoes",
+ "tongue",
+ "tooth",
+ "toothbrush",
+ "toothpaste",
+ "top",
+ "touch",
+ "town",
+ "toy",
+ "toys",
+ "trade",
+ "trail",
+ "train",
+ "trains",
+ "tramp",
+ "transport",
+ "tray",
+ "treatment",
+ "tree",
+ "trick",
+ "trip",
+ "trouble",
+ "trousers",
+ "truck",
+ "tub",
+ "turkey",
+ "turn",
+ "twig",
+ "twist",
+ "umbrella",
+ "uncle",
+ "underwear",
+ "unit",
+ "use",
+ "vacation",
+ "value",
+ "van",
+ "vase",
+ "vegetable",
+ "veil",
+ "vein",
+ "verse",
+ "vessel",
+ "vest",
+ "view",
+ "visitor",
+ "voice",
+ "volcano",
+ "volleyball",
+ "voyage",
+ "walk",
+ "wall",
+ "war",
+ "wash",
+ "waste",
+ "watch",
+ "water",
+ "wave",
+ "wax",
+ "way",
+ "wealth",
+ "weather",
+ "week",
+ "weight",
+ "wheel",
+ "whip",
+ "whistle",
+ "wilderness",
+ "wind",
+ "window",
+ "wine",
+ "wing",
+ "winter",
+ "wire",
+ "wish",
+ "woman",
+ "women",
+ "wood",
+ "wool",
+ "word",
+ "work",
+ "worm",
+ "wound",
+ "wren",
+ "wrench",
+ "wrist",
+ "writer",
+ "writing",
+ "yak",
+ "yam",
+ "yard",
+ "yarn",
+ "year",
+ "yoke",
+ "zebra",
+ "zephyr",
+ "zinc",
+ "zipper",
+ "zoo",
+];
+
+module.exports = Words;
\ No newline at end of file
diff --git a/server/engine/getMapCard.js b/server/engine/getMapCard.js
new file mode 100644
index 0000000..23309f0
--- /dev/null
+++ b/server/engine/getMapCard.js
@@ -0,0 +1,31 @@
+const WordRoles = require("./WordRoles");
+const shuffle = require("./shuffle");
+
+const blueAgents0 = new Array(9).fill(WordRoles.BLUE);
+const redAgents0 = new Array(8).fill(WordRoles.RED);
+const blueAgents1 = new Array(8).fill(WordRoles.BLUE);
+const redAgents1 = new Array(9).fill(WordRoles.RED);
+const innocentBystanders = new Array(7).fill(WordRoles.WHITE);
+const assassins = new Array(WordRoles.BLACK);
+const deck0 = new Array().concat(
+ blueAgents0,
+ redAgents0,
+ innocentBystanders,
+ assassins
+);
+const deck1 = new Array().concat(
+ blueAgents1,
+ redAgents1,
+ innocentBystanders,
+ assassins
+);
+
+const getMapCard = (binaryNum) => {
+ if (binaryNum === 0) {
+ return shuffle(deck0);
+ } else {
+ return shuffle(deck1);
+ }
+};
+
+module.exports = getMapCard;
diff --git a/server/engine/shuffle.js b/server/engine/shuffle.js
new file mode 100644
index 0000000..5455e4d
--- /dev/null
+++ b/server/engine/shuffle.js
@@ -0,0 +1,8 @@
+const shuffle = (array) => {
+ for (let i = array.length - 1; i > 0; i--) {
+ let j = Math.floor(Math.random() * (i + 1));
+ [array[i], array[j]] = [array[j], array[i]];
+ }
+ return array;
+};
+module.exports = shuffle;
diff --git a/server/package-lock.json b/server/package-lock.json
index d6a7d3d..3cd8ab9 100644
--- a/server/package-lock.json
+++ b/server/package-lock.json
@@ -259,25 +259,6 @@
"resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
"integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw=="
},
- "bl": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.0.tgz",
- "integrity": "sha512-wbgvOpqopSr7uq6fJrLH8EsvYMJf9gzfo2jCsL2eTy75qXPukA4pCgHamOQkZtY5vmfVtjB+P3LNlMHW5CEZXA==",
- "requires": {
- "readable-stream": "^2.3.5",
- "safe-buffer": "^5.1.1"
- }
- },
- "blob": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
- "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
- },
- "bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA=="
- },
"body-parser": {
"version": "1.18.3",
"resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
@@ -351,11 +332,6 @@
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
"dev": true
},
- "bson": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.4.tgz",
- "integrity": "sha512-S/yKGU1syOMzO86+dGpg2qGoDL0zvzcb262G+gqEy6TgP6rt6z6qxSFX/8X6vLC91P7G7C3nLs0+bvDzmvBA3Q=="
- },
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@@ -721,11 +697,6 @@
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
"dev": true
},
- "denque": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/denque/-/denque-1.4.1.tgz",
- "integrity": "sha512-OfzPuSZKGcgr96rf1oODnfjqBFmr1DVoc/TrItj3Ohe0Ah1C5WX5Baquw/9U9KovnQ88EqmJbD66rKYUQYN1tQ=="
- },
"depd": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
@@ -2150,11 +2121,6 @@
"esprima": "^4.0.0"
}
},
- "kareem": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
- "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
- },
"kind-of": {
"version": "6.0.2",
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
@@ -2262,12 +2228,6 @@
"p-is-promise": "^2.0.0"
}
},
- "memory-pager": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/memory-pager/-/memory-pager-1.5.0.tgz",
- "integrity": "sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==",
- "optional": true
- },
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
@@ -2428,49 +2388,6 @@
}
}
},
- "mongodb": {
- "version": "3.5.7",
- "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.5.7.tgz",
- "integrity": "sha512-lMtleRT+vIgY/JhhTn1nyGwnSMmJkJELp+4ZbrjctrnBxuLbj6rmLuJFz8W2xUzUqWmqoyVxJLYuC58ZKpcTYQ==",
- "requires": {
- "bl": "^2.2.0",
- "bson": "^1.1.4",
- "denque": "^1.4.1",
- "require_optional": "^1.0.1",
- "safe-buffer": "^5.1.2",
- "saslprep": "^1.0.0"
- }
- },
- "mongoose": {
- "version": "5.9.14",
- "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.9.14.tgz",
- "integrity": "sha512-LScxCruQv0YpU/9DasKdThd+3r3PFQbCgesmfa6g0pTDOIiD1A9N9OQsGYrDf+dyUksfLCxJYYF9qpBHLvS1tg==",
- "requires": {
- "bson": "^1.1.4",
- "kareem": "2.3.1",
- "mongodb": "3.5.7",
- "mongoose-legacy-pluralize": "1.0.2",
- "mpath": "0.7.0",
- "mquery": "3.2.2",
- "ms": "2.1.2",
- "regexp-clone": "1.0.0",
- "safe-buffer": "5.1.2",
- "sift": "7.0.1",
- "sliced": "1.0.1"
- },
- "dependencies": {
- "ms": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
- "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
- }
- }
- },
- "mongoose-legacy-pluralize": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
- "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
- },
"morgan": {
"version": "1.9.1",
"resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
@@ -2483,33 +2400,6 @@
"on-headers": "~1.0.1"
}
},
- "mpath": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.7.0.tgz",
- "integrity": "sha512-Aiq04hILxhz1L+f7sjGyn7IxYzWm1zLNNXcfhDtx04kZ2Gk7uvFdgZ8ts1cWa/6d0TQmag2yR8zSGZUmp0tFNg=="
- },
- "mquery": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.2.2.tgz",
- "integrity": "sha512-XB52992COp0KP230I3qloVUbkLUxJIu328HBP2t2EsxSFtf4W1HPSOBWOXf1bqxK4Xbb66lfMJ+Bpfd9/yZE1Q==",
- "requires": {
- "bluebird": "3.5.1",
- "debug": "3.1.0",
- "regexp-clone": "^1.0.0",
- "safe-buffer": "5.1.2",
- "sliced": "1.0.1"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "requires": {
- "ms": "2.0.0"
- }
- }
- }
- },
"ms": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -2997,11 +2887,6 @@
"safe-regex": "^1.1.0"
}
},
- "regexp-clone": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-1.0.0.tgz",
- "integrity": "sha512-TuAasHQNamyyJ2hb97IuBEif4qBHGjPHBS64sZwytpLEqtBQ1gPJTnOaQ6qmpET16cK14kkjbazl6+p0RRv0yw=="
- },
"registry-auth-token": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.4.0.tgz",
@@ -3046,20 +2931,6 @@
"integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
"dev": true
},
- "require_optional": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
- "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
- "requires": {
- "resolve-from": "^2.0.0",
- "semver": "^5.1.0"
- }
- },
- "resolve-from": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
- "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
- },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -3088,15 +2959,6 @@
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
},
- "saslprep": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/saslprep/-/saslprep-1.0.3.tgz",
- "integrity": "sha512-/MY/PEMbk2SuY5sScONwhUDsV2p77Znkb/q3nSVstq/yQzYJOH/Azh29p9oJLsl3LnQwSvZDKagDGBsBwSooag==",
- "optional": true,
- "requires": {
- "sparse-bitfield": "^3.0.3"
- }
- },
"semver": {
"version": "5.7.0",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
@@ -3186,21 +3048,11 @@
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
"integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM="
},
- "sift": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/sift/-/sift-7.0.1.tgz",
- "integrity": "sha512-oqD7PMJ+uO6jV9EQCl0LrRw1OwsiPsiFQR5AR30heR+4Dl7jBBbDLnNvWiak20tzZlSE1H7RB30SX/1j/YYT7g=="
- },
"signal-exit": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
},
- "sliced": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
- "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
- },
"snapdragon": {
"version": "0.8.2",
"resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
@@ -3459,15 +3311,6 @@
"resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
"integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM="
},
- "sparse-bitfield": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/sparse-bitfield/-/sparse-bitfield-3.0.3.tgz",
- "integrity": "sha1-/0rm5oZWBWuks+eSqzM004JzyhE=",
- "optional": true,
- "requires": {
- "memory-pager": "^1.0.2"
- }
- },
"split-string": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
diff --git a/server/package.json b/server/package.json
index 1d8dfde..0d8035b 100644
--- a/server/package.json
+++ b/server/package.json
@@ -13,7 +13,6 @@
"dotenv": "^8.0.0",
"express": "~4.16.1",
"http-errors": "~1.6.3",
- "mongoose": "^5.9.14",
"morgan": "~1.9.1",
"nodemon": "^1.19.1",
"socket.io": "^2.3.0"