Compare commits

..

6 Commits

30 changed files with 11680 additions and 24 deletions

1
.gitignore vendored
View File

@ -8,7 +8,6 @@ __pycache__/
# Distribution / packaging # Distribution / packaging
.Python .Python
build/
develop-eggs/ develop-eggs/
dist/ dist/
downloads/ downloads/

View File

@ -21,7 +21,7 @@ $ cd minecraft-bot/
## Running ## Running
``` ```
$ USERNAME=you@domain.com PASSWORD=supersecret SERVER=example.com ./run-linux.sh $ USERNAME=you@domain.com PASSWORD=supersecret SERVER=example.com ./run_linux.sh
``` ```
## Commands ## Commands

25
main.py
View File

@ -4,8 +4,15 @@ import time
import traceback import traceback
import json import json
import logging
log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)
from flask import Flask from flask import Flask
app = Flask(__name__) from flask_cors import CORS
build_folder = 'web_interface/build'
app = Flask(__name__, template_folder=build_folder, static_folder=build_folder, static_url_path='')
CORS(app)
from munch import Munch from munch import Munch
from watchdog.observers import Observer from watchdog.observers import Observer
@ -35,8 +42,8 @@ g.health = 20
g.food = 20 g.food = 20
g.sand_origin = None g.sand_origin = None
@app.route('/') @app.route('/api/global')
def hello_world(): def api_global():
data = json.dumps(g, default=lambda o: str(o), indent=4) data = json.dumps(g, default=lambda o: str(o), indent=4)
response = app.response_class( response = app.response_class(
@ -46,6 +53,10 @@ def hello_world():
) )
return response return response
@app.route('/')
def root():
return app.send_static_file('index.html')
reload_timeout = time.time() reload_timeout = time.time()
def main(): def main():
@ -82,6 +93,12 @@ def main():
if __name__ == '__main__': if __name__ == '__main__':
threading.Thread(target=app.run).start() host = '0.0.0.0'
port = 3300
threading.Thread(target=app.run, kwargs={'host': host, 'port': port}).start()
print('Web interface listening on port:', port)
print('Try going to http://localhost:' + str(port))
time.sleep(1) time.sleep(1)
main() main()

View File

@ -65,6 +65,7 @@ class CacheItemsStates:
return return
else: else:
self.trapped_chests.pop(0) self.trapped_chests.pop(0)
time.sleep(0.1)
def going_to_trapped_chest(self): def going_to_trapped_chest(self):
if utils.pint(self.g.pos) == self.opening: if utils.pint(self.g.pos) == self.opening:

View File

@ -64,6 +64,7 @@ class CheckThreatsStates:
return return
else: else:
print('Cant get to safety', self.safety) print('Cant get to safety', self.safety)
time.sleep(0.1)
print('Cant get to safety, aborting') print('Cant get to safety, aborting')
self.state = self.cleanup self.state = self.cleanup

View File

@ -139,8 +139,7 @@ class FillBlocksStates:
else: else:
print('Cant get to that block') print('Cant get to that block')
self.state = self.cleanup self.state = self.cleanup
#self.bad_sand.append(self.sand) time.sleep(0.1)
#self.state = self.find_new_sand
def going_to_block(self): def going_to_block(self):
if not len(self.g.path): if not len(self.g.path):

View File

@ -61,15 +61,8 @@ class GatherCropStates:
self.state = self.going_to_crop self.state = self.going_to_crop
else: else:
print('Cant get to it, blacklisting') print('Cant get to it, blacklisting')
time.sleep(0.1)
self.bad_crops.append(self.crop) self.bad_crops.append(self.crop)
self.wait_time = 0.5
self.state = self.wait_to_restart
def wait_to_restart(self):
# prevent timeouts
if self.wait_time > 0:
self.wait_time -= utils.TICK
else:
self.state = self.find_new_crop self.state = self.find_new_crop
def going_to_crop(self): def going_to_crop(self):

View File

@ -89,6 +89,7 @@ class GatherSandStates:
self.state = self.going_to_sand self.state = self.going_to_sand
else: else:
print('Cant get to that sand') print('Cant get to that sand')
time.sleep(0.1)
self.bad_sand.append(self.sand) self.bad_sand.append(self.sand)
self.state = self.find_new_sand self.state = self.find_new_sand

View File

@ -54,15 +54,8 @@ class GatherWartStates:
self.state = self.going_to_wart self.state = self.going_to_wart
else: else:
print('Cant get to it, blacklisting') print('Cant get to it, blacklisting')
time.sleep(0.1)
self.bad_warts.append(wart) self.bad_warts.append(wart)
self.wait_time = 0.5
self.state = self.wait_to_restart
def wait_to_restart(self):
# prevent timeouts
if self.wait_time > 0:
self.wait_time -= utils.TICK
else:
self.state = self.find_new_wart self.state = self.find_new_wart
def going_to_wart(self): def going_to_wart(self):

View File

@ -80,6 +80,7 @@ class GatherWoodStates:
self.state = self.going_to_tree self.state = self.going_to_tree
else: else:
self.openings.pop(0) self.openings.pop(0)
time.sleep(0.1)
def going_to_tree(self): def going_to_tree(self):
if utils.pint(self.g.pos) == self.openings[0]: if utils.pint(self.g.pos) == self.openings[0]:
@ -126,6 +127,7 @@ class GatherWoodStates:
else: else:
self.openings.pop(0) self.openings.pop(0)
self.state = self.choose_opening self.state = self.choose_opening
time.sleep(0.1)
def going_to_trunk_base(self): def going_to_trunk_base(self):
if utils.pint(self.g.pos) == self.tree: if utils.pint(self.g.pos) == self.tree:

View File

@ -61,6 +61,7 @@ class GrabSandStates:
return return
else: else:
print('Cant get to sand', self.sand) print('Cant get to sand', self.sand)
time.sleep(0.1)
print('Cant get to any more sand, aborting') print('Cant get to any more sand, aborting')
self.state = self.cleanup self.state = self.cleanup

View File

@ -100,6 +100,7 @@ class GrabSuppliesStates:
return return
else: else:
print('No path, blacklisting barrel') print('No path, blacklisting barrel')
time.sleep(0.1)
self.bad_barrels.append(self.barrel) self.bad_barrels.append(self.barrel)
self.state = self.choose_barrel self.state = self.choose_barrel

View File

@ -69,6 +69,7 @@ class SellToVillagerStates:
self.state = self.going_to_villager self.state = self.going_to_villager
else: else:
self.openings.pop(0) self.openings.pop(0)
time.sleep(0.1)
def going_to_villager(self): def going_to_villager(self):
if utils.pint(self.g.pos) == self.openings[0]: if utils.pint(self.g.pos) == self.openings[0]:

View File

@ -81,6 +81,7 @@ class SleepWithBedStates:
self.beds.pop(0) self.beds.pop(0)
self.bad_beds.append(bed) self.bad_beds.append(bed)
print('Cant get to bed, blacklisting') print('Cant get to bed, blacklisting')
time.sleep(0.1)
self.state = self.select_bed self.state = self.select_bed
def going_to_bed(self): def going_to_bed(self):

View File

@ -11,6 +11,7 @@ cryptography==3.4.7
distlib==0.3.0 distlib==0.3.0
distro==1.4.0 distro==1.4.0
Flask==1.1.2 Flask==1.1.2
Flask-Cors==3.0.10
html5lib==1.0.1 html5lib==1.0.1
idna==2.8 idna==2.8
ipaddr==2.2.0 ipaddr==2.2.0

20
web_interface/.gitignore vendored Normal file
View File

@ -0,0 +1,20 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

View File

@ -0,0 +1,17 @@
{
"files": {
"main.js": "/static/js/main.27336089.chunk.js",
"main.js.map": "/static/js/main.27336089.chunk.js.map",
"runtime-main.js": "/static/js/runtime-main.97b64705.js",
"runtime-main.js.map": "/static/js/runtime-main.97b64705.js.map",
"static/js/2.2b306052.chunk.js": "/static/js/2.2b306052.chunk.js",
"static/js/2.2b306052.chunk.js.map": "/static/js/2.2b306052.chunk.js.map",
"index.html": "/index.html",
"static/js/2.2b306052.chunk.js.LICENSE.txt": "/static/js/2.2b306052.chunk.js.LICENSE.txt"
},
"entrypoints": [
"static/js/runtime-main.97b64705.js",
"static/js/2.2b306052.chunk.js",
"static/js/main.27336089.chunk.js"
]
}

View File

@ -0,0 +1 @@
<!doctype html><html lang="en"><head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Web site created using create-react-app"/><title>React App</title></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],p=0,s=[];p<i.length;p++)f=i[p],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(c&&c(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var l=t[i];0!==o[l]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var i=this.webpackJsonpweb_interface=this.webpackJsonpweb_interface||[],l=i.push.bind(i);i.push=r,i=i.slice();for(var a=0;a<i.length;a++)r(i[a]);var c=l;t()}([])</script><script src="/static/js/2.2b306052.chunk.js"></script><script src="/static/js/main.27336089.chunk.js"></script></body></html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,41 @@
/*
object-assign
(c) Sindre Sorhus
@license MIT
*/
/** @license React v0.20.2
* scheduler.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react-dom.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react-jsx-runtime.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
/** @license React v17.0.2
* react.production.min.js
*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
(this.webpackJsonpweb_interface=this.webpackJsonpweb_interface||[]).push([[0],{41:function(e,t,n){"use strict";n.r(t);var c=n(2),r=n.n(c),s=n(14),a=n.n(s),i=n(4),j=n.n(i),l=n(15),d=n(16),o=n(5),p=n.n(o),b=n(0);p.a.defaults.baseURL=Object({NODE_ENV:"production",PUBLIC_URL:"",WDS_SOCKET_HOST:void 0,WDS_SOCKET_PATH:void 0,WDS_SOCKET_PORT:void 0,FAST_REFRESH:!0}).REACT_APP_SERVER;var u=function(){var e=Object(c.useState)(!1),t=Object(d.a)(e,2),n=t[0],r=t[1];return Object(c.useEffect)((function(){var e=setInterval(function(){var e=Object(l.a)(j.a.mark((function e(){var t;return j.a.wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return e.prev=0,e.next=3,p.a.get("/api/global");case 3:t=e.sent,r(t.data),e.next=10;break;case 7:e.prev=7,e.t0=e.catch(0),r(!1);case 10:case"end":return e.stop()}}),e,null,[[0,7]])})));return function(){return e.apply(this,arguments)}}(),500);return function(){return clearInterval(e)}}),[]),Object(b.jsx)("div",{className:"app",children:n&&Object(b.jsxs)(b.Fragment,{children:[Object(b.jsxs)("p",{children:["Name: ",n.name]}),Object(b.jsxs)("p",{children:["Pos: ",n.pos]}),Object(b.jsxs)("p",{children:["Yaw: ",n.yaw]}),Object(b.jsxs)("p",{children:["Pitch: ",n.pitch]}),Object(b.jsxs)("p",{children:["Dimention: ",n.dimension]}),Object(b.jsxs)("p",{children:["Players:",Object.values(n.players).map((function(e){return Object(b.jsx)("div",{children:n.player_names[e.player_uuid]})}))]}),Object(b.jsxs)("p",{children:["Holding: ",n.holding]}),Object(b.jsxs)("p",{children:["AFK: ","".concat(n.afk)]}),Object(b.jsxs)("p",{children:["Health: ",n.health]}),Object(b.jsxs)("p",{children:["Food: ",n.food]}),Object(b.jsxs)("p",{children:["Time: ",n.time]})]})})};a.a.render(Object(b.jsx)(r.a.StrictMode,{children:Object(b.jsx)(u,{})}),document.getElementById("root"))}},[[41,1,2]]]);
//# sourceMappingURL=main.27336089.chunk.js.map

View File

@ -0,0 +1 @@
{"version":3,"sources":["App.js","index.js"],"names":["axios","defaults","baseURL","process","REACT_APP_SERVER","App","useState","global","setGlobal","useEffect","interval","setInterval","a","get","res","data","clearInterval","className","name","pos","yaw","pitch","dimension","Object","values","players","map","x","player_names","player_uuid","holding","afk","health","food","time","ReactDOM","render","StrictMode","document","getElementById"],"mappings":"kNAGAA,IAAMC,SAASC,QAAUC,mIAAYC,iBAiDtBC,MA/Cf,WAAgB,IAAD,EACcC,oBAAS,GADvB,mBACPC,EADO,KACCC,EADD,KAiBd,OAdAC,qBAAU,WACT,IASMC,EAAWC,YATR,uCAAG,4BAAAC,EAAA,+EAEQZ,IAAMa,IAAI,eAFlB,OAEJC,EAFI,OAGVN,EAAUM,EAAIC,MAHJ,gDAKVP,GAAU,GALA,yDAAH,qDASyB,KAClC,OAAO,kBAAMQ,cAAcN,MACzB,IAGF,qBAAKO,UAAU,MAAf,SACEV,GACA,qCACC,uCAAUA,EAAOW,QACjB,sCAASX,EAAOY,OAChB,sCAASZ,EAAOa,OAChB,wCAAWb,EAAOc,SAElB,4CAAed,EAAOe,aAEtB,yCACEC,OAAOC,OAAOjB,EAAOkB,SAASC,KAAI,SAAAC,GAAC,OACnC,8BACEpB,EAAOqB,aAAaD,EAAEE,qBAK1B,0CAAatB,EAAOuB,WACpB,gDAAYvB,EAAOwB,QACnB,yCAAYxB,EAAOyB,UACnB,uCAAUzB,EAAO0B,QACjB,uCAAU1B,EAAO2B,cCzCtBC,IAASC,OACR,cAAC,IAAMC,WAAP,UACC,cAAC,EAAD,MAEDC,SAASC,eAAe,W","file":"static/js/main.27336089.chunk.js","sourcesContent":["import React, { useState, useEffect } from 'react';\nimport axios from 'axios';\n\naxios.defaults.baseURL = process.env.REACT_APP_SERVER;\n\nfunction App() {\n\tconst [global, setGlobal] = useState(false);\n\n\tuseEffect(() => {\n\t\tconst get = async() => {\n\t\t\ttry {\n\t\t\t\tconst res = await axios.get('/api/global');\n\t\t\t\tsetGlobal(res.data);\n\t\t\t} catch (error) {\n\t\t\t\tsetGlobal(false);\n\t\t\t}\n\t\t};\n\n\t\tconst interval = setInterval(get, 500);\n\t\treturn () => clearInterval(interval);\n\t}, []);\n\n\treturn (\n\t\t<div className=\"app\">\n\t\t\t{global &&\n\t\t\t\t<>\n\t\t\t\t\t<p>Name: {global.name}</p>\n\t\t\t\t\t<p>Pos: {global.pos}</p>\n\t\t\t\t\t<p>Yaw: {global.yaw}</p>\n\t\t\t\t\t<p>Pitch: {global.pitch}</p>\n\n\t\t\t\t\t<p>Dimention: {global.dimension}</p>\n\n\t\t\t\t\t<p>Players:\n\t\t\t\t\t\t{Object.values(global.players).map(x =>\n\t\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t\t{global.player_names[x.player_uuid]}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</p>\n\n\t\t\t\t\t<p>Holding: {global.holding}</p>\n\t\t\t\t\t<p>AFK: {`${global.afk}`}</p>\n\t\t\t\t\t<p>Health: {global.health}</p>\n\t\t\t\t\t<p>Food: {global.food}</p>\n\t\t\t\t\t<p>Time: {global.time}</p>\n\t\t\t\t</>\n\t\t\t}\n\t\t</div>\n\t);\n}\n\nexport default App;\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App';\n\nReactDOM.render(\n\t<React.StrictMode>\n\t\t<App />\n\t</React.StrictMode>,\n\tdocument.getElementById('root')\n);\n"],"sourceRoot":""}

View File

@ -0,0 +1,2 @@
!function(e){function r(r){for(var n,f,i=r[0],l=r[1],a=r[2],p=0,s=[];p<i.length;p++)f=i[p],Object.prototype.hasOwnProperty.call(o,f)&&o[f]&&s.push(o[f][0]),o[f]=0;for(n in l)Object.prototype.hasOwnProperty.call(l,n)&&(e[n]=l[n]);for(c&&c(r);s.length;)s.shift()();return u.push.apply(u,a||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,i=1;i<t.length;i++){var l=t[i];0!==o[l]&&(n=!1)}n&&(u.splice(r--,1),e=f(f.s=t[0]))}return e}var n={},o={1:0},u=[];function f(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,f),t.l=!0,t.exports}f.m=e,f.c=n,f.d=function(e,r,t){f.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},f.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},f.t=function(e,r){if(1&r&&(e=f(e)),8&r)return e;if(4&r&&"object"===typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(f.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)f.d(t,n,function(r){return e[r]}.bind(null,n));return t},f.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return f.d(r,"a",r),r},f.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},f.p="/";var i=this.webpackJsonpweb_interface=this.webpackJsonpweb_interface||[],l=i.push.bind(i);i.push=r,i=i.slice();for(var a=0;a<i.length;a++)r(i[a]);var c=l;t()}([]);
//# sourceMappingURL=runtime-main.97b64705.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,39 @@
{
"name": "web_interface",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.11.4",
"@testing-library/react": "^11.1.0",
"@testing-library/user-event": "^12.1.10",
"axios": "^0.21.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "4.0.3",
"web-vitals": "^1.0.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

View File

@ -0,0 +1,36 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>

53
web_interface/src/App.js Normal file
View File

@ -0,0 +1,53 @@
import React, { useState, useEffect } from 'react';
import axios from 'axios';
axios.defaults.baseURL = process.env.REACT_APP_SERVER;
function App() {
const [global, setGlobal] = useState(false);
useEffect(() => {
const get = async() => {
try {
const res = await axios.get('/api/global');
setGlobal(res.data);
} catch (error) {
setGlobal(false);
}
};
const interval = setInterval(get, 500);
return () => clearInterval(interval);
}, []);
return (
<div className="app">
{global &&
<>
<p>Name: {global.name}</p>
<p>Pos: {global.pos}</p>
<p>Yaw: {global.yaw}</p>
<p>Pitch: {global.pitch}</p>
<p>Dimention: {global.dimension}</p>
<p>Players:
{Object.values(global.players).map(x =>
<div>
{global.player_names[x.player_uuid]}
</div>
)}
</p>
<p>Holding: {global.holding}</p>
<p>AFK: {`${global.afk}`}</p>
<p>Health: {global.health}</p>
<p>Food: {global.food}</p>
<p>Time: {global.time}</p>
</>
}
</div>
);
}
export default App;

View File

@ -0,0 +1,10 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

11418
web_interface/yarn.lock Normal file

File diff suppressed because it is too large Load Diff