From 2b33f89d8c94a0e2cba3e226d260354e041d0b28 Mon Sep 17 00:00:00 2001 From: j3d1 Date: Sun, 26 Nov 2023 21:47:24 +0000 Subject: [PATCH 01/76] Update Website/templates/documentation.html --- Website/templates/documentation.html | 92 ++++++++++++++-------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/Website/templates/documentation.html b/Website/templates/documentation.html index 29df8c7..3af2f42 100644 --- a/Website/templates/documentation.html +++ b/Website/templates/documentation.html @@ -1,47 +1,47 @@ - - - - Documentation - - - - - -
-

index page | user and tag list

-

https://hannover.ccc.de/gitlab/anton/matekasse

-
-

Documentation

- -

 

-
-

API:

-

http://matekasse.server.c3h/api/tag_id?={tag_id}

-

Response: - {"mode":"error" "error":"{error}"} or - {"mode":"message","username":"{username}","message":"{message}"} or - {"mode":"balance", "username":"{username}", "balance":"{balance}"} -

-

-

http://matekasse.server.c3h/api/change?id={user_id}&?change={change}

-

- If change = None or NaN the change will be -1 -

-

- Response: - {"mode":"error" "error":"{error}"} or - {"mode":"balance", "username":"{username}", "balance":"{balance}"} -

-

-

Error Codes:

-

170: Tag already exists

-

054: Tag does not exists

-

757: Usere already exists

-

043: User does not exists

-

352: Timeout

-

095: Input is not a Number

-

418: I'm a teapot

-
- - + + + + Documentation + + + + + +
+

index page | user and tag list

+

https://hannover.ccc.de/gitlab/anton/matekasse

+
+

Documentation

+ +

 

+
+

API:

+

http://matekasse.server.c3h/api/tag_id?={tag_id}

+

Response: + {"mode":"error" "error":"{error}"} or + {"mode":"message","username":"{username}","message":"{message}"} or + {"mode":"balance", "username":"{username}", "balance":"{balance}"} +

+

+

http://matekasse.server.c3h/api/change?id={user_id}&?change={change}

+

+ If change = None or NaN the change will be -1 +

+

+ Response: + {"mode":"error" "error":"{error}"} or + {"mode":"balance", "username":"{username}", "balance":"{balance}"} +

+

+

Error Codes:

+

170: Tag already in use

+

054: Tag does not exists

+

757: User already exists

+

043: User does not exists

+

352: Timeout

+

095: Input is not a Number

+

418: I'm a teapot

+
+ + \ No newline at end of file From d9aff6a56a01b6293f360d2ddb0d94400d7dd81a Mon Sep 17 00:00:00 2001 From: 2000-Trek Date: Fri, 1 Dec 2023 23:23:11 +0100 Subject: [PATCH 02/76] Documentation api to post --- Website/templates/documentation.html | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Website/templates/documentation.html b/Website/templates/documentation.html index 3af2f42..17f04e1 100644 --- a/Website/templates/documentation.html +++ b/Website/templates/documentation.html @@ -16,14 +16,16 @@

 

API:

-

http://matekasse.server.c3h/api/tag_id?={tag_id}

+

http://matekasse.server.c3h/api/tag_id

+

Post method "id"= tag id

Response: {"mode":"error" "error":"{error}"} or {"mode":"message","username":"{username}","message":"{message}"} or {"mode":"balance", "username":"{username}", "balance":"{balance}"}



-

http://matekasse.server.c3h/api/change?id={user_id}&?change={change}

+

http://matekasse.server.c3h/api/change

+

Post method "id" = user id, "change"=change

If change = None or NaN the change will be -1

From 3832282101a225e7b56c413fbb3aba848b3dc9a0 Mon Sep 17 00:00:00 2001 From: 2000-Trek Date: Sat, 2 Dec 2023 17:27:36 +0100 Subject: [PATCH 03/76] change balance next to balance --- Website/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/__init__.py b/Website/__init__.py index 856b26a..699b1dd 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -83,7 +83,7 @@ def create_app(test_config=None): users = c.fetchall() text = "" for i in users: - text = text + f'

{escape(i[1])}: {i[2]/100}€



' + text = text + f'

{escape(i[1])}: {i[2]/100}€



' return ''' From f927a70f6058965dd94ff82b36e6c1918e02f43c Mon Sep 17 00:00:00 2001 From: 2000-Trek Date: Sat, 2 Dec 2023 18:14:34 +0100 Subject: [PATCH 04/76] removed get method from /api/change --- Website/__init__.py | 9 +++------ Website/templates/documentation.html | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index 699b1dd..266a535 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -108,7 +108,7 @@ def create_app(test_config=None): c.execute("SELECT * FROM transaction_log ORDER BY ROWID DESC LIMIT 100") transactionlist = c.fetchall() for i in transactionlist: - text = text + f"

{i[0]} userid: {i[1]} {i[2]} {i[3]} to {i[4]}

" + text = text + f'
{i[0]} userid: {i[1]} {i[2]} {i[3]} to {i[4]}

' return text @app.route("/list/user", methods=['GET']) @@ -327,14 +327,11 @@ def create_app(test_config=None): leave_room(session[id]) #api - @app.route("/api/change", methods=['GET', 'POST']) + @app.route("/api/balance", methods=['POST']) def api_change(): db = get_db() c = db.cursor() - try: - userid = request.form["id"] - except: - userid = request.args.get("id") + userid = request.form["id"] c.execute("SELECT * FROM users WHERE id=?", [userid]) user_list = c.fetchall() if user_list != []: diff --git a/Website/templates/documentation.html b/Website/templates/documentation.html index 17f04e1..ccc6024 100644 --- a/Website/templates/documentation.html +++ b/Website/templates/documentation.html @@ -24,7 +24,7 @@ {"mode":"balance", "username":"{username}", "balance":"{balance}"}



-

http://matekasse.server.c3h/api/change

+

http://matekasse.server.c3h/api/balance

Post method "id" = user id, "change"=change

If change = None or NaN the change will be -1 From e11512f458001b9794d41551100d38760bbfc8ae Mon Sep 17 00:00:00 2001 From: 2000-Trek Date: Wed, 20 Dec 2023 19:47:38 +0100 Subject: [PATCH 05/76] 1 ct --- Website/__init__.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index 266a535..81bfd0a 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -83,7 +83,7 @@ def create_app(test_config=None): users = c.fetchall() text = "" for i in users: - text = text + f'

{escape(i[1])}: {i[2]/100}€



' + text = text + f'

{escape(i[1])}: {i[2]/100}€



' return ''' @@ -137,7 +137,7 @@ def create_app(test_config=None):

{escape(user[1])} : {escape(user[2]/100)}€

-

+



Tags:

@@ -206,7 +206,6 @@ def create_app(test_config=None): try: user_id = request.form["id"] change = float(request.form["change"]) - print(change) except: return render_template("error.html", error_code="095") c.execute(f"SELECT * FROM users WHERE id=?", [user_id]) From e9acd07fb469a9c490ea23294644ef13b8d84ec3 Mon Sep 17 00:00:00 2001 From: bton Date: Wed, 14 Feb 2024 20:52:50 +0100 Subject: [PATCH 06/76] test --- Website/__init__.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Website/__init__.py b/Website/__init__.py index 81bfd0a..2c06ae1 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -358,6 +358,7 @@ def create_app(test_config=None): c = db.cursor() try: tag_id = request.form["id"] + print(tag_id) except: tag_id = request.args.get("id") c.execute(f"SELECT * FROM tags WHERE tagid=?", [tag_id]) @@ -427,4 +428,4 @@ def create_app(test_config=None): def documentation(): return render_template("documentation.html") - return {"app":app,"socketio":socketio} \ No newline at end of file + return {"app":app,"socketio":socketio} From 56aa79378bdd52962640da1678f1ad7b00f85ec2 Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 16 Feb 2024 19:54:32 +0100 Subject: [PATCH 07/76] Doc Input Error --- Website/templates/documentation.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Website/templates/documentation.html b/Website/templates/documentation.html index ccc6024..c20f963 100644 --- a/Website/templates/documentation.html +++ b/Website/templates/documentation.html @@ -42,8 +42,9 @@

043: User does not exists

352: Timeout

095: Input is not a Number

+

638: Wrong Input

418: I'm a teapot

- \ No newline at end of file + From 64580f02cb20e2ee5dd33acb65f3eb119e5ecca0 Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 16 Feb 2024 21:19:11 +0100 Subject: [PATCH 08/76] New error --- Website/__init__.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index 2c06ae1..d6deb4d 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -358,9 +358,8 @@ def create_app(test_config=None): c = db.cursor() try: tag_id = request.form["id"] - print(tag_id) except: - tag_id = request.args.get("id") + return make_response(json.dumps({"mode":"error", "error":"638"})) c.execute(f"SELECT * FROM tags WHERE tagid=?", [tag_id]) tag_list = c.fetchall() From fd5fd4d78c7a5bb8a30a65995ba058bca09b0844 Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 16 Feb 2024 22:51:32 +0100 Subject: [PATCH 09/76] =?UTF-8?q?-1.5=E2=82=AC=20Button=20und=20preis=20va?= =?UTF-8?q?r?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Website/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index d6deb4d..71b264c 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -6,7 +6,7 @@ from markupsafe import escape from .db import get_db from datetime import datetime finished = None - +preis = 1.5 #Ein Getraenk #flask_config DATABASE = './Website/mate.db' @@ -83,7 +83,7 @@ def create_app(test_config=None): users = c.fetchall() text = "" for i in users: - text = text + f'

{escape(i[1])}: {i[2]/100}€



' + text = text + f'

{escape(i[1])}: {i[2]/100}€



' return ''' @@ -350,7 +350,7 @@ def create_app(test_config=None): return make_response(json.dumps({"mode":"error","error":"043"})) - @app.route("/api/tag_id", methods=['GET', 'POST']) + @app.route("/api/tag_id", methods=['POST']) def get_id(): global finished global message @@ -410,7 +410,7 @@ def create_app(test_config=None): if user_list != []: balance_old = user_list[0][2] if user_queue.qsize() == 0: - c.execute(f"UPDATE users SET balance = balance - 150 WHERE id={tag[1]}") + c.execute(f"UPDATE users SET balance = balance - {preis*100} WHERE id={tag[1]}") db.commit() c.execute(f"SELECT * FROM users WHERE id={tag[1]}") user = c.fetchone() From 2432eed1ae6aff9fed97fd4994e0cdc8a925bb5e Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 16 Feb 2024 23:11:12 +0100 Subject: [PATCH 10/76] Doc repariert --- Website/templates/documentation.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Website/templates/documentation.html b/Website/templates/documentation.html index c20f963..a706288 100644 --- a/Website/templates/documentation.html +++ b/Website/templates/documentation.html @@ -17,7 +17,7 @@

API:

http://matekasse.server.c3h/api/tag_id

-

Post method "id"= tag id

+

Post method {"id":tag_id}

Response: {"mode":"error" "error":"{error}"} or {"mode":"message","username":"{username}","message":"{message}"} or @@ -25,7 +25,7 @@



http://matekasse.server.c3h/api/balance

-

Post method "id" = user id, "change"=change

+

Post method {"id":user_id, "change":change}

If change = None or NaN the change will be -1

From 5179ec792cb14e80edf5728d694988d8cfa32366 Mon Sep 17 00:00:00 2001 From: bton Date: Sat, 17 Feb 2024 02:12:27 +0100 Subject: [PATCH 11/76] jinja --- Website/__init__.py | 104 ++++------------------------ Website/templates/adduser.html | 2 +- Website/templates/confirmation.html | 17 +++++ Website/templates/index.html | 11 +++ Website/templates/list.html | 29 ++++++++ Website/templates/redirect.html | 8 +++ Website/templates/removeuser.html | 9 +++ Website/templates/user.html | 39 +++++++++++ 8 files changed, 128 insertions(+), 91 deletions(-) create mode 100644 Website/templates/confirmation.html create mode 100644 Website/templates/index.html create mode 100644 Website/templates/list.html create mode 100644 Website/templates/redirect.html create mode 100644 Website/templates/removeuser.html create mode 100644 Website/templates/user.html diff --git a/Website/__init__.py b/Website/__init__.py index 71b264c..dc82896 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -1,5 +1,5 @@ import queue, time, uuid, json, logging, datetime, os -from flask import Flask, render_template, request, make_response, session, send_file, g +from flask import Flask, render_template, render_template_string, request, make_response, session, send_file, g from flask_socketio import SocketIO, join_room, leave_room from flask_session import Session from markupsafe import escape @@ -10,13 +10,6 @@ preis = 1.5 #Ein Getraenk #flask_config DATABASE = './Website/mate.db' -#def create_logs(app): -# now = datetime.datetime.now().strftime('%d-%m-%Y-%H-%M-%S') -# logging.basicConfig(filename=f"logs/matekasse-{now}.log",filemode='w', format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' ,encoding='utf-8', level=logging.INFO) -# app.logger = logging.getLogger('db') -# -# app.logger.info("Website is starting") - def log(type=None, userid=None, before=None, after=None): db = get_db() c = db.cursor() @@ -64,16 +57,7 @@ def create_app(test_config=None): @app.route("/") def index(): - return """ - user and tag list -

The creator of this website accepts no liability for any linguistic or technical errors!

-

- Doumentation - - """ + return render_template("index.html") @app.route("/list") def list(): @@ -81,24 +65,7 @@ def create_app(test_config=None): c = db.cursor() c.execute("SELECT * FROM users") users = c.fetchall() - text = "" - for i in users: - text = text + f'

{escape(i[1])}: {i[2]/100}€



' - return ''' - - - - Strichliste -

user and tag list | Documentation

-
-
-

- ''' + text + '' + return render_template("list.html", users=users, preis=preis) @app.route("/transactionlist") def transactionlist(): @@ -117,41 +84,18 @@ def create_app(test_config=None): c = db.cursor() id = request.args.get("id") c.execute(f"SELECT * FROM users WHERE id=?", [id]) - user_list = c.fetchall() - if user_list != []: - user = user_list[0] + user = c.fetchone() + if user != None : c.execute(f"SELECT * FROM tags WHERE userid={user[0]}") tags = c.fetchall() - text = "" - for tag in tags: - text = text + f'

' - return f""" - - - - {escape(user[1])} -

user and tag list | Documentation

-

{escape(user[1])} : {escape(user[2]/100)}€

-

-
-

-

-

-

Tags:

- {text} -

-
- - """ + return render_template("user.html", user=user, tags=tags) + else: return render_template("error.html", error_code="043") - + @app.route("/adduser", methods=['POST']) def new_user(): - return render_template("adduser.html") + return render_template("adduser.html") @app.route("/removeuser", methods=['POST']) def remove_user(): @@ -166,9 +110,8 @@ def create_app(test_config=None): app.logger.info(f"Deleted all tags from user ?", [user_id]) c.execute(f"DELETE FROM users WHERE id=?", [user_id]) db.commit() - log(type="removeuser", userid=user_id, before=user_name) socketio.emit("update", "update") - return f'remove user

user and tag list | Documentation

Deleted user {escape(user_name)}

return to the tags and user list

' + return render_template("removeuser.html", user_name=user_name) else: return render_template("error.html", error_code="043") @@ -186,15 +129,8 @@ def create_app(test_config=None): socketio.emit("update", "update") c.execute(f"SELECT * FROM users WHERE username=?", [username]) user = c.fetchone() - log(type="adduser", userid=user[0], after=user[1]) - return """ - - -

tag was sucsesfully added

- - """ + return render_template("redirect.html") + else: return render_template("error.html", error_code="757") @@ -218,13 +154,7 @@ def create_app(test_config=None): user = c.fetchone() log(type="balance", userid=user[0], before=balance_old, after=user[2]) socketio.emit("update", "update") - return """ - - - - """ + return render_template("redirect.html") else: return render_template("error.html", error_code="043") @@ -288,13 +218,7 @@ def create_app(test_config=None): db.commit() message = f"Removed {tag_id} from user {user_id}" log(type="removetag", userid=user_id, before=tag_id) - return f""" - - - - """ + return render_template("redirect.html") else: return render_template("error.html", error_code="054") diff --git a/Website/templates/adduser.html b/Website/templates/adduser.html index 7368ebe..a1a74e0 100644 --- a/Website/templates/adduser.html +++ b/Website/templates/adduser.html @@ -5,4 +5,4 @@

- \ No newline at end of file + diff --git a/Website/templates/confirmation.html b/Website/templates/confirmation.html new file mode 100644 index 0000000..b6b96e4 --- /dev/null +++ b/Website/templates/confirmation.html @@ -0,0 +1,17 @@ + + + + diff --git a/Website/templates/index.html b/Website/templates/index.html new file mode 100644 index 0000000..75f4c32 --- /dev/null +++ b/Website/templates/index.html @@ -0,0 +1,11 @@ + + user and tag list +

The creator of this website accepts no liability for any linguistic or technical errors!

+

+ Doumentation + + + diff --git a/Website/templates/list.html b/Website/templates/list.html new file mode 100644 index 0000000..37e1a42 --- /dev/null +++ b/Website/templates/list.html @@ -0,0 +1,29 @@ + + + + + Strichliste +

user and tag list | Documentation

+
+
+

+ {% for i in users %} +
+

+ {{i[1]|safe}}: {{i[2]/100}}€ +

+ + +
+
+ + +
+

+ {% endfor %} + diff --git a/Website/templates/redirect.html b/Website/templates/redirect.html new file mode 100644 index 0000000..9848c78 --- /dev/null +++ b/Website/templates/redirect.html @@ -0,0 +1,8 @@ + + + +

redirekting

+ destination + diff --git a/Website/templates/removeuser.html b/Website/templates/removeuser.html new file mode 100644 index 0000000..b6c9ea6 --- /dev/null +++ b/Website/templates/removeuser.html @@ -0,0 +1,9 @@ + + remove user +

+

+ user and tag list | Documentation +

+

Deleted user {{user_name|safe}}

+ return to the tags and user list +

diff --git a/Website/templates/user.html b/Website/templates/user.html new file mode 100644 index 0000000..db30f4b --- /dev/null +++ b/Website/templates/user.html @@ -0,0 +1,39 @@ + + + + + {{user[1]|safe}} +

user and tag list | Documentation

+

{{user[1]|safe}} : {{user[2]/100}}€

+

+ + +
+
+ + +
+

+
+ + +
+

+

+

Tags:

+ {% for tag in tags %} +

+

+ + + + +
+

+ {% endfor %} +

+
+ From 66babf1b2c4791a9680129cb098947d7e9839405 Mon Sep 17 00:00:00 2001 From: bton Date: Sat, 17 Feb 2024 02:14:08 +0100 Subject: [PATCH 12/76] delted stuff --- main.py | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 main.py diff --git a/main.py b/main.py deleted file mode 100644 index 6376dba..0000000 --- a/main.py +++ /dev/null @@ -1,20 +0,0 @@ -from venv import create -from Website import create_app -from flask_socketio import SocketIO -import atexit, sqlite3, sys, datetime, logging - -app_data = create_app() -app = app_data["app"] - -def exit_handler(): - sys.exit("Program sucsesfully exited") - -def main(): - app_data = create_app() - app = app_data["app"] - socketio = app_data["socketio"] - atexit.register(exit_handler) - socketio.run(app, host='0.0.0.0', port=5000) - -if __name__ == "__main__": - main() \ No newline at end of file From 55124040aed8febc6992ab6e3c182b6fd483e97e Mon Sep 17 00:00:00 2001 From: bton Date: Sat, 17 Feb 2024 02:16:49 +0100 Subject: [PATCH 13/76] fixed the README --- README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README b/README index 7886119..b3e92b0 100644 --- a/README +++ b/README @@ -8,5 +8,5 @@ How to get started: create the log folder: mkdir logs start the program: - python main.py - You can now accses the Website on http://127.0.0.1:5000 \ No newline at end of file + venv/bin/gunicorn -b "127.0.0.1:5000" -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 main:app + You can now accses the Website on http://127.0.0.1:5000 From d55b7c5aea1c7c0721a16e03642d83093915563d Mon Sep 17 00:00:00 2001 From: bton Date: Tue, 20 Feb 2024 17:33:56 +0100 Subject: [PATCH 14/76] balance get api --- Website/__init__.py | 56 +++++++++++++++++----------- Website/templates/documentation.html | 1 + 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index dc82896..7e5af6b 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -249,29 +249,41 @@ def create_app(test_config=None): socketio.emit("error", "418", to=session[id]) leave_room(session[id]) - #api - @app.route("/api/balance", methods=['POST']) + @app.route("/api/balance", methods=['POST', 'GET']) def api_change(): - db = get_db() - c = db.cursor() - userid = request.form["id"] - c.execute("SELECT * FROM users WHERE id=?", [userid]) - user_list = c.fetchall() - if user_list != []: - user = user_list[0] - try: - change = int(request.args.get("change")) - except: - change = -1.5 - c.execute(f"UPDATE users SET balance = balance + {change*100} WHERE id={user[0]}") - db.commit() - c.execute(f"SELECT * FROM users WHERE id = {userid}") - user_new = c.fetchone() - log(type="balance", userid=user[0], before=user[2], after=user_new[2]) - socketio.emit("update", "update") - return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user_new[2]})) - else: - return make_response(json.dumps({"mode":"error","error":"043"})) + if request.method == 'POST': + db = get_db() + c = db.cursor() + userid = request.form["id"] + c.execute("SELECT * FROM users WHERE id=?", [userid]) + user_list = c.fetchall() + if user_list != []: + user = user_list[0] + try: + change = int(request.args.get("change")) + except: + change = -1.5 + c.execute(f"UPDATE users SET balance = balance + {change*100} WHERE id={user[0]}") + db.commit() + c.execute(f"SELECT * FROM users WHERE id = {userid}") + user_new = c.fetchone() + log(type="balance", userid=user[0], before=user[2], after=user_new[2]) + socketio.emit("update", "update") + return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user_new[2]})) + else: + return make_response(json.dumps({"mode":"error","error":"043"})) + + elif request.method == 'GET': + db = get_db() + c = db.cursor() + userid = reqest.args.get("id") + c.execute("SELECT * FROM users WHERE id=?", [userid]) + user = c.fetchone() + if user != None: + return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user[2]})) + else: + return make_response(json.dumps({"mode":"error", "error":"043"})) + @app.route("/api/tag_id", methods=['POST']) diff --git a/Website/templates/documentation.html b/Website/templates/documentation.html index a706288..d290e17 100644 --- a/Website/templates/documentation.html +++ b/Website/templates/documentation.html @@ -29,6 +29,7 @@

If change = None or NaN the change will be -1

+

Get method ?id=user_id

Response: {"mode":"error" "error":"{error}"} or From 8d25e0b6459c9e11c213ef934c1fa9c8a8acc57f Mon Sep 17 00:00:00 2001 From: bton Date: Tue, 20 Feb 2024 18:05:14 +0100 Subject: [PATCH 15/76] main.py wird doch gebraucht --- Website/templates/list.html | 2 +- Website/templates/user.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Website/templates/list.html b/Website/templates/list.html index 37e1a42..247da05 100644 --- a/Website/templates/list.html +++ b/Website/templates/list.html @@ -1,5 +1,5 @@ - + - - \ No newline at end of file +{% extends "base.html" %} +{% block customscript %} + +{% endblock %} diff --git a/Website/templates/adduser.html b/Website/templates/adduser.html index a1a74e0..1d2c97a 100644 --- a/Website/templates/adduser.html +++ b/Website/templates/adduser.html @@ -1,8 +1,10 @@ - - - add user -

user and tag list | Documentation

-

-

-

- +{% extends "base.html" %} +{% block title %} +add user +{% endblock %} +{% block content %} +
+ +
+

+{% endblock %} diff --git a/Website/templates/base.html b/Website/templates/base.html index 0925b8d..07f8b40 100644 --- a/Website/templates/base.html +++ b/Website/templates/base.html @@ -1,17 +1,24 @@ - - - {% block title %} {% endblock %} - FlaskApp - - - - -
-
- {% block content %} {% endblock %} -
- + + {% block title %}{% endblock %} + + + {% block customscript %}{% endblock %} + + + +
+
+ {% block content %} {% endblock %} +
+ \ No newline at end of file diff --git a/Website/templates/change.html b/Website/templates/change.html index c2d9635..e2d4a92 100644 --- a/Website/templates/change.html +++ b/Website/templates/change.html @@ -1,6 +1,5 @@ - - - +{% extends "base.html" %} +{% block customscript %} - \ No newline at end of file +{% endblock %} \ No newline at end of file diff --git a/Website/templates/confirmation.html b/Website/templates/confirmation.html index b6b96e4..0c676e2 100644 --- a/Website/templates/confirmation.html +++ b/Website/templates/confirmation.html @@ -1,17 +1,16 @@ - - - - +{% extends "base.html" %} +{% block customscript %} + +{% endblock %} diff --git a/Website/templates/documentation.html b/Website/templates/documentation.html index d290e17..16c3c95 100644 --- a/Website/templates/documentation.html +++ b/Website/templates/documentation.html @@ -1,16 +1,11 @@ - - - - Documentation - - - - - - +{% extends "base.html" %} +{% block title %} +Documentation +{% endblock %} +{% block customscript %} + +{% endblock %} +{% block content %}

Documentation

 

@@ -46,6 +41,4 @@

638: Wrong Input

418: I'm a teapot

- - - +{% endblock %} diff --git a/Website/templates/error.html b/Website/templates/error.html index 00fb406..08b73df 100644 --- a/Website/templates/error.html +++ b/Website/templates/error.html @@ -1,8 +1,8 @@ - - - Error -

user and tag list | Documentation

-

+{% extends "base.html" %} +{% block title %}Error{% endblock %} +{% block customscript %} +

user and tag list | Documentation

+

Error: {{error_code}} -

- \ No newline at end of file +

+{% endblock %} \ No newline at end of file diff --git a/Website/templates/index.html b/Website/templates/index.html index 75f4c32..68e5bbc 100644 --- a/Website/templates/index.html +++ b/Website/templates/index.html @@ -1,11 +1,12 @@ - - user and tag list +{% extends "base.html" %} +{% block customscript %} + +{% endblock %} +{% block content %} +user and tag list

The creator of this website accepts no liability for any linguistic or technical errors!



Doumentation - - - +{% endblock %} diff --git a/Website/templates/list.html b/Website/templates/list.html index e03038e..6196ea5 100644 --- a/Website/templates/list.html +++ b/Website/templates/list.html @@ -1,29 +1,35 @@ - - - - - Strichliste -

user and tag list | Documentation

-
-
-

- {% for i in users %} -
-

- {{i[1]|safe}}: {{i[2]/100}}€ -

- - -
-
- - -
-

- {% endfor %} - +{% extends "base.html" %} +{% block title %} +Strichliste +{% endblock %} +{% block customscript %} + +{% endblock %} +{% block content %} +
+ +
+
+ +
+

+{% for i in users %} +
+

+ {{i[1]|safe}}: {{i[2]/100}}€ +

+ + +
+
+ + +
+

+{% endfor %} +{% endblock %} diff --git a/Website/templates/redirect.html b/Website/templates/redirect.html index 9848c78..089634e 100644 --- a/Website/templates/redirect.html +++ b/Website/templates/redirect.html @@ -1,8 +1,12 @@ - - - -

redirekting

- destination - +{% extends "base.html" %} +{% block title %} +{% endblock %} +{% block content %} +

redirekting

+destination +{% endblock %} +{% block customscript %} + +{% endblock %} diff --git a/Website/templates/removetag.html b/Website/templates/removetag.html index f84d34d..42b87d7 100644 --- a/Website/templates/removetag.html +++ b/Website/templates/removetag.html @@ -1,7 +1,6 @@ - - - - - \ No newline at end of file +{% endblock %} diff --git a/Website/templates/removeuser.html b/Website/templates/removeuser.html index b6c9ea6..1e2031d 100644 --- a/Website/templates/removeuser.html +++ b/Website/templates/removeuser.html @@ -1,9 +1,10 @@ - - remove user +{% extends "base.html" %} +{% block title %} + remove user +{% endblock %} +{% block content %}

-

- user and tag list | Documentation -

Deleted user {{user_name|safe}}

return to the tags and user list

+{% endblock %} diff --git a/Website/templates/user.html b/Website/templates/user.html index 4bafdf4..7bdb05a 100644 --- a/Website/templates/user.html +++ b/Website/templates/user.html @@ -1,39 +1,46 @@ - - - - - {{user[1]|safe}} -

user and tag list | Documentation

-

{{user[1]|safe}} : {{user[2]/100}}€

-

- - -
-
- - -
-

-
- - -
-

-

-

Tags:

- {% for tag in tags %} -

-

- - - - -
-

- {% endfor %} -

-
- +{% extends "base.html" %} +{% block customscript %} + +{% endblock %} +{% block title %} + {{user[1]|safe}} +{% endblock %} +{% block content %} +

user and tag list | Documentation

+

{{user[1]|safe}} : {{user[2]/100}}€

+

+ + +
+
+ + +
+

+
+ + +
+

+

+

Tags:

+{% for tag in tags %} +

+

+ + + + +
+

+{% endfor %} +

+
+ +
+{% endblock %} From 1f227df35892cd4acb7aa597615c75e55a7684fc Mon Sep 17 00:00:00 2001 From: lubiana Date: Wed, 21 Feb 2024 22:13:24 +0100 Subject: [PATCH 20/76] hupsala noch was vergessen --- Website/templates/user.html | 1 - 1 file changed, 1 deletion(-) diff --git a/Website/templates/user.html b/Website/templates/user.html index 7bdb05a..eca6f5f 100644 --- a/Website/templates/user.html +++ b/Website/templates/user.html @@ -11,7 +11,6 @@ {{user[1]|safe}} {% endblock %} {% block content %} -

user and tag list | Documentation

{{user[1]|safe}} : {{user[2]/100}}€

From 109f7eb4c28fb64ea486f042a9850acb9252c262 Mon Sep 17 00:00:00 2001 From: bton Date: Wed, 21 Feb 2024 23:33:32 +0100 Subject: [PATCH 21/76] removed lines from main.py --- main.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/main.py b/main.py index c37091a..96d2fb1 100644 --- a/main.py +++ b/main.py @@ -3,9 +3,6 @@ from Website import create_app from flask_socketio import SocketIO import atexit, sqlite3, sys, datetime, logging -app_data = create_app() -app = app_data["app"] - def exit_handler(): sys.exit("Program sucsesfully exited") From 34eb392ce0304288480426ea7a695283bc870611 Mon Sep 17 00:00:00 2001 From: bton Date: Wed, 21 Feb 2024 23:36:32 +0100 Subject: [PATCH 22/76] doch nicht --- main.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/main.py b/main.py index 96d2fb1..c37091a 100644 --- a/main.py +++ b/main.py @@ -3,6 +3,9 @@ from Website import create_app from flask_socketio import SocketIO import atexit, sqlite3, sys, datetime, logging +app_data = create_app() +app = app_data["app"] + def exit_handler(): sys.exit("Program sucsesfully exited") From ccb4d64cde653b4861acc1029ee1be95feb87a4c Mon Sep 17 00:00:00 2001 From: bton Date: Thu, 22 Feb 2024 00:04:59 +0100 Subject: [PATCH 23/76] Updated README --- README | 2 -- 1 file changed, 2 deletions(-) diff --git a/README b/README index b3e92b0..e86ae96 100644 --- a/README +++ b/README @@ -5,8 +5,6 @@ How to get started: source venv/bin/activate install requiremens: pip install -r requirements.txt - create the log folder: - mkdir logs start the program: venv/bin/gunicorn -b "127.0.0.1:5000" -k geventwebsocket.gunicorn.workers.GeventWebSocketWorker -w 1 main:app You can now accses the Website on http://127.0.0.1:5000 From 701d9c2f1ed546fa769cee8874e11957c938be21 Mon Sep 17 00:00:00 2001 From: bton Date: Thu, 22 Feb 2024 00:19:59 +0100 Subject: [PATCH 24/76] =?UTF-8?q?main=20wurde=20ges=C3=A4ubert?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/main.py b/main.py index c37091a..776c459 100644 --- a/main.py +++ b/main.py @@ -10,8 +10,6 @@ def exit_handler(): sys.exit("Program sucsesfully exited") def main(): - app_data = create_app() - app = app_data["app"] socketio = app_data["socketio"] atexit.register(exit_handler) socketio.run(app, host='0.0.0.0', port=5000) From 1a51402170223b3b2f9e1349771158f982c087fb Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 23 Feb 2024 22:47:12 +0100 Subject: [PATCH 25/76] float to int --- Website/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index 5cc2176..05ff891 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -141,14 +141,14 @@ def create_app(test_config=None): c = db.cursor() try: user_id = request.form["id"] - change = float(request.form["change"]) + change = int(request.form["change"] * 100) except: return render_template("error.html", error_code="095") c.execute(f"SELECT * FROM users WHERE id=?", [user_id]) users = c.fetchall() if users != []: balance_old = users[0][2] - c.execute(f"UPDATE users SET balance = balance + {change*100} WHERE id={user_id}") + c.execute(f"UPDATE users SET balance = balance + {change} WHERE id={user_id}") db.commit() c.execute(f"SELECT * FROM users WHERE id={user_id}") user = c.fetchone() From 389e6ffcee9dac53e5432e71237c1089159915d5 Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 23 Feb 2024 22:49:25 +0100 Subject: [PATCH 26/76] AHHHHH --- Website/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index 05ff891..722a152 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -141,14 +141,14 @@ def create_app(test_config=None): c = db.cursor() try: user_id = request.form["id"] - change = int(request.form["change"] * 100) + change = float(request.form["change"]) except: return render_template("error.html", error_code="095") c.execute(f"SELECT * FROM users WHERE id=?", [user_id]) users = c.fetchall() if users != []: balance_old = users[0][2] - c.execute(f"UPDATE users SET balance = balance + {change} WHERE id={user_id}") + c.execute(f"UPDATE users SET balance = balance + {change * 100} WHERE id={user_id}") db.commit() c.execute(f"SELECT * FROM users WHERE id={user_id}") user = c.fetchone() From a8fec178e6957ff36ee9d6f8608d886a9ae84897 Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 23 Feb 2024 23:57:31 +0100 Subject: [PATCH 27/76] fixed number errors --- Website/__init__.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index 722a152..2d65eb9 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -141,14 +141,15 @@ def create_app(test_config=None): c = db.cursor() try: user_id = request.form["id"] - change = float(request.form["change"]) + change = int(float(request.form["change"]) * 100) + print(change) except: return render_template("error.html", error_code="095") c.execute(f"SELECT * FROM users WHERE id=?", [user_id]) users = c.fetchall() if users != []: balance_old = users[0][2] - c.execute(f"UPDATE users SET balance = balance + {change * 100} WHERE id={user_id}") + c.execute(f"UPDATE users SET balance = balance + {change} WHERE id={user_id}") db.commit() c.execute(f"SELECT * FROM users WHERE id={user_id}") user = c.fetchone() From 64e0c340c3e5f1f05e53dd34d53946d0c91d0fc7 Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 23 Feb 2024 23:57:54 +0100 Subject: [PATCH 28/76] removed print --- Website/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/Website/__init__.py b/Website/__init__.py index 2d65eb9..d9f929f 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -142,7 +142,6 @@ def create_app(test_config=None): try: user_id = request.form["id"] change = int(float(request.form["change"]) * 100) - print(change) except: return render_template("error.html", error_code="095") c.execute(f"SELECT * FROM users WHERE id=?", [user_id]) From 5cb4dcc53356143f1a62a4ffb562e10b49d76d3b Mon Sep 17 00:00:00 2001 From: bton Date: Sat, 24 Feb 2024 00:14:43 +0100 Subject: [PATCH 29/76] float errors fixed --- Website/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/__init__.py b/Website/__init__.py index d9f929f..2bad171 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -141,7 +141,7 @@ def create_app(test_config=None): c = db.cursor() try: user_id = request.form["id"] - change = int(float(request.form["change"]) * 100) + change = int(float(request.form["change"]) * float(100)) except: return render_template("error.html", error_code="095") c.execute(f"SELECT * FROM users WHERE id=?", [user_id]) From ac907638e6d908ab27ca7610d59dd66a2de173b4 Mon Sep 17 00:00:00 2001 From: bton Date: Sun, 25 Feb 2024 17:24:44 +0100 Subject: [PATCH 30/76] log und so --- Website/__init__.py | 113 +++++++++++++++++++++--------------- Website/db.py | 27 ++++++++- Website/schema.sql | 11 ++-- Website/templates/base.html | 3 +- 4 files changed, 99 insertions(+), 55 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index 2bad171..5c70140 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -3,19 +3,13 @@ from flask import Flask, render_template, render_template_string, request, make_ from flask_socketio import SocketIO, join_room, leave_room from flask_session import Session from markupsafe import escape -from .db import get_db +from .db import get_db, change_db from datetime import datetime finished = None -preis = 1.5 #Ein Getraenk +preis = 150 #Ein Getraenk #flask_config DATABASE = './Website/mate.db' -def log(type=None, userid=None, before=None, after=None): - db = get_db() - c = db.cursor() - c.execute("INSERT or IGNORE INTO transaction_log (timestamp, userid, type, before, after) VALUES (?, ?, ?, ?, ?)", [datetime.now(), userid, type, before, after]) - db.commit() - def create_app(test_config=None): app = Flask(__name__) key = str(uuid.uuid4().hex) @@ -28,10 +22,9 @@ def create_app(test_config=None): try: os.makedirs(app.instance_path) + except OSError: pass - #with app.app_context(): - # create_logs(app) Session(app) socketio = SocketIO(app) @@ -51,10 +44,6 @@ def create_app(test_config=None): def favicon(): return send_file("../static/Logo_CCC.svg.png") - #@app.route('/socket.io.js') - #def socketiojs(): - # return url_for('static', filename='socket.io.js') - @app.route("/") def index(): return render_template("index.html") @@ -65,17 +54,54 @@ def create_app(test_config=None): c = db.cursor() c.execute("SELECT * FROM users") users = c.fetchall() - return render_template("list.html", users=users, preis=preis) + return render_template("list.html", users=users, preis=preis/100) @app.route("/transactionlist") def transactionlist(): db = get_db() c = db.cursor() text = "" - c.execute("SELECT * FROM transaction_log ORDER BY ROWID DESC LIMIT 100") + c.execute("SELECT * FROM transaction_log ORDER BY ROWID DESC LIMIT 1000") transactionlist = c.fetchall() for i in transactionlist: - text = text + f'{i[0]} userid: {i[1]} {i[2]} {i[3]} to {i[4]}

' + statement = i[1] + user_id = i[2] + before = i[3] + after = i[4] + change = i[5] + if statement == "balance": + reverse_statement = "balance" + reverse_user_id = user_id + reverse_before = None + reverse_after = None + reverse_change = change *(-1) + elif statement == "adduser": + reverse_statement = "removeuser" + reverse_user_id = user_id + reverse_before = after + reverse_after = None + reverse_change = None + elif statement == "removeuser": + reverse_statement = "adduser" + reverse_user_id = user_id + reverse_before = None + reverse_after = before + reverse_change = None + elif statement == "addtag": + reverse_statement = "removetag" + reverse_user_id = user_id + reverse_before = after + reverse_after = None + reverse_change = None + elif statement == "removetag": + reverse_statement = "addtag" + reverse_user_id = user_id + reverse_before = None + reverse_after = beforeaddtag + reverse_change = None + else: + raise Exception(statement) + text = text + f'

{i[0]} {statement} userid:{user_id} {before} {after} {change}



' return text @app.route("/list/user", methods=['GET']) @@ -103,13 +129,10 @@ def create_app(test_config=None): c = db.cursor() user_id = request.form["id"] c.execute(f"SELECT * FROM users WHERE id=?", [user_id]) - users = c.fetchall() - if users != []: - user_name = users[0][1] - c.execute(f"DELETE FROM tags WHERE userid=?", [user_id]) - app.logger.info(f"Deleted all tags from user ?", [user_id]) - c.execute(f"DELETE FROM users WHERE id=?", [user_id]) - db.commit() + user = c.fetchone() + if user != None: + user_name = user[1] + change_db("removeuser", user_id=user_id, before=user_name) socketio.emit("update", "update") return render_template("removeuser.html", user_name=user_name) else: @@ -124,13 +147,11 @@ def create_app(test_config=None): return render_template("error.html", error_code="418") c.execute("SELECT * FROM users WHERE username=?", [username]) if c.fetchall() == []: - c.execute("INSERT or IGNORE INTO users (username, balance) VALUES (?, 0)", [username]) - db.commit() + change_db("adduser", after=username) socketio.emit("update", "update") c.execute(f"SELECT * FROM users WHERE username=?", [username]) user = c.fetchone() return render_template("redirect.html") - else: return render_template("error.html", error_code="757") @@ -148,11 +169,7 @@ def create_app(test_config=None): users = c.fetchall() if users != []: balance_old = users[0][2] - c.execute(f"UPDATE users SET balance = balance + {change} WHERE id={user_id}") - db.commit() - c.execute(f"SELECT * FROM users WHERE id={user_id}") - user = c.fetchone() - log(type="balance", userid=user[0], before=balance_old, after=user[2]) + change_db("balance", change=change, user_id=user_id) socketio.emit("update", "update") return render_template("redirect.html") else: @@ -262,12 +279,8 @@ def create_app(test_config=None): try: change = int(request.args.get("change")) except: - change = -1.5 - c.execute(f"UPDATE users SET balance = balance + {change*100} WHERE id={user[0]}") - db.commit() - c.execute(f"SELECT * FROM users WHERE id = {userid}") - user_new = c.fetchone() - log(type="balance", userid=user[0], before=user[2], after=user_new[2]) + change = preis + change_db("balance", user_id=userid, change=change) socketio.emit("update", "update") return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user_new[2]})) else: @@ -290,8 +303,6 @@ def create_app(test_config=None): def get_id(): global finished global message - db = get_db() - c = db.cursor() try: tag_id = request.form["id"] except: @@ -315,20 +326,16 @@ def create_app(test_config=None): finished = queue_item return make_response(json.dumps({"mode":"error","error":"170"})) else: - c.execute(f"INSERT OR IGNORE INTO tags (tagid, userid) VALUES ({tag_id}, ?)", [user_id]) - db.commit() + change_db("addtag", after=tag_id) message = f"Added {tag_id} to {username}" - log(type="addtag", userid=user_id ,after=tag_id) finished = queue_item return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was added"})) elif state == "remove": c.execute(f"SELECT * FROM tags WHERE (tagid = {tag_id} AND userid = ?)", [user_id]) tags = c.fetchall() if tags != []: - c.execute(f"DELETE FROM tags WHERE (tagid = {tag_id} AND userid = ?)", [user_id]) db.commit() message = f"Removed {tag_id} from {username}" - log(type="removetag", userid=user_id, before=tag_id) finished = queue_item return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was removed"})) else: @@ -346,11 +353,9 @@ def create_app(test_config=None): if user_list != []: balance_old = user_list[0][2] if user_queue.qsize() == 0: - c.execute(f"UPDATE users SET balance = balance - {preis*100} WHERE id={tag[1]}") - db.commit() + change_db("balance", user_id=tag[1], change=preis) c.execute(f"SELECT * FROM users WHERE id={tag[1]}") user = c.fetchone() - log(type="balance", userid=user[0], before=balance_old, after=user[2]) socketio.emit("update", "update") return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user[2]/100})) else: @@ -358,6 +363,18 @@ def create_app(test_config=None): socketio.emit("update", "update") return make_response(json.dumps({"mode":"error","error":"054"})) + + @app.route("/api/change", methods=['POST']) + def reroll(): + statement = request.form["statement"] + user_id = request.form["user_id"] + before = request.form["before"] + after = request.form["after"] + change = request.form["change"] + change_db(statement, user_id, before, after, change) + socketio.emit("update", "update") + return render_template("index.html") + #Documentation @app.route("/documentation") def documentation(): diff --git a/Website/db.py b/Website/db.py index a805a88..9ad03a3 100644 --- a/Website/db.py +++ b/Website/db.py @@ -1,9 +1,34 @@ from re import M import sqlite3 - +from datetime import datetime import click from flask import current_app, g +def log(statement, user_id, before, after, change): + db = get_db() + c = db.cursor() + c.execute("INSERT INTO transaction_log (timestamp, type, user_id, before, after, change) VALUES (?, ?, ?, ?, ?, ?)", [datetime.now(), statement, user_id, before, after, change]) + db.commit() + +def change_db(statement, user_id=None, before=None, after=None, change=None): + db = get_db() + c = db.cursor() + if statement == "adduser" and after != None: + c.execute("INSERT or IGNORE INTO users (username, balance) VALUES (?, 0)", [after]) + user_id = c.lastrowid + elif statement == "removeuser" and user_id != None and before != None: + c.execute("DELETE FROM tags WHERE userid=?", [user_id]) + c.execute("DELETE FROM users WHERE id=?", [user_id]) + elif statement == "addtag" and after != None and user_id != None: + c.execute("INSERT OR IGNORE INTO tags (tagid, userid) VALUES ?, ?)", [after, user_id]) + elif statement == "removetag" and before != None and user_id != None: + c.execute("DELETE FROM tags WHERE (tagid = ? AND userid = ?)", [before, user_id]) + elif statement == "balance" and change != None and user_id != None: + c.execute("UPDATE users SET balance = balance + ? WHERE id=?", [change, user_id]) + else: + raise Exception("wrong or missing argument for change_db") + log(statement, user_id, before, after, change) + db.commit() def get_db(): if 'db' not in g: diff --git a/Website/schema.sql b/Website/schema.sql index 56a152e..70f454e 100644 --- a/Website/schema.sql +++ b/Website/schema.sql @@ -13,9 +13,10 @@ CREATE TABLE IF NOT EXISTS "tags" ( ); CREATE TABLE IF NOT EXISTS "transaction_log" ( "timestamp" INTEGER NOT NULL, - "userid" INTEGER NOT NULL, - "type" TEXT NOT NULL, - "before" TEXT, - "after" TEXT + "type" TEXT NOT NULL, + "user_id" INTEGER, + "before" TEXT, + "after" TEXT, + "change" INTEGER ); -COMMIT; \ No newline at end of file +COMMIT; diff --git a/Website/templates/base.html b/Website/templates/base.html index 07f8b40..763a753 100644 --- a/Website/templates/base.html +++ b/Website/templates/base.html @@ -14,6 +14,7 @@

index page | user and tag list | Documentation + | transactionlist


@@ -21,4 +22,4 @@ {% block content %} {% endblock %} - \ No newline at end of file + From 0147e61c6bb907570a59a8e8fd7fe3d86aa3a46e Mon Sep 17 00:00:00 2001 From: bton Date: Sun, 25 Feb 2024 17:36:36 +0100 Subject: [PATCH 31/76] Es muss im Stable getestet werden --- Website/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/__init__.py b/Website/__init__.py index 5c70140..45b4abb 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -326,7 +326,7 @@ def create_app(test_config=None): finished = queue_item return make_response(json.dumps({"mode":"error","error":"170"})) else: - change_db("addtag", after=tag_id) + change_db("addtag", after=tag_id, user_id=user_id) message = f"Added {tag_id} to {username}" finished = queue_item return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was added"})) From dc71f8dcf438b03a3a003ad0869664ece21b643f Mon Sep 17 00:00:00 2001 From: bton Date: Sun, 25 Feb 2024 17:53:25 +0100 Subject: [PATCH 32/76] ahh --- Website/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Website/__init__.py b/Website/__init__.py index 45b4abb..43666a8 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -301,6 +301,8 @@ def create_app(test_config=None): @app.route("/api/tag_id", methods=['POST']) def get_id(): + db = get_db() + c = db.curosor() global finished global message try: From 7f1f9089618ec0c8f2e6baa28c6149b9954149a4 Mon Sep 17 00:00:00 2001 From: bton Date: Sun, 25 Feb 2024 17:54:51 +0100 Subject: [PATCH 33/76] ahh --- Website/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Website/__init__.py b/Website/__init__.py index 43666a8..7697c3c 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -302,7 +302,7 @@ def create_app(test_config=None): @app.route("/api/tag_id", methods=['POST']) def get_id(): db = get_db() - c = db.curosor() + c = db.cursor() global finished global message try: From ce009a278b9c93bd140a38da837b1028e178d354 Mon Sep 17 00:00:00 2001 From: bton Date: Fri, 1 Mar 2024 21:59:30 +0100 Subject: [PATCH 34/76] new db system --- Website/__init__.py | 37 ++++++++++++++++++++---------- Website/db.py | 55 ++++++++++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 28 deletions(-) diff --git a/Website/__init__.py b/Website/__init__.py index 7697c3c..5d9bae9 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -3,7 +3,8 @@ from flask import Flask, render_template, render_template_string, request, make_ from flask_socketio import SocketIO, join_room, leave_room from flask_session import Session from markupsafe import escape -from .db import get_db, change_db +from .db import get_db +import .db as db from datetime import datetime finished = None preis = 150 #Ein Getraenk @@ -132,7 +133,7 @@ def create_app(test_config=None): user = c.fetchone() if user != None: user_name = user[1] - change_db("removeuser", user_id=user_id, before=user_name) + db.remove_user(user_id) socketio.emit("update", "update") return render_template("removeuser.html", user_name=user_name) else: @@ -147,7 +148,7 @@ def create_app(test_config=None): return render_template("error.html", error_code="418") c.execute("SELECT * FROM users WHERE username=?", [username]) if c.fetchall() == []: - change_db("adduser", after=username) + db.add_user(username) socketio.emit("update", "update") c.execute(f"SELECT * FROM users WHERE username=?", [username]) user = c.fetchone() @@ -169,7 +170,7 @@ def create_app(test_config=None): users = c.fetchall() if users != []: balance_old = users[0][2] - change_db("balance", change=change, user_id=user_id) + db.change_balance(user_id, change) socketio.emit("update", "update") return render_template("redirect.html") else: @@ -231,10 +232,8 @@ def create_app(test_config=None): c = db.cursor() c.execute(f"SELECT * FROM tags WHERE (tagid = ? AND userid = ?)", [tag_id, user_id]) if c.fetchall != []: - c.execute(f"DELETE FROM tags WHERE (tagid = ? AND userid = ?)", [tag_id, user_id]) - db.commit() + db.remove_tag(tag_id) message = f"Removed {tag_id} from user {user_id}" - log(type="removetag", userid=user_id, before=tag_id) return render_template("redirect.html") else: return render_template("error.html", error_code="054") @@ -279,8 +278,8 @@ def create_app(test_config=None): try: change = int(request.args.get("change")) except: - change = preis - change_db("balance", user_id=userid, change=change) + change = preis + db.change_balance(user_id, change) socketio.emit("update", "update") return make_response(json.dumps({"mode":"balance", "username":user[1], "balance":user_new[2]})) else: @@ -328,7 +327,7 @@ def create_app(test_config=None): finished = queue_item return make_response(json.dumps({"mode":"error","error":"170"})) else: - change_db("addtag", after=tag_id, user_id=user_id) + db.add_tag(user_id, tag_id) message = f"Added {tag_id} to {username}" finished = queue_item return make_response(json.dumps({"mode":"message","username":"{}".format(username),"message":"A tag was added"})) @@ -355,7 +354,7 @@ def create_app(test_config=None): if user_list != []: balance_old = user_list[0][2] if user_queue.qsize() == 0: - change_db("balance", user_id=tag[1], change=preis) + db.change_balance(tag[1], preis) c.execute(f"SELECT * FROM users WHERE id={tag[1]}") user = c.fetchone() socketio.emit("update", "update") @@ -373,7 +372,20 @@ def create_app(test_config=None): before = request.form["before"] after = request.form["after"] change = request.form["change"] - change_db(statement, user_id, before, after, change) + + if statement == "adduser": + db.add_user(after) + elif statement == "removeuser": + db.remove_user(user_id) + elif statement == "addtag": + db.add_tag(user_id, after) + elif statement == "removetag": + db.remove_tag(befor) + elif statement == "balance": + db.change_balance(user_id, change) + else: + return make_response(json.dumps({"mode":"error", "error":"418"})) #Error code + socketio.emit("update", "update") return render_template("index.html") @@ -382,4 +394,5 @@ def create_app(test_config=None): def documentation(): return render_template("documentation.html") + return {"app":app,"socketio":socketio} diff --git a/Website/db.py b/Website/db.py index 9ad03a3..f586494 100644 --- a/Website/db.py +++ b/Website/db.py @@ -10,24 +10,47 @@ def log(statement, user_id, before, after, change): c.execute("INSERT INTO transaction_log (timestamp, type, user_id, before, after, change) VALUES (?, ?, ?, ?, ?, ?)", [datetime.now(), statement, user_id, before, after, change]) db.commit() -def change_db(statement, user_id=None, before=None, after=None, change=None): +def add_user(after): db = get_db() c = db.cursor() - if statement == "adduser" and after != None: - c.execute("INSERT or IGNORE INTO users (username, balance) VALUES (?, 0)", [after]) - user_id = c.lastrowid - elif statement == "removeuser" and user_id != None and before != None: - c.execute("DELETE FROM tags WHERE userid=?", [user_id]) - c.execute("DELETE FROM users WHERE id=?", [user_id]) - elif statement == "addtag" and after != None and user_id != None: - c.execute("INSERT OR IGNORE INTO tags (tagid, userid) VALUES ?, ?)", [after, user_id]) - elif statement == "removetag" and before != None and user_id != None: - c.execute("DELETE FROM tags WHERE (tagid = ? AND userid = ?)", [before, user_id]) - elif statement == "balance" and change != None and user_id != None: - c.execute("UPDATE users SET balance = balance + ? WHERE id=?", [change, user_id]) - else: - raise Exception("wrong or missing argument for change_db") - log(statement, user_id, before, after, change) + c.execute("INSERT or IGNORE INTO users (username, balance) VALUES (?, 0)", [after]) + user_id = c.lastrowid + log("add_user", user_id=user_id, after=after) + db.commit() + +def remove_user(user_id): + db = get_db() + c = db.cursor() + c.execute("SELECT * FROM users WHERE id = ?", [user_id]) + user_name = c.fetchone()[1] + c.execute("SELECT * FROM tags WHERE userid = ?", [user_id]) + for tag in c.fetchall(): + remove_tag(tag[0]) + c.execute("DELETE FROM users WHERE id = ?", [user_id]) + log("remove_user", user_id=user_id, before=user_name) + db.commit() + +def add_tag(user_id, tag_id): + db = get_db() + c = db.cursor() + c.execute("INSERT OR IGNORE INTO tags (tagid, userid) VALUES ?, ?)", [tag_id, user_id]) + db.commit() + log("addtag", after=tag_id, user_id=user_id) + +def remove_tag(tag_id): + db = get_db() + c = db.cursor() + c.execute("SELECT * FROM tags WHERE tagid = ?", [tag_id]) + user_id = c.fetchone()[1] + c.execute("DELETE FROM tags WHERE tagid = ?", [tag_id]) + log("removetag", before=tag_id, user_id=user_id) + db.commit() + +def change_balance(user_id, change): + db = get_db() + c = db.cursor() + c.execute("UPDATE users SET balance = balance + ? WHERE id=?", [change, user_id]) + log("balance", user_id=user_id, change=change) db.commit() def get_db(): From 389c14358e8188964c937f02f646c1e3d47c6f62 Mon Sep 17 00:00:00 2001 From: lubiana Date: Thu, 22 Feb 2024 18:31:19 +0100 Subject: [PATCH 35/76] add css / wolkenflattern wegwerfen --- Website/__init__.py | 9 +++++++++ Website/templates/base.html | 6 ++++-- static/new.min.css | 8 ++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 static/new.min.css diff --git a/Website/__init__.py b/Website/__init__.py index 7697c3c..e0978d3 100644 --- a/Website/__init__.py +++ b/Website/__init__.py @@ -41,9 +41,18 @@ def create_app(test_config=None): #website @app.route('/favicon.ico') + @app.route('/ccc_logo.png') def favicon(): return send_file("../static/Logo_CCC.svg.png") + @app.route('/socket.io.js') + def socketiojs(): + return send_file('../static/socket.io.js') + + @app.route('/new.css') + def newcss(): + return send_file('../static/new.min.css') + @app.route("/") def index(): return render_template("index.html") diff --git a/Website/templates/base.html b/Website/templates/base.html index 763a753..69fdd57 100644 --- a/Website/templates/base.html +++ b/Website/templates/base.html @@ -2,11 +2,13 @@ {% block title %}{% endblock %} - - + + + {% block customscript %}{% endblock %} diff --git a/static/new.min.css b/static/new.min.css new file mode 100644 index 0000000..175ae21 --- /dev/null +++ b/static/new.min.css @@ -0,0 +1,8 @@ +/** + * Minified by jsDelivr using clean-css v4.2.1. + * Original file: /npm/@exampledev/new.css@1.1.2/new.css + * + * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files + */ +:root{--nc-font-sans:'Inter',-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Oxygen,Ubuntu,Cantarell,'Open Sans','Helvetica Neue',sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--nc-font-mono:Consolas,monaco,'Ubuntu Mono','Liberation Mono','Courier New',Courier,monospace;--nc-tx-1:#000000;--nc-tx-2:#1A1A1A;--nc-bg-1:#FFFFFF;--nc-bg-2:#F6F8FA;--nc-bg-3:#E5E7EB;--nc-lk-1:#0070F3;--nc-lk-2:#0366D6;--nc-lk-tx:#FFFFFF;--nc-ac-1:#79FFE1;--nc-ac-tx:#0C4047}@media (prefers-color-scheme:dark){:root{--nc-tx-1:#ffffff;--nc-tx-2:#eeeeee;--nc-bg-1:#000000;--nc-bg-2:#111111;--nc-bg-3:#222222;--nc-lk-1:#3291FF;--nc-lk-2:#0070F3;--nc-lk-tx:#FFFFFF;--nc-ac-1:#7928CA;--nc-ac-tx:#FFFFFF}}*{margin:0;padding:0}address,area,article,aside,audio,blockquote,datalist,details,dl,fieldset,figure,form,iframe,img,input,meter,nav,ol,optgroup,option,output,p,pre,progress,ruby,section,table,textarea,ul,video{margin-bottom:1rem}button,html,input,select{font-family:var(--nc-font-sans)}body{margin:0 auto;max-width:750px;padding:2rem;border-radius:6px;overflow-x:hidden;word-break:break-word;overflow-wrap:break-word;background:var(--nc-bg-1);color:var(--nc-tx-2);font-size:1.03rem;line-height:1.5}::selection{background:var(--nc-ac-1);color:var(--nc-ac-tx)}h1,h2,h3,h4,h5,h6{line-height:1;color:var(--nc-tx-1);padding-top:.875rem}h1,h2,h3{color:var(--nc-tx-1);padding-bottom:2px;margin-bottom:8px;border-bottom:1px solid var(--nc-bg-2)}h4,h5,h6{margin-bottom:.3rem}h1{font-size:2.25rem}h2{font-size:1.85rem}h3{font-size:1.55rem}h4{font-size:1.25rem}h5{font-size:1rem}h6{font-size:.875rem}a{color:var(--nc-lk-1)}a:hover{color:var(--nc-lk-2)}abbr:hover{cursor:help}blockquote{padding:1.5rem;background:var(--nc-bg-2);border-left:5px solid var(--nc-bg-3)}abbr{cursor:help}blockquote :last-child{padding-bottom:0;margin-bottom:0}header{background:var(--nc-bg-2);border-bottom:1px solid var(--nc-bg-3);padding:2rem 1.5rem;margin:-2rem calc(0px - (50vw - 50%)) 2rem;padding-left:calc(50vw - 50%);padding-right:calc(50vw - 50%)}header h1,header h2,header h3{padding-bottom:0;border-bottom:0}header>:first-child{margin-top:0;padding-top:0}header>:last-child{margin-bottom:0}a button,button,input[type=button],input[type=reset],input[type=submit]{font-size:1rem;display:inline-block;padding:6px 12px;text-align:center;text-decoration:none;white-space:nowrap;background:var(--nc-lk-1);color:var(--nc-lk-tx);border:0;border-radius:4px;box-sizing:border-box;cursor:pointer;color:var(--nc-lk-tx)}a button[disabled],button[disabled],input[type=button][disabled],input[type=reset][disabled],input[type=submit][disabled]{cursor:default;opacity:.5;cursor:not-allowed}.button:focus,.button:hover,button:focus,button:hover,input[type=button]:focus,input[type=button]:hover,input[type=reset]:focus,input[type=reset]:hover,input[type=submit]:focus,input[type=submit]:hover{background:var(--nc-lk-2)}code,kbd,pre,samp{font-family:var(--nc-font-mono)}code,kbd,pre,samp{background:var(--nc-bg-2);border:1px solid var(--nc-bg-3);border-radius:4px;padding:3px 6px;font-size:.9rem}kbd{border-bottom:3px solid var(--nc-bg-3)}pre{padding:1rem 1.4rem;max-width:100%;overflow:auto}pre code{background:inherit;font-size:inherit;color:inherit;border:0;padding:0;margin:0}code pre{display:inline;background:inherit;font-size:inherit;color:inherit;border:0;padding:0;margin:0}details{padding:.6rem 1rem;background:var(--nc-bg-2);border:1px solid var(--nc-bg-3);border-radius:4px}summary{cursor:pointer;font-weight:700}details[open]{padding-bottom:.75rem}details[open] summary{margin-bottom:6px}details[open]>:last-child{margin-bottom:0}dt{font-weight:700}dd::before{content:'→ '}hr{border:0;border-bottom:1px solid var(--nc-bg-3);margin:1rem auto}fieldset{margin-top:1rem;padding:2rem;border:1px solid var(--nc-bg-3);border-radius:4px}legend{padding:auto .5rem}table{border-collapse:collapse;width:100%}td,th{border:1px solid var(--nc-bg-3);text-align:left;padding:.5rem}th{background:var(--nc-bg-2)}tr:nth-child(even){background:var(--nc-bg-2)}table caption{font-weight:700;margin-bottom:.5rem}textarea{max-width:100%}ol,ul{padding-left:2rem}li{margin-top:.4rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}mark{padding:3px 6px;background:var(--nc-ac-1);color:var(--nc-ac-tx)}input,select,textarea{padding:6px 12px;margin-bottom:.5rem;background:var(--nc-bg-2);color:var(--nc-tx-2);border:1px solid var(--nc-bg-3);border-radius:4px;box-shadow:none;box-sizing:border-box}img{max-width:100%} +/*# sourceMappingURL=/sm/4a51164882967d28a74fabce02685c18fa45a529b77514edc75d708f04dd08b9.map */ \ No newline at end of file From 64ce118f807432e6bfd2ac459b4cb114b6cdb7d2 Mon Sep 17 00:00:00 2001 From: lubiana Date: Thu, 22 Feb 2024 21:13:24 +0100 Subject: [PATCH 36/76] add static socket.io.js --- .gitignore | 1 - static/socket.io.js | 6046 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 6046 insertions(+), 1 deletion(-) create mode 100644 static/socket.io.js diff --git a/.gitignore b/.gitignore index 89bbf08..bf6fab7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ *.db -socket.io.js __pycache__/ logs/* venv/* diff --git a/static/socket.io.js b/static/socket.io.js new file mode 100644 index 0000000..005c9c9 --- /dev/null +++ b/static/socket.io.js @@ -0,0 +1,6046 @@ +/*! + * Socket.IO v4.0.1 + * (c) 2014-2021 Guillermo Rauch + * Released under the MIT License. + */ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(); + else if(typeof define === 'function' && define.amd) + define([], factory); + else if(typeof exports === 'object') + exports["io"] = factory(); + else + root["io"] = factory(); +})(self, function() { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); +/******/ } +/******/ }; +/******/ +/******/ // define __esModule on exports +/******/ __webpack_require__.r = function(exports) { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ +/******/ // create a fake namespace object +/******/ // mode & 1: value is a module id, require it +/******/ // mode & 2: merge all properties of value into the ns +/******/ // mode & 4: return value when already ns object +/******/ // mode & 8|1: behave like require +/******/ __webpack_require__.t = function(value, mode) { +/******/ if(mode & 1) value = __webpack_require__(value); +/******/ if(mode & 8) return value; +/******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; +/******/ var ns = Object.create(null); +/******/ __webpack_require__.r(ns); +/******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); +/******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); +/******/ return ns; +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = "./build/index.js"); +/******/ }) +/************************************************************************/ +/******/ ({ + +/***/ "./build/index.js": +/*!************************!*\ + !*** ./build/index.js ***! + \************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Socket = exports.io = exports.Manager = exports.protocol = void 0; + +var url_1 = __webpack_require__(/*! ./url */ "./build/url.js"); + +var manager_1 = __webpack_require__(/*! ./manager */ "./build/manager.js"); + +var socket_1 = __webpack_require__(/*! ./socket */ "./build/socket.js"); + +Object.defineProperty(exports, "Socket", { + enumerable: true, + get: function get() { + return socket_1.Socket; + } +}); + +var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("socket.io-client"); +/** + * Module exports. + */ + + +module.exports = exports = lookup; +/** + * Managers cache. + */ + +var cache = exports.managers = {}; + +function lookup(uri, opts) { + if (_typeof(uri) === "object") { + opts = uri; + uri = undefined; + } + + opts = opts || {}; + var parsed = url_1.url(uri, opts.path); + var source = parsed.source; + var id = parsed.id; + var path = parsed.path; + var sameNamespace = cache[id] && path in cache[id]["nsps"]; + var newConnection = opts.forceNew || opts["force new connection"] || false === opts.multiplex || sameNamespace; + var io; + + if (newConnection) { + debug("ignoring socket cache for %s", source); + io = new manager_1.Manager(source, opts); + } else { + if (!cache[id]) { + debug("new io instance for %s", source); + cache[id] = new manager_1.Manager(source, opts); + } + + io = cache[id]; + } + + if (parsed.query && !opts.query) { + opts.query = parsed.queryKey; + } + + return io.socket(parsed.path, opts); +} + +exports.io = lookup; +/** + * Protocol version. + * + * @public + */ + +var socket_io_parser_1 = __webpack_require__(/*! socket.io-parser */ "./node_modules/socket.io-parser/dist/index.js"); + +Object.defineProperty(exports, "protocol", { + enumerable: true, + get: function get() { + return socket_io_parser_1.protocol; + } +}); +/** + * `connect`. + * + * @param {String} uri + * @public + */ + +exports.connect = lookup; +/** + * Expose constructors for standalone build. + * + * @public + */ + +var manager_2 = __webpack_require__(/*! ./manager */ "./build/manager.js"); + +Object.defineProperty(exports, "Manager", { + enumerable: true, + get: function get() { + return manager_2.Manager; + } +}); +exports["default"] = lookup; + +/***/ }), + +/***/ "./build/manager.js": +/*!**************************!*\ + !*** ./build/manager.js ***! + \**************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Manager = void 0; + +var eio = __webpack_require__(/*! engine.io-client */ "./node_modules/engine.io-client/lib/index.js"); + +var socket_1 = __webpack_require__(/*! ./socket */ "./build/socket.js"); + +var parser = __webpack_require__(/*! socket.io-parser */ "./node_modules/socket.io-parser/dist/index.js"); + +var on_1 = __webpack_require__(/*! ./on */ "./build/on.js"); + +var Backoff = __webpack_require__(/*! backo2 */ "./node_modules/backo2/index.js"); + +var typed_events_1 = __webpack_require__(/*! ./typed-events */ "./build/typed-events.js"); + +var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("socket.io-client:manager"); + +var Manager = /*#__PURE__*/function (_typed_events_1$Stric) { + _inherits(Manager, _typed_events_1$Stric); + + var _super = _createSuper(Manager); + + function Manager(uri, opts) { + var _this; + + _classCallCheck(this, Manager); + + _this = _super.call(this); + _this.nsps = {}; + _this.subs = []; + + if (uri && "object" === _typeof(uri)) { + opts = uri; + uri = undefined; + } + + opts = opts || {}; + opts.path = opts.path || "/socket.io"; + _this.opts = opts; + + _this.reconnection(opts.reconnection !== false); + + _this.reconnectionAttempts(opts.reconnectionAttempts || Infinity); + + _this.reconnectionDelay(opts.reconnectionDelay || 1000); + + _this.reconnectionDelayMax(opts.reconnectionDelayMax || 5000); + + _this.randomizationFactor(opts.randomizationFactor || 0.5); + + _this.backoff = new Backoff({ + min: _this.reconnectionDelay(), + max: _this.reconnectionDelayMax(), + jitter: _this.randomizationFactor() + }); + + _this.timeout(null == opts.timeout ? 20000 : opts.timeout); + + _this._readyState = "closed"; + _this.uri = uri; + + var _parser = opts.parser || parser; + + _this.encoder = new _parser.Encoder(); + _this.decoder = new _parser.Decoder(); + _this._autoConnect = opts.autoConnect !== false; + if (_this._autoConnect) _this.open(); + return _this; + } + + _createClass(Manager, [{ + key: "reconnection", + value: function reconnection(v) { + if (!arguments.length) return this._reconnection; + this._reconnection = !!v; + return this; + } + }, { + key: "reconnectionAttempts", + value: function reconnectionAttempts(v) { + if (v === undefined) return this._reconnectionAttempts; + this._reconnectionAttempts = v; + return this; + } + }, { + key: "reconnectionDelay", + value: function reconnectionDelay(v) { + var _a; + + if (v === undefined) return this._reconnectionDelay; + this._reconnectionDelay = v; + (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMin(v); + return this; + } + }, { + key: "randomizationFactor", + value: function randomizationFactor(v) { + var _a; + + if (v === undefined) return this._randomizationFactor; + this._randomizationFactor = v; + (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setJitter(v); + return this; + } + }, { + key: "reconnectionDelayMax", + value: function reconnectionDelayMax(v) { + var _a; + + if (v === undefined) return this._reconnectionDelayMax; + this._reconnectionDelayMax = v; + (_a = this.backoff) === null || _a === void 0 ? void 0 : _a.setMax(v); + return this; + } + }, { + key: "timeout", + value: function timeout(v) { + if (!arguments.length) return this._timeout; + this._timeout = v; + return this; + } + /** + * Starts trying to reconnect if reconnection is enabled and we have not + * started reconnecting yet + * + * @private + */ + + }, { + key: "maybeReconnectOnOpen", + value: function maybeReconnectOnOpen() { + // Only try to reconnect if it's the first time we're connecting + if (!this._reconnecting && this._reconnection && this.backoff.attempts === 0) { + // keeps reconnection from firing twice for the same reconnection loop + this.reconnect(); + } + } + /** + * Sets the current transport `socket`. + * + * @param {Function} fn - optional, callback + * @return self + * @public + */ + + }, { + key: "open", + value: function open(fn) { + var _this2 = this; + + debug("readyState %s", this._readyState); + if (~this._readyState.indexOf("open")) return this; + debug("opening %s", this.uri); + this.engine = eio(this.uri, this.opts); + var socket = this.engine; + var self = this; + this._readyState = "opening"; + this.skipReconnect = false; // emit `open` + + var openSubDestroy = on_1.on(socket, "open", function () { + self.onopen(); + fn && fn(); + }); // emit `error` + + var errorSub = on_1.on(socket, "error", function (err) { + debug("error"); + self.cleanup(); + self._readyState = "closed"; + + _this2.emitReserved("error", err); + + if (fn) { + fn(err); + } else { + // Only do this if there is no fn to handle the error + self.maybeReconnectOnOpen(); + } + }); + + if (false !== this._timeout) { + var timeout = this._timeout; + debug("connect attempt will timeout after %d", timeout); + + if (timeout === 0) { + openSubDestroy(); // prevents a race condition with the 'open' event + } // set timer + + + var timer = setTimeout(function () { + debug("connect attempt timed out after %d", timeout); + openSubDestroy(); + socket.close(); + socket.emit("error", new Error("timeout")); + }, timeout); + + if (this.opts.autoUnref) { + timer.unref(); + } + + this.subs.push(function subDestroy() { + clearTimeout(timer); + }); + } + + this.subs.push(openSubDestroy); + this.subs.push(errorSub); + return this; + } + /** + * Alias for open() + * + * @return self + * @public + */ + + }, { + key: "connect", + value: function connect(fn) { + return this.open(fn); + } + /** + * Called upon transport open. + * + * @private + */ + + }, { + key: "onopen", + value: function onopen() { + debug("open"); // clear old subs + + this.cleanup(); // mark as open + + this._readyState = "open"; + this.emitReserved("open"); // add new subs + + var socket = this.engine; + this.subs.push(on_1.on(socket, "ping", this.onping.bind(this)), on_1.on(socket, "data", this.ondata.bind(this)), on_1.on(socket, "error", this.onerror.bind(this)), on_1.on(socket, "close", this.onclose.bind(this)), on_1.on(this.decoder, "decoded", this.ondecoded.bind(this))); + } + /** + * Called upon a ping. + * + * @private + */ + + }, { + key: "onping", + value: function onping() { + this.emitReserved("ping"); + } + /** + * Called with data. + * + * @private + */ + + }, { + key: "ondata", + value: function ondata(data) { + this.decoder.add(data); + } + /** + * Called when parser fully decodes a packet. + * + * @private + */ + + }, { + key: "ondecoded", + value: function ondecoded(packet) { + this.emitReserved("packet", packet); + } + /** + * Called upon socket error. + * + * @private + */ + + }, { + key: "onerror", + value: function onerror(err) { + debug("error", err); + this.emitReserved("error", err); + } + /** + * Creates a new socket for the given `nsp`. + * + * @return {Socket} + * @public + */ + + }, { + key: "socket", + value: function socket(nsp, opts) { + var socket = this.nsps[nsp]; + + if (!socket) { + socket = new socket_1.Socket(this, nsp, opts); + this.nsps[nsp] = socket; + } + + return socket; + } + /** + * Called upon a socket close. + * + * @param socket + * @private + */ + + }, { + key: "_destroy", + value: function _destroy(socket) { + var nsps = Object.keys(this.nsps); + + for (var _i = 0, _nsps = nsps; _i < _nsps.length; _i++) { + var nsp = _nsps[_i]; + var _socket = this.nsps[nsp]; + + if (_socket.active) { + debug("socket %s is still active, skipping close", nsp); + return; + } + } + + this._close(); + } + /** + * Writes a packet. + * + * @param packet + * @private + */ + + }, { + key: "_packet", + value: function _packet(packet) { + debug("writing packet %j", packet); + var encodedPackets = this.encoder.encode(packet); + + for (var i = 0; i < encodedPackets.length; i++) { + this.engine.write(encodedPackets[i], packet.options); + } + } + /** + * Clean up transport subscriptions and packet buffer. + * + * @private + */ + + }, { + key: "cleanup", + value: function cleanup() { + debug("cleanup"); + this.subs.forEach(function (subDestroy) { + return subDestroy(); + }); + this.subs.length = 0; + this.decoder.destroy(); + } + /** + * Close the current socket. + * + * @private + */ + + }, { + key: "_close", + value: function _close() { + debug("disconnect"); + this.skipReconnect = true; + this._reconnecting = false; + + if ("opening" === this._readyState) { + // `onclose` will not fire because + // an open event never happened + this.cleanup(); + } + + this.backoff.reset(); + this._readyState = "closed"; + if (this.engine) this.engine.close(); + } + /** + * Alias for close() + * + * @private + */ + + }, { + key: "disconnect", + value: function disconnect() { + return this._close(); + } + /** + * Called upon engine close. + * + * @private + */ + + }, { + key: "onclose", + value: function onclose(reason) { + debug("onclose"); + this.cleanup(); + this.backoff.reset(); + this._readyState = "closed"; + this.emitReserved("close", reason); + + if (this._reconnection && !this.skipReconnect) { + this.reconnect(); + } + } + /** + * Attempt a reconnection. + * + * @private + */ + + }, { + key: "reconnect", + value: function reconnect() { + var _this3 = this; + + if (this._reconnecting || this.skipReconnect) return this; + var self = this; + + if (this.backoff.attempts >= this._reconnectionAttempts) { + debug("reconnect failed"); + this.backoff.reset(); + this.emitReserved("reconnect_failed"); + this._reconnecting = false; + } else { + var delay = this.backoff.duration(); + debug("will wait %dms before reconnect attempt", delay); + this._reconnecting = true; + var timer = setTimeout(function () { + if (self.skipReconnect) return; + debug("attempting reconnect"); + + _this3.emitReserved("reconnect_attempt", self.backoff.attempts); // check again for the case socket closed in above events + + + if (self.skipReconnect) return; + self.open(function (err) { + if (err) { + debug("reconnect attempt error"); + self._reconnecting = false; + self.reconnect(); + + _this3.emitReserved("reconnect_error", err); + } else { + debug("reconnect success"); + self.onreconnect(); + } + }); + }, delay); + + if (this.opts.autoUnref) { + timer.unref(); + } + + this.subs.push(function subDestroy() { + clearTimeout(timer); + }); + } + } + /** + * Called upon successful reconnect. + * + * @private + */ + + }, { + key: "onreconnect", + value: function onreconnect() { + var attempt = this.backoff.attempts; + this._reconnecting = false; + this.backoff.reset(); + this.emitReserved("reconnect", attempt); + } + }]); + + return Manager; +}(typed_events_1.StrictEventEmitter); + +exports.Manager = Manager; + +/***/ }), + +/***/ "./build/on.js": +/*!*********************!*\ + !*** ./build/on.js ***! + \*********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.on = void 0; + +function on(obj, ev, fn) { + obj.on(ev, fn); + return function subDestroy() { + obj.off(ev, fn); + }; +} + +exports.on = on; + +/***/ }), + +/***/ "./build/socket.js": +/*!*************************!*\ + !*** ./build/socket.js ***! + \*************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _createForOfIteratorHelper(o, allowArrayLike) { var it; if (typeof Symbol === "undefined" || o[Symbol.iterator] == null) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = o[Symbol.iterator](); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; } + +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } + +function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.Socket = void 0; + +var socket_io_parser_1 = __webpack_require__(/*! socket.io-parser */ "./node_modules/socket.io-parser/dist/index.js"); + +var on_1 = __webpack_require__(/*! ./on */ "./build/on.js"); + +var typed_events_1 = __webpack_require__(/*! ./typed-events */ "./build/typed-events.js"); + +var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("socket.io-client:socket"); +/** + * Internal events. + * These events can't be emitted by the user. + */ + + +var RESERVED_EVENTS = Object.freeze({ + connect: 1, + connect_error: 1, + disconnect: 1, + disconnecting: 1, + // EventEmitter reserved events: https://nodejs.org/api/events.html#events_event_newlistener + newListener: 1, + removeListener: 1 +}); + +var Socket = /*#__PURE__*/function (_typed_events_1$Stric) { + _inherits(Socket, _typed_events_1$Stric); + + var _super = _createSuper(Socket); + + /** + * `Socket` constructor. + * + * @public + */ + function Socket(io, nsp, opts) { + var _this; + + _classCallCheck(this, Socket); + + _this = _super.call(this); + _this.receiveBuffer = []; + _this.sendBuffer = []; + _this.ids = 0; + _this.acks = {}; + _this.flags = {}; + _this.io = io; + _this.nsp = nsp; + _this.ids = 0; + _this.acks = {}; + _this.receiveBuffer = []; + _this.sendBuffer = []; + _this.connected = false; + _this.disconnected = true; + _this.flags = {}; + + if (opts && opts.auth) { + _this.auth = opts.auth; + } + + if (_this.io._autoConnect) _this.open(); + return _this; + } + /** + * Subscribe to open, close and packet events + * + * @private + */ + + + _createClass(Socket, [{ + key: "subEvents", + value: function subEvents() { + if (this.subs) return; + var io = this.io; + this.subs = [on_1.on(io, "open", this.onopen.bind(this)), on_1.on(io, "packet", this.onpacket.bind(this)), on_1.on(io, "error", this.onerror.bind(this)), on_1.on(io, "close", this.onclose.bind(this))]; + } + /** + * Whether the Socket will try to reconnect when its Manager connects or reconnects + */ + + }, { + key: "connect", + + /** + * "Opens" the socket. + * + * @public + */ + value: function connect() { + if (this.connected) return this; + this.subEvents(); + if (!this.io["_reconnecting"]) this.io.open(); // ensure open + + if ("open" === this.io._readyState) this.onopen(); + return this; + } + /** + * Alias for connect() + */ + + }, { + key: "open", + value: function open() { + return this.connect(); + } + /** + * Sends a `message` event. + * + * @return self + * @public + */ + + }, { + key: "send", + value: function send() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + args.unshift("message"); + this.emit.apply(this, args); + return this; + } + /** + * Override `emit`. + * If the event is in `events`, it's emitted normally. + * + * @return self + * @public + */ + + }, { + key: "emit", + value: function emit(ev) { + if (RESERVED_EVENTS.hasOwnProperty(ev)) { + throw new Error('"' + ev + '" is a reserved event name'); + } + + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + args.unshift(ev); + var packet = { + type: socket_io_parser_1.PacketType.EVENT, + data: args + }; + packet.options = {}; + packet.options.compress = this.flags.compress !== false; // event ack callback + + if ("function" === typeof args[args.length - 1]) { + debug("emitting packet with ack id %d", this.ids); + this.acks[this.ids] = args.pop(); + packet.id = this.ids++; + } + + var isTransportWritable = this.io.engine && this.io.engine.transport && this.io.engine.transport.writable; + var discardPacket = this.flags["volatile"] && (!isTransportWritable || !this.connected); + + if (discardPacket) { + debug("discard packet as the transport is not currently writable"); + } else if (this.connected) { + this.packet(packet); + } else { + this.sendBuffer.push(packet); + } + + this.flags = {}; + return this; + } + /** + * Sends a packet. + * + * @param packet + * @private + */ + + }, { + key: "packet", + value: function packet(_packet) { + _packet.nsp = this.nsp; + + this.io._packet(_packet); + } + /** + * Called upon engine `open`. + * + * @private + */ + + }, { + key: "onopen", + value: function onopen() { + var _this2 = this; + + debug("transport is open - connecting"); + + if (typeof this.auth == "function") { + this.auth(function (data) { + _this2.packet({ + type: socket_io_parser_1.PacketType.CONNECT, + data: data + }); + }); + } else { + this.packet({ + type: socket_io_parser_1.PacketType.CONNECT, + data: this.auth + }); + } + } + /** + * Called upon engine or manager `error`. + * + * @param err + * @private + */ + + }, { + key: "onerror", + value: function onerror(err) { + if (!this.connected) { + this.emitReserved("connect_error", err); + } + } + /** + * Called upon engine `close`. + * + * @param reason + * @private + */ + + }, { + key: "onclose", + value: function onclose(reason) { + debug("close (%s)", reason); + this.connected = false; + this.disconnected = true; + delete this.id; + this.emitReserved("disconnect", reason); + } + /** + * Called with socket packet. + * + * @param packet + * @private + */ + + }, { + key: "onpacket", + value: function onpacket(packet) { + var sameNamespace = packet.nsp === this.nsp; + if (!sameNamespace) return; + + switch (packet.type) { + case socket_io_parser_1.PacketType.CONNECT: + if (packet.data && packet.data.sid) { + var id = packet.data.sid; + this.onconnect(id); + } else { + this.emitReserved("connect_error", new Error("It seems you are trying to reach a Socket.IO server in v2.x with a v3.x client, but they are not compatible (more information here: https://socket.io/docs/v3/migrating-from-2-x-to-3-0/)")); + } + + break; + + case socket_io_parser_1.PacketType.EVENT: + this.onevent(packet); + break; + + case socket_io_parser_1.PacketType.BINARY_EVENT: + this.onevent(packet); + break; + + case socket_io_parser_1.PacketType.ACK: + this.onack(packet); + break; + + case socket_io_parser_1.PacketType.BINARY_ACK: + this.onack(packet); + break; + + case socket_io_parser_1.PacketType.DISCONNECT: + this.ondisconnect(); + break; + + case socket_io_parser_1.PacketType.CONNECT_ERROR: + var err = new Error(packet.data.message); // @ts-ignore + + err.data = packet.data.data; + this.emitReserved("connect_error", err); + break; + } + } + /** + * Called upon a server event. + * + * @param packet + * @private + */ + + }, { + key: "onevent", + value: function onevent(packet) { + var args = packet.data || []; + debug("emitting event %j", args); + + if (null != packet.id) { + debug("attaching ack callback to event"); + args.push(this.ack(packet.id)); + } + + if (this.connected) { + this.emitEvent(args); + } else { + this.receiveBuffer.push(Object.freeze(args)); + } + } + }, { + key: "emitEvent", + value: function emitEvent(args) { + if (this._anyListeners && this._anyListeners.length) { + var listeners = this._anyListeners.slice(); + + var _iterator = _createForOfIteratorHelper(listeners), + _step; + + try { + for (_iterator.s(); !(_step = _iterator.n()).done;) { + var listener = _step.value; + listener.apply(this, args); + } + } catch (err) { + _iterator.e(err); + } finally { + _iterator.f(); + } + } + + _get(_getPrototypeOf(Socket.prototype), "emit", this).apply(this, args); + } + /** + * Produces an ack callback to emit with an event. + * + * @private + */ + + }, { + key: "ack", + value: function ack(id) { + var self = this; + var sent = false; + return function () { + // prevent double callbacks + if (sent) return; + sent = true; + + for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { + args[_key3] = arguments[_key3]; + } + + debug("sending ack %j", args); + self.packet({ + type: socket_io_parser_1.PacketType.ACK, + id: id, + data: args + }); + }; + } + /** + * Called upon a server acknowlegement. + * + * @param packet + * @private + */ + + }, { + key: "onack", + value: function onack(packet) { + var ack = this.acks[packet.id]; + + if ("function" === typeof ack) { + debug("calling ack %s with %j", packet.id, packet.data); + ack.apply(this, packet.data); + delete this.acks[packet.id]; + } else { + debug("bad ack %s", packet.id); + } + } + /** + * Called upon server connect. + * + * @private + */ + + }, { + key: "onconnect", + value: function onconnect(id) { + debug("socket connected with id %s", id); + this.id = id; + this.connected = true; + this.disconnected = false; + this.emitReserved("connect"); + this.emitBuffered(); + } + /** + * Emit buffered events (received and emitted). + * + * @private + */ + + }, { + key: "emitBuffered", + value: function emitBuffered() { + var _this3 = this; + + this.receiveBuffer.forEach(function (args) { + return _this3.emitEvent(args); + }); + this.receiveBuffer = []; + this.sendBuffer.forEach(function (packet) { + return _this3.packet(packet); + }); + this.sendBuffer = []; + } + /** + * Called upon server disconnect. + * + * @private + */ + + }, { + key: "ondisconnect", + value: function ondisconnect() { + debug("server disconnect (%s)", this.nsp); + this.destroy(); + this.onclose("io server disconnect"); + } + /** + * Called upon forced client/server side disconnections, + * this method ensures the manager stops tracking us and + * that reconnections don't get triggered for this. + * + * @private + */ + + }, { + key: "destroy", + value: function destroy() { + if (this.subs) { + // clean subscriptions to avoid reconnections + this.subs.forEach(function (subDestroy) { + return subDestroy(); + }); + this.subs = undefined; + } + + this.io["_destroy"](this); + } + /** + * Disconnects the socket manually. + * + * @return self + * @public + */ + + }, { + key: "disconnect", + value: function disconnect() { + if (this.connected) { + debug("performing disconnect (%s)", this.nsp); + this.packet({ + type: socket_io_parser_1.PacketType.DISCONNECT + }); + } // remove socket from pool + + + this.destroy(); + + if (this.connected) { + // fire events + this.onclose("io client disconnect"); + } + + return this; + } + /** + * Alias for disconnect() + * + * @return self + * @public + */ + + }, { + key: "close", + value: function close() { + return this.disconnect(); + } + /** + * Sets the compress flag. + * + * @param compress - if `true`, compresses the sending data + * @return self + * @public + */ + + }, { + key: "compress", + value: function compress(_compress) { + this.flags.compress = _compress; + return this; + } + /** + * Sets a modifier for a subsequent event emission that the event message will be dropped when this socket is not + * ready to send messages. + * + * @returns self + * @public + */ + + }, { + key: "onAny", + + /** + * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the + * callback. + * + * @param listener + * @public + */ + value: function onAny(listener) { + this._anyListeners = this._anyListeners || []; + + this._anyListeners.push(listener); + + return this; + } + /** + * Adds a listener that will be fired when any event is emitted. The event name is passed as the first argument to the + * callback. The listener is added to the beginning of the listeners array. + * + * @param listener + * @public + */ + + }, { + key: "prependAny", + value: function prependAny(listener) { + this._anyListeners = this._anyListeners || []; + + this._anyListeners.unshift(listener); + + return this; + } + /** + * Removes the listener that will be fired when any event is emitted. + * + * @param listener + * @public + */ + + }, { + key: "offAny", + value: function offAny(listener) { + if (!this._anyListeners) { + return this; + } + + if (listener) { + var listeners = this._anyListeners; + + for (var i = 0; i < listeners.length; i++) { + if (listener === listeners[i]) { + listeners.splice(i, 1); + return this; + } + } + } else { + this._anyListeners = []; + } + + return this; + } + /** + * Returns an array of listeners that are listening for any event that is specified. This array can be manipulated, + * e.g. to remove listeners. + * + * @public + */ + + }, { + key: "listenersAny", + value: function listenersAny() { + return this._anyListeners || []; + } + }, { + key: "active", + get: function get() { + return !!this.subs; + } + }, { + key: "volatile", + get: function get() { + this.flags["volatile"] = true; + return this; + } + }]); + + return Socket; +}(typed_events_1.StrictEventEmitter); + +exports.Socket = Socket; + +/***/ }), + +/***/ "./build/typed-events.js": +/*!*******************************!*\ + !*** ./build/typed-events.js ***! + \*******************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } + +function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.StrictEventEmitter = void 0; + +var Emitter = __webpack_require__(/*! component-emitter */ "./node_modules/component-emitter/index.js"); +/** + * Strictly typed version of an `EventEmitter`. A `TypedEventEmitter` takes type + * parameters for mappings of event names to event data types, and strictly + * types method calls to the `EventEmitter` according to these event maps. + * + * @typeParam ListenEvents - `EventsMap` of user-defined events that can be + * listened to with `on` or `once` + * @typeParam EmitEvents - `EventsMap` of user-defined events that can be + * emitted with `emit` + * @typeParam ReservedEvents - `EventsMap` of reserved events, that can be + * emitted by socket.io with `emitReserved`, and can be listened to with + * `listen`. + */ + + +var StrictEventEmitter = /*#__PURE__*/function (_Emitter) { + _inherits(StrictEventEmitter, _Emitter); + + var _super = _createSuper(StrictEventEmitter); + + function StrictEventEmitter() { + _classCallCheck(this, StrictEventEmitter); + + return _super.apply(this, arguments); + } + + _createClass(StrictEventEmitter, [{ + key: "on", + + /** + * Adds the `listener` function as an event listener for `ev`. + * + * @param ev Name of the event + * @param listener Callback function + */ + value: function on(ev, listener) { + _get(_getPrototypeOf(StrictEventEmitter.prototype), "on", this).call(this, ev, listener); + + return this; + } + /** + * Adds a one-time `listener` function as an event listener for `ev`. + * + * @param ev Name of the event + * @param listener Callback function + */ + + }, { + key: "once", + value: function once(ev, listener) { + _get(_getPrototypeOf(StrictEventEmitter.prototype), "once", this).call(this, ev, listener); + + return this; + } + /** + * Emits an event. + * + * @param ev Name of the event + * @param args Values to send to listeners of this event + */ + + }, { + key: "emit", + value: function emit(ev) { + var _get2; + + for (var _len = arguments.length, args = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { + args[_key - 1] = arguments[_key]; + } + + (_get2 = _get(_getPrototypeOf(StrictEventEmitter.prototype), "emit", this)).call.apply(_get2, [this, ev].concat(args)); + + return this; + } + /** + * Emits a reserved event. + * + * This method is `protected`, so that only a class extending + * `StrictEventEmitter` can emit its own reserved events. + * + * @param ev Reserved event name + * @param args Arguments to emit along with the event + */ + + }, { + key: "emitReserved", + value: function emitReserved(ev) { + var _get3; + + for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) { + args[_key2 - 1] = arguments[_key2]; + } + + (_get3 = _get(_getPrototypeOf(StrictEventEmitter.prototype), "emit", this)).call.apply(_get3, [this, ev].concat(args)); + + return this; + } + /** + * Returns the listeners listening to an event. + * + * @param event Event name + * @returns Array of listeners subscribed to `event` + */ + + }, { + key: "listeners", + value: function listeners(event) { + return _get(_getPrototypeOf(StrictEventEmitter.prototype), "listeners", this).call(this, event); + } + }]); + + return StrictEventEmitter; +}(Emitter); + +exports.StrictEventEmitter = StrictEventEmitter; + +/***/ }), + +/***/ "./build/url.js": +/*!**********************!*\ + !*** ./build/url.js ***! + \**********************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.url = void 0; + +var parseuri = __webpack_require__(/*! parseuri */ "./node_modules/parseuri/index.js"); + +var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("socket.io-client:url"); +/** + * URL parser. + * + * @param uri - url + * @param path - the request path of the connection + * @param loc - An object meant to mimic window.location. + * Defaults to window.location. + * @public + */ + + +function url(uri) { + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ""; + var loc = arguments.length > 2 ? arguments[2] : undefined; + var obj = uri; // default to window.location + + loc = loc || typeof location !== "undefined" && location; + if (null == uri) uri = loc.protocol + "//" + loc.host; // relative path support + + if (typeof uri === "string") { + if ("/" === uri.charAt(0)) { + if ("/" === uri.charAt(1)) { + uri = loc.protocol + uri; + } else { + uri = loc.host + uri; + } + } + + if (!/^(https?|wss?):\/\//.test(uri)) { + debug("protocol-less url %s", uri); + + if ("undefined" !== typeof loc) { + uri = loc.protocol + "//" + uri; + } else { + uri = "https://" + uri; + } + } // parse + + + debug("parse %s", uri); + obj = parseuri(uri); + } // make sure we treat `localhost:80` and `localhost` equally + + + if (!obj.port) { + if (/^(http|ws)$/.test(obj.protocol)) { + obj.port = "80"; + } else if (/^(http|ws)s$/.test(obj.protocol)) { + obj.port = "443"; + } + } + + obj.path = obj.path || "/"; + var ipv6 = obj.host.indexOf(":") !== -1; + var host = ipv6 ? "[" + obj.host + "]" : obj.host; // define unique id + + obj.id = obj.protocol + "://" + host + ":" + obj.port + path; // define href + + obj.href = obj.protocol + "://" + host + (loc && loc.port === obj.port ? "" : ":" + obj.port); + return obj; +} + +exports.url = url; + +/***/ }), + +/***/ "./node_modules/backo2/index.js": +/*!**************************************!*\ + !*** ./node_modules/backo2/index.js ***! + \**************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +/** + * Expose `Backoff`. + */ +module.exports = Backoff; +/** + * Initialize backoff timer with `opts`. + * + * - `min` initial timeout in milliseconds [100] + * - `max` max timeout [10000] + * - `jitter` [0] + * - `factor` [2] + * + * @param {Object} opts + * @api public + */ + +function Backoff(opts) { + opts = opts || {}; + this.ms = opts.min || 100; + this.max = opts.max || 10000; + this.factor = opts.factor || 2; + this.jitter = opts.jitter > 0 && opts.jitter <= 1 ? opts.jitter : 0; + this.attempts = 0; +} +/** + * Return the backoff duration. + * + * @return {Number} + * @api public + */ + + +Backoff.prototype.duration = function () { + var ms = this.ms * Math.pow(this.factor, this.attempts++); + + if (this.jitter) { + var rand = Math.random(); + var deviation = Math.floor(rand * this.jitter * ms); + ms = (Math.floor(rand * 10) & 1) == 0 ? ms - deviation : ms + deviation; + } + + return Math.min(ms, this.max) | 0; +}; +/** + * Reset the number of attempts. + * + * @api public + */ + + +Backoff.prototype.reset = function () { + this.attempts = 0; +}; +/** + * Set the minimum duration + * + * @api public + */ + + +Backoff.prototype.setMin = function (min) { + this.ms = min; +}; +/** + * Set the maximum duration + * + * @api public + */ + + +Backoff.prototype.setMax = function (max) { + this.max = max; +}; +/** + * Set the jitter + * + * @api public + */ + + +Backoff.prototype.setJitter = function (jitter) { + this.jitter = jitter; +}; + +/***/ }), + +/***/ "./node_modules/component-emitter/index.js": +/*!*************************************************!*\ + !*** ./node_modules/component-emitter/index.js ***! + \*************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +/** + * Expose `Emitter`. + */ +if (true) { + module.exports = Emitter; +} +/** + * Initialize a new `Emitter`. + * + * @api public + */ + + +function Emitter(obj) { + if (obj) return mixin(obj); +} + +; +/** + * Mixin the emitter properties. + * + * @param {Object} obj + * @return {Object} + * @api private + */ + +function mixin(obj) { + for (var key in Emitter.prototype) { + obj[key] = Emitter.prototype[key]; + } + + return obj; +} +/** + * Listen on the given `event` with `fn`. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + +Emitter.prototype.on = Emitter.prototype.addEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; + (this._callbacks['$' + event] = this._callbacks['$' + event] || []).push(fn); + return this; +}; +/** + * Adds an `event` listener that will be invoked a single + * time then automatically removed. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + +Emitter.prototype.once = function (event, fn) { + function on() { + this.off(event, on); + fn.apply(this, arguments); + } + + on.fn = fn; + this.on(event, on); + return this; +}; +/** + * Remove the given callback for `event` or all + * registered callbacks. + * + * @param {String} event + * @param {Function} fn + * @return {Emitter} + * @api public + */ + + +Emitter.prototype.off = Emitter.prototype.removeListener = Emitter.prototype.removeAllListeners = Emitter.prototype.removeEventListener = function (event, fn) { + this._callbacks = this._callbacks || {}; // all + + if (0 == arguments.length) { + this._callbacks = {}; + return this; + } // specific event + + + var callbacks = this._callbacks['$' + event]; + if (!callbacks) return this; // remove all handlers + + if (1 == arguments.length) { + delete this._callbacks['$' + event]; + return this; + } // remove specific handler + + + var cb; + + for (var i = 0; i < callbacks.length; i++) { + cb = callbacks[i]; + + if (cb === fn || cb.fn === fn) { + callbacks.splice(i, 1); + break; + } + } // Remove event specific arrays for event types that no + // one is subscribed for to avoid memory leak. + + + if (callbacks.length === 0) { + delete this._callbacks['$' + event]; + } + + return this; +}; +/** + * Emit `event` with the given args. + * + * @param {String} event + * @param {Mixed} ... + * @return {Emitter} + */ + + +Emitter.prototype.emit = function (event) { + this._callbacks = this._callbacks || {}; + var args = new Array(arguments.length - 1), + callbacks = this._callbacks['$' + event]; + + for (var i = 1; i < arguments.length; i++) { + args[i - 1] = arguments[i]; + } + + if (callbacks) { + callbacks = callbacks.slice(0); + + for (var i = 0, len = callbacks.length; i < len; ++i) { + callbacks[i].apply(this, args); + } + } + + return this; +}; +/** + * Return array of callbacks for `event`. + * + * @param {String} event + * @return {Array} + * @api public + */ + + +Emitter.prototype.listeners = function (event) { + this._callbacks = this._callbacks || {}; + return this._callbacks['$' + event] || []; +}; +/** + * Check if this emitter has `event` handlers. + * + * @param {String} event + * @return {Boolean} + * @api public + */ + + +Emitter.prototype.hasListeners = function (event) { + return !!this.listeners(event).length; +}; + +/***/ }), + +/***/ "./node_modules/debug/src/browser.js": +/*!*******************************************!*\ + !*** ./node_modules/debug/src/browser.js ***! + \*******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +/* eslint-env browser */ + +/** + * This is the web browser implementation of `debug()`. + */ +exports.formatArgs = formatArgs; +exports.save = save; +exports.load = load; +exports.useColors = useColors; +exports.storage = localstorage(); + +exports.destroy = function () { + var warned = false; + return function () { + if (!warned) { + warned = true; + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + }; +}(); +/** + * Colors. + */ + + +exports.colors = ['#0000CC', '#0000FF', '#0033CC', '#0033FF', '#0066CC', '#0066FF', '#0099CC', '#0099FF', '#00CC00', '#00CC33', '#00CC66', '#00CC99', '#00CCCC', '#00CCFF', '#3300CC', '#3300FF', '#3333CC', '#3333FF', '#3366CC', '#3366FF', '#3399CC', '#3399FF', '#33CC00', '#33CC33', '#33CC66', '#33CC99', '#33CCCC', '#33CCFF', '#6600CC', '#6600FF', '#6633CC', '#6633FF', '#66CC00', '#66CC33', '#9900CC', '#9900FF', '#9933CC', '#9933FF', '#99CC00', '#99CC33', '#CC0000', '#CC0033', '#CC0066', '#CC0099', '#CC00CC', '#CC00FF', '#CC3300', '#CC3333', '#CC3366', '#CC3399', '#CC33CC', '#CC33FF', '#CC6600', '#CC6633', '#CC9900', '#CC9933', '#CCCC00', '#CCCC33', '#FF0000', '#FF0033', '#FF0066', '#FF0099', '#FF00CC', '#FF00FF', '#FF3300', '#FF3333', '#FF3366', '#FF3399', '#FF33CC', '#FF33FF', '#FF6600', '#FF6633', '#FF9900', '#FF9933', '#FFCC00', '#FFCC33']; +/** + * Currently only WebKit-based Web Inspectors, Firefox >= v31, + * and the Firebug extension (any Firefox version) are known + * to support "%c" CSS customizations. + * + * TODO: add a `localStorage` variable to explicitly enable/disable colors + */ +// eslint-disable-next-line complexity + +function useColors() { + // NB: In an Electron preload script, document will be defined but not fully + // initialized. Since we know we're in Chrome, we'll just detect this case + // explicitly + if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) { + return true; + } // Internet Explorer and Edge do not support colors. + + + if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) { + return false; + } // Is webkit? http://stackoverflow.com/a/16459606/376773 + // document is undefined in react-native: https://github.com/facebook/react-native/pull/1632 + + + return typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance || // Is firebug? http://stackoverflow.com/a/398120/376773 + typeof window !== 'undefined' && window.console && (window.console.firebug || window.console.exception && window.console.table) || // Is firefox >= v31? + // https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages + typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/) && parseInt(RegExp.$1, 10) >= 31 || // Double check webkit in userAgent just in case we are in a worker + typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/); +} +/** + * Colorize log arguments if enabled. + * + * @api public + */ + + +function formatArgs(args) { + args[0] = (this.useColors ? '%c' : '') + this.namespace + (this.useColors ? ' %c' : ' ') + args[0] + (this.useColors ? '%c ' : ' ') + '+' + module.exports.humanize(this.diff); + + if (!this.useColors) { + return; + } + + var c = 'color: ' + this.color; + args.splice(1, 0, c, 'color: inherit'); // The final "%c" is somewhat tricky, because there could be other + // arguments passed either before or after the %c, so we need to + // figure out the correct index to insert the CSS into + + var index = 0; + var lastC = 0; + args[0].replace(/%[a-zA-Z%]/g, function (match) { + if (match === '%%') { + return; + } + + index++; + + if (match === '%c') { + // We only are interested in the *last* %c + // (the user may have provided their own) + lastC = index; + } + }); + args.splice(lastC, 0, c); +} +/** + * Invokes `console.debug()` when available. + * No-op when `console.debug` is not a "function". + * If `console.debug` is not available, falls back + * to `console.log`. + * + * @api public + */ + + +exports.log = console.debug || console.log || function () {}; +/** + * Save `namespaces`. + * + * @param {String} namespaces + * @api private + */ + + +function save(namespaces) { + try { + if (namespaces) { + exports.storage.setItem('debug', namespaces); + } else { + exports.storage.removeItem('debug'); + } + } catch (error) {// Swallow + // XXX (@Qix-) should we be logging these? + } +} +/** + * Load `namespaces`. + * + * @return {String} returns the previously persisted debug modes + * @api private + */ + + +function load() { + var r; + + try { + r = exports.storage.getItem('debug'); + } catch (error) {// Swallow + // XXX (@Qix-) should we be logging these? + } // If debug isn't set in LS, and we're in Electron, try to load $DEBUG + + + if (!r && typeof process !== 'undefined' && 'env' in process) { + r = process.env.DEBUG; + } + + return r; +} +/** + * Localstorage attempts to return the localstorage. + * + * This is necessary because safari throws + * when a user disables cookies/localstorage + * and you attempt to access it. + * + * @return {LocalStorage} + * @api private + */ + + +function localstorage() { + try { + // TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context + // The Browser also has localStorage in the global context. + return localStorage; + } catch (error) {// Swallow + // XXX (@Qix-) should we be logging these? + } +} + +module.exports = __webpack_require__(/*! ./common */ "./node_modules/debug/src/common.js")(exports); +var formatters = module.exports.formatters; +/** + * Map %j to `JSON.stringify()`, since no Web Inspectors do that by default. + */ + +formatters.j = function (v) { + try { + return JSON.stringify(v); + } catch (error) { + return '[UnexpectedJSONParseError]: ' + error.message; + } +}; + +/***/ }), + +/***/ "./node_modules/debug/src/common.js": +/*!******************************************!*\ + !*** ./node_modules/debug/src/common.js ***! + \******************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); } + +function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } + +function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } + +function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && Symbol.iterator in Object(iter)) return Array.from(iter); } + +function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); } + +function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } + +/** + * This is the common logic for both the Node.js and web browser + * implementations of `debug()`. + */ +function setup(env) { + createDebug.debug = createDebug; + createDebug["default"] = createDebug; + createDebug.coerce = coerce; + createDebug.disable = disable; + createDebug.enable = enable; + createDebug.enabled = enabled; + createDebug.humanize = __webpack_require__(/*! ms */ "./node_modules/ms/index.js"); + createDebug.destroy = destroy; + Object.keys(env).forEach(function (key) { + createDebug[key] = env[key]; + }); + /** + * The currently active debug mode names, and names to skip. + */ + + createDebug.names = []; + createDebug.skips = []; + /** + * Map of special "%n" handling functions, for the debug "format" argument. + * + * Valid key names are a single, lower or upper-case letter, i.e. "n" and "N". + */ + + createDebug.formatters = {}; + /** + * Selects a color for a debug namespace + * @param {String} namespace The namespace string for the for the debug instance to be colored + * @return {Number|String} An ANSI color code for the given namespace + * @api private + */ + + function selectColor(namespace) { + var hash = 0; + + for (var i = 0; i < namespace.length; i++) { + hash = (hash << 5) - hash + namespace.charCodeAt(i); + hash |= 0; // Convert to 32bit integer + } + + return createDebug.colors[Math.abs(hash) % createDebug.colors.length]; + } + + createDebug.selectColor = selectColor; + /** + * Create a debugger with the given `namespace`. + * + * @param {String} namespace + * @return {Function} + * @api public + */ + + function createDebug(namespace) { + var prevTime; + var enableOverride = null; + + function debug() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + // Disabled? + if (!debug.enabled) { + return; + } + + var self = debug; // Set `diff` timestamp + + var curr = Number(new Date()); + var ms = curr - (prevTime || curr); + self.diff = ms; + self.prev = prevTime; + self.curr = curr; + prevTime = curr; + args[0] = createDebug.coerce(args[0]); + + if (typeof args[0] !== 'string') { + // Anything else let's inspect with %O + args.unshift('%O'); + } // Apply any `formatters` transformations + + + var index = 0; + args[0] = args[0].replace(/%([a-zA-Z%])/g, function (match, format) { + // If we encounter an escaped % then don't increase the array index + if (match === '%%') { + return '%'; + } + + index++; + var formatter = createDebug.formatters[format]; + + if (typeof formatter === 'function') { + var val = args[index]; + match = formatter.call(self, val); // Now we need to remove `args[index]` since it's inlined in the `format` + + args.splice(index, 1); + index--; + } + + return match; + }); // Apply env-specific formatting (colors, etc.) + + createDebug.formatArgs.call(self, args); + var logFn = self.log || createDebug.log; + logFn.apply(self, args); + } + + debug.namespace = namespace; + debug.useColors = createDebug.useColors(); + debug.color = createDebug.selectColor(namespace); + debug.extend = extend; + debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release. + + Object.defineProperty(debug, 'enabled', { + enumerable: true, + configurable: false, + get: function get() { + return enableOverride === null ? createDebug.enabled(namespace) : enableOverride; + }, + set: function set(v) { + enableOverride = v; + } + }); // Env-specific initialization logic for debug instances + + if (typeof createDebug.init === 'function') { + createDebug.init(debug); + } + + return debug; + } + + function extend(namespace, delimiter) { + var newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace); + newDebug.log = this.log; + return newDebug; + } + /** + * Enables a debug mode by namespaces. This can include modes + * separated by a colon and wildcards. + * + * @param {String} namespaces + * @api public + */ + + + function enable(namespaces) { + createDebug.save(namespaces); + createDebug.names = []; + createDebug.skips = []; + var i; + var split = (typeof namespaces === 'string' ? namespaces : '').split(/[\s,]+/); + var len = split.length; + + for (i = 0; i < len; i++) { + if (!split[i]) { + // ignore empty strings + continue; + } + + namespaces = split[i].replace(/\*/g, '.*?'); + + if (namespaces[0] === '-') { + createDebug.skips.push(new RegExp('^' + namespaces.substr(1) + '$')); + } else { + createDebug.names.push(new RegExp('^' + namespaces + '$')); + } + } + } + /** + * Disable debug output. + * + * @return {String} namespaces + * @api public + */ + + + function disable() { + var namespaces = [].concat(_toConsumableArray(createDebug.names.map(toNamespace)), _toConsumableArray(createDebug.skips.map(toNamespace).map(function (namespace) { + return '-' + namespace; + }))).join(','); + createDebug.enable(''); + return namespaces; + } + /** + * Returns true if the given mode name is enabled, false otherwise. + * + * @param {String} name + * @return {Boolean} + * @api public + */ + + + function enabled(name) { + if (name[name.length - 1] === '*') { + return true; + } + + var i; + var len; + + for (i = 0, len = createDebug.skips.length; i < len; i++) { + if (createDebug.skips[i].test(name)) { + return false; + } + } + + for (i = 0, len = createDebug.names.length; i < len; i++) { + if (createDebug.names[i].test(name)) { + return true; + } + } + + return false; + } + /** + * Convert regexp to namespace + * + * @param {RegExp} regxep + * @return {String} namespace + * @api private + */ + + + function toNamespace(regexp) { + return regexp.toString().substring(2, regexp.toString().length - 2).replace(/\.\*\?$/, '*'); + } + /** + * Coerce `val`. + * + * @param {Mixed} val + * @return {Mixed} + * @api private + */ + + + function coerce(val) { + if (val instanceof Error) { + return val.stack || val.message; + } + + return val; + } + /** + * XXX DO NOT USE. This is a temporary stub function. + * XXX It WILL be removed in the next major release. + */ + + + function destroy() { + console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.'); + } + + createDebug.enable(createDebug.load()); + return createDebug; +} + +module.exports = setup; + +/***/ }), + +/***/ "./node_modules/engine.io-client/lib/globalThis.browser.js": +/*!*****************************************************************!*\ + !*** ./node_modules/engine.io-client/lib/globalThis.browser.js ***! + \*****************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports) { + +module.exports = function () { + if (typeof self !== "undefined") { + return self; + } else if (typeof window !== "undefined") { + return window; + } else { + return Function("return this")(); + } +}(); + +/***/ }), + +/***/ "./node_modules/engine.io-client/lib/index.js": +/*!****************************************************!*\ + !*** ./node_modules/engine.io-client/lib/index.js ***! + \****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var Socket = __webpack_require__(/*! ./socket */ "./node_modules/engine.io-client/lib/socket.js"); + +module.exports = function (uri, opts) { + return new Socket(uri, opts); +}; +/** + * Expose deps for legacy compatibility + * and standalone browser access. + */ + + +module.exports.Socket = Socket; +module.exports.protocol = Socket.protocol; // this is an int + +module.exports.Transport = __webpack_require__(/*! ./transport */ "./node_modules/engine.io-client/lib/transport.js"); +module.exports.transports = __webpack_require__(/*! ./transports/index */ "./node_modules/engine.io-client/lib/transports/index.js"); +module.exports.parser = __webpack_require__(/*! engine.io-parser */ "./node_modules/engine.io-parser/lib/index.js"); + +/***/ }), + +/***/ "./node_modules/engine.io-client/lib/socket.js": +/*!*****************************************************!*\ + !*** ./node_modules/engine.io-client/lib/socket.js ***! + \*****************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); } + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +var transports = __webpack_require__(/*! ./transports/index */ "./node_modules/engine.io-client/lib/transports/index.js"); + +var Emitter = __webpack_require__(/*! component-emitter */ "./node_modules/component-emitter/index.js"); + +var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("engine.io-client:socket"); + +var parser = __webpack_require__(/*! engine.io-parser */ "./node_modules/engine.io-parser/lib/index.js"); + +var parseuri = __webpack_require__(/*! parseuri */ "./node_modules/parseuri/index.js"); + +var parseqs = __webpack_require__(/*! parseqs */ "./node_modules/parseqs/index.js"); + +var Socket = /*#__PURE__*/function (_Emitter) { + _inherits(Socket, _Emitter); + + var _super = _createSuper(Socket); + + /** + * Socket constructor. + * + * @param {String|Object} uri or options + * @param {Object} options + * @api public + */ + function Socket(uri) { + var _this; + + var opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + _classCallCheck(this, Socket); + + _this = _super.call(this); + + if (uri && "object" === _typeof(uri)) { + opts = uri; + uri = null; + } + + if (uri) { + uri = parseuri(uri); + opts.hostname = uri.host; + opts.secure = uri.protocol === "https" || uri.protocol === "wss"; + opts.port = uri.port; + if (uri.query) opts.query = uri.query; + } else if (opts.host) { + opts.hostname = parseuri(opts.host).host; + } + + _this.secure = null != opts.secure ? opts.secure : typeof location !== "undefined" && "https:" === location.protocol; + + if (opts.hostname && !opts.port) { + // if no port is specified manually, use the protocol default + opts.port = _this.secure ? "443" : "80"; + } + + _this.hostname = opts.hostname || (typeof location !== "undefined" ? location.hostname : "localhost"); + _this.port = opts.port || (typeof location !== "undefined" && location.port ? location.port : _this.secure ? 443 : 80); + _this.transports = opts.transports || ["polling", "websocket"]; + _this.readyState = ""; + _this.writeBuffer = []; + _this.prevBufferLen = 0; + _this.opts = _extends({ + path: "/engine.io", + agent: false, + withCredentials: false, + upgrade: true, + jsonp: true, + timestampParam: "t", + rememberUpgrade: false, + rejectUnauthorized: true, + perMessageDeflate: { + threshold: 1024 + }, + transportOptions: {} + }, opts); + _this.opts.path = _this.opts.path.replace(/\/$/, "") + "/"; + + if (typeof _this.opts.query === "string") { + _this.opts.query = parseqs.decode(_this.opts.query); + } // set on handshake + + + _this.id = null; + _this.upgrades = null; + _this.pingInterval = null; + _this.pingTimeout = null; // set on heartbeat + + _this.pingTimeoutTimer = null; + + if (typeof addEventListener === "function") { + addEventListener("beforeunload", function () { + if (_this.transport) { + // silently close the transport + _this.transport.removeAllListeners(); + + _this.transport.close(); + } + }, false); + + if (_this.hostname !== "localhost") { + _this.offlineEventListener = function () { + _this.onClose("transport close"); + }; + + addEventListener("offline", _this.offlineEventListener, false); + } + } + + _this.open(); + + return _this; + } + /** + * Creates transport of the given type. + * + * @param {String} transport name + * @return {Transport} + * @api private + */ + + + _createClass(Socket, [{ + key: "createTransport", + value: function createTransport(name) { + debug('creating transport "%s"', name); + var query = clone(this.opts.query); // append engine.io protocol identifier + + query.EIO = parser.protocol; // transport name + + query.transport = name; // session id if we already have one + + if (this.id) query.sid = this.id; + + var opts = _extends({}, this.opts.transportOptions[name], this.opts, { + query: query, + socket: this, + hostname: this.hostname, + secure: this.secure, + port: this.port + }); + + debug("options: %j", opts); + return new transports[name](opts); + } + /** + * Initializes transport to use and starts probe. + * + * @api private + */ + + }, { + key: "open", + value: function open() { + var transport; + + if (this.opts.rememberUpgrade && Socket.priorWebsocketSuccess && this.transports.indexOf("websocket") !== -1) { + transport = "websocket"; + } else if (0 === this.transports.length) { + // Emit error on next tick so it can be listened to + var self = this; + setTimeout(function () { + self.emit("error", "No transports available"); + }, 0); + return; + } else { + transport = this.transports[0]; + } + + this.readyState = "opening"; // Retry with the next transport if the transport is disabled (jsonp: false) + + try { + transport = this.createTransport(transport); + } catch (e) { + debug("error while creating transport: %s", e); + this.transports.shift(); + this.open(); + return; + } + + transport.open(); + this.setTransport(transport); + } + /** + * Sets the current transport. Disables the existing one (if any). + * + * @api private + */ + + }, { + key: "setTransport", + value: function setTransport(transport) { + debug("setting transport %s", transport.name); + var self = this; + + if (this.transport) { + debug("clearing existing transport %s", this.transport.name); + this.transport.removeAllListeners(); + } // set up transport + + + this.transport = transport; // set up transport listeners + + transport.on("drain", function () { + self.onDrain(); + }).on("packet", function (packet) { + self.onPacket(packet); + }).on("error", function (e) { + self.onError(e); + }).on("close", function () { + self.onClose("transport close"); + }); + } + /** + * Probes a transport. + * + * @param {String} transport name + * @api private + */ + + }, { + key: "probe", + value: function probe(name) { + debug('probing transport "%s"', name); + var transport = this.createTransport(name, { + probe: 1 + }); + var failed = false; + var self = this; + Socket.priorWebsocketSuccess = false; + + function onTransportOpen() { + if (self.onlyBinaryUpgrades) { + var upgradeLosesBinary = !this.supportsBinary && self.transport.supportsBinary; + failed = failed || upgradeLosesBinary; + } + + if (failed) return; + debug('probe transport "%s" opened', name); + transport.send([{ + type: "ping", + data: "probe" + }]); + transport.once("packet", function (msg) { + if (failed) return; + + if ("pong" === msg.type && "probe" === msg.data) { + debug('probe transport "%s" pong', name); + self.upgrading = true; + self.emit("upgrading", transport); + if (!transport) return; + Socket.priorWebsocketSuccess = "websocket" === transport.name; + debug('pausing current transport "%s"', self.transport.name); + self.transport.pause(function () { + if (failed) return; + if ("closed" === self.readyState) return; + debug("changing transport and sending upgrade packet"); + cleanup(); + self.setTransport(transport); + transport.send([{ + type: "upgrade" + }]); + self.emit("upgrade", transport); + transport = null; + self.upgrading = false; + self.flush(); + }); + } else { + debug('probe transport "%s" failed', name); + var err = new Error("probe error"); + err.transport = transport.name; + self.emit("upgradeError", err); + } + }); + } + + function freezeTransport() { + if (failed) return; // Any callback called by transport should be ignored since now + + failed = true; + cleanup(); + transport.close(); + transport = null; + } // Handle any error that happens while probing + + + function onerror(err) { + var error = new Error("probe error: " + err); + error.transport = transport.name; + freezeTransport(); + debug('probe transport "%s" failed because of error: %s', name, err); + self.emit("upgradeError", error); + } + + function onTransportClose() { + onerror("transport closed"); + } // When the socket is closed while we're probing + + + function onclose() { + onerror("socket closed"); + } // When the socket is upgraded while we're probing + + + function onupgrade(to) { + if (transport && to.name !== transport.name) { + debug('"%s" works - aborting "%s"', to.name, transport.name); + freezeTransport(); + } + } // Remove all listeners on the transport and on self + + + function cleanup() { + transport.removeListener("open", onTransportOpen); + transport.removeListener("error", onerror); + transport.removeListener("close", onTransportClose); + self.removeListener("close", onclose); + self.removeListener("upgrading", onupgrade); + } + + transport.once("open", onTransportOpen); + transport.once("error", onerror); + transport.once("close", onTransportClose); + this.once("close", onclose); + this.once("upgrading", onupgrade); + transport.open(); + } + /** + * Called when connection is deemed open. + * + * @api public + */ + + }, { + key: "onOpen", + value: function onOpen() { + debug("socket open"); + this.readyState = "open"; + Socket.priorWebsocketSuccess = "websocket" === this.transport.name; + this.emit("open"); + this.flush(); // we check for `readyState` in case an `open` + // listener already closed the socket + + if ("open" === this.readyState && this.opts.upgrade && this.transport.pause) { + debug("starting upgrade probes"); + var i = 0; + var l = this.upgrades.length; + + for (; i < l; i++) { + this.probe(this.upgrades[i]); + } + } + } + /** + * Handles a packet. + * + * @api private + */ + + }, { + key: "onPacket", + value: function onPacket(packet) { + if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) { + debug('socket receive: type "%s", data "%s"', packet.type, packet.data); + this.emit("packet", packet); // Socket is live - any packet counts + + this.emit("heartbeat"); + + switch (packet.type) { + case "open": + this.onHandshake(JSON.parse(packet.data)); + break; + + case "ping": + this.resetPingTimeout(); + this.sendPacket("pong"); + this.emit("pong"); + break; + + case "error": + var err = new Error("server error"); + err.code = packet.data; + this.onError(err); + break; + + case "message": + this.emit("data", packet.data); + this.emit("message", packet.data); + break; + } + } else { + debug('packet received with socket readyState "%s"', this.readyState); + } + } + /** + * Called upon handshake completion. + * + * @param {Object} handshake obj + * @api private + */ + + }, { + key: "onHandshake", + value: function onHandshake(data) { + this.emit("handshake", data); + this.id = data.sid; + this.transport.query.sid = data.sid; + this.upgrades = this.filterUpgrades(data.upgrades); + this.pingInterval = data.pingInterval; + this.pingTimeout = data.pingTimeout; + this.onOpen(); // In case open handler closes socket + + if ("closed" === this.readyState) return; + this.resetPingTimeout(); + } + /** + * Sets and resets ping timeout timer based on server pings. + * + * @api private + */ + + }, { + key: "resetPingTimeout", + value: function resetPingTimeout() { + var _this2 = this; + + clearTimeout(this.pingTimeoutTimer); + this.pingTimeoutTimer = setTimeout(function () { + _this2.onClose("ping timeout"); + }, this.pingInterval + this.pingTimeout); + + if (this.opts.autoUnref) { + this.pingTimeoutTimer.unref(); + } + } + /** + * Called on `drain` event + * + * @api private + */ + + }, { + key: "onDrain", + value: function onDrain() { + this.writeBuffer.splice(0, this.prevBufferLen); // setting prevBufferLen = 0 is very important + // for example, when upgrading, upgrade packet is sent over, + // and a nonzero prevBufferLen could cause problems on `drain` + + this.prevBufferLen = 0; + + if (0 === this.writeBuffer.length) { + this.emit("drain"); + } else { + this.flush(); + } + } + /** + * Flush write buffers. + * + * @api private + */ + + }, { + key: "flush", + value: function flush() { + if ("closed" !== this.readyState && this.transport.writable && !this.upgrading && this.writeBuffer.length) { + debug("flushing %d packets in socket", this.writeBuffer.length); + this.transport.send(this.writeBuffer); // keep track of current length of writeBuffer + // splice writeBuffer and callbackBuffer on `drain` + + this.prevBufferLen = this.writeBuffer.length; + this.emit("flush"); + } + } + /** + * Sends a message. + * + * @param {String} message. + * @param {Function} callback function. + * @param {Object} options. + * @return {Socket} for chaining. + * @api public + */ + + }, { + key: "write", + value: function write(msg, options, fn) { + this.sendPacket("message", msg, options, fn); + return this; + } + }, { + key: "send", + value: function send(msg, options, fn) { + this.sendPacket("message", msg, options, fn); + return this; + } + /** + * Sends a packet. + * + * @param {String} packet type. + * @param {String} data. + * @param {Object} options. + * @param {Function} callback function. + * @api private + */ + + }, { + key: "sendPacket", + value: function sendPacket(type, data, options, fn) { + if ("function" === typeof data) { + fn = data; + data = undefined; + } + + if ("function" === typeof options) { + fn = options; + options = null; + } + + if ("closing" === this.readyState || "closed" === this.readyState) { + return; + } + + options = options || {}; + options.compress = false !== options.compress; + var packet = { + type: type, + data: data, + options: options + }; + this.emit("packetCreate", packet); + this.writeBuffer.push(packet); + if (fn) this.once("flush", fn); + this.flush(); + } + /** + * Closes the connection. + * + * @api private + */ + + }, { + key: "close", + value: function close() { + var self = this; + + if ("opening" === this.readyState || "open" === this.readyState) { + this.readyState = "closing"; + + if (this.writeBuffer.length) { + this.once("drain", function () { + if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } + }); + } else if (this.upgrading) { + waitForUpgrade(); + } else { + close(); + } + } + + function close() { + self.onClose("forced close"); + debug("socket closing - telling transport to close"); + self.transport.close(); + } + + function cleanupAndClose() { + self.removeListener("upgrade", cleanupAndClose); + self.removeListener("upgradeError", cleanupAndClose); + close(); + } + + function waitForUpgrade() { + // wait for upgrade to finish since we can't send packets while pausing a transport + self.once("upgrade", cleanupAndClose); + self.once("upgradeError", cleanupAndClose); + } + + return this; + } + /** + * Called upon transport error + * + * @api private + */ + + }, { + key: "onError", + value: function onError(err) { + debug("socket error %j", err); + Socket.priorWebsocketSuccess = false; + this.emit("error", err); + this.onClose("transport error", err); + } + /** + * Called upon transport close. + * + * @api private + */ + + }, { + key: "onClose", + value: function onClose(reason, desc) { + if ("opening" === this.readyState || "open" === this.readyState || "closing" === this.readyState) { + debug('socket close with reason: "%s"', reason); + var self = this; // clear timers + + clearTimeout(this.pingIntervalTimer); + clearTimeout(this.pingTimeoutTimer); // stop event from firing again for transport + + this.transport.removeAllListeners("close"); // ensure transport won't stay open + + this.transport.close(); // ignore further transport communication + + this.transport.removeAllListeners(); + + if (typeof removeEventListener === "function") { + removeEventListener("offline", this.offlineEventListener, false); + } // set ready state + + + this.readyState = "closed"; // clear session id + + this.id = null; // emit close event + + this.emit("close", reason, desc); // clean buffers after, so users can still + // grab the buffers on `close` event + + self.writeBuffer = []; + self.prevBufferLen = 0; + } + } + /** + * Filters upgrades, returning only those matching client transports. + * + * @param {Array} server upgrades + * @api private + * + */ + + }, { + key: "filterUpgrades", + value: function filterUpgrades(upgrades) { + var filteredUpgrades = []; + var i = 0; + var j = upgrades.length; + + for (; i < j; i++) { + if (~this.transports.indexOf(upgrades[i])) filteredUpgrades.push(upgrades[i]); + } + + return filteredUpgrades; + } + }]); + + return Socket; +}(Emitter); + +Socket.priorWebsocketSuccess = false; +/** + * Protocol version. + * + * @api public + */ + +Socket.protocol = parser.protocol; // this is an int + +function clone(obj) { + var o = {}; + + for (var i in obj) { + if (obj.hasOwnProperty(i)) { + o[i] = obj[i]; + } + } + + return o; +} + +module.exports = Socket; + +/***/ }), + +/***/ "./node_modules/engine.io-client/lib/transport.js": +/*!********************************************************!*\ + !*** ./node_modules/engine.io-client/lib/transport.js ***! + \********************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +var parser = __webpack_require__(/*! engine.io-parser */ "./node_modules/engine.io-parser/lib/index.js"); + +var Emitter = __webpack_require__(/*! component-emitter */ "./node_modules/component-emitter/index.js"); + +var debug = __webpack_require__(/*! debug */ "./node_modules/debug/src/browser.js")("engine.io-client:transport"); + +var Transport = /*#__PURE__*/function (_Emitter) { + _inherits(Transport, _Emitter); + + var _super = _createSuper(Transport); + + /** + * Transport abstract constructor. + * + * @param {Object} options. + * @api private + */ + function Transport(opts) { + var _this; + + _classCallCheck(this, Transport); + + _this = _super.call(this); + _this.opts = opts; + _this.query = opts.query; + _this.readyState = ""; + _this.socket = opts.socket; + return _this; + } + /** + * Emits an error. + * + * @param {String} str + * @return {Transport} for chaining + * @api public + */ + + + _createClass(Transport, [{ + key: "onError", + value: function onError(msg, desc) { + var err = new Error(msg); + err.type = "TransportError"; + err.description = desc; + this.emit("error", err); + return this; + } + /** + * Opens the transport. + * + * @api public + */ + + }, { + key: "open", + value: function open() { + if ("closed" === this.readyState || "" === this.readyState) { + this.readyState = "opening"; + this.doOpen(); + } + + return this; + } + /** + * Closes the transport. + * + * @api private + */ + + }, { + key: "close", + value: function close() { + if ("opening" === this.readyState || "open" === this.readyState) { + this.doClose(); + this.onClose(); + } + + return this; + } + /** + * Sends multiple packets. + * + * @param {Array} packets + * @api private + */ + + }, { + key: "send", + value: function send(packets) { + if ("open" === this.readyState) { + this.write(packets); + } else { + // this might happen if the transport was silently closed in the beforeunload event handler + debug("transport is not open, discarding packets"); + } + } + /** + * Called upon open + * + * @api private + */ + + }, { + key: "onOpen", + value: function onOpen() { + this.readyState = "open"; + this.writable = true; + this.emit("open"); + } + /** + * Called with data. + * + * @param {String} data + * @api private + */ + + }, { + key: "onData", + value: function onData(data) { + var packet = parser.decodePacket(data, this.socket.binaryType); + this.onPacket(packet); + } + /** + * Called with a decoded packet. + */ + + }, { + key: "onPacket", + value: function onPacket(packet) { + this.emit("packet", packet); + } + /** + * Called upon close. + * + * @api private + */ + + }, { + key: "onClose", + value: function onClose() { + this.readyState = "closed"; + this.emit("close"); + } + }]); + + return Transport; +}(Emitter); + +module.exports = Transport; + +/***/ }), + +/***/ "./node_modules/engine.io-client/lib/transports/index.js": +/*!***************************************************************!*\ + !*** ./node_modules/engine.io-client/lib/transports/index.js ***! + \***************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +var XMLHttpRequest = __webpack_require__(/*! ../../contrib/xmlhttprequest-ssl/XMLHttpRequest */ "./node_modules/engine.io-client/lib/xmlhttprequest.js"); + +var XHR = __webpack_require__(/*! ./polling-xhr */ "./node_modules/engine.io-client/lib/transports/polling-xhr.js"); + +var JSONP = __webpack_require__(/*! ./polling-jsonp */ "./node_modules/engine.io-client/lib/transports/polling-jsonp.js"); + +var websocket = __webpack_require__(/*! ./websocket */ "./node_modules/engine.io-client/lib/transports/websocket.js"); + +exports.polling = polling; +exports.websocket = websocket; +/** + * Polling transport polymorphic constructor. + * Decides on xhr vs jsonp based on feature detection. + * + * @api private + */ + +function polling(opts) { + var xhr; + var xd = false; + var xs = false; + var jsonp = false !== opts.jsonp; + + if (typeof location !== "undefined") { + var isSSL = "https:" === location.protocol; + var port = location.port; // some user agents have empty `location.port` + + if (!port) { + port = isSSL ? 443 : 80; + } + + xd = opts.hostname !== location.hostname || port !== opts.port; + xs = opts.secure !== isSSL; + } + + opts.xdomain = xd; + opts.xscheme = xs; + xhr = new XMLHttpRequest(opts); + + if ("open" in xhr && !opts.forceJSONP) { + return new XHR(opts); + } else { + if (!jsonp) throw new Error("JSONP disabled"); + return new JSONP(opts); + } +} + +/***/ }), + +/***/ "./node_modules/engine.io-client/lib/transports/polling-jsonp.js": +/*!***********************************************************************!*\ + !*** ./node_modules/engine.io-client/lib/transports/polling-jsonp.js ***! + \***********************************************************************/ +/*! no static exports found */ +/***/ (function(module, exports, __webpack_require__) { + +function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } + +function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } + +function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } + +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } + +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } + +function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } + +function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +var Polling = __webpack_require__(/*! ./polling */ "./node_modules/engine.io-client/lib/transports/polling.js"); + +var globalThis = __webpack_require__(/*! ../globalThis */ "./node_modules/engine.io-client/lib/globalThis.browser.js"); + +var rNewline = /\n/g; +var rEscapedNewline = /\\n/g; +/** + * Global JSONP callbacks. + */ + +var callbacks; + +var JSONPPolling = /*#__PURE__*/function (_Polling) { + _inherits(JSONPPolling, _Polling); + + var _super = _createSuper(JSONPPolling); + + /** + * JSONP Polling constructor. + * + * @param {Object} opts. + * @api public + */ + function JSONPPolling(opts) { + var _this; + + _classCallCheck(this, JSONPPolling); + + _this = _super.call(this, opts); + _this.query = _this.query || {}; // define global callbacks array if not present + // we do this here (lazily) to avoid unneeded global pollution + + if (!callbacks) { + // we need to consider multiple engines in the same page + callbacks = globalThis.___eio = globalThis.___eio || []; + } // callback identifier + + + _this.index = callbacks.length; // add callback to jsonp global + + var self = _assertThisInitialized(_this); + + callbacks.push(function (msg) { + self.onData(msg); + }); // append to query string + + _this.query.j = _this.index; + return _this; + } + /** + * JSONP only supports binary as base64 encoded strings + */ + + + _createClass(JSONPPolling, [{ + key: "doClose", + + /** + * Closes the socket. + * + * @api private + */ + value: function doClose() { + if (this.script) { + // prevent spurious errors from being emitted when the window is unloaded + this.script.onerror = function () {}; + + this.script.parentNode.removeChild(this.script); + this.script = null; + } + + if (this.form) { + this.form.parentNode.removeChild(this.form); + this.form = null; + this.iframe = null; + } + + _get(_getPrototypeOf(JSONPPolling.prototype), "doClose", this).call(this); + } + /** + * Starts a poll cycle. + * + * @api private + */ + + }, { + key: "doPoll", + value: function doPoll() { + var self = this; + var script = document.createElement("script"); + + if (this.script) { + this.script.parentNode.removeChild(this.script); + this.script = null; + } + + script.async = true; + script.src = this.uri(); + + script.onerror = function (e) { + self.onError("jsonp poll error", e); + }; + + var insertAt = document.getElementsByTagName("script")[0]; + + if (insertAt) { + insertAt.parentNode.insertBefore(script, insertAt); + } else { + (document.head || document.body).appendChild(script); + } + + this.script = script; + var isUAgecko = "undefined" !== typeof navigator && /gecko/i.test(navigator.userAgent); + + if (isUAgecko) { + setTimeout(function () { + var iframe = document.createElement("iframe"); + document.body.appendChild(iframe); + document.body.removeChild(iframe); + }, 100); + } + } + /** + * Writes with a hidden iframe. + * + * @param {String} data to send + * @param {Function} called upon flush. + * @api private + */ + + }, { + key: "doWrite", + value: function doWrite(data, fn) { + var self = this; + var iframe; + + if (!this.form) { + var form = document.createElement("form"); + var area = document.createElement("textarea"); + var id = this.iframeId = "eio_iframe_" + this.index; + form.className = "socketio"; + form.style.position = "absolute"; + form.style.top = "-1000px"; + form.style.left = "-1000px"; + form.target = id; + form.method = "POST"; + form.setAttribute("accept-charset", "utf-8"); + area.name = "d"; + form.appendChild(area); + document.body.appendChild(form); + this.form = form; + this.area = area; + } + + this.form.action = this.uri(); + + function complete() { + initIframe(); + fn(); + } + + function initIframe() { + if (self.iframe) { + try { + self.form.removeChild(self.iframe); + } catch (e) { + self.onError("jsonp polling iframe removal error", e); + } + } + + try { + // ie6 dynamic iframes with target="" support (thanks Chris Lambacher) + var html = '