diff --git a/aiserver.py b/aiserver.py index c9eb7e16..81a3eb3b 100644 --- a/aiserver.py +++ b/aiserver.py @@ -7,14 +7,15 @@ # External packages import eventlet +from eventlet import tpool eventlet.monkey_patch(all=True, thread=False) +#eventlet.monkey_patch(os=True, select=True, socket=True, thread=True, time=True, psycopg=True) import os os.system("") __file__ = os.path.dirname(os.path.realpath(__file__)) os.chdir(__file__) os.environ['EVENTLET_THREADPOOL_SIZE'] = '1' os.environ['TOKENIZERS_PARALLELISM'] = 'false' -from eventlet import tpool import logging logging.getLogger("urllib3").setLevel(logging.ERROR) @@ -228,7 +229,7 @@ class Send_to_socketio(object): print(bar, end="") time.sleep(0.01) try: - emit('from_server', {'cmd': 'model_load_status', 'data': bar.replace(" ", " ")}, broadcast=True) + emit('from_server', {'cmd': 'model_load_status', 'data': bar.replace(" ", " ")}, broadcast=True, room="UI_1") except: pass @@ -245,6 +246,7 @@ app = Flask(__name__, root_path=os.getcwd()) app.config['SECRET KEY'] = 'secret!' app.config['TEMPLATES_AUTO_RELOAD'] = True socketio = SocketIO(app, async_method="eventlet") +#socketio = SocketIO(app, async_method="eventlet", logger=True, engineio_logger=True) koboldai_settings.socketio = socketio print("{0}OK!{1}".format(colors.GREEN, colors.END)) @@ -263,9 +265,9 @@ def sendModelSelection(menu="mainmenu", folder="./models"): showdelete=True else: showdelete=False - emit('from_server', {'cmd': 'show_model_menu', 'data': menu_list, 'menu': menu, 'breadcrumbs': breadcrumbs, "showdelete": showdelete}, broadcast=True) + emit('from_server', {'cmd': 'show_model_menu', 'data': menu_list, 'menu': menu, 'breadcrumbs': breadcrumbs, "showdelete": showdelete}, broadcast=True, room="UI_1") else: - emit('from_server', {'cmd': 'show_model_menu', 'data': model_menu[menu], 'menu': menu, 'breadcrumbs': [], "showdelete": False}, broadcast=True) + emit('from_server', {'cmd': 'show_model_menu', 'data': model_menu[menu], 'menu': menu, 'breadcrumbs': [], "showdelete": False}, broadcast=True, room="UI_1") def get_folder_path_info(base): if base == 'This PC': @@ -794,7 +796,7 @@ def check_for_sp_change(): time.sleep(0.1) if(system_settings.sp_changed): with app.app_context(): - emit('from_server', {'cmd': 'spstatitems', 'data': {system_settings.spfilename: system_settings.spmeta} if system_settings.allowsp and len(system_settings.spfilename) else {}}, namespace=None, broadcast=True) + emit('from_server', {'cmd': 'spstatitems', 'data': {system_settings.spfilename: system_settings.spmeta} if system_settings.allowsp and len(system_settings.spfilename) else {}}, namespace=None, broadcast=True, room="UI_1") system_settings.sp_changed = False socketio.start_background_task(check_for_sp_change) @@ -1040,7 +1042,7 @@ def get_model_info(model, directory=""): 'gpu':gpu, 'layer_count':layer_count, 'breakmodel':breakmodel, 'disk_break_value': disk_blocks, 'accelerate': utils.HAS_ACCELERATE, 'break_values': break_values, 'gpu_count': gpu_count, - 'url': url, 'gpu_names': gpu_names}, broadcast=True) + 'url': url, 'gpu_names': gpu_names}, broadcast=True, room="UI_1") if key_value != "": get_oai_models(key_value) @@ -1112,12 +1114,12 @@ def get_oai_models(key): if changed: with open("settings/{}.settings".format(model_settings.model), "w") as file: js["apikey"] = key - file.write(json.dumps(js, indent=3)) + file.write(json.dumps(js, indent=3), room="UI_1") emit('from_server', {'cmd': 'oai_engines', 'data': engines, 'online_model': online_model}, broadcast=True) else: # Something went wrong, print the message and quit since we can't initialize an engine - print("{0}ERROR!{1}".format(colors.RED, colors.END)) + print("{0}ERROR!{1}".format(colors.RED, colors.END), room="UI_1") print(req.json()) emit('from_server', {'cmd': 'errmsg', 'data': req.json()}) @@ -1392,7 +1394,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal if not initial_load: set_aibusy(True) if model_settings.model != 'ReadOnly': - emit('from_server', {'cmd': 'model_load_status', 'data': "Loading {}".format(model_settings.model)}, broadcast=True) + emit('from_server', {'cmd': 'model_load_status', 'data': "Loading {}".format(model_settings.model)}, broadcast=True, room="UI_1") #Have to add a sleep so the server will send the emit for some reason time.sleep(0.1) if gpu_layers is not None: @@ -2058,7 +2060,7 @@ def load_model(use_gpu=True, gpu_layers=None, disk_layers=None, initial_load=Fal final_startup() if not initial_load: set_aibusy(False) - emit('from_server', {'cmd': 'hide_model_name'}, broadcast=True) + emit('from_server', {'cmd': 'hide_model_name'}, broadcast=True, room="UI_1") time.sleep(0.1) if not story_settings.gamestarted: @@ -2235,7 +2237,7 @@ def load_lua_scripts(): pass system_settings.lua_running = False if(system_settings.serverstarted): - emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True, room="UI_1") sendUSStatItems() print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) @@ -2722,7 +2724,7 @@ def execute_inmod(): except lupa.LuaError as e: system_settings.lua_koboldbridge.obliterate_multiverse() system_settings.lua_running = False - emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True, room="UI_1") sendUSStatItems() print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) @@ -2734,13 +2736,13 @@ def execute_genmod(): def execute_outmod(): setgamesaved(False) - emit('from_server', {'cmd': 'hidemsg', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'hidemsg', 'data': ''}, broadcast=True, room="UI_1") try: tpool.execute(system_settings.lua_koboldbridge.execute_outmod) except lupa.LuaError as e: system_settings.lua_koboldbridge.obliterate_multiverse() system_settings.lua_running = False - emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True, room="UI_1") sendUSStatItems() print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) @@ -2764,6 +2766,8 @@ def execute_outmod(): #==================================================================# @socketio.on('connect') def do_connect(): + if request.args.get("rely") == "true": + return join_room("UI_{}".format(request.args.get('ui'))) print("Joining Room UI_{}".format(request.args.get('ui'))) #Send all variables to client @@ -2772,51 +2776,51 @@ def do_connect(): user_settings.send_to_ui() system_settings.send_to_ui() print("{0}Client connected!{1}".format(colors.GREEN, colors.END)) - emit('from_server', {'cmd': 'setchatname', 'data': story_settings.chatname}) - emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}) - emit('from_server', {'cmd': 'connected', 'smandelete': system_settings.smandelete, 'smanrename': system_settings.smanrename, 'modelname': getmodelname()}) + emit('from_server', {'cmd': 'setchatname', 'data': story_settings.chatname}, room="UI_1") + emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, room="UI_1") + emit('from_server', {'cmd': 'connected', 'smandelete': system_settings.smandelete, 'smanrename': system_settings.smanrename, 'modelname': getmodelname()}, room="UI_1") if(system_settings.host): - emit('from_server', {'cmd': 'runs_remotely'}) + emit('from_server', {'cmd': 'runs_remotely'}, room="UI_1") if(system_settings.flaskwebgui): - emit('from_server', {'cmd': 'flaskwebgui'}) + emit('from_server', {'cmd': 'flaskwebgui'}, room="UI_1") if(system_settings.allowsp): - emit('from_server', {'cmd': 'allowsp', 'data': system_settings.allowsp}) + emit('from_server', {'cmd': 'allowsp', 'data': system_settings.allowsp}, room="UI_1") sendUSStatItems() - emit('from_server', {'cmd': 'spstatitems', 'data': {system_settings.spfilename: system_settings.spmeta} if system_settings.allowsp and len(system_settings.spfilename) else {}}, broadcast=True) + emit('from_server', {'cmd': 'spstatitems', 'data': {system_settings.spfilename: system_settings.spmeta} if system_settings.allowsp and len(system_settings.spfilename) else {}}, broadcast=True, room="UI_1") if(not story_settings.gamestarted): setStartState() sendsettings() refresh_settings() user_settings.laststory = None - emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}) + emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, room="UI_1") sendwi() - emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}) - emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}) + emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, room="UI_1") + emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, room="UI_1") story_settings.mode = "play" else: # Game in session, send current game data and ready state to browser refresh_story() sendsettings() refresh_settings() - emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}) + emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, room="UI_1") sendwi() - emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}) - emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}) + emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, room="UI_1") + emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, room="UI_1") if(story_settings.mode == "play"): if(not system_settings.aibusy): - emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}) + emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, room="UI_1") else: - emit('from_server', {'cmd': 'setgamestate', 'data': 'wait'}) + emit('from_server', {'cmd': 'setgamestate', 'data': 'wait'}, room="UI_1") elif(story_settings.mode == "edit"): - emit('from_server', {'cmd': 'editmode', 'data': 'true'}) + emit('from_server', {'cmd': 'editmode', 'data': 'true'}, room="UI_1") elif(story_settings.mode == "memory"): - emit('from_server', {'cmd': 'memmode', 'data': 'true'}) + emit('from_server', {'cmd': 'memmode', 'data': 'true'}, room="UI_1") elif(story_settings.mode == "wi"): - emit('from_server', {'cmd': 'wimode', 'data': 'true'}) + emit('from_server', {'cmd': 'wimode', 'data': 'true'}, room="UI_1") - emit('from_server', {'cmd': 'gamesaved', 'data': story_settings.gamesaved}, broadcast=True) + emit('from_server', {'cmd': 'gamesaved', 'data': story_settings.gamesaved}, broadcast=True, room="UI_1") #==================================================================# # Event triggered when browser SocketIO sends data to the server @@ -2839,7 +2843,7 @@ def get_message(msg): raise ValueError("Chatname must be a string") story_settings.chatname = msg['chatname'] settingschanged() - emit('from_server', {'cmd': 'setchatname', 'data': story_settings.chatname}) + emit('from_server', {'cmd': 'setchatname', 'data': story_settings.chatname}, room="UI_1") story_settings.recentrng = story_settings.recentrngm = None actionsubmit(msg['data'], actionmode=msg['actionmode']) elif(story_settings.mode == "edit"): @@ -2858,7 +2862,7 @@ def get_message(msg): raise ValueError("Chatname must be a string") story_settings.chatname = msg['chatname'] settingschanged() - emit('from_server', {'cmd': 'setchatname', 'data': story_settings.chatname}) + emit('from_server', {'cmd': 'setchatname', 'data': story_settings.chatname}, room="UI_1") actionretry(msg['data']) # Back/Undo Action elif(msg['cmd'] == 'back'): @@ -2870,10 +2874,10 @@ def get_message(msg): elif(msg['cmd'] == 'edit'): if(story_settings.mode == "play"): story_settings.mode = "edit" - emit('from_server', {'cmd': 'editmode', 'data': 'true'}, broadcast=True) + emit('from_server', {'cmd': 'editmode', 'data': 'true'}, broadcast=True, room="UI_1") elif(story_settings.mode == "edit"): story_settings.mode = "play" - emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True, room="UI_1") # EditLine Action (old) elif(msg['cmd'] == 'editline'): editrequest(int(msg['data'])) @@ -2901,62 +2905,62 @@ def get_message(msg): randomGameRequest(msg['data'], memory=msg['memory']) elif(msg['cmd'] == 'settemp'): model_settings.temp = float(msg['data']) - emit('from_server', {'cmd': 'setlabeltemp', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabeltemp', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'settopp'): model_settings.top_p = float(msg['data']) - emit('from_server', {'cmd': 'setlabeltopp', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabeltopp', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'settopk'): model_settings.top_k = int(msg['data']) - emit('from_server', {'cmd': 'setlabeltopk', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabeltopk', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'settfs'): model_settings.tfs = float(msg['data']) - emit('from_server', {'cmd': 'setlabeltfs', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabeltfs', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'settypical'): model_settings.typical = float(msg['data']) - emit('from_server', {'cmd': 'setlabeltypical', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabeltypical', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'settopa'): model_settings.top_a = float(msg['data']) - emit('from_server', {'cmd': 'setlabeltopa', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabeltopa', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'setreppen'): model_settings.rep_pen = float(msg['data']) - emit('from_server', {'cmd': 'setlabelreppen', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabelreppen', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'setreppenslope'): model_settings.rep_pen_slope = float(msg['data']) - emit('from_server', {'cmd': 'setlabelreppenslope', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabelreppenslope', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'setreppenrange'): model_settings.rep_pen_range = float(msg['data']) - emit('from_server', {'cmd': 'setlabelreppenrange', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabelreppenrange', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'setoutput'): model_settings.genamt = int(msg['data']) - emit('from_server', {'cmd': 'setlabeloutput', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabeloutput', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'settknmax'): model_settings.max_length = int(msg['data']) - emit('from_server', {'cmd': 'setlabeltknmax', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabeltknmax', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'setikgen'): model_settings.ikgen = int(msg['data']) - emit('from_server', {'cmd': 'setlabelikgen', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabelikgen', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() # Author's Note field update @@ -2965,7 +2969,7 @@ def get_message(msg): # Author's Note depth update elif(msg['cmd'] == 'anotedepth'): story_settings.andepth = int(msg['data']) - emit('from_server', {'cmd': 'setlabelanotedepth', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'setlabelanotedepth', 'data': msg['data']}, broadcast=True, room="UI_1") settingschanged() refresh_settings() # Format - Trim incomplete sentences @@ -2997,10 +3001,10 @@ def get_message(msg): elif(msg['cmd'] == 'importselect'): user_settings.importnum = int(msg["data"].replace("import", "")) elif(msg['cmd'] == 'importcancel'): - emit('from_server', {'cmd': 'popupshow', 'data': False}) + emit('from_server', {'cmd': 'popupshow', 'data': False}, room="UI_1") user_settings.importjs = {} elif(msg['cmd'] == 'importaccept'): - emit('from_server', {'cmd': 'popupshow', 'data': False}) + emit('from_server', {'cmd': 'popupshow', 'data': False}, room="UI_1") importgame() elif(msg['cmd'] == 'wi'): togglewimode() @@ -3022,19 +3026,19 @@ def get_message(msg): elif(msg['cmd'] == 'wiexpand'): assert 0 <= int(msg['data']) < len(story_settings.worldinfo) setgamesaved(False) - emit('from_server', {'cmd': 'wiexpand', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'wiexpand', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wiexpandfolder'): assert 0 <= int(msg['data']) < len(story_settings.worldinfo) setgamesaved(False) - emit('from_server', {'cmd': 'wiexpandfolder', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'wiexpandfolder', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wifoldercollapsecontent'): setgamesaved(False) story_settings.wifolders_d[msg['data']]['collapsed'] = True - emit('from_server', {'cmd': 'wifoldercollapsecontent', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'wifoldercollapsecontent', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wifolderexpandcontent'): setgamesaved(False) story_settings.wifolders_d[msg['data']]['collapsed'] = False - emit('from_server', {'cmd': 'wifolderexpandcontent', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'wifolderexpandcontent', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wiupdate'): setgamesaved(False) num = int(msg['num']) @@ -3042,7 +3046,7 @@ def get_message(msg): for field in fields: if(field in msg['data'] and type(msg['data'][field]) is str): story_settings.worldinfo[num][field] = msg['data'][field] - emit('from_server', {'cmd': 'wiupdate', 'num': msg['num'], 'data': {field: story_settings.worldinfo[num][field] for field in fields}}, broadcast=True) + emit('from_server', {'cmd': 'wiupdate', 'num': msg['num'], 'data': {field: story_settings.worldinfo[num][field] for field in fields}}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wifolderupdate'): setgamesaved(False) uid = int(msg['uid']) @@ -3050,23 +3054,23 @@ def get_message(msg): for field in fields: if(field in msg['data'] and type(msg['data'][field]) is (str if field != "collapsed" else bool)): story_settings.wifolders_d[uid][field] = msg['data'][field] - emit('from_server', {'cmd': 'wifolderupdate', 'uid': msg['uid'], 'data': {field: story_settings.wifolders_d[uid][field] for field in fields}}, broadcast=True) + emit('from_server', {'cmd': 'wifolderupdate', 'uid': msg['uid'], 'data': {field: story_settings.wifolders_d[uid][field] for field in fields}}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wiselon'): setgamesaved(False) story_settings.worldinfo[msg['data']]["selective"] = True - emit('from_server', {'cmd': 'wiselon', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'wiselon', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wiseloff'): setgamesaved(False) story_settings.worldinfo[msg['data']]["selective"] = False - emit('from_server', {'cmd': 'wiseloff', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'wiseloff', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wiconstanton'): setgamesaved(False) story_settings.worldinfo[msg['data']]["constant"] = True - emit('from_server', {'cmd': 'wiconstanton', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'wiconstanton', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'wiconstantoff'): setgamesaved(False) story_settings.worldinfo[msg['data']]["constant"] = False - emit('from_server', {'cmd': 'wiconstantoff', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'wiconstantoff', 'data': msg['data']}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'sendwilist'): commitwi(msg['data']) elif(msg['cmd'] == 'aidgimport'): @@ -3081,9 +3085,9 @@ def get_message(msg): getsplist() elif(msg['cmd'] == 'uslistrequest'): unloaded, loaded = getuslist() - emit('from_server', {'cmd': 'buildus', 'data': {"unloaded": unloaded, "loaded": loaded}}) + emit('from_server', {'cmd': 'buildus', 'data': {"unloaded": unloaded, "loaded": loaded}}, room="UI_1") elif(msg['cmd'] == 'samplerlistrequest'): - emit('from_server', {'cmd': 'buildsamplers', 'data': model_settings.sampler_order}) + emit('from_server', {'cmd': 'buildsamplers', 'data': model_settings.sampler_order}, room="UI_1") elif(msg['cmd'] == 'usloaded'): system_settings.userscripts = [] for userscript in msg['data']: @@ -3131,7 +3135,7 @@ def get_message(msg): load_model(use_gpu=msg['use_gpu'], gpu_layers=msg['gpu_layers'], disk_layers=msg['disk_layers'], online_model=msg['online_model']) elif(msg['cmd'] == 'show_model'): print("Model Name: {}".format(getmodelname())) - emit('from_server', {'cmd': 'show_model_name', 'data': getmodelname()}, broadcast=True) + emit('from_server', {'cmd': 'show_model_name', 'data': getmodelname()}, broadcast=True, room="UI_1") elif(msg['cmd'] == 'selectmodel'): # This is run when a model line is selected from the UI (line from the model_menu variable) that is tagged as not a menu # otherwise we should be running the msg['cmd'] == 'list_model' @@ -3160,7 +3164,7 @@ def get_message(msg): try: get_model_info(model_settings.model) except: - emit('from_server', {'cmd': 'errmsg', 'data': "The model entered doesn't exist."}) + emit('from_server', {'cmd': 'errmsg', 'data': "The model entered doesn't exist."}, room="UI_1") elif msg['data'] in ('NeoCustom', 'GPT2Custom'): if check_if_dir_is_model(msg['path']): model_settings.model = msg['data'] @@ -3212,12 +3216,12 @@ def get_message(msg): pinsequence(msg['data']) elif(msg['cmd'] == 'setnumseq'): model_settings.numseqs = int(msg['data']) - emit('from_server', {'cmd': 'setlabelnumseq', 'data': msg['data']}) + emit('from_server', {'cmd': 'setlabelnumseq', 'data': msg['data']}, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'setwidepth'): user_settings.widepth = int(msg['data']) - emit('from_server', {'cmd': 'setlabelwidepth', 'data': msg['data']}) + emit('from_server', {'cmd': 'setlabelwidepth', 'data': msg['data']}, room="UI_1") settingschanged() refresh_settings() elif(msg['cmd'] == 'setuseprompt'): @@ -3258,7 +3262,7 @@ def get_message(msg): wiimportrequest() elif(msg['cmd'] == 'debug'): user_settings.debug = msg['data'] - emit('from_server', {'cmd': 'set_debug', 'data': msg['data']}, broadcast=True) + emit('from_server', {'cmd': 'set_debug', 'data': msg['data']}, broadcast=True, room="UI_1") if user_settings.debug: send_debug() @@ -3269,7 +3273,7 @@ def sendUSStatItems(): _, loaded = getuslist() loaded = loaded if system_settings.lua_running else [] last_userscripts = [e["filename"] for e in loaded] - emit('from_server', {'cmd': 'usstatitems', 'data': loaded, 'flash': last_userscripts != system_settings.last_userscripts}, broadcast=True) + emit('from_server', {'cmd': 'usstatitems', 'data': loaded, 'flash': last_userscripts != system_settings.last_userscripts}, broadcast=True, room="UI_1") system_settings.last_userscripts = last_userscripts #==================================================================# @@ -3292,25 +3296,25 @@ def setStartState(): txt = txt + "Please load a game or enter a prompt below to begin!" if(system_settings.noai): txt = txt + "Please load or import a story to read. There is no AI in this mode." - emit('from_server', {'cmd': 'updatescreen', 'gamestarted': story_settings.gamestarted, 'data': txt}, broadcast=True) - emit('from_server', {'cmd': 'setgamestate', 'data': 'start'}, broadcast=True) + emit('from_server', {'cmd': 'updatescreen', 'gamestarted': story_settings.gamestarted, 'data': txt}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setgamestate', 'data': 'start'}, broadcast=True, room="UI_1") #==================================================================# # Transmit applicable settings to SocketIO to build UI sliders/toggles #==================================================================# def sendsettings(): # Send settings for selected AI type - emit('from_server', {'cmd': 'reset_menus'}) + emit('from_server', {'cmd': 'reset_menus'}, room="UI_1") if(model_settings.model != "InferKit"): for set in gensettings.gensettingstf: - emit('from_server', {'cmd': 'addsetting', 'data': set}) + emit('from_server', {'cmd': 'addsetting', 'data': set}, room="UI_1") else: for set in gensettings.gensettingsik: - emit('from_server', {'cmd': 'addsetting', 'data': set}) + emit('from_server', {'cmd': 'addsetting', 'data': set}, room="UI_1") # Send formatting options for frm in gensettings.formatcontrols: - emit('from_server', {'cmd': 'addformat', 'data': frm}) + emit('from_server', {'cmd': 'addformat', 'data': frm}, room="UI_1") # Add format key to vars if it wasn't loaded with client.settings if(not frm["id"] in user_settings.formatoptns): user_settings.formatoptns[frm["id"]] = False; @@ -3321,7 +3325,7 @@ def sendsettings(): def setgamesaved(gamesaved): assert type(gamesaved) is bool if(gamesaved != story_settings.gamesaved): - emit('from_server', {'cmd': 'gamesaved', 'data': gamesaved}, broadcast=True) + emit('from_server', {'cmd': 'gamesaved', 'data': gamesaved}, broadcast=True, room="UI_1") story_settings.gamesaved = gamesaved #==================================================================# @@ -3335,7 +3339,7 @@ def check_for_backend_compilation(): for _ in range(31): time.sleep(0.06276680299820175) if(system_settings.compiling): - emit('from_server', {'cmd': 'warnmsg', 'data': 'Compiling TPU backend—this usually takes 1–2 minutes...'}, broadcast=True) + emit('from_server', {'cmd': 'warnmsg', 'data': 'Compiling TPU backend—this usually takes 1–2 minutes...'}, broadcast=True, room="UI_1") break system_settings.checking = False @@ -3383,14 +3387,14 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False, # Save this first action as the prompt story_settings.prompt = data # Clear the startup text from game screen - emit('from_server', {'cmd': 'updatescreen', 'gamestarted': False, 'data': 'Please wait, generating story...'}, broadcast=True) + emit('from_server', {'cmd': 'updatescreen', 'gamestarted': False, 'data': 'Please wait, generating story...'}, broadcast=True, room="UI_1") calcsubmit(data) # Run the first action through the generator if(not system_settings.abort and system_settings.lua_koboldbridge.restart_sequence is not None and len(story_settings.genseqs) == 0): data = "" force_submit = True disable_recentrng = True continue - emit('from_server', {'cmd': 'scrolldown', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'scrolldown', 'data': ''}, broadcast=True, room="UI_1") break else: # Save this first action as the prompt @@ -3407,7 +3411,7 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False, genresult(genout[0]["generated_text"], flash=False) refresh_story() if(len(story_settings.actions) > 0): - emit('from_server', {'cmd': 'texteffect', 'data': story_settings.actions.get_last_key() + 1}, broadcast=True) + emit('from_server', {'cmd': 'texteffect', 'data': story_settings.actions.get_last_key() + 1}, broadcast=True, room="UI_1") if(not system_settings.abort and system_settings.lua_koboldbridge.restart_sequence is not None): data = "" force_submit = True @@ -3424,7 +3428,7 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False, genselect(genout) refresh_story() set_aibusy(0) - emit('from_server', {'cmd': 'scrolldown', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'scrolldown', 'data': ''}, broadcast=True, room="UI_1") break else: # Apply input formatting & scripts before sending to tokenizer @@ -3451,7 +3455,7 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False, force_submit = True disable_recentrng = True continue - emit('from_server', {'cmd': 'scrolldown', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'scrolldown', 'data': ''}, broadcast=True, room="UI_1") break else: for i in range(model_settings.numseqs): @@ -3478,7 +3482,7 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False, continue genselect(genout) set_aibusy(0) - emit('from_server', {'cmd': 'scrolldown', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'scrolldown', 'data': ''}, broadcast=True, room="UI_1") break #==================================================================# @@ -3486,7 +3490,7 @@ def actionsubmit(data, actionmode=0, force_submit=False, force_prompt_gen=False, #==================================================================# def actionretry(data): if(system_settings.noai): - emit('from_server', {'cmd': 'errmsg', 'data': "Retry function unavailable in Read Only mode."}) + emit('from_server', {'cmd': 'errmsg', 'data': "Retry function unavailable in Read Only mode."}, room="UI_1") return if(story_settings.recentrng is not None): if(not system_settings.aibusy): @@ -3496,7 +3500,7 @@ def actionretry(data): actionsubmit("", actionmode=story_settings.actionmode, force_submit=True) send_debug() elif(not story_settings.useprompt): - emit('from_server', {'cmd': 'errmsg', 'data': "Please enable \"Always Add Prompt\" to retry with your prompt."}) + emit('from_server', {'cmd': 'errmsg', 'data': "Please enable \"Always Add Prompt\" to retry with your prompt."}, room="UI_1") #==================================================================# # @@ -3512,7 +3516,7 @@ def actionback(): remove_story_chunk(last_key + 1) success = True elif(len(story_settings.genseqs) == 0): - emit('from_server', {'cmd': 'errmsg', 'data': "Cannot delete the prompt."}) + emit('from_server', {'cmd': 'errmsg', 'data': "Cannot delete the prompt."}, room="UI_1") success = False else: story_settings.genseqs = [] @@ -3523,12 +3527,12 @@ def actionback(): def actionredo(): genout = [[x['text'], "redo" if x['Previous Selection'] else "pinned" if x['Pinned'] else "normal"] for x in story_settings.actions.get_redo_options()] if len(genout) == 0: - emit('from_server', {'cmd': 'popuperror', 'data': "There's nothing to redo"}, broadcast=True) + emit('from_server', {'cmd': 'popuperror', 'data': "There's nothing to redo"}, broadcast=True, room="UI_1") elif len(genout) == 1: genresult(genout[0][0], flash=True, ignore_formatting=True) else: story_settings.genseqs = [{"generated_text": x[0]} for x in genout] - emit('from_server', {'cmd': 'genseqs', 'data': genout}, broadcast=True) + emit('from_server', {'cmd': 'genseqs', 'data': genout}, broadcast=True, room="UI_1") send_debug() #==================================================================# @@ -3864,13 +3868,13 @@ def generate(txt, minimum, maximum, found_entries=None): if(issubclass(type(e), lupa.LuaError)): system_settings.lua_koboldbridge.obliterate_multiverse() system_settings.lua_running = False - emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True, room="UI_1") sendUSStatItems() print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) print("{0}{1}{2}".format(colors.YELLOW, "Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.", colors.END), file=sys.stderr) else: - emit('from_server', {'cmd': 'errmsg', 'data': 'Error occurred during generator call; please check console.'}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': 'Error occurred during generator call; please check console.'}, broadcast=True, room="UI_1") print("{0}{1}{2}".format(colors.RED, traceback.format_exc().replace("\033", ""), colors.END), file=sys.stderr) set_aibusy(0) return @@ -3928,7 +3932,7 @@ def genresult(genout, flash=True, ignore_formatting=False): story_settings.actions.append(genout) update_story_chunk('last') if(flash): - emit('from_server', {'cmd': 'texteffect', 'data': story_settings.actions.get_last_key() + 1 if len(story_settings.actions) else 0}, broadcast=True) + emit('from_server', {'cmd': 'texteffect', 'data': story_settings.actions.get_last_key() + 1 if len(story_settings.actions) else 0}, broadcast=True, room="UI_1") send_debug() #==================================================================# @@ -3955,7 +3959,7 @@ def genselect(genout): genout = story_settings.actions.get_current_options_no_edits(ui=1) # Send sequences to UI for selection - emit('from_server', {'cmd': 'genseqs', 'data': genout}, broadcast=True) + emit('from_server', {'cmd': 'genseqs', 'data': genout}, broadcast=True, room="UI_1") send_debug() #==================================================================# @@ -3968,8 +3972,8 @@ def selectsequence(n): if(len(system_settings.lua_koboldbridge.feedback) != 0): story_settings.actions.append(system_settings.lua_koboldbridge.feedback) update_story_chunk('last') - emit('from_server', {'cmd': 'texteffect', 'data': story_settings.actions.get_last_key() + 1 if len(story_settings.actions) else 0}, broadcast=True) - emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'texteffect', 'data': story_settings.actions.get_last_key() + 1 if len(story_settings.actions) else 0}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True, room="UI_1") story_settings.genseqs = [] if(system_settings.lua_koboldbridge.restart_sequence is not None): @@ -4066,7 +4070,7 @@ def sendtocolab(txt, min, max): else: errmsg = "Colab API Error: Failed to get a reply from the server. Please check the colab console." print("{0}{1}{2}".format(colors.RED, errmsg, colors.END)) - emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True, room="UI_1") set_aibusy(0) #==================================================================# @@ -4166,13 +4170,13 @@ def tpumtjgenerate(txt, minimum, maximum, found_entries=None): if(issubclass(type(e), lupa.LuaError)): system_settings.lua_koboldbridge.obliterate_multiverse() system_settings.lua_running = False - emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': 'Lua script error; please check console.'}, broadcast=True, room="UI_1") sendUSStatItems() print("{0}{1}{2}".format(colors.RED, "***LUA ERROR***: ", colors.END), end="", file=sys.stderr) print("{0}{1}{2}".format(colors.RED, str(e).replace("\033", ""), colors.END), file=sys.stderr) print("{0}{1}{2}".format(colors.YELLOW, "Lua engine stopped; please open 'Userscripts' and press Load to reinitialize scripts.", colors.END), file=sys.stderr) else: - emit('from_server', {'cmd': 'errmsg', 'data': 'Error occurred during generator call; please check console.'}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': 'Error occurred during generator call; please check console.'}, broadcast=True, room="UI_1") print("{0}{1}{2}".format(colors.RED, traceback.format_exc().replace("\033", ""), colors.END), file=sys.stderr) set_aibusy(0) return @@ -4274,7 +4278,7 @@ def refresh_story(): item = system_settings.comregex_ui.sub(lambda m: '\n'.join('' + l + '' for l in m.group().split('\n')), item) # Add special formatting to comments item = system_settings.acregex_ui.sub('\\1', item) # Add special formatting to adventure actions text_parts.extend(('', item, '')) - emit('from_server', {'cmd': 'updatescreen', 'gamestarted': story_settings.gamestarted, 'data': formatforhtml(''.join(text_parts))}, broadcast=True) + emit('from_server', {'cmd': 'updatescreen', 'gamestarted': story_settings.gamestarted, 'data': formatforhtml(''.join(text_parts))}, broadcast=True, room="UI_1") #==================================================================# @@ -4306,7 +4310,7 @@ def update_story_chunk(idx: Union[int, str]): item = system_settings.acregex_ui.sub('\\1', item) # Add special formatting to adventure actions chunk_text = f'{formatforhtml(item)}' - emit('from_server', {'cmd': 'updatechunk', 'data': {'index': idx, 'html': chunk_text}}, broadcast=True) + emit('from_server', {'cmd': 'updatechunk', 'data': {'index': idx, 'html': chunk_text}}, broadcast=True, room="UI_1") setgamesaved(False) @@ -4319,7 +4323,7 @@ def update_story_chunk(idx: Union[int, str]): # Signals the Game Screen to remove one of the chunks #==================================================================# def remove_story_chunk(idx: int): - emit('from_server', {'cmd': 'removechunk', 'data': idx}, broadcast=True) + emit('from_server', {'cmd': 'removechunk', 'data': idx}, broadcast=True, room="UI_1") setgamesaved(False) @@ -4328,45 +4332,45 @@ def remove_story_chunk(idx: int): #==================================================================# def refresh_settings(): # Suppress toggle change events while loading state - emit('from_server', {'cmd': 'allowtoggle', 'data': False}, broadcast=True) + emit('from_server', {'cmd': 'allowtoggle', 'data': False}, broadcast=True, room="UI_1") if(model_settings.model != "InferKit"): - emit('from_server', {'cmd': 'updatetemp', 'data': model_settings.temp}, broadcast=True) - emit('from_server', {'cmd': 'updatetopp', 'data': model_settings.top_p}, broadcast=True) - emit('from_server', {'cmd': 'updatetopk', 'data': model_settings.top_k}, broadcast=True) - emit('from_server', {'cmd': 'updatetfs', 'data': model_settings.tfs}, broadcast=True) - emit('from_server', {'cmd': 'updatetypical', 'data': model_settings.typical}, broadcast=True) - emit('from_server', {'cmd': 'updatetopa', 'data': model_settings.top_a}, broadcast=True) - emit('from_server', {'cmd': 'updatereppen', 'data': model_settings.rep_pen}, broadcast=True) - emit('from_server', {'cmd': 'updatereppenslope', 'data': model_settings.rep_pen_slope}, broadcast=True) - emit('from_server', {'cmd': 'updatereppenrange', 'data': model_settings.rep_pen_range}, broadcast=True) - emit('from_server', {'cmd': 'updateoutlen', 'data': model_settings.genamt}, broadcast=True) - emit('from_server', {'cmd': 'updatetknmax', 'data': model_settings.max_length}, broadcast=True) - emit('from_server', {'cmd': 'updatenumseq', 'data': model_settings.numseqs}, broadcast=True) + emit('from_server', {'cmd': 'updatetemp', 'data': model_settings.temp}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatetopp', 'data': model_settings.top_p}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatetopk', 'data': model_settings.top_k}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatetfs', 'data': model_settings.tfs}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatetypical', 'data': model_settings.typical}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatetopa', 'data': model_settings.top_a}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatereppen', 'data': model_settings.rep_pen}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatereppenslope', 'data': model_settings.rep_pen_slope}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatereppenrange', 'data': model_settings.rep_pen_range}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updateoutlen', 'data': model_settings.genamt}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatetknmax', 'data': model_settings.max_length}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatenumseq', 'data': model_settings.numseqs}, broadcast=True, room="UI_1") else: - emit('from_server', {'cmd': 'updatetemp', 'data': model_settings.temp}, broadcast=True) - emit('from_server', {'cmd': 'updatetopp', 'data': model_settings.top_p}, broadcast=True) - emit('from_server', {'cmd': 'updateikgen', 'data': model_settings.ikgen}, broadcast=True) + emit('from_server', {'cmd': 'updatetemp', 'data': model_settings.temp}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatetopp', 'data': model_settings.top_p}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updateikgen', 'data': model_settings.ikgen}, broadcast=True, room="UI_1") - emit('from_server', {'cmd': 'updateanotedepth', 'data': story_settings.andepth}, broadcast=True) - emit('from_server', {'cmd': 'updatewidepth', 'data': user_settings.widepth}, broadcast=True) - emit('from_server', {'cmd': 'updateuseprompt', 'data': story_settings.useprompt}, broadcast=True) - emit('from_server', {'cmd': 'updateadventure', 'data': story_settings.adventure}, broadcast=True) - emit('from_server', {'cmd': 'updatechatmode', 'data': story_settings.chatmode}, broadcast=True) - emit('from_server', {'cmd': 'updatedynamicscan', 'data': story_settings.dynamicscan}, broadcast=True) - emit('from_server', {'cmd': 'updateautosave', 'data': user_settings.autosave}, broadcast=True) - emit('from_server', {'cmd': 'updatenopromptgen', 'data': user_settings.nopromptgen}, broadcast=True) - emit('from_server', {'cmd': 'updaterngpersist', 'data': user_settings.rngpersist}, broadcast=True) - emit('from_server', {'cmd': 'updatenogenmod', 'data': user_settings.nogenmod}, broadcast=True) + emit('from_server', {'cmd': 'updateanotedepth', 'data': story_settings.andepth}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatewidepth', 'data': user_settings.widepth}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updateuseprompt', 'data': story_settings.useprompt}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updateadventure', 'data': story_settings.adventure}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatechatmode', 'data': story_settings.chatmode}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatedynamicscan', 'data': story_settings.dynamicscan}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updateautosave', 'data': user_settings.autosave}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatenopromptgen', 'data': user_settings.nopromptgen}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updaterngpersist', 'data': user_settings.rngpersist}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatenogenmod', 'data': user_settings.nogenmod}, broadcast=True, room="UI_1") - emit('from_server', {'cmd': 'updatefrmttriminc', 'data': user_settings.formatoptns["frmttriminc"]}, broadcast=True) - emit('from_server', {'cmd': 'updatefrmtrmblln', 'data': user_settings.formatoptns["frmtrmblln"]}, broadcast=True) - emit('from_server', {'cmd': 'updatefrmtrmspch', 'data': user_settings.formatoptns["frmtrmspch"]}, broadcast=True) - emit('from_server', {'cmd': 'updatefrmtadsnsp', 'data': user_settings.formatoptns["frmtadsnsp"]}, broadcast=True) - emit('from_server', {'cmd': 'updatesingleline', 'data': user_settings.formatoptns["singleline"]}, broadcast=True) + emit('from_server', {'cmd': 'updatefrmttriminc', 'data': user_settings.formatoptns["frmttriminc"]}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatefrmtrmblln', 'data': user_settings.formatoptns["frmtrmblln"]}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatefrmtrmspch', 'data': user_settings.formatoptns["frmtrmspch"]}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatefrmtadsnsp', 'data': user_settings.formatoptns["frmtadsnsp"]}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'updatesingleline', 'data': user_settings.formatoptns["singleline"]}, broadcast=True, room="UI_1") # Allow toggle events again - emit('from_server', {'cmd': 'allowtoggle', 'data': True}, broadcast=True) + emit('from_server', {'cmd': 'allowtoggle', 'data': True}, broadcast=True, room="UI_1") #==================================================================# # Sets the logical and display states for the AI Busy condition @@ -4374,10 +4378,10 @@ def refresh_settings(): def set_aibusy(state): if(state): system_settings.aibusy = True - emit('from_server', {'cmd': 'setgamestate', 'data': 'wait'}, broadcast=True) + emit('from_server', {'cmd': 'setgamestate', 'data': 'wait'}, broadcast=True, room="UI_1") else: system_settings.aibusy = False - emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True) + emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True, room="UI_1") #==================================================================# # @@ -4389,8 +4393,8 @@ def editrequest(n): txt = story_settings.actions[n-1] story_settings.editln = n - emit('from_server', {'cmd': 'setinputtext', 'data': txt}, broadcast=True) - emit('from_server', {'cmd': 'enablesubmit', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'setinputtext', 'data': txt}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'enablesubmit', 'data': ''}, broadcast=True, room="UI_1") #==================================================================# # @@ -4404,8 +4408,8 @@ def editsubmit(data): story_settings.mode = "play" update_story_chunk(story_settings.editln) - emit('from_server', {'cmd': 'texteffect', 'data': story_settings.editln}, broadcast=True) - emit('from_server', {'cmd': 'editmode', 'data': 'false'}) + emit('from_server', {'cmd': 'texteffect', 'data': story_settings.editln}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'editmode', 'data': 'false'}, room="UI_1") send_debug() #==================================================================# @@ -4421,7 +4425,7 @@ def deleterequest(): story_settings.actions.delete_action(story_settings.editln-1) story_settings.mode = "play" remove_story_chunk(story_settings.editln) - emit('from_server', {'cmd': 'editmode', 'data': 'false'}) + emit('from_server', {'cmd': 'editmode', 'data': 'false'}, room="UI_1") send_debug() #==================================================================# @@ -4442,8 +4446,8 @@ def inlineedit(chunk, data): setgamesaved(False) update_story_chunk(chunk) - emit('from_server', {'cmd': 'texteffect', 'data': chunk}, broadcast=True) - emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'texteffect', 'data': chunk}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True, room="UI_1") send_debug() #==================================================================# @@ -4456,8 +4460,8 @@ def inlinedelete(chunk): if(chunk == 0): # Send error message update_story_chunk(chunk) - emit('from_server', {'cmd': 'errmsg', 'data': "Cannot delete the prompt."}) - emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': "Cannot delete the prompt."}, room="UI_1") + emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True, room="UI_1") else: if(chunk-1 in story_settings.actions): story_settings.actions.delete_action(chunk-1) @@ -4465,7 +4469,7 @@ def inlinedelete(chunk): print(f"WARNING: Attempted to delete non-existent chunk {chunk}") setgamesaved(False) remove_story_chunk(chunk) - emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True, room="UI_1") send_debug() #==================================================================# @@ -4474,13 +4478,13 @@ def inlinedelete(chunk): def togglememorymode(): if(story_settings.mode == "play"): story_settings.mode = "memory" - emit('from_server', {'cmd': 'memmode', 'data': 'true'}, broadcast=True) - emit('from_server', {'cmd': 'setinputtext', 'data': story_settings.memory}, broadcast=True) - emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True) - emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True) + emit('from_server', {'cmd': 'memmode', 'data': 'true'}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setinputtext', 'data': story_settings.memory}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True, room="UI_1") elif(story_settings.mode == "memory"): story_settings.mode = "play" - emit('from_server', {'cmd': 'memmode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'memmode', 'data': 'false'}, broadcast=True, room="UI_1") #==================================================================# # Toggles the game mode for WI editing and sends UI commands @@ -4488,13 +4492,13 @@ def togglememorymode(): def togglewimode(): if(story_settings.mode == "play"): story_settings.mode = "wi" - emit('from_server', {'cmd': 'wimode', 'data': 'true'}, broadcast=True) + emit('from_server', {'cmd': 'wimode', 'data': 'true'}, broadcast=True, room="UI_1") elif(story_settings.mode == "wi"): # Commit WI fields first requestwi() # Then set UI state back to Play story_settings.mode = "play" - emit('from_server', {'cmd': 'wimode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'wimode', 'data': 'false'}, broadcast=True, room="UI_1") sendwi() #==================================================================# @@ -4512,7 +4516,7 @@ def addwiitem(folder_uid=None): story_settings.worldinfo[-1]["uid"] = uid if(folder_uid is not None): story_settings.wifolders_u[folder_uid].append(story_settings.worldinfo[-1]) - emit('from_server', {'cmd': 'addwiitem', 'data': ob}, broadcast=True) + emit('from_server', {'cmd': 'addwiitem', 'data': ob}, broadcast=True, room="UI_1") #==================================================================# # Creates a new WI folder with an unused cryptographically secure random UID @@ -4526,7 +4530,7 @@ def addwifolder(): story_settings.wifolders_d[uid] = ob story_settings.wifolders_l.append(uid) story_settings.wifolders_u[uid] = [] - emit('from_server', {'cmd': 'addwifolder', 'uid': uid, 'data': ob}, broadcast=True) + emit('from_server', {'cmd': 'addwifolder', 'uid': uid, 'data': ob}, broadcast=True, room="UI_1") addwiitem(folder_uid=uid) #==================================================================# @@ -4573,7 +4577,7 @@ def sendwi(): ln = len(story_settings.worldinfo) # Clear contents of WI container - emit('from_server', {'cmd': 'wistart', 'wifolders_d': story_settings.wifolders_d, 'wifolders_l': story_settings.wifolders_l, 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'wistart', 'wifolders_d': story_settings.wifolders_d, 'wifolders_l': story_settings.wifolders_l, 'data': ''}, broadcast=True, room="UI_1") # Stable-sort WI entries in order of folder stablesortwi() @@ -4588,12 +4592,12 @@ def sendwi(): last_folder = ... for wi in story_settings.worldinfo: if(wi["folder"] != last_folder): - emit('from_server', {'cmd': 'addwifolder', 'uid': wi["folder"], 'data': story_settings.wifolders_d[wi["folder"]] if wi["folder"] is not None else None}, broadcast=True) + emit('from_server', {'cmd': 'addwifolder', 'uid': wi["folder"], 'data': story_settings.wifolders_d[wi["folder"]] if wi["folder"] is not None else None}, broadcast=True, room="UI_1") last_folder = wi["folder"] ob = wi - emit('from_server', {'cmd': 'addwiitem', 'data': ob}, broadcast=True) + emit('from_server', {'cmd': 'addwiitem', 'data': ob}, broadcast=True, room="UI_1") - emit('from_server', {'cmd': 'wifinish', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'wifinish', 'data': ''}, broadcast=True, room="UI_1") #==================================================================# # Request current contents of all WI HTML elements @@ -4602,7 +4606,7 @@ def requestwi(): list = [] for wi in story_settings.worldinfo: list.append(wi["num"]) - emit('from_server', {'cmd': 'requestwiitem', 'data': list}) + emit('from_server', {'cmd': 'requestwiitem', 'data': list}, room="UI_1") #==================================================================# # Stable-sort WI items so that items in the same folder are adjacent, @@ -4779,17 +4783,17 @@ def checkworldinfo(txt, allowed_entries=None, allowed_folders=None, force_use_tx # Commit changes to Memory storage #==================================================================# def memsubmit(data): - emit('from_server', {'cmd': 'setinputtext', 'data': data}, broadcast=True) + emit('from_server', {'cmd': 'setinputtext', 'data': data}, broadcast=True, room="UI_1") # Maybe check for length at some point # For now just send it to storage if(data != story_settings.memory): setgamesaved(False) story_settings.memory = data story_settings.mode = "play" - emit('from_server', {'cmd': 'memmode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'memmode', 'data': 'false'}, broadcast=True, room="UI_1") # Ask for contents of Author's Note field - emit('from_server', {'cmd': 'getanote', 'data': ''}) + emit('from_server', {'cmd': 'getanote', 'data': ''}, room="UI_1") #==================================================================# # Commit changes to Author's Note @@ -4807,8 +4811,8 @@ def anotesubmit(data, template=""): settingschanged() story_settings.authornotetemplate = template - emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True) - emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True) + emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True, room="UI_1") #==================================================================# # Assembles game data into a request to InferKit API @@ -4857,7 +4861,7 @@ def ikrequest(txt): print("{0}{1}{2}".format(colors.CYAN, genout, colors.END)) story_settings.actions.append(genout) update_story_chunk('last') - emit('from_server', {'cmd': 'texteffect', 'data': story_settings.actions.get_last_key() + 1 if len(story_settings.actions) else 0}, broadcast=True) + emit('from_server', {'cmd': 'texteffect', 'data': story_settings.actions.get_last_key() + 1 if len(story_settings.actions) else 0}, broadcast=True, room="UI_1") send_debug() set_aibusy(0) else: @@ -4869,7 +4873,7 @@ def ikrequest(txt): code = er["errors"][0]["extensions"]["code"] errmsg = "InferKit API Error: {0} - {1}".format(req.status_code, code) - emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True, room="UI_1") set_aibusy(0) #==================================================================# @@ -4962,7 +4966,7 @@ def oairequest(txt, min, max): message = er["error"]["message"] errmsg = "OpenAI API Error: {0} - {1}".format(type, message) - emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True) + emit('from_server', {'cmd': 'errmsg', 'data': errmsg}, broadcast=True, room="UI_1") set_aibusy(0) #==================================================================# @@ -4970,11 +4974,11 @@ def oairequest(txt, min, max): #==================================================================# def exitModes(): if(story_settings.mode == "edit"): - emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'editmode', 'data': 'false'}, broadcast=True, room="UI_1") elif(story_settings.mode == "memory"): - emit('from_server', {'cmd': 'memmode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'memmode', 'data': 'false'}, broadcast=True, room="UI_1") elif(story_settings.mode == "wi"): - emit('from_server', {'cmd': 'wimode', 'data': 'false'}, broadcast=True) + emit('from_server', {'cmd': 'wimode', 'data': 'false'}, broadcast=True, room="UI_1") story_settings.mode = "play" #==================================================================# @@ -4992,15 +4996,15 @@ def saveas(data): user_settings.saveow = False user_settings.svowname = "" if(e is None): - emit('from_server', {'cmd': 'hidesaveas', 'data': ''}) + emit('from_server', {'cmd': 'hidesaveas', 'data': ''}, room="UI_1") else: print("{0}{1}{2}".format(colors.RED, str(e), colors.END)) - emit('from_server', {'cmd': 'popuperror', 'data': str(e)}) + emit('from_server', {'cmd': 'popuperror', 'data': str(e)}, room="UI_1") else: # File exists, prompt for overwrite user_settings.saveow = True user_settings.svowname = name - emit('from_server', {'cmd': 'askforoverwrite', 'data': ''}) + emit('from_server', {'cmd': 'askforoverwrite', 'data': ''}, room="UI_1") #==================================================================# # Launch in-browser story-delete prompt @@ -5010,13 +5014,13 @@ def deletesave(name): e = fileops.deletesave(name) if(e is None): if(system_settings.smandelete): - emit('from_server', {'cmd': 'hidepopupdelete', 'data': ''}) + emit('from_server', {'cmd': 'hidepopupdelete', 'data': ''}, room="UI_1") getloadlist() else: - emit('from_server', {'cmd': 'popuperror', 'data': "The server denied your request to delete this story"}) + emit('from_server', {'cmd': 'popuperror', 'data': "The server denied your request to delete this story"}, room="UI_1") else: print("{0}{1}{2}".format(colors.RED, str(e), colors.END)) - emit('from_server', {'cmd': 'popuperror', 'data': str(e)}) + emit('from_server', {'cmd': 'popuperror', 'data': str(e)}, room="UI_1") #==================================================================# # Launch in-browser story-rename prompt @@ -5031,18 +5035,18 @@ def renamesave(name, newname): user_settings.svowname = "" if(e is None): if(system_settings.smanrename): - emit('from_server', {'cmd': 'hidepopuprename', 'data': ''}) + emit('from_server', {'cmd': 'hidepopuprename', 'data': ''}, room="UI_1") getloadlist() else: - emit('from_server', {'cmd': 'popuperror', 'data': "The server denied your request to rename this story"}) + emit('from_server', {'cmd': 'popuperror', 'data': "The server denied your request to rename this story"}, room="UI_1") else: print("{0}{1}{2}".format(colors.RED, str(e), colors.END)) - emit('from_server', {'cmd': 'popuperror', 'data': str(e)}) + emit('from_server', {'cmd': 'popuperror', 'data': str(e)}, room="UI_1") else: # File exists, prompt for overwrite user_settings.saveow = True user_settings.svowname = newname - emit('from_server', {'cmd': 'askforoverwrite', 'data': ''}) + emit('from_server', {'cmd': 'askforoverwrite', 'data': ''}, room="UI_1") #==================================================================# # Save the currently running story @@ -5052,7 +5056,7 @@ def save(): if(".json" in system_settings.savedir): saveRequest(system_settings.savedir) else: - emit('from_server', {'cmd': 'saveas', 'data': ''}) + emit('from_server', {'cmd': 'saveas', 'data': ''}, room="UI_1") #==================================================================# # Save the story via file browser @@ -5128,7 +5132,7 @@ def saveRequest(savpath, savepins=True): if(filename.endswith('.json')): filename = filename[:-5] user_settings.laststory = filename - emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True) + emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True, room="UI_1") setgamesaved(True) print("{0}Story saved to {1}!{2}".format(colors.GREEN, path.basename(savpath), colors.END)) @@ -5136,14 +5140,14 @@ def saveRequest(savpath, savepins=True): # Show list of saved stories #==================================================================# def getloadlist(): - emit('from_server', {'cmd': 'buildload', 'data': fileops.getstoryfiles()}) + emit('from_server', {'cmd': 'buildload', 'data': fileops.getstoryfiles()}, room="UI_1") #==================================================================# # Show list of soft prompts #==================================================================# def getsplist(): if(system_settings.allowsp): - emit('from_server', {'cmd': 'buildsp', 'data': fileops.getspfiles(model_settings.modeldim)}) + emit('from_server', {'cmd': 'buildsp', 'data': fileops.getspfiles(model_settings.modeldim)}, room="UI_1") #==================================================================# # Get list of userscripts @@ -5311,15 +5315,15 @@ def loadRequest(loadpath, filename=None): if(filename.endswith('.json')): _filename = filename[:-5] user_settings.laststory = _filename - emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True) + emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True, room="UI_1") setgamesaved(True) sendwi() - emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True) - emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True) - emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True) + emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True, room="UI_1") refresh_story() - emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True) - emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True, room="UI_1") print("{0}Story loaded from {1}!{2}".format(colors.GREEN, filename, colors.END)) send_debug() @@ -5343,7 +5347,7 @@ def importRequest(): user_settings.importjs = user_settings.importjs["stories"] # Clear Popup Contents - emit('from_server', {'cmd': 'clearpopup', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'clearpopup', 'data': ''}, broadcast=True, room="UI_1") # Initialize vars num = 0 @@ -5365,11 +5369,11 @@ def importRequest(): ob["acts"] = len(story["actions"]) elif("actionWindow" in story): ob["acts"] = len(story["actionWindow"]) - emit('from_server', {'cmd': 'addimportline', 'data': ob}) + emit('from_server', {'cmd': 'addimportline', 'data': ob}, room="UI_1") num += 1 # Show Popup - emit('from_server', {'cmd': 'popupshow', 'data': True}) + emit('from_server', {'cmd': 'popupshow', 'data': True}, room="UI_1") #==================================================================# # Import an AIDungon game selected in popup @@ -5468,15 +5472,15 @@ def importgame(): # Refresh game screen user_settings.laststory = None - emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True) + emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True, room="UI_1") setgamesaved(False) sendwi() - emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True) - emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True) - emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True) + emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True, room="UI_1") refresh_story() - emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True) - emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True) + emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'hidegenseqs', 'data': ''}, broadcast=True, room="UI_1") #==================================================================# # Import an aidg.club prompt and start a new game with it. @@ -5550,14 +5554,14 @@ def importAidgRequest(id): # Refresh game screen user_settings.laststory = None - emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True) + emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True, room="UI_1") setgamesaved(False) sendwi() - emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True) - emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True) - emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True) + emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True, room="UI_1") refresh_story() - emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True) + emit('from_server', {'cmd': 'setgamestate', 'data': 'ready'}, broadcast=True, room="UI_1") #==================================================================# # Import World Info JSON file @@ -5643,19 +5647,19 @@ def newGameRequest(): # Refresh game screen user_settings.laststory = None - emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True) + emit('from_server', {'cmd': 'setstoryname', 'data': user_settings.laststory}, broadcast=True, room="UI_1") setgamesaved(True) sendwi() - emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True) - emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True) - emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True) + emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanote', 'data': story_settings.authornote}, broadcast=True, room="UI_1") + emit('from_server', {'cmd': 'setanotetemplate', 'data': story_settings.authornotetemplate}, broadcast=True, room="UI_1") setStartState() def randomGameRequest(topic, memory=""): if(system_settings.noai): newGameRequest() story_settings.memory = memory - emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True) + emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True, room="UI_1") return story_settings.recentrng = topic story_settings.recentrngm = memory @@ -5668,7 +5672,7 @@ def randomGameRequest(topic, memory=""): system_settings.lua_koboldbridge.feedback = None actionsubmit("", force_submit=True, force_prompt_gen=True) story_settings.memory = memory - emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True) + emit('from_server', {'cmd': 'setmemory', 'data': story_settings.memory}, broadcast=True, room="UI_1") def final_startup(): # Prevent tokenizer from taking extra time the first time it's used @@ -5749,7 +5753,7 @@ def send_debug(): except: pass - emit('from_server', {'cmd': 'debug_info', 'data': debug_info}, broadcast=True) + emit('from_server', {'cmd': 'debug_info', 'data': debug_info}, broadcast=True, room="UI_1") #==================================================================# # Event triggered when browser SocketIO detects a variable change @@ -5825,6 +5829,22 @@ def UI_2_back(data): def UI_2_redo(data): pass +#==================================================================# +# Event triggered to rely a message +#==================================================================# +@socketio.on('relay') +def UI_2_relay(data): + socketio.emit(data[0], data[1], **data[2]) + + +#==================================================================# +# Test +#==================================================================# +@app.route("/actions") +def show_actions(): + return story_settings.actions.actions + + #==================================================================# # Final startup commands to launch Flask app @@ -5843,7 +5863,6 @@ if __name__ == "__main__": # Start Flask/SocketIO (Blocking, so this must be last method!) port = args.port if "port" in args and args.port is not None else 5000 - #socketio.run(app, host='0.0.0.0', port=port) if(system_settings.host): if(args.localtunnel): import subprocess, shutil diff --git a/gensettings.py b/gensettings.py index 14ba7970..648dcce0 100644 --- a/gensettings.py +++ b/gensettings.py @@ -319,7 +319,19 @@ gensettingstf = [ "menu_path": "user", "classname": "user", "name": "debug" - } + }, + { + "uitype": "dropdown", + "unit": "text", + "label": "Story Mode", + "id": "actionmode", + "default": 0, + "tooltip": "Choose the mode of KoboldAI", + "menu_path": "Story", + "classname": "story", + "name": "actionmode", + 'children': [{'text': 'Story', 'value': 0}, {'text':'Adventure','value':1}, {'text':'Chat', 'value':2}] + } ] gensettingsik =[{ diff --git a/koboldai_settings.py b/koboldai_settings.py index f76f2ca1..ee783061 100644 --- a/koboldai_settings.py +++ b/koboldai_settings.py @@ -1,8 +1,11 @@ from flask_socketio import emit, join_room, leave_room, rooms -import os -import re +import os, re, time, threading +import socketio as socketio_client socketio = None +main_thread_id = threading.get_ident() +rely_clients = {} + def clean_var_for_emit(value): if isinstance(value, KoboldStoryRegister): @@ -12,19 +15,43 @@ def clean_var_for_emit(value): else: return value -def process_variable_changes(classname, name, value, old_value): - #Special Case for KoboldStoryRegister - if isinstance(value, KoboldStoryRegister): - print("resetting") - socketio.emit("reset_story", {}, broadcast=True, room="UI_2") - for i in range(len(value.actions)): - socketio.emit("var_changed", {"classname": "actions", "name": "Selected Text", "old_value": None, "value": {"id": i, "text": value[i]}}, broadcast=True, room="UI_2") - socketio.emit("var_changed", {"classname": "actions", "name": "Options", "old_value": None, "value": {"id": i, "options": value.actions[i]['Options']}}, broadcast=True, room="UI_2") - else: - #print("{}: {} changed from {} to {}".format(classname, name, old_value, value)) - #if name == "Selected Text": - # print({"classname": classname, "name": name, "old_value": clean_var_for_emit(old_value), "value": clean_var_for_emit(value)}) - socketio.emit("var_changed", {"classname": classname, "name": name, "old_value": clean_var_for_emit(old_value), "value": clean_var_for_emit(value)}, broadcast=True, room="UI_2") +def process_variable_changes(classname, name, value, old_value, debug_message=None): + if socketio is not None: + if debug_message is not None: + print("{} {}: {} changed from {} to {}".format(debug_message, classname, name, old_value, value)) + if value != old_value: + #Special Case for KoboldStoryRegister + if isinstance(value, KoboldStoryRegister): + print("We got a story register") + print(value) + socketio.emit("reset_story", {}, broadcast=True, room="UI_2") + for i in range(len(value.actions)): + socketio.emit("var_changed", {"classname": "actions", "name": "Selected Text", "old_value": None, "value": {"id": i, "text": value[i]}}, include_self=True, broadcast=True, room="UI_2") + socketio.emit("var_changed", {"classname": "actions", "name": "Options", "old_value": None, "value": {"id": i, "options": value.actions[i]['Options']}}, include_self=True, broadcast=True, room="UI_2") + else: + #If we got a variable change from a thread other than what the app is run it, eventlet seems to block and no further messages are sent. Instead, we'll rely the message to the app and have the main thread send it + if main_thread_id != threading.get_ident(): + if threading.get_ident() in rely_clients: + sio = rely_clients[threading.get_ident()] + else: + start_time = time.time() + print("getting client") + sio = socketio_client.Client() + @sio.event + def connect(): + print("I'm connected!") + sio.connect('http://localhost:5000/?rely=true') + rely_clients[threading.get_ident()] = sio + print("got client, took {}".format(time.time()-start_time)) + #release no longer used clients + for thread in rely_clients: + if thread not in [x.ident for x in threading.enumerate()]: + del rely_clients[thread] + sio.emit("relay", {"emit": "var_changed", "data": {"classname": classname, "name": name, "old_value": clean_var_for_emit(old_value), "value": clean_var_for_emit(value)}, "include_self":True, "broadcast":True, "room":"UI_2"}) + else: + socketio.emit("var_changed", {"classname": classname, "name": name, "old_value": clean_var_for_emit(old_value), "value": clean_var_for_emit(value)}, include_self=True, broadcast=True, room="UI_2") + #eventlet.sleep() + #socketio.sleep(0) class settings(object): @@ -39,7 +66,6 @@ class settings(object): class model_settings(settings): local_only_variables = ['badwordsids', 'apikey', '_class_init'] settings_name = "model" - __class_initialized = False def __init__(self): self.model = "" # Model ID string chosen at startup self.model_type = "" # Model Type (Automatically taken from the model config) @@ -75,26 +101,20 @@ class model_settings(settings): self.presets = [] # Holder for presets self.selected_preset = "" - #Must be at end of __init__ - self.__class_initialized = True def __setattr__(self, name, value): old_value = getattr(self, name, None) super().__setattr__(name, value) - if self.__class_initialized and name != '__class_initialized': - #Put variable change actions here - if name not in self.local_only_variables and name[0] != "_": - process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value) - - #Since I haven't migrated the old_ui to use the new actions class for options, let's sync the metadata and options here - if name == 'actions_metadata': - print(value) + #Put variable change actions here + if name not in self.local_only_variables and name[0] != "_": + process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value) + class story_settings(settings): + #local_only_variables = ['generated_tkns'] local_only_variables = [] settings_name = "story" - __class_initialized = False def __init__(self): self.lastact = "" # The last action received from the user self.submission = "" # Same as above, but after applying input formatting @@ -138,21 +158,17 @@ class story_settings(settings): self.dynamicscan = False self.recentedit = False - #Must be at end of __init__ - self.__class_initialized = True def __setattr__(self, name, value): old_value = getattr(self, name, None) super().__setattr__(name, value) - if self.__class_initialized and name != '__class_initialized': - #Put variable change actions here - if name not in self.local_only_variables and name[0] != "_": - process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value) + #Put variable change actions here + if name not in self.local_only_variables and name[0] != "_": + process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value) class user_settings(settings): local_only_variables = [] settings_name = "user" - __class_initialized = False def __init__(self): self.wirmvwhtsp = False # Whether to remove leading whitespace from WI entries self.widepth = 3 # How many historical actions to scan for WI hits @@ -172,22 +188,18 @@ class user_settings(settings): self.nogenmod = False self.debug = False # If set to true, will send debug information to the client for display - #Must be at end of __init__ - self.__class_initialized = True def __setattr__(self, name, value): old_value = getattr(self, name, None) super().__setattr__(name, value) - if self.__class_initialized and name != '__class_initialized': - #Put variable change actions here - if name not in self.local_only_variables and name[0] != "_": - process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value) + #Put variable change actions here + if name not in self.local_only_variables and name[0] != "_": + process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value) class system_settings(settings): local_only_variables = ['lua_state', 'lua_logname', 'lua_koboldbridge', 'lua_kobold', 'lua_koboldcore', 'regex_sl', 'acregex_ai', 'acregex_ui', 'comregex_ai', 'comregex_ui'] settings_name = "system" - __class_initialized = False def __init__(self): self.noai = False # Runs the script without starting up the transformers pipeline self.aibusy = False # Stops submissions while the AI is working @@ -234,16 +246,13 @@ class system_settings(settings): self.use_colab_tpu = os.environ.get("COLAB_TPU_ADDR", "") != "" or os.environ.get("TPU_NAME", "") != "" # Whether or not we're in a Colab TPU instance or Kaggle TPU instance and are going to use the TPU rather than the CPU self.aria2_port = 6799 #Specify the port on which aria2's RPC interface will be open if aria2 is installed (defaults to 6799) - #Must be at end of __init__ - self.__class_initialized = True def __setattr__(self, name, value): old_value = getattr(self, name, None) super().__setattr__(name, value) - if self.__class_initialized and name != '__class_initialized': - #Put variable change actions here - if name not in self.local_only_variables and name[0] != "_": - process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value) + #Put variable change actions here + if name not in self.local_only_variables and name[0] != "_": + process_variable_changes(self.__class__.__name__.replace("_settings", ""), name, value, old_value) class KoboldStoryRegister(object): @@ -330,17 +339,10 @@ class KoboldStoryRegister(object): self.action_count+=1 if self.action_count in self.actions: self.actions[self.action_count]["Selected Text"] = text - print("looking for old option that matches") for item in self.actions[self.action_count]["Options"]: if item['text'] == text: - print("found it") old_options = self.actions[self.action_count]["Options"] del item - print("old: ") - print(old_options) - print() - print("New: ") - print(self.actions[self.action_count]["Options"]) process_variable_changes("actions", "Options", {"id": self.action_count, "options": self.actions[self.action_count]["Options"]}, {"id": self.action_count, "options": old_options}) else: @@ -348,25 +350,23 @@ class KoboldStoryRegister(object): process_variable_changes("actions", "Selected Text", {"id": self.action_count, "text": text}, None) def append_options(self, option_list): + print("appending options for {}".format(self.action_count+1)) if self.action_count+1 in self.actions: - print("1") - old_options = self.actions[self.action_count+1]["Options"] + old_options = self.actions[self.action_count+1]["Options"].copy() self.actions[self.action_count+1]['Options'].extend([{"text": x, "Pinned": False, "Previous Selection": False, "Edited": False} for x in option_list]) - for item in option_list: - process_variable_changes("actions", "Options", {"id": self.action_count+1, "options": self.actions[self.action_count+1]["Options"]}, {"id": self.action_count+1, "options": old_options}) else: - print("2") old_options = None self.actions[self.action_count+1] = {"Selected Text": "", "Options": [{"text": x, "Pinned": False, "Previous Selection": False, "Edited": False} for x in option_list]} - process_variable_changes("actions", "Options", {"id": self.action_count+1, "options": self.actions[self.action_count+1]["Options"]}, {"id": self.action_count+1, "options": old_options}) + process_variable_changes("actions", "Options", {"id": self.action_count+1, "options": self.actions[self.action_count+1]["Options"]}, {"id": self.action_count+1, "options": old_options}, debug_message="wtf") def clear_unused_options(self, pointer=None): + print("clearing options for {}".format(self.action_count+1)) new_options = [] old_options = None if pointer is None: pointer = self.action_count+1 if pointer in self.actions: - old_options = self.actions[pointer]["Options"] + old_options = self.actions[pointer]["Options"].copy() self.actions[pointer]["Options"] = [x for x in self.actions[pointer]["Options"] if x["Pinned"] or x["Previous Selection"] or x["Edited"]] new_options = self.actions[pointer]["Options"] process_variable_changes("actions", "Options", {"id": pointer, "options": new_options}, {"id": pointer, "options": old_options}) @@ -382,20 +382,20 @@ class KoboldStoryRegister(object): def set_pin(self, action_step, option_number): if action_step in self.actions: if option_number < len(self.actions[action_step]['Options']): - old_options = self.actions[action_step]["Options"] + old_options = self.actions[action_step]["Options"].copy() self.actions[action_step]['Options'][option_number]['Pinned'] = True process_variable_changes("actions", "Options", {"id": action_step, "options": self.actions[action_step]["Options"]}, {"id": action_step, "options": old_options}) def unset_pin(self, action_step, option_number): if action_step in self.actions: - old_options = self.actions[action_step]["Options"] + old_options = self.actions[action_step]["Options"].copy() if option_number < len(self.actions[action_step]['Options']): self.actions[action_step]['Options'][option_number]['Pinned'] = False process_variable_changes("actions", "Options", {"id": action_step, "options": self.actions[action_step]["Options"]}, {"id": action_step, "options": old_options}) def use_option(self, action_step, option_number): if action_step in self.actions: - old_options = self.actions[action_step]["Options"] + old_options = self.actions[action_step]["Options"].copy() old_text = self.actions[action_step]["Selected Text"] if option_number < len(self.actions[action_step]['Options']): self.actions[action_step]["Selected Text"] = self.actions[action_step]['Options'][option_number]['text'] @@ -405,7 +405,7 @@ class KoboldStoryRegister(object): def delete_action(self, action_id): if action_id in self.actions: - old_options = self.actions[action_id]["Options"] + old_options = self.actions[action_id]["Options"].copy() old_text = self.actions[action_id]["Selected Text"] self.actions[action_id]["Options"].append({"text": self.actions[action_id]["Selected Text"], "Pinned": False, "Previous Selection": True, "Edited": False}) self.actions[action_id]["Selected Text"] = "" @@ -468,7 +468,7 @@ class KoboldStoryRegister(object): return [] else: if self.action_count+1 in self.actions: - return [[x, "pinned" if x['Pinned'] else 'normal'] for x in self.actions[self.action_count+1]["Options"] if x["Edited"] == False and x['Previous Selection'] == False] + return [[x['text'], "pinned" if x['Pinned'] else 'normal'] for x in self.actions[self.action_count+1]["Options"] if x["Edited"] == False and x['Previous Selection'] == False] else: return [] @@ -495,6 +495,12 @@ class KoboldStoryRegister(object): return [x for x in self.actions[self.action_count+1]['Options'] if x['Pinned'] or x['Previous Selection']] else: return [] + + def __setattr__(self, name, value): + old_value = getattr(self, name, None) + super().__setattr__(name, value) + if name == 'action_count': + process_variable_changes("actions", "Action Count", value, old_value) diff --git a/static/application.js b/static/application.js index 8b2cbb53..b256e3ef 100644 --- a/static/application.js +++ b/static/application.js @@ -1359,7 +1359,6 @@ function setStartState() { function parsegenseqs(seqs) { seqselcontents.html(""); - console.log(seqs); var i; for(i=0; i { + console.log("Lost connection from: "+reason); // "transport error" +}); socket.on('reset_story', function(){reset_story();}); socket.on('var_changed', function(data){var_changed(data);}); //socket.onAny(function(event_name, data) {console.log({"event": event_name, "data": data});}); @@ -20,6 +22,7 @@ function disconnect() { } function reset_story() { + console.log("Resetting story"); var story_area = document.getElementById('Selected Text'); while (story_area.firstChild) { story_area.removeChild(story_area.firstChild); @@ -43,7 +46,7 @@ function fix_text(val) { } function create_options(data) { - console.log(data.value.options); + console.log(data); if (document.getElementById("Select Options Chunk "+data.value.id)) { var option_chunk = document.getElementById("Select Options Chunk "+data.value.id) } else { @@ -200,7 +203,7 @@ function var_changed(data) { } else { var elements_to_change = document.getElementsByClassName("var_sync_"+data.classname+"_"+data.name); for (item of elements_to_change) { - if (item.tagName.toLowerCase() === 'input') { + if ((item.tagName.toLowerCase() === 'input') || (item.tagName.toLowerCase() === 'select')) { item.value = fix_text(data.value); } else { item.textContent = fix_text(data.value); diff --git a/static/socket.io.min.js b/static/socket.io.min.js index 8560bedd..e627c13a 100644 --- a/static/socket.io.min.js +++ b/static/socket.io.min.js @@ -1,7 +1,7 @@ /*! - * Socket.IO v4.4.1 + * Socket.IO v4.5.1 * (c) 2014-2022 Guillermo Rauch * Released under the MIT License. */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).io=e()}(this,(function(){"use strict";function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=new Array(e);n=t.length?{done:!0}:{done:!1,value:t[r++]}},e:function(t){throw t},f:o}}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 i,s=!0,a=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return s=t.done,t},e:function(t){a=!0,i=t},f:function(){try{s||null==n.return||n.return()}finally{if(a)throw i}}}}var d=/^(?:(?![^:@]+:[^:@\/]*@)(http|https|ws|wss):\/\/)?((?:(([^:@]*)(?::([^:@]*))?)?@)?((?:[a-f0-9]{0,4}:){2,7}[a-f0-9]{0,4}|[^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/,y=["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],v=function(t){var e=t,n=t.indexOf("["),r=t.indexOf("]");-1!=n&&-1!=r&&(t=t.substring(0,n)+t.substring(n,r).replace(/:/g,";")+t.substring(r,t.length));for(var o,i,s=d.exec(t||""),a={},c=14;c--;)a[y[c]]=s[c]||"";return-1!=n&&-1!=r&&(a.source=e,a.host=a.host.substring(1,a.host.length-1).replace(/;/g,":"),a.authority=a.authority.replace("[","").replace("]","").replace(/;/g,":"),a.ipv6uri=!0),a.pathNames=function(t,e){var n=/\/{2,9}/g,r=e.replace(n,"/").split("/");"/"!=e.substr(0,1)&&0!==e.length||r.splice(0,1);"/"==e.substr(e.length-1,1)&&r.splice(r.length-1,1);return r}(0,a.path),a.queryKey=(o=a.query,i={},o.replace(/(?:^|&)([^&=]*)=?([^&]*)/g,(function(t,e,n){e&&(i[e]=n)})),i),a};var m={exports:{}};try{m.exports="undefined"!=typeof XMLHttpRequest&&"withCredentials"in new XMLHttpRequest}catch(t){m.exports=!1}var g=m.exports,k="undefined"!=typeof self?self:"undefined"!=typeof window?window:Function("return this")();function b(t){var e=t.xdomain;try{if("undefined"!=typeof XMLHttpRequest&&(!e||g))return new XMLHttpRequest}catch(t){}if(!e)try{return new(k[["Active"].concat("Object").join("X")])("Microsoft.XMLHTTP")}catch(t){}}function w(t){for(var e=arguments.length,n=new Array(e>1?e-1:0),r=1;r1?{type:O[n],data:t.substring(1)}:{type:O[n]}:S},M=function(t,e){if(I){var n=function(t){var e,n,r,o,i,s=.75*t.length,a=t.length,c=0;"="===t[t.length-1]&&(s--,"="===t[t.length-2]&&s--);var u=new ArrayBuffer(s),h=new Uint8Array(u);for(e=0;e>4,h[c++]=(15&r)<<4|o>>2,h[c++]=(3&o)<<6|63&i;return u}(t);return U(n,e)}return{base64:!0,data:t}},U=function(t,e){return"blob"===e&&t instanceof ArrayBuffer?new Blob([t]):t},V=String.fromCharCode(30),H=function(t){i(o,t);var n=h(o);function o(t){var r;return e(this,o),(r=n.call(this)).writable=!1,A(c(r),t),r.opts=t,r.query=t.query,r.readyState="",r.socket=t.socket,r}return r(o,[{key:"onError",value:function(t,e){var n=new Error(t);return n.type="TransportError",n.description=e,f(s(o.prototype),"emit",this).call(this,"error",n),this}},{key:"open",value:function(){return"closed"!==this.readyState&&""!==this.readyState||(this.readyState="opening",this.doOpen()),this}},{key:"close",value:function(){return"opening"!==this.readyState&&"open"!==this.readyState||(this.doClose(),this.onClose()),this}},{key:"send",value:function(t){"open"===this.readyState&&this.write(t)}},{key:"onOpen",value:function(){this.readyState="open",this.writable=!0,f(s(o.prototype),"emit",this).call(this,"open")}},{key:"onData",value:function(t){var e=F(t,this.socket.binaryType);this.onPacket(e)}},{key:"onPacket",value:function(t){f(s(o.prototype),"emit",this).call(this,"packet",t)}},{key:"onClose",value:function(){this.readyState="closed",f(s(o.prototype),"emit",this).call(this,"close")}}]),o}(R),K="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_".split(""),Y={},z=0,$=0;function W(t){var e="";do{e=K[t%64]+e,t=Math.floor(t/64)}while(t>0);return e}function J(){var t=W(+new Date);return t!==D?(z=0,D=t):t+"."+W(z++)}for(;$<64;$++)Y[K[$]]=$;J.encode=W,J.decode=function(t){var e=0;for($=0;$0&&void 0!==arguments[0]?arguments[0]:{};return o(t,{xd:this.xd,xs:this.xs},this.opts),new nt(this.uri(),t)}},{key:"doWrite",value:function(t,e){var n=this,r=this.request({method:"POST",data:t});r.on("success",e),r.on("error",(function(t){n.onError("xhr post error",t)}))}},{key:"doPoll",value:function(){var t=this,e=this.request();e.on("data",this.onData.bind(this)),e.on("error",(function(e){t.onError("xhr poll error",e)})),this.pollXhr=e}}]),s}(Q),nt=function(t){i(o,t);var n=h(o);function o(t,r){var i;return e(this,o),A(c(i=n.call(this)),r),i.opts=r,i.method=r.method||"GET",i.uri=t,i.async=!1!==r.async,i.data=void 0!==r.data?r.data:null,i.create(),i}return r(o,[{key:"create",value:function(){var t=this,e=w(this.opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");e.xdomain=!!this.opts.xd,e.xscheme=!!this.opts.xs;var n=this.xhr=new b(e);try{n.open(this.method,this.uri,this.async);try{if(this.opts.extraHeaders)for(var r in n.setDisableHeaderCheck&&n.setDisableHeaderCheck(!0),this.opts.extraHeaders)this.opts.extraHeaders.hasOwnProperty(r)&&n.setRequestHeader(r,this.opts.extraHeaders[r])}catch(t){}if("POST"===this.method)try{n.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(t){}try{n.setRequestHeader("Accept","*/*")}catch(t){}"withCredentials"in n&&(n.withCredentials=this.opts.withCredentials),this.opts.requestTimeout&&(n.timeout=this.opts.requestTimeout),n.onreadystatechange=function(){4===n.readyState&&(200===n.status||1223===n.status?t.onLoad():t.setTimeoutFn((function(){t.onError("number"==typeof n.status?n.status:0)}),0))},n.send(this.data)}catch(e){return void this.setTimeoutFn((function(){t.onError(e)}),0)}"undefined"!=typeof document&&(this.index=o.requestsCount++,o.requests[this.index]=this)}},{key:"onSuccess",value:function(){this.emit("success"),this.cleanup()}},{key:"onData",value:function(t){this.emit("data",t),this.onSuccess()}},{key:"onError",value:function(t){this.emit("error",t),this.cleanup(!0)}},{key:"cleanup",value:function(t){if(void 0!==this.xhr&&null!==this.xhr){if(this.xhr.onreadystatechange=Z,t)try{this.xhr.abort()}catch(t){}"undefined"!=typeof document&&delete o.requests[this.index],this.xhr=null}}},{key:"onLoad",value:function(){var t=this.xhr.responseText;null!==t&&this.onData(t)}},{key:"abort",value:function(){this.cleanup()}}]),o}(R);if(nt.requestsCount=0,nt.requests={},"undefined"!=typeof document)if("function"==typeof attachEvent)attachEvent("onunload",rt);else if("function"==typeof addEventListener){addEventListener("onpagehide"in k?"pagehide":"unload",rt,!1)}function rt(){for(var t in nt.requests)nt.requests.hasOwnProperty(t)&&nt.requests[t].abort()}var ot="function"==typeof Promise&&"function"==typeof Promise.resolve?function(t){return Promise.resolve().then(t)}:function(t,e){return e(t,0)},it=k.WebSocket||k.MozWebSocket,st="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase(),at=function(t){i(o,t);var n=h(o);function o(t){var r;return e(this,o),(r=n.call(this,t)).supportsBinary=!t.forceBase64,r}return r(o,[{key:"name",get:function(){return"websocket"}},{key:"doOpen",value:function(){if(this.check()){var t=this.uri(),e=this.opts.protocols,n=st?{}:w(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(n.headers=this.opts.extraHeaders);try{this.ws=st?new it(t,e,n):e?new it(t,e):new it(t)}catch(t){return this.emit("error",t)}this.ws.binaryType=this.socket.binaryType||"arraybuffer",this.addEventListeners()}}},{key:"addEventListeners",value:function(){var t=this;this.ws.onopen=function(){t.opts.autoUnref&&t.ws._socket.unref(),t.onOpen()},this.ws.onclose=this.onClose.bind(this),this.ws.onmessage=function(e){return t.onData(e.data)},this.ws.onerror=function(e){return t.onError("websocket error",e)}}},{key:"write",value:function(t){var e=this;this.writable=!1;for(var n=function(n){var r=t[n],o=n===t.length-1;x(r,e.supportsBinary,(function(t){try{e.ws.send(t)}catch(t){}o&&ot((function(){e.writable=!0,e.emit("drain")}),e.setTimeoutFn)}))},r=0;r1&&void 0!==arguments[1]?arguments[1]:{};return e(this,a),r=s.call(this),n&&"object"===t(n)&&(i=n,n=null),n?(n=v(n),i.hostname=n.host,i.secure="https"===n.protocol||"wss"===n.protocol,i.port=n.port,n.query&&(i.query=n.query)):i.host&&(i.hostname=v(i.host).host),A(c(r),i),r.secure=null!=i.secure?i.secure:"undefined"!=typeof location&&"https:"===location.protocol,i.hostname&&!i.port&&(i.port=r.secure?"443":"80"),r.hostname=i.hostname||("undefined"!=typeof location?location.hostname:"localhost"),r.port=i.port||("undefined"!=typeof location&&location.port?location.port:r.secure?"443":"80"),r.transports=i.transports||["polling","websocket"],r.readyState="",r.writeBuffer=[],r.prevBufferLen=0,r.opts=o({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!0},i),r.opts.path=r.opts.path.replace(/\/$/,"")+"/","string"==typeof r.opts.query&&(r.opts.query=G.decode(r.opts.query)),r.id=null,r.upgrades=null,r.pingInterval=null,r.pingTimeout=null,r.pingTimeoutTimer=null,"function"==typeof addEventListener&&(r.opts.closeOnBeforeunload&&addEventListener("beforeunload",(function(){r.transport&&(r.transport.removeAllListeners(),r.transport.close())}),!1),"localhost"!==r.hostname&&(r.offlineEventListener=function(){r.onClose("transport close")},addEventListener("offline",r.offlineEventListener,!1))),r.open(),r}return r(a,[{key:"createTransport",value:function(t){var e=function(t){var e={};for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n]);return e}(this.opts.query);e.EIO=4,e.transport=t,this.id&&(e.sid=this.id);var n=o({},this.opts.transportOptions[t],this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port});return new ct[t](n)}},{key:"open",value:function(){var t,e=this;if(this.opts.rememberUpgrade&&a.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket"))t="websocket";else{if(0===this.transports.length)return void this.setTimeoutFn((function(){e.emitReserved("error","No transports available")}),0);t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(t){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)}},{key:"setTransport",value:function(t){var e=this;this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",this.onDrain.bind(this)).on("packet",this.onPacket.bind(this)).on("error",this.onError.bind(this)).on("close",(function(){e.onClose("transport close")}))}},{key:"probe",value:function(t){var e=this,n=this.createTransport(t),r=!1;a.priorWebsocketSuccess=!1;var o=function(){r||(n.send([{type:"ping",data:"probe"}]),n.once("packet",(function(t){if(!r)if("pong"===t.type&&"probe"===t.data){if(e.upgrading=!0,e.emitReserved("upgrading",n),!n)return;a.priorWebsocketSuccess="websocket"===n.name,e.transport.pause((function(){r||"closed"!==e.readyState&&(f(),e.setTransport(n),n.send([{type:"upgrade"}]),e.emitReserved("upgrade",n),n=null,e.upgrading=!1,e.flush())}))}else{var o=new Error("probe error");o.transport=n.name,e.emitReserved("upgradeError",o)}})))};function i(){r||(r=!0,f(),n.close(),n=null)}var s=function(t){var r=new Error("probe error: "+t);r.transport=n.name,i(),e.emitReserved("upgradeError",r)};function c(){s("transport closed")}function u(){s("socket closed")}function h(t){n&&t.name!==n.name&&i()}var f=function(){n.removeListener("open",o),n.removeListener("error",s),n.removeListener("close",c),e.off("close",u),e.off("upgrading",h)};n.once("open",o),n.once("error",s),n.once("close",c),this.once("close",u),this.once("upgrading",h),n.open()}},{key:"onOpen",value:function(){if(this.readyState="open",a.priorWebsocketSuccess="websocket"===this.transport.name,this.emitReserved("open"),this.flush(),"open"===this.readyState&&this.opts.upgrade&&this.transport.pause)for(var t=0,e=this.upgrades.length;t0;case bt.ACK:case bt.BINARY_ACK:return Array.isArray(n)}}}]),a}(R);var Et=function(){function t(n){e(this,t),this.packet=n,this.buffers=[],this.reconPack=n}return r(t,[{key:"takeBinaryData",value:function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=gt(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null}},{key:"finishedReconstruction",value:function(){this.reconPack=null,this.buffers=[]}}]),t}(),At=Object.freeze({__proto__:null,protocol:5,get PacketType(){return bt},Encoder:wt,Decoder:_t});function Rt(t,e,n){return t.on(e,n),function(){t.off(e,n)}}var Tt=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1}),Ct=function(t){i(o,t);var n=h(o);function o(t,r,i){var s;return e(this,o),(s=n.call(this)).connected=!1,s.disconnected=!0,s.receiveBuffer=[],s.sendBuffer=[],s.ids=0,s.acks={},s.flags={},s.io=t,s.nsp=r,i&&i.auth&&(s.auth=i.auth),s.io._autoConnect&&s.open(),s}return r(o,[{key:"subEvents",value:function(){if(!this.subs){var t=this.io;this.subs=[Rt(t,"open",this.onopen.bind(this)),Rt(t,"packet",this.onpacket.bind(this)),Rt(t,"error",this.onerror.bind(this)),Rt(t,"close",this.onclose.bind(this))]}}},{key:"active",get:function(){return!!this.subs}},{key:"connect",value:function(){return this.connected||(this.subEvents(),this.io._reconnecting||this.io.open(),"open"===this.io._readyState&&this.onopen()),this}},{key:"open",value:function(){return this.connect()}},{key:"send",value:function(){for(var t=arguments.length,e=new Array(t),n=0;n1?e-1:0),r=1;r0&&t.jitter<=1?t.jitter:0,this.attempts=0}St.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n}return 0|Math.min(t,this.max)},St.prototype.reset=function(){this.attempts=0},St.prototype.setMin=function(t){this.ms=t},St.prototype.setMax=function(t){this.max=t},St.prototype.setJitter=function(t){this.jitter=t};var Bt=function(n){i(s,n);var o=h(s);function s(n,r){var i,a;e(this,s),(i=o.call(this)).nsps={},i.subs=[],n&&"object"===t(n)&&(r=n,n=void 0),(r=r||{}).path=r.path||"/socket.io",i.opts=r,A(c(i),r),i.reconnection(!1!==r.reconnection),i.reconnectionAttempts(r.reconnectionAttempts||1/0),i.reconnectionDelay(r.reconnectionDelay||1e3),i.reconnectionDelayMax(r.reconnectionDelayMax||5e3),i.randomizationFactor(null!==(a=r.randomizationFactor)&&void 0!==a?a:.5),i.backoff=new Ot({min:i.reconnectionDelay(),max:i.reconnectionDelayMax(),jitter:i.randomizationFactor()}),i.timeout(null==r.timeout?2e4:r.timeout),i._readyState="closed",i.uri=n;var u=r.parser||At;return i.encoder=new u.Encoder,i.decoder=new u.Decoder,i._autoConnect=!1!==r.autoConnect,i._autoConnect&&i.open(),i}return r(s,[{key:"reconnection",value:function(t){return arguments.length?(this._reconnection=!!t,this):this._reconnection}},{key:"reconnectionAttempts",value:function(t){return void 0===t?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}},{key:"reconnectionDelay",value:function(t){var e;return void 0===t?this._reconnectionDelay:(this._reconnectionDelay=t,null===(e=this.backoff)||void 0===e||e.setMin(t),this)}},{key:"randomizationFactor",value:function(t){var e;return void 0===t?this._randomizationFactor:(this._randomizationFactor=t,null===(e=this.backoff)||void 0===e||e.setJitter(t),this)}},{key:"reconnectionDelayMax",value:function(t){var e;return void 0===t?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,null===(e=this.backoff)||void 0===e||e.setMax(t),this)}},{key:"timeout",value:function(t){return arguments.length?(this._timeout=t,this):this._timeout}},{key:"maybeReconnectOnOpen",value:function(){!this._reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()}},{key:"open",value:function(t){var e=this;if(~this._readyState.indexOf("open"))return this;this.engine=new ut(this.uri,this.opts);var n=this.engine,r=this;this._readyState="opening",this.skipReconnect=!1;var o=Rt(n,"open",(function(){r.onopen(),t&&t()})),i=Rt(n,"error",(function(n){r.cleanup(),r._readyState="closed",e.emitReserved("error",n),t?t(n):r.maybeReconnectOnOpen()}));if(!1!==this._timeout){var s=this._timeout;0===s&&o();var a=this.setTimeoutFn((function(){o(),n.close(),n.emit("error",new Error("timeout"))}),s);this.opts.autoUnref&&a.unref(),this.subs.push((function(){clearTimeout(a)}))}return this.subs.push(o),this.subs.push(i),this}},{key:"connect",value:function(t){return this.open(t)}},{key:"onopen",value:function(){this.cleanup(),this._readyState="open",this.emitReserved("open");var t=this.engine;this.subs.push(Rt(t,"ping",this.onping.bind(this)),Rt(t,"data",this.ondata.bind(this)),Rt(t,"error",this.onerror.bind(this)),Rt(t,"close",this.onclose.bind(this)),Rt(this.decoder,"decoded",this.ondecoded.bind(this)))}},{key:"onping",value:function(){this.emitReserved("ping")}},{key:"ondata",value:function(t){this.decoder.add(t)}},{key:"ondecoded",value:function(t){this.emitReserved("packet",t)}},{key:"onerror",value:function(t){this.emitReserved("error",t)}},{key:"socket",value:function(t,e){var n=this.nsps[t];return n||(n=new Ct(this,t,e),this.nsps[t]=n),n}},{key:"_destroy",value:function(t){for(var e=0,n=Object.keys(this.nsps);e=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{var n=this.backoff.duration();this._reconnecting=!0;var r=this.setTimeoutFn((function(){e.skipReconnect||(t.emitReserved("reconnect_attempt",e.backoff.attempts),e.skipReconnect||e.open((function(n){n?(e._reconnecting=!1,e.reconnect(),t.emitReserved("reconnect_error",n)):e.onreconnect()})))}),n);this.opts.autoUnref&&r.unref(),this.subs.push((function(){clearTimeout(r)}))}}},{key:"onreconnect",value:function(){var t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t)}}]),s}(R),Nt={};function xt(e,n){"object"===t(e)&&(n=e,e=void 0);var r,o=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2?arguments[2]:void 0,r=t;n=n||"undefined"!=typeof location&&location,null==t&&(t=n.protocol+"//"+n.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?n.protocol+t:n.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==n?n.protocol+"//"+t:"https://"+t),r=v(t)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";var o=-1!==r.host.indexOf(":")?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+o+":"+r.port+e,r.href=r.protocol+"://"+o+(n&&n.port===r.port?"":":"+r.port),r}(e,(n=n||{}).path||"/socket.io"),i=o.source,s=o.id,a=o.path,c=Nt[s]&&a in Nt[s].nsps;return n.forceNew||n["force new connection"]||!1===n.multiplex||c?r=new Bt(i,n):(Nt[s]||(Nt[s]=new Bt(i,n)),r=Nt[s]),o.query&&!n.query&&(n.query=o.queryKey),r.socket(o.path,n)}return o(xt,{Manager:Bt,Socket:Ct,io:xt,connect:xt}),xt})); +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).io=e()}(this,(function(){"use strict";function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function n(t,e){for(var n=0;nt.length)&&(e=t.length);for(var n=0,r=new Array(e);n=t.length?{done:!0}:{done:!1,value:t[r++]}},e:function(t){throw t},f:i}}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 o,s=!0,a=!1;return{s:function(){n=n.call(t)},n:function(){var t=n.next();return s=t.done,t},e:function(t){a=!0,o=t},f:function(){try{s||null==n.return||n.return()}finally{if(a)throw o}}}}var g=Object.create(null);g.open="0",g.close="1",g.ping="2",g.pong="3",g.message="4",g.upgrade="5",g.noop="6";var m=Object.create(null);Object.keys(g).forEach((function(t){m[g[t]]=t}));for(var k={type:"error",data:"parser error"},b="function"==typeof Blob||"undefined"!=typeof Blob&&"[object BlobConstructor]"===Object.prototype.toString.call(Blob),w="function"==typeof ArrayBuffer,_=function(t,e,n){var r,i=t.type,o=t.data;return b&&o instanceof Blob?e?n(o):A(o,n):w&&(o instanceof ArrayBuffer||(r=o,"function"==typeof ArrayBuffer.isView?ArrayBuffer.isView(r):r&&r.buffer instanceof ArrayBuffer))?e?n(o):A(new Blob([o]),n):n(g[i]+(o||""))},A=function(t,e){var n=new FileReader;return n.onload=function(){var t=n.result.split(",")[1];e("b"+t)},n.readAsDataURL(t)},E="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",O="undefined"==typeof Uint8Array?[]:new Uint8Array(256),R=0;R1?{type:m[n],data:t.substring(1)}:{type:m[n]}:k},B=function(t,e){if(T){var n=function(t){var e,n,r,i,o,s=.75*t.length,a=t.length,c=0;"="===t[t.length-1]&&(s--,"="===t[t.length-2]&&s--);var u=new ArrayBuffer(s),h=new Uint8Array(u);for(e=0;e>4,h[c++]=(15&r)<<4|i>>2,h[c++]=(3&i)<<6|63&o;return u}(t);return S(n,e)}return{base64:!0,data:t}},S=function(t,e){return"blob"===e&&t instanceof ArrayBuffer?new Blob([t]):t},N=String.fromCharCode(30);function x(t){if(t)return function(t){for(var e in x.prototype)t[e]=x.prototype[e];return t}(t)}x.prototype.on=x.prototype.addEventListener=function(t,e){return this._callbacks=this._callbacks||{},(this._callbacks["$"+t]=this._callbacks["$"+t]||[]).push(e),this},x.prototype.once=function(t,e){function n(){this.off(t,n),e.apply(this,arguments)}return n.fn=e,this.on(t,n),this},x.prototype.off=x.prototype.removeListener=x.prototype.removeAllListeners=x.prototype.removeEventListener=function(t,e){if(this._callbacks=this._callbacks||{},0==arguments.length)return this._callbacks={},this;var n,r=this._callbacks["$"+t];if(!r)return this;if(1==arguments.length)return delete this._callbacks["$"+t],this;for(var i=0;i1?e-1:0),r=1;r0);return e}function z(){var t=Y(+new Date);return t!==D?(H=0,D=t):t+"."+Y(H++)}for(;K<64;K++)V[U[K]]=K;function W(t){var e="";for(var n in t)t.hasOwnProperty(n)&&(e.length&&(e+="&"),e+=encodeURIComponent(n)+"="+encodeURIComponent(t[n]));return e}function $(t){for(var e={},n=t.split("&"),r=0,i=n.length;r0&&void 0!==arguments[0]?arguments[0]:{};return i(t,{xd:this.xd,xs:this.xs},this.opts),new et(this.uri(),t)}},{key:"doWrite",value:function(t,e){var n=this,r=this.request({method:"POST",data:t});r.on("success",e),r.on("error",(function(t,e){n.onError("xhr post error",t,e)}))}},{key:"doPoll",value:function(){var t=this,e=this.request();e.on("data",this.onData.bind(this)),e.on("error",(function(e,n){t.onError("xhr poll error",e,n)})),this.pollXhr=e}}]),s}(M),et=function(t){o(i,t);var n=p(i);function i(t,r){var o;return e(this,i),I(f(o=n.call(this)),r),o.opts=r,o.method=r.method||"GET",o.uri=t,o.async=!1!==r.async,o.data=void 0!==r.data?r.data:null,o.create(),o}return r(i,[{key:"create",value:function(){var t=this,e=P(this.opts,"agent","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","autoUnref");e.xdomain=!!this.opts.xd,e.xscheme=!!this.opts.xs;var n=this.xhr=new G(e);try{n.open(this.method,this.uri,this.async);try{if(this.opts.extraHeaders)for(var r in n.setDisableHeaderCheck&&n.setDisableHeaderCheck(!0),this.opts.extraHeaders)this.opts.extraHeaders.hasOwnProperty(r)&&n.setRequestHeader(r,this.opts.extraHeaders[r])}catch(t){}if("POST"===this.method)try{n.setRequestHeader("Content-type","text/plain;charset=UTF-8")}catch(t){}try{n.setRequestHeader("Accept","*/*")}catch(t){}"withCredentials"in n&&(n.withCredentials=this.opts.withCredentials),this.opts.requestTimeout&&(n.timeout=this.opts.requestTimeout),n.onreadystatechange=function(){4===n.readyState&&(200===n.status||1223===n.status?t.onLoad():t.setTimeoutFn((function(){t.onError("number"==typeof n.status?n.status:0)}),0))},n.send(this.data)}catch(e){return void this.setTimeoutFn((function(){t.onError(e)}),0)}"undefined"!=typeof document&&(this.index=i.requestsCount++,i.requests[this.index]=this)}},{key:"onError",value:function(t){this.emitReserved("error",t,this.xhr),this.cleanup(!0)}},{key:"cleanup",value:function(t){if(void 0!==this.xhr&&null!==this.xhr){if(this.xhr.onreadystatechange=Q,t)try{this.xhr.abort()}catch(t){}"undefined"!=typeof document&&delete i.requests[this.index],this.xhr=null}}},{key:"onLoad",value:function(){var t=this.xhr.responseText;null!==t&&(this.emitReserved("data",t),this.emitReserved("success"),this.cleanup())}},{key:"abort",value:function(){this.cleanup()}}]),i}(x);if(et.requestsCount=0,et.requests={},"undefined"!=typeof document)if("function"==typeof attachEvent)attachEvent("onunload",nt);else if("function"==typeof addEventListener){addEventListener("onpagehide"in L?"pagehide":"unload",nt,!1)}function nt(){for(var t in et.requests)et.requests.hasOwnProperty(t)&&et.requests[t].abort()}var rt="function"==typeof Promise&&"function"==typeof Promise.resolve?function(t){return Promise.resolve().then(t)}:function(t,e){return e(t,0)},it=L.WebSocket||L.MozWebSocket,ot="undefined"!=typeof navigator&&"string"==typeof navigator.product&&"reactnative"===navigator.product.toLowerCase(),st=function(t){o(i,t);var n=p(i);function i(t){var r;return e(this,i),(r=n.call(this,t)).supportsBinary=!t.forceBase64,r}return r(i,[{key:"name",get:function(){return"websocket"}},{key:"doOpen",value:function(){if(this.check()){var t=this.uri(),e=this.opts.protocols,n=ot?{}:P(this.opts,"agent","perMessageDeflate","pfx","key","passphrase","cert","ca","ciphers","rejectUnauthorized","localAddress","protocolVersion","origin","maxPayload","family","checkServerIdentity");this.opts.extraHeaders&&(n.headers=this.opts.extraHeaders);try{this.ws=ot?new it(t,e,n):e?new it(t,e):new it(t)}catch(t){return this.emitReserved("error",t)}this.ws.binaryType=this.socket.binaryType||"arraybuffer",this.addEventListeners()}}},{key:"addEventListeners",value:function(){var t=this;this.ws.onopen=function(){t.opts.autoUnref&&t.ws._socket.unref(),t.onOpen()},this.ws.onclose=function(e){return t.onClose({description:"websocket connection closed",context:e})},this.ws.onmessage=function(e){return t.onData(e.data)},this.ws.onerror=function(e){return t.onError("websocket error",e)}}},{key:"write",value:function(t){var e=this;this.writable=!1;for(var n=function(n){var r=t[n],i=n===t.length-1;_(r,e.supportsBinary,(function(t){try{e.ws.send(t)}catch(t){}i&&rt((function(){e.writable=!0,e.emitReserved("drain")}),e.setTimeoutFn)}))},r=0;r1&&void 0!==arguments[1]?arguments[1]:{};return e(this,a),r=s.call(this),n&&"object"===t(n)&&(o=n,n=null),n?(n=ht(n),o.hostname=n.host,o.secure="https"===n.protocol||"wss"===n.protocol,o.port=n.port,n.query&&(o.query=n.query)):o.host&&(o.hostname=ht(o.host).host),I(f(r),o),r.secure=null!=o.secure?o.secure:"undefined"!=typeof location&&"https:"===location.protocol,o.hostname&&!o.port&&(o.port=r.secure?"443":"80"),r.hostname=o.hostname||("undefined"!=typeof location?location.hostname:"localhost"),r.port=o.port||("undefined"!=typeof location&&location.port?location.port:r.secure?"443":"80"),r.transports=o.transports||["polling","websocket"],r.readyState="",r.writeBuffer=[],r.prevBufferLen=0,r.opts=i({path:"/engine.io",agent:!1,withCredentials:!1,upgrade:!0,timestampParam:"t",rememberUpgrade:!1,rejectUnauthorized:!0,perMessageDeflate:{threshold:1024},transportOptions:{},closeOnBeforeunload:!0},o),r.opts.path=r.opts.path.replace(/\/$/,"")+"/","string"==typeof r.opts.query&&(r.opts.query=$(r.opts.query)),r.id=null,r.upgrades=null,r.pingInterval=null,r.pingTimeout=null,r.pingTimeoutTimer=null,"function"==typeof addEventListener&&(r.opts.closeOnBeforeunload&&addEventListener("beforeunload",(function(){r.transport&&(r.transport.removeAllListeners(),r.transport.close())}),!1),"localhost"!==r.hostname&&(r.offlineEventListener=function(){r.onClose("transport close",{description:"network connection lost"})},addEventListener("offline",r.offlineEventListener,!1))),r.open(),r}return r(a,[{key:"createTransport",value:function(t){var e=i({},this.opts.query);e.EIO=4,e.transport=t,this.id&&(e.sid=this.id);var n=i({},this.opts.transportOptions[t],this.opts,{query:e,socket:this,hostname:this.hostname,secure:this.secure,port:this.port});return new at[t](n)}},{key:"open",value:function(){var t,e=this;if(this.opts.rememberUpgrade&&a.priorWebsocketSuccess&&-1!==this.transports.indexOf("websocket"))t="websocket";else{if(0===this.transports.length)return void this.setTimeoutFn((function(){e.emitReserved("error","No transports available")}),0);t=this.transports[0]}this.readyState="opening";try{t=this.createTransport(t)}catch(t){return this.transports.shift(),void this.open()}t.open(),this.setTransport(t)}},{key:"setTransport",value:function(t){var e=this;this.transport&&this.transport.removeAllListeners(),this.transport=t,t.on("drain",this.onDrain.bind(this)).on("packet",this.onPacket.bind(this)).on("error",this.onError.bind(this)).on("close",(function(t){return e.onClose("transport close",t)}))}},{key:"probe",value:function(t){var e=this,n=this.createTransport(t),r=!1;a.priorWebsocketSuccess=!1;var i=function(){r||(n.send([{type:"ping",data:"probe"}]),n.once("packet",(function(t){if(!r)if("pong"===t.type&&"probe"===t.data){if(e.upgrading=!0,e.emitReserved("upgrading",n),!n)return;a.priorWebsocketSuccess="websocket"===n.name,e.transport.pause((function(){r||"closed"!==e.readyState&&(f(),e.setTransport(n),n.send([{type:"upgrade"}]),e.emitReserved("upgrade",n),n=null,e.upgrading=!1,e.flush())}))}else{var i=new Error("probe error");i.transport=n.name,e.emitReserved("upgradeError",i)}})))};function o(){r||(r=!0,f(),n.close(),n=null)}var s=function(t){var r=new Error("probe error: "+t);r.transport=n.name,o(),e.emitReserved("upgradeError",r)};function c(){s("transport closed")}function u(){s("socket closed")}function h(t){n&&t.name!==n.name&&o()}var f=function(){n.removeListener("open",i),n.removeListener("error",s),n.removeListener("close",c),e.off("close",u),e.off("upgrading",h)};n.once("open",i),n.once("error",s),n.once("close",c),this.once("close",u),this.once("upgrading",h),n.open()}},{key:"onOpen",value:function(){if(this.readyState="open",a.priorWebsocketSuccess="websocket"===this.transport.name,this.emitReserved("open"),this.flush(),"open"===this.readyState&&this.opts.upgrade&&this.transport.pause)for(var t=0,e=this.upgrades.length;t1))return this.writeBuffer;for(var t,e=1,n=0;n=57344?n+=3:(r++,n+=4);return n}(t):Math.ceil(1.33*(t.byteLength||t.size))),n>0&&e>this.maxPayload)return this.writeBuffer.slice(0,n);e+=2}return this.writeBuffer}},{key:"write",value:function(t,e,n){return this.sendPacket("message",t,e,n),this}},{key:"send",value:function(t,e,n){return this.sendPacket("message",t,e,n),this}},{key:"sendPacket",value:function(t,e,n,r){if("function"==typeof e&&(r=e,e=void 0),"function"==typeof n&&(r=n,n=null),"closing"!==this.readyState&&"closed"!==this.readyState){(n=n||{}).compress=!1!==n.compress;var i={type:t,data:e,options:n};this.emitReserved("packetCreate",i),this.writeBuffer.push(i),r&&this.once("flush",r),this.flush()}}},{key:"close",value:function(){var t=this,e=function(){t.onClose("forced close"),t.transport.close()},n=function n(){t.off("upgrade",n),t.off("upgradeError",n),e()},r=function(){t.once("upgrade",n),t.once("upgradeError",n)};return"opening"!==this.readyState&&"open"!==this.readyState||(this.readyState="closing",this.writeBuffer.length?this.once("drain",(function(){t.upgrading?r():e()})):this.upgrading?r():e()),this}},{key:"onError",value:function(t){a.priorWebsocketSuccess=!1,this.emitReserved("error",t),this.onClose("transport error",t)}},{key:"onClose",value:function(t,e){"opening"!==this.readyState&&"open"!==this.readyState&&"closing"!==this.readyState||(this.clearTimeoutFn(this.pingTimeoutTimer),this.transport.removeAllListeners("close"),this.transport.close(),this.transport.removeAllListeners(),"function"==typeof removeEventListener&&removeEventListener("offline",this.offlineEventListener,!1),this.readyState="closed",this.id=null,this.emitReserved("close",t,e),this.writeBuffer=[],this.prevBufferLen=0)}},{key:"filterUpgrades",value:function(t){for(var e=[],n=0,r=t.length;n0;case _t.ACK:case _t.BINARY_ACK:return Array.isArray(n)}}}]),a}(x),Ot=function(){function t(n){e(this,t),this.packet=n,this.buffers=[],this.reconPack=n}return r(t,[{key:"takeBinaryData",value:function(t){if(this.buffers.push(t),this.buffers.length===this.reconPack.attachments){var e=bt(this.reconPack,this.buffers);return this.finishedReconstruction(),e}return null}},{key:"finishedReconstruction",value:function(){this.reconPack=null,this.buffers=[]}}]),t}(),Rt=Object.freeze({__proto__:null,protocol:5,get PacketType(){return _t},Encoder:At,Decoder:Et});function Tt(t,e,n){return t.on(e,n),function(){t.off(e,n)}}var Ct=Object.freeze({connect:1,connect_error:1,disconnect:1,disconnecting:1,newListener:1,removeListener:1}),Bt=function(t){o(i,t);var n=p(i);function i(t,r,o){var s;return e(this,i),(s=n.call(this)).connected=!1,s.receiveBuffer=[],s.sendBuffer=[],s.ids=0,s.acks={},s.flags={},s.io=t,s.nsp=r,o&&o.auth&&(s.auth=o.auth),s.io._autoConnect&&s.open(),s}return r(i,[{key:"disconnected",get:function(){return!this.connected}},{key:"subEvents",value:function(){if(!this.subs){var t=this.io;this.subs=[Tt(t,"open",this.onopen.bind(this)),Tt(t,"packet",this.onpacket.bind(this)),Tt(t,"error",this.onerror.bind(this)),Tt(t,"close",this.onclose.bind(this))]}}},{key:"active",get:function(){return!!this.subs}},{key:"connect",value:function(){return this.connected||(this.subEvents(),this.io._reconnecting||this.io.open(),"open"===this.io._readyState&&this.onopen()),this}},{key:"open",value:function(){return this.connect()}},{key:"send",value:function(){for(var t=arguments.length,e=new Array(t),n=0;n1?e-1:0),r=1;r0&&t.jitter<=1?t.jitter:0,this.attempts=0}St.prototype.duration=function(){var t=this.ms*Math.pow(this.factor,this.attempts++);if(this.jitter){var e=Math.random(),n=Math.floor(e*this.jitter*t);t=0==(1&Math.floor(10*e))?t-n:t+n}return 0|Math.min(t,this.max)},St.prototype.reset=function(){this.attempts=0},St.prototype.setMin=function(t){this.ms=t},St.prototype.setMax=function(t){this.max=t},St.prototype.setJitter=function(t){this.jitter=t};var Nt=function(n){o(s,n);var i=p(s);function s(n,r){var o,a;e(this,s),(o=i.call(this)).nsps={},o.subs=[],n&&"object"===t(n)&&(r=n,n=void 0),(r=r||{}).path=r.path||"/socket.io",o.opts=r,I(f(o),r),o.reconnection(!1!==r.reconnection),o.reconnectionAttempts(r.reconnectionAttempts||1/0),o.reconnectionDelay(r.reconnectionDelay||1e3),o.reconnectionDelayMax(r.reconnectionDelayMax||5e3),o.randomizationFactor(null!==(a=r.randomizationFactor)&&void 0!==a?a:.5),o.backoff=new St({min:o.reconnectionDelay(),max:o.reconnectionDelayMax(),jitter:o.randomizationFactor()}),o.timeout(null==r.timeout?2e4:r.timeout),o._readyState="closed",o.uri=n;var c=r.parser||Rt;return o.encoder=new c.Encoder,o.decoder=new c.Decoder,o._autoConnect=!1!==r.autoConnect,o._autoConnect&&o.open(),o}return r(s,[{key:"reconnection",value:function(t){return arguments.length?(this._reconnection=!!t,this):this._reconnection}},{key:"reconnectionAttempts",value:function(t){return void 0===t?this._reconnectionAttempts:(this._reconnectionAttempts=t,this)}},{key:"reconnectionDelay",value:function(t){var e;return void 0===t?this._reconnectionDelay:(this._reconnectionDelay=t,null===(e=this.backoff)||void 0===e||e.setMin(t),this)}},{key:"randomizationFactor",value:function(t){var e;return void 0===t?this._randomizationFactor:(this._randomizationFactor=t,null===(e=this.backoff)||void 0===e||e.setJitter(t),this)}},{key:"reconnectionDelayMax",value:function(t){var e;return void 0===t?this._reconnectionDelayMax:(this._reconnectionDelayMax=t,null===(e=this.backoff)||void 0===e||e.setMax(t),this)}},{key:"timeout",value:function(t){return arguments.length?(this._timeout=t,this):this._timeout}},{key:"maybeReconnectOnOpen",value:function(){!this._reconnecting&&this._reconnection&&0===this.backoff.attempts&&this.reconnect()}},{key:"open",value:function(t){var e=this;if(~this._readyState.indexOf("open"))return this;this.engine=new ft(this.uri,this.opts);var n=this.engine,r=this;this._readyState="opening",this.skipReconnect=!1;var i=Tt(n,"open",(function(){r.onopen(),t&&t()})),o=Tt(n,"error",(function(n){r.cleanup(),r._readyState="closed",e.emitReserved("error",n),t?t(n):r.maybeReconnectOnOpen()}));if(!1!==this._timeout){var s=this._timeout;0===s&&i();var a=this.setTimeoutFn((function(){i(),n.close(),n.emit("error",new Error("timeout"))}),s);this.opts.autoUnref&&a.unref(),this.subs.push((function(){clearTimeout(a)}))}return this.subs.push(i),this.subs.push(o),this}},{key:"connect",value:function(t){return this.open(t)}},{key:"onopen",value:function(){this.cleanup(),this._readyState="open",this.emitReserved("open");var t=this.engine;this.subs.push(Tt(t,"ping",this.onping.bind(this)),Tt(t,"data",this.ondata.bind(this)),Tt(t,"error",this.onerror.bind(this)),Tt(t,"close",this.onclose.bind(this)),Tt(this.decoder,"decoded",this.ondecoded.bind(this)))}},{key:"onping",value:function(){this.emitReserved("ping")}},{key:"ondata",value:function(t){this.decoder.add(t)}},{key:"ondecoded",value:function(t){this.emitReserved("packet",t)}},{key:"onerror",value:function(t){this.emitReserved("error",t)}},{key:"socket",value:function(t,e){var n=this.nsps[t];return n||(n=new Bt(this,t,e),this.nsps[t]=n),n}},{key:"_destroy",value:function(t){for(var e=0,n=Object.keys(this.nsps);e=this._reconnectionAttempts)this.backoff.reset(),this.emitReserved("reconnect_failed"),this._reconnecting=!1;else{var n=this.backoff.duration();this._reconnecting=!0;var r=this.setTimeoutFn((function(){e.skipReconnect||(t.emitReserved("reconnect_attempt",e.backoff.attempts),e.skipReconnect||e.open((function(n){n?(e._reconnecting=!1,e.reconnect(),t.emitReserved("reconnect_error",n)):e.onreconnect()})))}),n);this.opts.autoUnref&&r.unref(),this.subs.push((function(){clearTimeout(r)}))}}},{key:"onreconnect",value:function(){var t=this.backoff.attempts;this._reconnecting=!1,this.backoff.reset(),this.emitReserved("reconnect",t)}}]),s}(x),xt={};function Lt(e,n){"object"===t(e)&&(n=e,e=void 0);var r,i=function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2?arguments[2]:void 0,r=t;n=n||"undefined"!=typeof location&&location,null==t&&(t=n.protocol+"//"+n.host),"string"==typeof t&&("/"===t.charAt(0)&&(t="/"===t.charAt(1)?n.protocol+t:n.host+t),/^(https?|wss?):\/\//.test(t)||(t=void 0!==n?n.protocol+"//"+t:"https://"+t),r=ht(t)),r.port||(/^(http|ws)$/.test(r.protocol)?r.port="80":/^(http|ws)s$/.test(r.protocol)&&(r.port="443")),r.path=r.path||"/";var i=-1!==r.host.indexOf(":")?"["+r.host+"]":r.host;return r.id=r.protocol+"://"+i+":"+r.port+e,r.href=r.protocol+"://"+i+(n&&n.port===r.port?"":":"+r.port),r}(e,(n=n||{}).path||"/socket.io"),o=i.source,s=i.id,a=i.path,c=xt[s]&&a in xt[s].nsps;return n.forceNew||n["force new connection"]||!1===n.multiplex||c?r=new Nt(o,n):(xt[s]||(xt[s]=new Nt(o,n)),r=xt[s]),i.query&&!n.query&&(n.query=i.queryKey),r.socket(i.path,n)}return i(Lt,{Manager:Nt,Socket:Bt,io:Lt,connect:Lt}),Lt})); //# sourceMappingURL=socket.io.min.js.map diff --git a/templates/index_new.html b/templates/index_new.html index 47cf4c79..3946af2f 100644 --- a/templates/index_new.html +++ b/templates/index_new.html @@ -37,8 +37,9 @@ -
+ +
@@ -54,9 +55,7 @@
Status:
- options: -
-
+
diff --git a/templates/settings item.html b/templates/settings item.html index 62b41416..44f15da2 100644 --- a/templates/settings item.html +++ b/templates/settings item.html @@ -26,8 +26,8 @@ {% elif item["uitype"] == "toggle" %} - {% elif item['uuitype'] == "dropdown" %} - {% for option in item['children'] %} {% endfor %}