diff --git a/kits/ActionEditorModal.js b/kits/ActionEditorModal.js
new file mode 100644
index 0000000..e69de29
diff --git a/kits/ActionModules.js b/kits/ActionModules.js
new file mode 100644
index 0000000..b633cd2
--- /dev/null
+++ b/kits/ActionModules.js
@@ -0,0 +1,586 @@
+function newObject(type) {
+ createCheckpoint({
+ recacheFolders: true
+ });
+ if (type == 1) {
+ let additionalData = {
+ channel: {
+ type: 'id',
+ value: ''
+ }
+ };
+
+ let highlightedGroupType = 'event'
+ if (botData.commands[lastObj].type == 'action') {
+ highlightedGroupType = botData.commands[lastObj].trigger
+ }
+
+ if (highlightedGroupType == 'slashCommand') {
+ additionalData = {
+ channel: {
+ type: "commandInteraction",
+ value: ""
+ }
+ }
+ } else if (highlightedGroupType != 'event') {
+ }
+ customIDsCalculated++
+ let newAct = {
+ name: "Send Message",
+ file: "sendmessage.js",
+ data: {
+ "name": "Send Message",
+ "messageContent": "Hello World!",
+ "actionRows": [],
+ "embeds": [],
+ channel: {
+ type: "command",
+ value: ""
+ },
+ replyToInteraction: true,
+ storeAs: {
+ value: "",
+ type: "temporary"
+ }
+ },
+ id: customIDsCalculated + new Date().getTime()
+ };
+
+ botData.commands[lastObj].actions.splice(((lastAct != undefined) ? Number(lastAct) : 0) + 1, 0, newAct)
+ botData.commands[lastObj].actions.filter(
+ (e) => e != undefined || e != null,
+ );
+ lastAct = botData.commands[lastObj].actions.length;
+ saveLocally();
+ refreshActions(true);
+ document.getElementById(`${lastObj}Groupcount`).innerHTML = lastAct;
+
+ if (editorSettings.editActionsOnCreation) {
+ highlight(document.getElementById(`Action${botData.commands[lastObj].actions.length - 1}`)).then(() => {
+ editAction({ picker: true });
+ })
+ }
+ } else {
+ let type = "action";
+ let trigger;
+ let extra = {};
+ if (selectedGroupType == "command") {
+ trigger = "textCommand";
+ switch (settings.defaultCommandType) {
+ case 'Slash':
+ trigger = 'slashCommand';
+ break
+
+ case 'Message':
+ trigger = 'messageContent'
+ break
+
+ case 'Message Command':
+ trigger = 'message'
+ break
+
+ case 'User Command':
+ trigger = 'user'
+ break
+ }
+ extra = { boundary: { worksIn: "guild", limits: [] }, parameters: [], description: "No Description" };
+ }
+ if (selectedGroupType == "event") {
+ extra = { eventFile: "message_create.js", eventData: ["", ""] };
+
+ type = "event";
+ trigger = "event";
+ }
+
+ let newGroup = {
+ name: "",
+ type: type,
+ trigger,
+ actions: [],
+ customId: new Date().getTime(),
+ ...extra,
+ folder: [lastFolder]
+ };
+
+ // if (lastFolder && !cachedFolders[lastFolder].closed) {
+ // botData.commands.splice(cachedFolders[lastFolder].last + 1, 0, newGroup);
+ // } else {
+ // botData.commands.splice(Number(lastObj || cachedFolders[lastFolder]?.last || botData.commands.length) + 1, 0, newGroup);
+ // newGroup.folder = null;
+ // }
+ botData.commands.push(newGroup)
+
+ const folderUsed = lastFolder;
+
+ lastObj = botData.commands.length;
+ saveLocally();
+ recacheFolders();
+ refreshGroups(true);
+
+
+ setTimeout(async () => {
+ await highlight(document.getElementById(`Group${folderUsed ? cachedFolders[folderUsed].last : botData.commands.length - 1}`));
+ }, 10);
+ }
+ checkSaveStatus()
+}
+
+async function deleteFolder(folderID) {
+ let keepGoing = false;
+ if (editorSettings.commandDeletionScreening) {
+ try {
+ keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: getString(strings.editor.folder_deletion_confirmation, [cachedFolders[lastFolder].name]) }, 'deletionModalInteraction');
+ if (!keepGoing) return;
+ } catch (error) {
+ keepGoing = true;
+ }
+ }
+
+ createCheckpoint({ recacheFolders: true });
+ delete botData.folders[folderID];
+
+ await recacheFolders(); await refreshGroups();
+
+ setTimeout(() => {
+ highlight(document.getElementById('Group0'));
+ }, 100);
+}
+
+function duplicateGroup(index) {
+ createCheckpoint();
+ botData.commands.splice(parseFloat(index) + 1, 0, JSON.parse(JSON.stringify(botData.commands[index])))
+
+ botData.commands[parseFloat(index) + 1].customId = new Date().getTime()
+ saveLocally();
+
+ recacheFolders();
+ refreshGroups();
+}
+
+async function deleteCommand(index) {
+ if (editorSettings.commandDeletionScreening) {
+ let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: getString(botData.commands[index].type == 'action' ? strings.editor.command_deletion_confirmation : strings.editor.event_deletion_confirmation, [botData.commands[index].name]) }, 'deletionModalInteraction');
+ if (!keepGoing) return;
+ }
+ await new Promise(res => {
+ document.getElementById(`Group${index}`).style.transition = `all 0.${editorSettings.fastAnimation}s ease`
+
+ document.getElementById(`Group${index}`).style.opacity = '0'
+ document.getElementById(`Group${index}`).style.height = '0'
+ document.getElementById(`Group${index}`).style.paddingTop = '0'
+ document.getElementById(`Group${index}`).style.paddingBottom = '0'
+ document.getElementById(`Group${index}`).style.marginTop = '0'
+ document.getElementById(`Group${index}`).style.marginBottom = '0'
+
+ setTimeout(() => {
+ res()
+ }, editorSettings.fastAnimation * 100);
+ })
+
+ try {
+ createCheckpoint();
+ botData.commands.splice(index, 1);
+ saveLocally();
+ recacheFolders();
+ refreshGroups();
+ } catch (err) { console.error(err) }
+
+ if (selectedGroupType == 'slash') {
+ setHighlightedGroup(2)
+ } else if (selectedGroupType == 'text') {
+ setHighlightedGroup(1)
+ } else if (selectedGroupType == 'event') {
+ setHighlightedGroup(3)
+ }
+ document.getElementById('actionbar').innerHTML = ''
+
+ refreshGroups();
+}
+
+async function deleteAction(index) {
+ if (editorSettings.actionDeletionScreening) {
+ let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: `Are you sure you want to delete ${botData.commands[lastObj].actions[index].name}?` }, 'deletionModalInteraction');
+ if (!keepGoing) return;
+ }
+
+
+ await new Promise(res => {
+ document.getElementById(`Action${index}`).style.transition = `all 0.${editorSettings.fastAnimation}s ease`
+
+ document.getElementById(`Action${index}`).style.opacity = '0'
+ document.getElementById(`Action${index}`).style.height = '0'
+ document.getElementById(`Action${index}`).style.paddingTop = '0'
+ document.getElementById(`Action${index}`).style.paddingBottom = '0'
+ document.getElementById(`Action${index}`).style.marginTop = '0'
+ document.getElementById(`Action${index}`).style.marginBottom = '0'
+
+ setTimeout(() => {
+ res()
+ }, editorSettings.fastAnimation * 100);
+ })
+ createCheckpoint()
+ let deserializedAction = botData.commands[lastObj].actions[index];
+ botData.commands[lastObj].actions.splice(index, 1);
+ saveLocally();
+ refreshActions();
+ document.getElementById(`${lastObj}Groupcount`).innerHTML = botData.commands[lastObj].actions.length;
+}
+
+let timing;
+
+var draggedGroup;
+var draggedOverGroup;
+var draggedOverFolder;
+var lastDraggedOverFolder;
+var stillOverFolder = {}
+var stillOver = false;
+var lastDraggedOverThing;
+var draggedFolder;
+
+function handleFolderDragStart(folder) {
+ timing = new Date().getTime();
+ draggedFolder = folder;
+}
+
+function handleFolderDragEnd() {
+ if (new Date().getTime() - timing < 100) return;
+ createCheckpoint({ recacheFolders: true });
+ let folder = cachedFolders[draggedFolder];
+
+ let transferredGroups = 0;
+
+ let newPosition = parseFloat(draggedOverGroup);
+ let toTransfer;
+
+ if (folder.last == folder.first) {
+ toTransfer = 1;
+ } else {
+ toTransfer = Number(folder.last + 1) - folder.first
+ }
+
+ let folderArray = [draggedFolder];
+
+ if (draggedOverFolder) {
+ folderArray = [draggedOverFolder, ...folderArray];
+ }
+
+ while (transferredGroups < toTransfer) {
+ botData.commands[folder.first].folder = folderArray;
+ transferredGroups++
+
+ botData.commands = moveArrayElement(botData.commands, folder.first, newPosition);
+
+ if (newPosition < folder.first) {
+ newPosition++
+ folder.first = folder.first + 1;
+ }
+ }
+
+ recacheFolders();
+ saveLocally();
+
+ refreshGroups();
+
+ draggedFolder = undefined;
+}
+
+function handleGroupDrag(group) {
+ timing = new Date().getTime();
+ draggedGroup = group.id.split("Group")[1];
+}
+function groupDragOverHandle(event, group) {
+ group.classList.add("goofyhovereffectlite");
+ /*
+ placeholderGroup = document.createElement('div')
+ placeholderGroup.style.animationName = 'fade'
+ placeholderGroup.style.marginTop = '41px'
+ placeholderGroup.style.marginBottom = '-35px'
+ */
+
+ event.preventDefault();
+ draggedOverGroup = group.id.split("Group")[1];
+ group.style.animationName = "";
+ group.style.animationDuration = "";
+ group.style.animationDelay = "";
+ lastDraggedOverThing = 1;
+}
+
+function handleGroupDragEnd(group) {
+ group.classList.remove("goofyhovereffectlite");
+}
+
+function handleGroupDrop(group) {
+ createCheckpoint({ recacheFolders: true });
+ refreshGroups();
+ if (new Date().getTime() - timing < 100) return;
+ let oldPosition = parseFloat(draggedGroup);
+ let newPosition = parseFloat(draggedOverGroup);
+ let newFolder = null;
+
+ if (draggedOverGroup && draggedOverFolder) {
+ botData.commands[oldPosition].folder = botData.commands[newPosition].folder;
+ } else {
+ botData.commands[oldPosition].folder = null;
+ }
+
+ lastObj = newPosition;
+ botData.commands = moveArrayElement(
+ botData.commands,
+ oldPosition,
+ newPosition,
+ );
+
+ saveLocally();
+ recacheFolders();
+ refreshGroups();
+ checkSaveStatus();
+
+ draggedOverFolder = undefined;
+ lastDraggedOverFolder = undefined;
+ stillOver = false;
+}
+
+var draggedAction;
+var draggedOverAction;
+function handleActionDrag(action) {
+ timing = new Date().getTime();
+ draggedAction = action.id.split("Action")[1];
+}
+function actionDragOverHandle(event, action) {
+ action.classList.add("flash");
+ action.style.animationName = "";
+ action.style.animationDuration = "";
+ action.style.animationDuration = '0.6s';
+ action.style.animationDelay = "";
+ event.preventDefault();
+ draggedOverAction = action.id.split("Action")[1];
+}
+function handleActionDragEnd(action) {
+ action.classList.remove("flash");
+}
+function moveArrayElement(arr, old_index, new_index) {
+ const element = arr[old_index];
+ arr.splice(old_index, 1);
+ arr.splice(new_index, 0, element);
+
+ return arr;
+}
+function handleActionDrop(action) {
+ refreshActions();
+ createCheckpoint();
+ if (new Date().getTime() - timing < 100) return;
+
+ let oldPosition = parseFloat(draggedAction);
+ let newPosition = parseFloat(draggedOverAction);
+ lastType = 1;
+
+ botData.commands[lastObj].actions = moveArrayElement(
+ botData.commands[lastObj].actions,
+ oldPosition,
+ newPosition,
+ );
+ saveLocally();
+ refreshActions();
+ checkSaveStatus()
+}
+
+refreshGroups()
+
+function setHighlightedGroup(type) {
+ let oldGroupType;
+ let trigger = 'action'
+ if (selectedGroupType == "command") {
+ oldGroupType = 1;
+ }
+ if (selectedGroupType == "event") {
+ oldGroupType = 3;
+ }
+
+ if (type == 1 || type == 2) {
+ selectedGroupType = "command";
+ prioritizeCommandOptions();
+ document.getElementById('types-EVENTS').style.background = ''
+ document.getElementById('types-COMMANDS').style.background = 'var(--accent)'
+ }
+
+ if (type == 3) {
+ trigger = 'event'
+ prioritizeEvents();
+ selectedGroupType = "event";
+ document.getElementById('types-COMMANDS').style.background = ''
+ document.getElementById('types-EVENTS').style.background = 'var(--accent)'
+ }
+
+ refreshGroups();
+}
+
+if (!Array.isArray(botData.commands)) {
+ transferProject();
+
+ location.reload();
+}
+function transferProject() {
+ botData.commands = Object.values(botData.commands);
+ saveLocally();
+ for (let command in botData.commands) {
+ botData.commands[command].actions = Object.values(
+ botData.commands[command].actions,
+ );
+ console.log(botData.commands[command].actions);
+ saveLocally();
+ for (let action of botData.commands[command].actions) {
+ try {
+ let actionBase = require(`${processPath}/AppData/Actions/${action.file}`);
+ for (let UIelement in actionBase.UI) {
+ if (UIelement.startsWith("actions")) {
+ action.data[actionBase.UI[UIelement]] = Object.values(
+ action.data[actionBase.UI[UIelement]],
+ );
+ saveLocally();
+ }
+ }
+ } catch (err) { }
+ }
+ }
+}
+
+function storeCaretPosition(element) {
+ let selection = window.getSelection();
+ if (selection.rangeCount > 0) {
+ let range = selection.getRangeAt(0);
+ let preSelectionRange = range.cloneRange();
+ preSelectionRange.selectNodeContents(element);
+ preSelectionRange.setEnd(range.startContainer, range.startOffset);
+ let caretOffset = preSelectionRange.toString().length;
+
+ element.dataset.caretOffset = caretOffset;
+ }
+}
+
+function restoreCaretPosition(element) {
+ let caretOffset = parseInt(element.dataset.caretOffset) || 0;
+ let textNode = element.firstChild;
+
+ if (textNode && textNode.nodeType === Node.TEXT_NODE) {
+ let range = document.createRange();
+ range.setStart(textNode, Math.min(caretOffset, textNode.length));
+ range.setEnd(textNode, Math.min(caretOffset, textNode.length));
+
+ let selection = window.getSelection();
+ selection.removeAllRanges();
+ selection.addRange(range);
+ }
+}
+
+function validateInputSpaces(div) {
+ storeCaretPosition(div);
+
+ var sanitizedText = div.innerText.replaceAll('\n', '')
+
+ sanitizedText = sanitizedText.substr(0, 32);
+
+ div.innerHTML = sanitizedText;
+ restoreCaretPosition(div);
+}
+
+let isTypeManagerOpen = false;
+function dropTypes() {
+ if (isTypeManagerOpen) {
+ return
+ }
+ var element = document.getElementById('edutor');
+ element.scrollTop = element.scrollHeight;
+
+ isTypeManagerOpen = true;
+ let typeManager = document.getElementById('typeOfGroup');
+ // typeManager.classList.remove('hoverable')
+ let types = {
+ messageContent: "Message Content",
+ textCommand: "Text Command",
+ slashCommand: "Slash Command",
+ message: "Message Command",
+ user: "User Command"
+ }
+ let commandType = botData.commands[lastObj].trigger
+ typeManager.onclick = () => {
+ isTypeManagerOpen = false;
+
+ typeManager.onclick = () => {
+ dropTypes();
+ }
+
+ const innerHeight = typeManager.clientHeight;
+ typeManager.style.animationDuration = "";
+ typeManager.style.setProperty("--inner-height", innerHeight + "px");
+ typeManager.style.animationName = "shrink";
+ typeManager.style.animationDuration = "200ms";
+ setTimeout(() => {
+ typeManager.innerHTML = `${types[botData.commands[lastObj].trigger]}`
+ // typeManager.classList.add('hoverable')
+ setTimeout(() => {
+ typeManager.style.animationName = 'unset'
+ typeManager.style.height = ''
+
+ highlight(document.getElementById(`Group${lastObj}`))
+ saveLocally();
+ }, 80);
+ }, 100);
+ }
+
+ for (let type in types) {
+ if (type != commandType) {
+ typeManager.innerHTML += `
+
${types[type]}
+ `
+ }
+ }
+}
+
+function declareAsRunningInFolder(event) {
+ if (!lastFolder) return;
+ event.preventDefault()
+ document.getElementById('actionbar').firstElementChild.style.opacity = '0';
+ document.getElementById('actionbar').firstElementChild.style.scale = '0.5';
+ document.getElementById('actionbar').firstElementChild.style.filter = 'blur(12px)';
+ document.getElementById('actionbar').firstElementChild.style.transition = `all var(--commonAnimation) var(--ease-strong)`
+ setTimeout(() => {
+ document.getElementById('actionbar').firstElementChild.style.display = 'none'
+ let element = document.createElement('btext');
+ element.style.opacity = '0';
+ element.style.margin = 'auto';
+ element.style.scale = '1.2';
+ element.style.filter = 'blur(12px)';
+ element.style.transition = `all var(--commonAnimation) var(--ease-strong)`
+ element.innerHTML = getString(strings.editor.release_to_add_to_folder, [cachedFolders[lastFolder].name]);
+ document.getElementById('actionbar').appendChild(element);
+
+ draggedOverFolder = lastFolder;
+ draggedOverGroup = cachedFolders[lastFolder].last + 1;
+
+ setTimeout(() => {
+ element.style.scale = '1';
+ element.style.opacity = '1';
+ element.style.filter = 'blur(0px)';
+ }, editorSettings.fastAnimation * 30);
+ }, editorSettings.commonAnimation * 100);
+}
+
+function declareAsNotRunningInFolder(event) {
+ if (!lastFolder) return;
+ event.preventDefault();
+ document.getElementById('actionbar').firstElementChild.nextElementSibling.style.scale = '1.2';
+ document.getElementById('actionbar').firstElementChild.nextElementSibling.style.opacity = '0';
+ document.getElementById('actionbar').firstElementChild.nextElementSibling.style.filter = 'blur(12px)';
+
+ setTimeout(() => {
+ document.getElementById('actionbar').firstElementChild.style.display = '';
+ setTimeout(() => {
+ document.getElementById('actionbar').firstElementChild.nextElementSibling.remove();
+ document.getElementById('actionbar').firstElementChild.style.opacity = ''
+ document.getElementById('actionbar').firstElementChild.style.scale = '';
+ document.getElementById('actionbar').firstElementChild.style.filter = '';
+ }, editorSettings.fastAnimation * 30);
+ }, editorSettings.commonAnimation * 100);
+
+ draggedOverFolder = undefined;
+}
\ No newline at end of file
diff --git a/kits/EditorBones.js b/kits/EditorBones.js
new file mode 100644
index 0000000..07263d7
--- /dev/null
+++ b/kits/EditorBones.js
@@ -0,0 +1,1909 @@
+
+let version = `4.22.0 SNAP 1 BETA`;
+const strings = getStrings();
+let loadedAutomations = [];
+
+
+const { app, ipcRenderer } = require("electron");
+let selectedGroupType = "slash";
+let copiedAction;
+let isBotOn;
+let lastFolder;
+let globalVars = {};
+let selectedActions = [];
+let serverVars = {};
+const fs = require("fs");
+setInterval(() => {
+ checkSaveStatus();
+}, 5000);
+
+const steamworks = require('steamworks.js');
+
+let client;
+try {
+ client = steamworks.init(appID);
+ // console.log('making')
+ // client.workshop.createItem(appID).then(e => {
+ // client.workshop.updateItem(e.itemId, {
+ // changeNote: "Create this",
+ // title: "Test Thing Yk",
+ // contentPath: "./Workshop_Items/Command"
+ // }).then(e => {
+ // console.log(e);
+ // client.workshop.getItem(e.itemId).then(aaaaaaaaaa => {
+ // console.log(aaaaaaaaaa)
+ // })
+ // })
+ // }).catch(err => console.log(err));
+} catch (error) {
+ console.log(error)
+ setTimeout(() => {
+ // notify('Unable to connect to steam, achievements & steam cloud will be unavailable')
+ }, 1000);
+}
+
+ipcRenderer.on('backupClose', () => {
+ document.body.style.opacity = 1;
+});
+
+let cachedActions = {};
+
+fs.readdirSync(`${processPath}/AppData/Actions`).forEach(act => {
+ try {
+ cachedActions[act] = require(`${processPath}/AppData/Actions/${act}`);
+ } catch (e) { }
+});
+
+
+
+ipcRenderer.on("botWindowStatus", (event, botOn) => {
+ if (botOn == false || botOn == true) {
+ isBotOn = true;
+ document.getElementById("botStatus").innerHTML = strings.editor.bot_states_short[1];
+ document.getElementById("turnBotOn").innerHTML = strings.editor.bot_states[0];
+ } else {
+ isBotOn = false;
+ document.getElementById("botStatus").innerHTML = strings.editor.bot_states_short[0];
+ document.getElementById("turnBotOn").innerHTML = strings.editor.bot_states[1];
+ }
+});
+
+ipcRenderer.on('aliases', (event, newAliases) => {
+ createCheckpoint();
+ botData.commands[lastObj].aliases = newAliases;
+ saveLocally();
+})
+
+ipcRenderer.on("eventSave", (event, eventData) => {
+ createCheckpoint();
+ botData.commands[lastObj].eventFile = eventData.file;
+ botData.commands[lastObj].eventData = eventData.data;
+ highlight(document.getElementById(`Group${lastObj}`));
+ checkSaveStatus();
+});
+
+function toggleBotStatus() {
+ if (!isBotOn) {
+ ipcRenderer.send("runBot");
+ } else {
+ ipcRenderer.send("shutdownBot");
+ }
+}
+
+function editAction(options) {
+ createCheckpoint();
+ checkSaveStatus();
+
+ let commandVars = [];
+
+ let variables = { temporary: [] };
+ let actionType = "text";
+ if (botData.commands[lastObj].type == "event") {
+ actionType = "event";
+ try {
+ let event = require(processPath +
+ "/AppData/Events/" +
+ botData.commands[lastObj].eventFile);
+ for (let eventVariableStorageName in event.nameSchemes) {
+ if (
+ event.preventStorage &&
+ event.preventStorage.includes(
+ event.nameSchemes[eventVariableStorageName]
+ )
+ ) {
+ } else {
+ commandVars.push(
+ botData.commands[lastObj].eventData[eventVariableStorageName]
+ );
+ }
+ }
+ } catch (err) { }
+ } else {
+ if (botData.commands[lastObj].trigger == "slashCommand") {
+ actionType = "slash";
+ if (botData.commands[lastObj].parameters) {
+ for (let parameterI in botData.commands[lastObj].parameters) {
+ let parameter = botData.commands[lastObj].parameters[parameterI];
+ commandVars.push(parameter.storeAs);
+ }
+ }
+ } else if (botData.commands[lastObj].trigger == 'user') {
+ actionType = "user";
+ } else if (botData.commands[lastObj].trigger == 'message') {
+ actionType = "message";
+ }
+ }
+
+ let endGlobal = [];
+ let endServer = [];
+ let thisGlobal = [];
+ let thisServer = [];
+
+ for (let cmd in globalVars) {
+ endGlobal = globalVars[cmd] || [];
+ }
+
+ for (let cmd in serverVars) {
+ endServer = serverVars[cmd] || [];
+ }
+
+ variables.global = endGlobal;
+ variables.server = endServer;
+
+ for (let action in botData.commands[lastObj].actions) {
+ let act = botData.commands[lastObj].actions[action];
+
+ if (action != lastAct) {
+ try {
+ let result = scrapeVars(cachedActions[act.file].UI, act.data);
+ commandVars = [...commandVars, ...result.temporary];
+ variables.global = [...variables.global, ...endGlobal, ...result.global];
+ variables.server = [...variables.server, ...endServer, ...result.server];
+ } catch (error) { console.log(error) }
+ } else {
+ try {
+ let result = scrapeVars(cachedActions[act.file].UI, act.data);
+ variables.temporary = result.temporary;
+ thisGlobal = [...thisGlobal, ...result.global];
+ thisServer = [...thisServer, ...result.server];
+ } catch (error) { console.log(error) }
+ }
+ }
+
+ variables.commandVars = commandVars;
+ variables.thisServer = thisServer;
+ variables.thisGlobal = thisGlobal;
+
+ ipcRenderer.send("editAction", {
+ action: lastAct,
+ actions: botData.commands[lastObj].actions,
+ variables: variables,
+ actionType: actionType,
+ options: (options || { picker: false })
+ });
+}
+
+ipcRenderer.on("childSave", (event, data, copied) => {
+ createCheckpoint()
+
+ botData.commands[lastObj].actions[lastAct] = data;
+ saveLocally();
+ refreshActions();
+ copiedAction = copied;
+
+ globalVars[botData.commands[lastObj].customId] = [];
+ serverVars[botData.commands[lastObj].customId] = [];
+
+ for (let act in botData.commands[lastObj].actions) {
+ let action = botData.commands[lastObj].actions[act];
+ try {
+ let UI = cachedActions[action.file].UI;
+ scrapeForVariables(UI, action.data, botData.commands[lastObj].customId);
+ } catch (err) { }
+ }
+ checkSaveStatus();
+});
+
+function openParameters() {
+ if (!botData.commands[lastObj].description) {
+ botData.commands[lastObj].description = "No Description";
+ }
+ ipcRenderer.send("editParameters", {
+ parameters: botData.commands[lastObj].parameters || [],
+ name: botData.commands[lastObj].name,
+ description: botData.commands[lastObj].description,
+ });
+}
+
+ipcRenderer.on("parametersSave", (event, data) => {
+ createCheckpoint();
+ botData.commands[lastObj].parameters = data.parameters;
+ saveLocally();
+ checkSaveStatus();
+ highlight(document.getElementById(`Group${lastObj}`));
+});
+
+ipcRenderer.on("childClose", () => {
+ document.body.style.opacity = "100%";
+});
+
+let lastHovered;
+let menu = null;
+let errorPending = false;
+var botData = JSON.parse(fs.readFileSync("./AppData/data.json", 'utf8'));
+let lastType = 0; // 0 = Command; 1 = Actions;
+let lastObj = 0;
+let lastAct = 0;
+let lastHighlighted;
+let themeColor = botData.color;
+if (ownSettings.theme == 'default') {
+ document.body.style.background = `linear-gradient(130deg, ${ownSettings.firstColor || `rgb(0, 0, 0)`}, ${ownSettings.secondColor || `rgb(18, 18, 18)`})`;
+} else {
+ document.body.style.background = `var(--main-background)`;
+}
+document.onkeydown = function (event) {
+ handleKeybind(event);
+};
+if (editorSettings.focus) {
+ if (botData.colorsVisibility) {
+ toggleColorsVisibility()
+ }
+}
+document.documentElement.style.setProperty("--highlight-color", botData.color);
+let customIDsCalculated = 0;
+let alreadyUsedIDs = {};
+let scrapeForVariables = (UI, data, cID) => {
+ for (let i in UI) {
+ try {
+ let element = UI[i];
+ if (typeof element != "string") {
+ if (
+ element.element == "storageInput" ||
+ element.element == "storage" ||
+ element.element == "store"
+ ) {
+ if (data[element.storeAs].type == "global") {
+ if (!globalVars[cID]) {
+ globalVars[cID] = [];
+ }
+ globalVars[cID].push(data[element.storeAs].value);
+ } else if (data[element.storeAs].type == "server") {
+ if (!serverVars[cID]) {
+ serverVars[cID] = [];
+ }
+
+ serverVars[cID].push(data[element.storeAs].value);
+ }
+ }
+ if (element.element == "menu") {
+ for (let menu in data[element.storeAs]) {
+ let elm = data[element.storeAs][data[element.storeAs][menu].type];
+ scrapeForVariables(
+ element.UItypes[data[element.storeAs][menu].type].UI,
+ data[element.storeAs][menu].data,
+ cID
+ );
+ }
+ }
+
+ if (element.element == "case" || element.element == "condition") {
+ if (data[element.storeAs].type == "runActions") {
+ for (let i in data[element.storeActionsAs]) {
+ let action = data[element.storeActionsAs][i];
+ if (!action.id || alreadyUsedIDs[action.id]) {
+ action.id = new Date().getTime() + customIDsCalculated;
+ customIDsCalculated++
+ }
+ alreadyUsedIDs[action.id] = true;
+ try {
+ let act = cachedActions[action.file];
+ scrapeForVariables(act.UI, action.data, cID);
+ } catch (err) { }
+ }
+ }
+ }
+
+ if (element.element == "actions") {
+ for (let i in data[element.storeAs]) {
+ let action = data[element.storeAs][i];
+ if (!action.id || alreadyUsedIDs[action.id]) {
+ action.id = new Date().getTime() + customIDsCalculated;
+ customIDsCalculated++
+ }
+ alreadyUsedIDs[action.id] = true;
+ try {
+ let act = cachedActions[action.file];
+ scrapeForVariables(act.UI, action.data, cID);
+ } catch (err) { }
+ }
+ }
+ }
+ } catch (err) {
+ }
+ }
+};
+
+
+let scrapeVars = (UI, data) => {
+ let toReturn = {
+ temporary: [],
+ server: [],
+ global: []
+ };
+ for (let i in UI) {
+ try {
+ let element = UI[i];
+ if (typeof element != "string") {
+ if (
+ element.element == "storageInput" ||
+ element.element == "storage" ||
+ element.element == "store"
+ ) {
+ if (data[element.storeAs].type == "temporary") {
+ toReturn.temporary = [...toReturn.temporary, data[element.storeAs].value];
+ }
+ if (data[element.storeAs].type == "server") {
+ toReturn.server = [...toReturn.server, data[element.storeAs].value];
+ }
+ if (data[element.storeAs].type == "global") {
+ toReturn.global = [...toReturn.global, data[element.storeAs].value];
+ }
+ }
+ if (element.element == "menu") {
+ for (let menu in data[element.storeAs]) {
+ let result = scrapeVars(element.UItypes[data[element.storeAs][menu].type].UI, data[element.storeAs][menu].data);
+ toReturn.temporary = [...toReturn.temporary, ...result.temporary];
+ toReturn.server = [...toReturn.server, ...result.server];
+ toReturn.global = [...toReturn.global, ...result.global];
+ }
+ }
+
+ if (element.element == "case" || element.element == "condition") {
+ if (data[element.storeAs].type == "runActions") {
+ for (let i in data[element.storeActionsAs]) {
+ let action = data[element.storeActionsAs][i];
+ try {
+ let act = cachedActions[action.file];
+ let result = scrapeVars(act.UI, action.data);
+ toReturn.temporary = [...toReturn.temporary, ...result.temporary];
+ toReturn.server = [...toReturn.server, ...result.server];
+ toReturn.global = [...toReturn.global, ...result.global];
+ } catch (err) { console.log(err) }
+ }
+ }
+ }
+
+ if (element.element == "actions") {
+ for (let i in data[element.storeAs]) {
+ let action = data[element.storeAs][i];
+ try {
+ let act = cachedActions[action.file];
+ let result = scrapeVars(act.UI, action.data);
+ toReturn.temporary = [...toReturn.temporary, ...result.temporary];
+ toReturn.server = [...toReturn.server, ...result.server];
+ toReturn.global = [...toReturn.global, ...result.global];
+ } catch (err) { console.log(err) }
+ }
+ }
+ }
+ } catch (err) {
+ }
+ }
+ return toReturn
+};
+
+for (let cmd in botData.commands) {
+ let command = botData.commands[cmd];
+ for (let i in command.actions) {
+ let action = command.actions[i];
+ if (!action.id || alreadyUsedIDs[action.id]) {
+ action.id = new Date().getTime() + customIDsCalculated;
+ customIDsCalculated++
+ }
+ alreadyUsedIDs[action.id] = true;
+
+ try {
+ let act = cachedActions[action.file];
+ scrapeForVariables(act.UI, action.data, command.customId);
+ } catch (err) { }
+ }
+}
+
+
+let clicks = 0;
+try {
+ clicks = settingsFS.readFileSync('./clicks', 'utf8');
+} catch (error) { }
+
+try {
+ setInterval(() => {
+ if (new Date().getHours() == 0) {
+ client.achievement.activate('MIDNIGHT')
+ }
+ if (botData.commands.length > 40) {
+ client.achievement.activate('ON_FIRE')
+ }
+ }, 60000);
+} catch (error) { }
+document.addEventListener('mousedown', () => {
+ clicks = Number(clicks);
+ if (clicks > 1250) {
+ client.achievement.activate('MADMAN')
+ }
+ if (clicks > 7500) {
+ client.achievement.activate('GRASS')
+ }
+ if (clicks > 20000) {
+ client.achievement.activate('TIMELESS')
+ }
+
+ clicks++
+
+ settingsFS.writeFileSync('./clicks', clicks.toString())
+});
+
+
+saveLocally()
+
+function refreshActions(fadeLast, dontUpdate, commandOverwrite) {
+ const toReplaceWith = lastObj;
+ lastObj = commandOverwrite || lastObj;
+
+ if (!dontUpdate) {
+ selectedActions = [];
+ document.getElementById("actionbar").innerHTML = "";
+ }
+ botData.commands[lastObj].actions = botData.commands[lastObj].actions.filter(
+ (action) => action != null
+ );
+ saveLocally();
+
+ let endHTML = "";
+ let endActions = [];
+
+ for (let a in botData.commands[lastObj].actions) {
+ let action = botData.commands[lastObj].actions[a];
+ let actionData;
+ let endAction = {
+ subtitle: "",
+ found: false,
+ file: action.file,
+ borderType: "bordercentere",
+ };
+ try {
+ actionData = cachedActions[action.file];
+ } catch (err) { }
+
+ // if (botData.commands[lastObj].actions[parseFloat(a) - 1] == undefined) {
+ // endAction.borderType = "borderbottom";
+ // } else if (botData.commands[lastObj].actions[parseFloat(a) + 1] == undefined) {
+ // endAction.borderType = "bordertop";
+ // }
+
+ if (actionData) {
+ endAction.found = true;
+ endAction.name = action.name;
+ try {
+ if (actionData.subtitle) {
+ if (typeof actionData.subtitle == "function") {
+ endAction.subtitle = actionData.subtitle(action.data, {
+ user: (user) => {
+ let translations = {
+ author: "Command Author",
+ mentioned: "Mentioned User",
+ user: "Command User",
+ messageAuthor: "Message Author",
+
+ id: "ID",
+
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["mentioned", "author", "user", "messageAuthor"];
+ if (!disabledInputTypes.includes(user.type)) {
+ return `${translations[user.type]} (${user.value || "Blank"
+ })`;
+ } else {
+ return `${translations[user.type]}`;
+ }
+ },
+ channel: (channel) => {
+ let translations = {
+ id: "Channel ID",
+ userID: "User ID",
+ command: "Command Channel",
+ user: "Command User",
+ commandAuthor: "Command Author",
+ mentionedChannel: "Mentioned Channel",
+ mentionedUser: "Mentioned User",
+
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = [
+ "command",
+ "commandAuthor",
+ "mentionedUser",
+ "mentionedChannel",
+ "user"
+ ];
+ if (!disabledInputTypes.includes(channel.type)) {
+ return `${translations[channel.type]} (${channel.value || "Blank"
+ })`;
+ } else {
+ return `${translations[channel.type]}`;
+ }
+ },
+ role: (role) => {
+ let translations = {
+ id: "ID",
+ mentioned: "Mentioned Role",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["mentioned"];
+ if (!disabledInputTypes.includes(role.type)) {
+ return `${translations[role.type]} (${role.value || "Blank"
+ })`;
+ } else {
+ return `${translations[role.type]}`;
+ }
+ },
+ guild: (guild) => {
+ let translations = {
+ current: "Current",
+ id: "ID",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["current"];
+ if (!disabledInputTypes.includes(guild.type)) {
+ return `${translations[guild.type]} (${guild.value || "Blank"})`;
+ } else {
+ return `${translations[guild.type]}`;
+ }
+ },
+ message: (message) => {
+ let translations = {
+ commandMessage: "Command Message",
+ interactionReply: "Command Reply",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["commandMessage", "interactionReply"];
+ if (!disabledInputTypes.includes(message.type)) {
+ return `${translations[message.type]} (${message.value || "Blank"
+ })`;
+ } else {
+ return `${translations[message.type]}`;
+ }
+ },
+ interaction: (interaction) => {
+ let translations = {
+ commandInteraction: "Command Interaction",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["commandInteraction"];
+ if (!disabledInputTypes.includes(interaction.type)) {
+ return `${translations[interaction.type]} (${interaction.value || "Blank"
+ })`;
+ } else {
+ return `${translations[interaction.type]}`;
+ }
+ },
+ image: (image) => {
+ let translations = {
+ file: "File",
+ url: "URL",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = [];
+ if (!disabledInputTypes.includes(image.type)) {
+ return `${translations[image.type]} (${image.value || "Blank"
+ })`;
+ } else {
+ return `${translations[image.type]}`;
+ }
+ },
+ variable: (variables) => {
+ let translations = {
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ temporary: "Temporary Variable",
+ server: "Server Variable",
+ global: "Global Variable",
+ };
+ return `${translations[variables.type]} (${variables.value || "Blank"
+ })`;
+ },
+ }, actionData);
+ } else {
+ let actionSubtitle = actionData.subtitle;
+ const subtitleRegex = /(\$\[.*?\]\$)/g;
+ endAction.subtitle = actionSubtitle.replace(
+ subtitleRegex,
+ (match, key) => {
+ let dataName = key
+ .split("$[")[1]
+ .split("]$")[0]
+ .replaceAll("*", "");
+ return action.data[dataName];
+ }
+ );
+ }
+ }
+ } catch (err) { }
+ } else {
+ endAction.name = action.name;
+ }
+
+ endAction.subtitle = endAction.subtitle?.replaceAll("<", "<");
+
+ endActions.push(endAction);
+ }
+
+ let leftSeparatorDisplay, rightSeparatorDisplay, subtitlePosition;
+
+ switch (editorSettings.subtitlePosition) {
+ case "left":
+ leftSeparatorDisplay = "none";
+ rightSeparatorDisplay = "inherit; margin-left: 5px !important;";
+ subtitlePosition = "margin-left: 5px !important; margin-right: auto;";
+ break;
+ case "right":
+ rightSeparatorDisplay = "none";
+ leftSeparatorDisplay =
+ "inherit; margin-right: 5px !important; margin-left: 10px !important;";
+ subtitlePosition = "margin-right: 0; margin-left: auto;";
+ deleteButtonStyling = "margin-left: 5px;";
+ break;
+ case "center":
+ rightSeparatorDisplay = "inherit";
+ leftSeparatorDisplay = "inherit; margin-left: 5px !important;";
+ subtitlePosition = "margin-right: 5px; margin-left: 5px;";
+ break;
+ }
+
+ if (editorSettings.focus) {
+ rightSeparatorDisplay = 'none'
+ leftSeparatorDisplay = 'none'
+ }
+
+ for (let index in endActions) {
+ let action = endActions[index];
+ let errors = "";
+
+ if (action.found == false) {
+ errors = `
+ Action Not Found!
+ `;
+ }
+ endHTML += `
+
+
+
${editorSettings.focus ? "" : "#"}${parseFloat(index) + 1}
+
${action.name.substring(0, 256)}
+ ${errors}
+
+
+
+
${action.subtitle.replaceAll("", "")}
+
+
+
+
+
+
+ `;
+ }
+
+ if (!dontUpdate) {
+ document.getElementById("actionbar").innerHTML = endHTML;
+
+ highlight(document.getElementById(`Action${lastAct}`));
+ } else {
+ return endHTML;
+ }
+ lastObj = toReplaceWith;
+}
+
+function hideAliases() {
+ let aliasBox = document.getElementById('Command_Name').nextElementSibling;
+ let commandNameBox = document.getElementById('Command_Name');
+ commandNameBox.classList.remove('rounded_less_right')
+
+ commandNameBox.style.marginRight = ''
+ commandNameBox.style.width = '100%'
+ aliasBox.style.display = 'none'
+}
+
+function showAliases() {
+ let aliasBox = document.getElementById('Command_Name').nextElementSibling;
+ let commandNameBox = document.getElementById('Command_Name');
+
+ commandNameBox.classList.add('rounded_less_right')
+
+ commandNameBox.style.width = 'var(--alias-shown-input-width)'
+ commandNameBox.style.marginRight = '0px'
+
+ aliasBox.style.width = '35px'
+ aliasBox.style.display = ''
+}
+
+let undoList = [];
+
+let redoList = [];
+
+function createCheckpoint(options) {
+ const newUndoStuff = {
+ JSON: JSON.stringify(botData.commands),
+ folders: JSON.stringify(botData.folders),
+ createdAt: Date.now(),
+ };
+
+ if (newUndoStuff.JSON == undoList[0]?.JSON) return
+
+ undoList.unshift(newUndoStuff);
+ redoList = [];
+
+ if (undoList.length > 200) {
+ undoList.splice(undoList.length - 1, 2)
+ }
+}
+
+function undo() {
+ if (areSettingsOpen) return;
+ let undoElement = undoList[0];
+
+ undoElement.JSON;
+
+ redoList.splice(0, 0, {
+ JSON: JSON.stringify(botData.commands),
+ folders: JSON.stringify(botData.folders),
+ createdAt: Date.now()
+ });
+
+ botData.commands = JSON.parse(undoElement.JSON);
+ botData.folders = JSON.parse(undoElement.folders);
+ undoList.splice(0, 1);
+ recacheFolders();
+ refreshGroups();
+ saveLocally();
+ checkSaveStatus();
+}
+
+function redo() {
+ if (areSettingsOpen) return;
+
+ let redoElement = redoList[0];
+ let oldJSON = JSON.stringify(botData.commands);
+ let oldFolders = JSON.stringify(botData.folders);
+ botData.commands = JSON.parse(redoElement.JSON);
+ botData.folders = JSON.parse(redoElement.folders);
+
+ redoElement.JSON = oldJSON;
+ redoElement.folders = oldFolders;
+
+ redoList.splice(0, 1);
+ undoList.splice(0, 0, redoElement);
+
+ recacheFolders();
+ refreshGroups();
+ saveLocally();
+ checkSaveStatus();
+}
+
+function newFolder() {
+ createCheckpoint();
+ const folderID = Number(`${new Date().getTime()}`);
+ let newFolder = {
+ name: "Folder",
+ color: null,
+ };
+
+ botData.folders[folderID] = newFolder;
+ if (Array.isArray(botData.commands[lastObj].folder)) {
+ botData.commands[lastObj].folder.push(folderID)
+ } else {
+ botData.commands[lastObj].folder = [folderID]
+ }
+
+
+ saveLocally();
+ recacheFolders();
+ refreshGroups();
+}
+let closedFolders = {};
+let cachedFolders = {};
+
+function hideEditorSpecifics() {
+ document.getElementById("infoTile").style.height = "0px";
+ document.getElementById("infoTile").style.paddingTop = "0px";
+ document.getElementById("infoTile").style.paddingBottom = "0px";
+ document.getElementById("infoTile").style.overflow = "hidden";
+ document.getElementById("infoTile").style.marginTop = "0";
+ document.getElementById('edutor').firstElementChild.classList.remove('borderbottomz')
+}
+function showEditorSpecifics(event) {
+ document.getElementById("infoTile").style.paddingTop = "0px";
+ document.getElementById("infoTile").style.paddingBottom = "0px";
+ document.getElementById("infoTile").style.marginTop = "4px";
+ document.getElementById("infoTile").style.height = "32px";
+
+ document.getElementById('edutor').firstElementChild.classList.add('borderbottomz')
+
+ if (event) {
+ hideTypeDropdown()
+ } else {
+ showTypeDropdown()
+ }
+}
+
+function hideTypeDropdown() {
+ let dropdownContainer = document.getElementById('typeDropdownContainer');
+ dropdownContainer.style.width = '0%'
+ dropdownContainer.style.display = 'none'
+ let inputContainer = document.getElementById('nameContainer');
+ inputContainer.style.width = '100%'
+}
+function showTypeDropdown() {
+ let dropdownContainer = document.getElementById('typeDropdownContainer');
+ dropdownContainer.style.width = '50%'
+ dropdownContainer.style.display = ''
+ let inputContainer = document.getElementById('nameContainer');
+ inputContainer.style.width = '50%'
+}
+
+function recacheFolders() {
+ if (!botData.folders) {
+ botData.folders = {};
+ saveLocally();
+ }
+
+ cachedFolders = {};
+ for (let f in botData.folders) {
+ let folder = botData.folders[f];
+ closedFolders[f] = folder.closed
+ cachedFolders[f] = {
+ ...folder,
+ id: f,
+ last: [],
+ first: []
+ };
+ }
+
+ let knownFoldersPlacement = {};
+
+ botData.commands.forEach((command, index) => {
+ if (!Array.isArray(command.folder) && command.folder) {
+ command.folder = [command.folder];
+ }
+
+ command.folder = Array.from(new Set(command.folder))
+ if (command.folder?.length > 10) {
+ let folder = command.folder;
+ command.folder = [folder[0], folder[1], folder[2], folder[3], folder[4], folder[5], folder[6], folder[7], folder[8], folder[9]]
+ }
+ for (let i in command.folder) {
+ if (!botData.folders[command.folder[i]]) {
+ command.folder.splice(i, 1);
+ saveLocally();
+ } else {
+ if (cachedFolders[command.folder[i]]) {
+ let commandFolder = command.folder[i];
+ if (!knownFoldersPlacement[commandFolder]) {
+ knownFoldersPlacement[commandFolder] = {};
+ }
+
+ if (knownFoldersPlacement[commandFolder].first == undefined) {
+ knownFoldersPlacement[commandFolder].first = index;
+ } else {
+ knownFoldersPlacement[commandFolder].last = index;
+ }
+ }
+ }
+ }
+ });
+
+ for (let f in cachedFolders) {
+ if (knownFoldersPlacement[f] && knownFoldersPlacement[f].first != undefined) {
+ if (knownFoldersPlacement[f] && knownFoldersPlacement[f].last == undefined) {
+ knownFoldersPlacement[f].last = knownFoldersPlacement[f]?.first;
+ }
+ cachedFolders[f] = { ...cachedFolders[f], ...knownFoldersPlacement[f] };
+ } else {
+ delete cachedFolders[f];
+ delete botData.folders[f];
+ saveLocally();
+ }
+ }
+}
+
+setTimeout(() => {
+ recacheFolders();
+ refreshGroups();
+}, 150);
+
+function refreshGroups(fadeLast, dontUpdate) {
+ let firstOnScreen = true;
+ let endHTML = "";
+ if (!dontUpdate) {
+ document.getElementById("commandbar").innerHTML = "";
+ }
+
+ let firstCompatibleGroup;
+
+ for (let cmd in botData.commands) {
+ if (!firstCompatibleGroup) {
+ try {
+ let command = botData.commands[cmd];
+
+ if (command.type == "action" && selectedGroupType == "command") {
+ firstCompatibleGroup = cmd;
+ } else if (command.type == "event" && selectedGroupType == "event") {
+ firstCompatibleGroup = cmd;
+ }
+ } catch (error) { }
+ }
+ }
+
+ let firstGroup;
+ var delay = 0;
+
+ for (let cmd in botData.commands) {
+ try {
+ if (!firstCompatibleGroup) {
+ document.getElementById("actionbar").innerHTML = "";
+ }
+ let groupType = botData.commands[cmd].type;
+ let endType;
+ if (groupType == "action") {
+ endType = "command";
+ } else {
+ endType = "event";
+ }
+
+ if (endType == selectedGroupType) {
+ if (!firstGroup) {
+ firstGroup = cmd;
+ }
+
+ let additional = "";
+ let endAdditional = "";
+ let folderNesting = false;
+ if (Array.isArray(botData.commands[cmd].folder)) {
+ for (let f in botData.commands[cmd].folder) {
+ if (cachedFolders[botData.commands[cmd].folder[f]]?.first == cmd) {
+ if (botData.commands[cmd].folder[f] != botData.commands[cmd].folder[0]) {
+ folderNesting = true;
+ } else {
+ folderNesting = false;
+ }
+
+ let folder = botData.commands[cmd].folder[f];
+ additional += `
+
+
+
+
${cachedFolders[folder].name.replaceAll("<", "<")}
+
+
↑
+
+
+ `;
+ marginTop = "0px";
+ firstOnScreen = false;
+ }
+
+ if (cachedFolders[botData.commands[cmd].folder[f]]?.last == cmd) {
+ endAdditional += `
`;
+ firstOnScreen = false;
+ }
+ }
+ }
+
+ delay++;
+ let preDeco = ``;
+
+ if (!editorSettings.hideCommandInvokers) {
+ let commandTriggerMap = {
+ textCommand: botData.prefix,
+ slashCommand: "/",
+ }
+
+ preDeco = commandTriggerMap[botData.commands[cmd].trigger] || ``;
+ }
+
+ let groupDecoration = ``;
+ endHTML += `
+ ${additional}
+
+
${preDeco}
+
+ ${botData.commands[cmd].name.substring(0, 24)}${botData.commands[cmd].name.length > 23 ? "..." : ""}
+
${botData.commands[cmd].actions.length} Actions ${groupDecoration}
+
+ ${endAdditional}
+ `;
+ }
+ } catch (error) {
+ botData.commands.splice(cmd, 1);
+ }
+ }
+
+ if (!dontUpdate) {
+ document.getElementById("commandbar").innerHTML = endHTML;
+ } else {
+ return endHTML;
+ }
+
+ let editor = document.getElementById("edutor");
+ if (delay == 0) {
+ editor.style.scale = "0.3";
+ editor.style.opacity = "0";
+ setTimeout(() => {
+ editor.style.scale = "0";
+ }, 150);
+ } else {
+ editor.style.scale = "1";
+ setTimeout(() => {
+ editor.style.scale = "1";
+ }, 150);
+ editor.style.opacity = "1";
+ }
+
+ if (document.getElementById(`Group${lastObj}`)) {
+ try {
+ highlight(document.getElementById(`Group${lastObj}`));
+ } catch (err) {
+ highlight(document.getElementById(`Group${firstCompatibleGroup}`));
+ }
+ } else {
+ highlight(document.getElementById(`Group${firstCompatibleGroup}`));
+ }
+}
+
+function recalculateFolderHeight(starterID, repeated) {
+ if (Array.isArray(botData.commands[cachedFolders[starterID].first].folder)) {
+ botData.commands[cachedFolders[starterID].first].folder.forEach((id) => {
+ if (id != starterID) return;
+ let folder = document.getElementById(`${id}`);
+ let folderContent = document.getElementById(`${id}content`);
+
+ if (closedFolders[id]) {
+ let height = folderContent.clientHeight;
+ folderContent.style.height = height + 'px';
+ folderContent.style.overflow = 'hidden';
+ folderContent.classList.add('closedFolder')
+
+
+ setTimeout(() => {
+ folderContent.style.height = '0px'
+ }, 10);
+ } else {
+ let heightGuesser = document.createElement('div');
+ heightGuesser.innerHTML = folderContent.innerHTML;
+ heightGuesser.style.opacity = '0';
+ document.body.appendChild(heightGuesser);
+ let height = heightGuesser.clientHeight;
+ folderContent.classList.remove('closedFolder')
+ heightGuesser.remove();
+
+ setTimeout(() => {
+ folderContent.style.height = (height + 0) + 'px';
+ setTimeout(() => {
+ folderContent.style.height = 'auto'
+ }, editorSettings.commonAnimation * 100);
+ }, 10);
+ }
+ })
+ }
+
+ setTimeout(() => {
+ if (repeated) return;
+ recalculateFolderHeight(id, true)
+ }, 30);
+}
+
+function toggleFolderVisibility(id, button) {
+ createCheckpoint({ recacheFolders: true });
+ if (!closedFolders[id]) {
+ botData.folders[id].closed = true;
+ closedFolders[id] = true;
+
+ setTimeout(() => {
+ button.style.transition = 'all 0.5s cubic-bezier(.41,-0.58,.48,1.53)'
+ button.style.rotate = '180deg'
+ saveLocally();
+ checkSaveStatus();
+ }, 10);
+ } else {
+ botData.folders[id].closed = false;
+ closedFolders[id] = false;
+
+ setTimeout(() => {
+ button.style.rotate = '359deg'
+ }, 10);
+ setTimeout(() => {
+ button.style.transition = 'all 0s ease'
+ setTimeout(() => {
+ button.style.rotate = '0deg'
+ setTimeout(() => {
+ button.style.transition = 'all 0.5s cubic-bezier(.41,-0.58,.48,1.53)'
+ }, 10);
+ }, 10);
+ }, 500);
+
+ setTimeout(() => {
+ saveLocally();
+ checkSaveStatus();
+ }, editorSettings.commonAnimation * 100);
+ }
+
+ recalculateFolderHeight(id);
+}
+
+function highlightFolder(id) {
+ hideTypeDropdown();
+ lastType = 2;
+ hideAliases()
+ hideEditorSpecifics();
+ try {
+ document.getElementById(`Group${lastObj}`).classList.remove('highlighted')
+ if (botData.commands[lastObj].color != undefined) {
+ document.getElementById(`Group${lastObj}`).style.background = botData.commands[lastObj].color.split(")") + " 0.09)";
+ } else {
+ document.getElementById(`Group${lastObj}`).style.background = "";
+ }
+ } catch (err) { }
+ lastObj = undefined;
+ if (editorSettings.focus) {
+ document.getElementById('actionsOf').innerHTML = ``
+ document.getElementById('actionbar').innerHTML = ''
+ } else {
+ document.getElementById('actionsOf').innerHTML = strings.editor.folder_no_actions;
+ document.getElementById('actionbar').classList.add('flexbox')
+ document.getElementById('actionbar').innerHTML = `
+
+ `
+ }
+
+ if (lastFolder) {
+ document.getElementById(lastFolder).classList.remove('highlighted')
+ if (cachedFolders[lastFolder]?.color) {
+ let color = cachedFolders[lastFolder].color.split(")");
+ document.getElementById(lastFolder).style.background = `${color} 0.10)`;
+ } else {
+ document.getElementById(lastFolder).style.background = ``;
+ }
+ }
+
+ lastFolder = id;
+ document.getElementById(lastFolder).classList.add('highlighted')
+
+ if (cachedFolders[id].color) {
+ let color = cachedFolders[lastFolder].color.split(")");
+ document.getElementById(id).style.background = `${color} 0.15)`;
+ } else {
+ document.getElementById(id).style.background = `var(--accent)`;
+ }
+
+ document.getElementById("Command_Description").value = botData.folders[id].description || "";
+
+ lastHighlightedType = 2;
+
+ document.getElementById("groupType").innerText = strings.editor.command_name_labels.folder;
+ document.getElementById("Command_Name").innerText = cachedFolders[lastFolder].name;
+ document.getElementById('actionbar').style.background = ''
+ document.getElementById('actiontoolbar').style.background = ''
+}
+
+function colorize(element, at, type) {
+ let color;
+ if (element.id.startsWith("Group")) {
+ if (!botData.commands[at].color) return;
+ color = botData.commands[at].color.split(")");
+ } else {
+ if (!cachedFolders[at]?.color) return;
+ color = cachedFolders[at].color.split(")");
+ }
+
+ let intensity;
+
+ if (element.id.startsWith("Group")) {
+ switch (type) {
+ case 1:
+ intensity = '0.18'
+ break
+
+ case 2:
+ if (lastObj == at) {
+ intensity = '0.15'
+ } else {
+ intensity = '0.09'
+ }
+ break
+
+ case 3:
+ intensity = '0.20'
+ break
+
+ case 4:
+ if (lastObj == at) {
+ intensity = '0.17'
+ } else {
+ intensity = '0.9'
+ }
+ break
+ }
+ element.style.background = `${color} ${intensity})`;
+ } else {
+ switch (type) {
+ default:
+ // hover
+ intensity = "0.15";
+ break;
+
+ case 2:
+ // hover leave
+ if (lastFolder == at) {
+ intensity = "0.20";
+ } else {
+ intensity = "0.1";
+ }
+ break;
+
+ case 3:
+ intensity = "0.25";
+ break;
+
+ case 4:
+ intensity = "0.10";
+ break;
+ }
+ element.style.background = `${color} ${intensity})`;
+ }
+
+}
+
+let commandParameters = document.getElementById("commandParameters");
+let groupOptions = document.getElementById("commandOptions");
+let groupEvents = document.getElementById("groupEvents");
+function resetElements() {
+ groupOptions.style.width = ``;
+ groupOptions.style.opacity = ``;
+ groupOptions.style.padding = ``;
+
+ groupEvents.style.padding = "0px";
+ groupEvents.style.opacity = "0%";
+ groupEvents.style.width = "0%";
+ groupEvents.innerHTML = ``;
+
+ commandParameters.style.padding = ``;
+ commandParameters.style.width = ``;
+ commandParameters.style.marginRight = ``;
+ commandParameters.style.opacity = ``;
+}
+
+resetElements();
+
+function prioritizeCommandOptions() {
+ resetElements();
+
+ commandParameters.style.width = `0%`;
+ commandParameters.style.padding = `0px`;
+ commandParameters.style.opacity = `0%`;
+ commandParameters.style.marginRight = "0px";
+
+ groupOptions.style.width = "calc(100% - 4px)";
+ groupOptions.style.marginRight = `0px`;
+}
+
+function prioritizeEvents() {
+ resetElements();
+
+ groupOptions.style.width = `0%`;
+ groupOptions.style.paddingTop = `0px`;
+ groupOptions.style.paddingBottom = `0px`;
+ groupOptions.style.opacity = `0%`;
+ groupOptions.style.marginRight = `0px`;
+ commandParameters.style.width = `0%`;
+ commandParameters.style.padding = `0px`;
+ commandParameters.style.opacity = `0%`;
+ commandParameters.style.marginRight = "0px";
+
+ groupEvents.style.padding = "";
+ groupEvents.style.width = "calc(100% - 4px)";
+ groupEvents.style.opacity = "";
+
+ try {
+ groupEvents.innerHTML = `
+ ${getString(strings.editor.event, [require(`${processPath}/AppData/Events/${botData.commands[lastObj].eventFile}`).name])}
+
+ `
+ } catch (err) {
+ groupEvents.innerHTML = `${getString(strings.editor.event, [strings.editor.none])}
`;
+ }
+}
+
+function returnToNormal() {
+ resetElements();
+}
+
+let lastHighlightedType = 0; // 0 = Group - 1 = Action - 2 = Folder
+
+let isHoldingCTRL = false;
+
+document.addEventListener('keydown', (key) => {
+ isHoldingCTRL = key.ctrlKey
+})
+document.addEventListener('keyup', (key) => {
+ isHoldingCTRL = key.ctrlKey
+})
+
+async function highlight(element) {
+ if (lastFolder) {
+ showTypeDropdown()
+ document.getElementById('actionbar').classList.remove('flexbox');
+ try {
+ if (cachedFolders[lastFolder].color) {
+ let color = cachedFolders[lastFolder].color.split(")");
+ document.getElementById(lastFolder).style.background = `${color} 0.10)`;
+ } else {
+ document.getElementById(lastFolder).style.background = "";
+ }
+ document.getElementById(lastFolder).classList.remove('highlighted');
+ } catch (err) { }
+ lastFolder = undefined;
+ }
+ try {
+ if (element.id.startsWith("Group")) {
+ selectedActions = []
+ lastType = 0;
+ setTimeout(() => {
+ lastHighlightedType = 0;
+ }, 1500);
+
+ showEditorSpecifics(
+ botData.commands[element.id.split("Group")[1]].type == "event"
+ );
+ try {
+ document.getElementById(`Group${lastObj}`).classList.remove('highlighted');
+
+ if (botData.commands[lastObj].color != undefined) {
+ document.getElementById(`Group${lastObj}`).style.background = botData.commands[lastObj].color.split(")") + " 0.09)";
+ } else {
+ document.getElementById(`Group${lastObj}`).style.background = "";
+ }
+ } catch (err) { }
+
+ element.style.background = "var(--accent)";
+ lastObj = element.id.split("Group")[1];
+
+ document.getElementById("Command_Name").innerText = botData.commands[lastObj].name;
+ document.getElementById("Command_Description").value = botData.commands[lastObj].description || "";
+
+ if (!editorSettings.focus) {
+ document.getElementById("actionsOf").innerHTML = getString(strings.editor.actions_of, [botData.commands[lastObj].name]);
+ } else {
+ document.getElementById("actionsOf").innerHTML = `${botData.commands[lastObj].name}`;
+ }
+
+
+ if (botData.commands[lastObj].color != undefined) {
+ element.style.background = botData.commands[lastObj].color.split(")") + " 0.15)";
+ }
+
+ refreshActions();
+ let group = botData.commands[lastObj];
+
+ if (botData.commands[lastObj].type == "action") {
+ if (botData.commands[lastObj].trigger != 'slashCommand') {
+ prioritizeCommandOptions();
+ }
+
+ document.getElementById('requiredPermissions').innerHTML = group.boundary?.limits.length || strings.misc.none;
+
+ switch (botData.commands[lastObj].trigger) {
+ case "slashCommand":
+ resetElements();
+ hideAliases();
+ document.getElementById('parameterCount').innerHTML = group.parameters?.length || strings.misc.none;
+ break;
+ case "textCommand":
+ showAliases();
+ break;
+ case "messageContent":
+ showAliases();
+ break;
+ case "message":
+ hideAliases();
+ break
+ case "user":
+ hideAliases();
+ break
+ }
+ } else {
+ prioritizeEvents();
+ hideAliases();
+ }
+
+ document.getElementById("groupType").innerText = strings.editor.command_name_labels[botData.commands[lastObj].trigger];
+
+ if (editorSettings.groupColorAppliesToActions == 'On') {
+ if (!botData.commands[lastObj].color) {
+ document.getElementById('actionbar').style.background = ''
+ document.getElementById('actiontoolbar').style.background = ''
+ } else {
+ document.getElementById('actionbar').style.background = `${botData.commands[lastObj].color.split(')')} 0.10)`
+ document.getElementById('actiontoolbar').style.background = `${botData.commands[lastObj].color.split(')')} 0.08)`
+ }
+ }
+
+ let typeManager = document.getElementById("typeOfGroup");
+ let types = {
+ messageContent: "Message Content",
+ textCommand: "Text Command",
+ slashCommand: "Slash Command",
+ message: "Message Command",
+ user: "User Command"
+ };
+
+ if (isTypeManagerOpen) {
+ typeManager.onclick();
+ } else {
+ typeManager.onclick = () => {
+ dropTypes();
+ };
+ }
+
+ typeManager.innerHTML = `${types[botData.commands[lastObj].trigger] || "No Type Available"}`
+
+ lastHighlightedType = 0;
+
+ let r, g, b;
+
+ let command = botData.commands[lastObj];
+ document.getElementById(`Group${lastObj}`).classList.add('highlighted');
+ } else {
+ lastHighlightedType = 1;
+ lastType = 1;
+ try {
+ if (!isHoldingCTRL) {
+ document.getElementById(`Action${lastAct}`).style.background = "";
+ document.getElementById(`Action${lastAct}`).classList.remove('highlighted');
+ }
+ } catch (err) {}
+
+ if (isHoldingCTRL && lastAct != element.id.split("Action")[1] && selectedActions.length == 0) {
+ selectedActions.push(lastAct)
+ }
+
+ lastAct = element.id.split("Action")[1];
+
+ if (!isHoldingCTRL) {
+ if (selectedActions.length != 0) {
+ refreshActions()
+ }
+ selectedActions = [];
+ document.getElementById(`Action${lastAct}`).classList.add('highlighted');
+ } else {
+ let eID = element.id.split("Action")[1];
+ if (selectedActions.length == 0 && eID != lastAct) {
+ selectedActions.push(lastAct)
+ }
+ if (selectedActions.includes(eID)) {
+ element.classList.remove('highlighted');
+ selectedActions.splice(selectedActions.indexOf(eID), 1)
+ } else {
+ selectedActions.push(eID);
+ document.getElementById(`Action${lastAct}`).classList.add('highlighted');
+ }
+ }
+ }
+ } catch (err) {}
+}
+
+(Element.prototype.appendBefore = function (element) {
+ element.parentNode.insertBefore(this, element);
+}),
+ false;
+(Element.prototype.appendAfter = function (element) {
+ element.parentNode.insertBefore(this, element.nextSibling);
+}),
+ false;
+
+let timesSaved = 0;
+
+function setCommandColor(r, g, b) {
+ client.achievement.activate('RAINBOWS')
+ if (lastFolder) {
+ if (r == '255' && g == '255' && b == '255') {
+ botData.folders[lastFolder].color = null
+ cachedFolders[lastFolder].color = null
+ } else {
+ botData.folders[lastFolder].color = `rgb(${r}, ${g}, ${b})`
+ cachedFolders[lastFolder].color = `rgb(${r}, ${g}, ${b})`
+ }
+ saveLocally();
+ checkSaveStatus();
+ colorize(document.getElementById(lastFolder), lastFolder, 1);
+ } else {
+ if (r == '255' && g == '255' && b == '255') {
+ botData.commands[lastObj].color = null
+ } else {
+ botData.commands[lastObj].color = `rgb(${r}, ${g}, ${b})`
+ }
+ saveLocally();
+ checkSaveStatus();
+
+ colorize(document.getElementById(`Group${lastObj}`), lastObj, 1);
+ }
+}
+
+function savePrj() {
+ timesSaved++
+ try {
+ fs.writeFileSync(
+ botData.prjSrc + "/AppData/data.json",
+ JSON.stringify(botData, null, 2)
+ );
+ } catch (err) { }
+
+
+ document.getElementById("saveStatus").style.filter = `blur(12px)`
+
+ setTimeout(() => {
+ document.getElementById("saveStatus").innerText = strings.editor.save_states[1];
+ document.getElementById("saveStatus").style.filter = `blur(0px)`
+ }, editorSettings.fastAnimation * 100);
+ lastKnownStatus = true;
+
+ document.getElementById("saveIcon").style.transform = '';
+
+ saveLocally();
+ if (timesSaved > 40) {
+ client.achievement.activate('SAFETY_FIRST');
+ }
+
+ if (ownSettings.restartOnSave != 'Off' && isBotOn) {
+ toggleBotStatus()
+ setTimeout(() => {
+ toggleBotStatus()
+ }, 500);
+ }
+}
+
+let lastKnownStatus;
+function checkSaveStatus() {
+ document.getElementById("saveStatus").style.transition = `all 0.${editorSettings.fastAnimation}s ease`
+
+ if (fs.readFileSync("./AppData/data.json", "utf8") == fs.readFileSync(`${botData.prjSrc}/AppData/data.json`, "utf8")) {
+ document.getElementById("saveIcon").style.transform = '';
+ if (lastKnownStatus == true) return true;
+
+ lastKnownStatus = true
+
+ document.getElementById("saveStatus").style.filter = `blur(12px)`
+
+ setTimeout(() => {
+ document.getElementById("saveStatus").innerText = strings.editor.save_states[1];
+ document.getElementById("saveStatus").style.filter = `blur(0px)`
+ }, editorSettings.fastAnimation * 100);
+
+ return true;
+ } else {
+ document.getElementById("saveIcon").style.transform = 'translateY(12px)';
+ if (lastKnownStatus == false) return false;
+ lastKnownStatus = false;
+ document.getElementById("saveStatus").style.filter = `blur(12px)`
+
+ setTimeout(() => {
+ document.getElementById("saveStatus").innerText = strings.editor.save_states[0];
+ document.getElementById("saveStatus").style.filter = `blur(0px)`
+ }, editorSettings.fastAnimation * 100);
+
+ return false;
+ }
+}
+
+
+function openEvent() {
+ try {
+ ipcRenderer.send("editEvent", {
+ name: require(processPath +
+ "/AppData/Events/" +
+ botData.commands[lastObj].eventFile).name,
+ event: botData.commands[lastObj].eventFile,
+ data: botData.commands[lastObj].eventData,
+ });
+ } catch (err) {
+ ipcRenderer.send("editEvent", {
+ name: "Bot Ready",
+ event: "bot_ready.js",
+ data: [""],
+ });
+ }
+}
+
+function openPermissionEditor() {
+ ipcRenderer.send("openPerms", botData.commands[lastObj]);
+ ipcRenderer.once("boundaryData", (event, data) => {
+ createCheckpoint()
+ botData.commands[lastObj].boundary = data;
+ highlight(document.getElementById(`Group${lastObj}`));
+ });
+}
+
+function setGroupColor(elm) {
+
+ createCheckpoint();
+ if (lastFolder) {
+ if (elm == null) {
+ botData.folders[lastFolder].color = null;
+ cachedFolders[lastFolder].color = null;
+ saveLocally();
+ document.getElementById(lastFolder).classList.remove('coloredAction')
+ document.getElementById(lastFolder).classList.add('action')
+ document.getElementById(lastFolder).style.background = `#ffffff25`
+ return;
+ }
+ let color = elm.style.background;
+ cachedFolders[lastFolder].color = color;
+ botData.folders[lastFolder].color = color;
+ document.getElementById(lastFolder).classList.remove('action')
+ document.getElementById(lastFolder).classList.add('coloredAction')
+ saveLocally();
+
+ document.getElementById(lastFolder).style.background = `${cachedFolders[lastFolder].color.split(')')} 0.20`;
+ recacheFolders()
+ } else {
+ const last = `${lastObj}`;
+ if (elm == null) {
+ botData.commands[lastObj].color = undefined;
+ refreshGroups();
+ return;
+ }
+ let color = elm.style.background;
+ botData.commands[lastObj].color = color;
+ refreshGroups();
+ saveLocally();
+ }
+
+ if (editorSettings.focus) {
+ toggleColorsVisibility()
+ }
+
+ client.achievement.activate('RAINBOWS');
+}
+
+function toggleColorsVisibility() {
+ return
+ if (botData.colorsVisibility == undefined) {
+ botData.colorsVisibility = false;
+ }
+ if (botData.colorsVisibility == true) {
+ document.getElementById("colorsSelector").style.width = "0%";
+ document.getElementById("colorsSelector").style.marginLeft = "-10px";
+ document.getElementById("colorsSelector").style.paddingLeft = "0px";
+ document.getElementById("colorsSelector").style.paddingRight = "0px";
+
+ setTimeout(() => {
+ document.getElementById("colorsSelector").style.marginLeft = "";
+ }, 250);
+ botData.colorsVisibility = false;
+ } else {
+ document.getElementById("colorsSelector").style.marginLeft = "";
+ document.getElementById("colorsSelector").style.width = "calc(100% - 55px)";
+ document.getElementById("colorsSelector").style.paddingLeft = "3px";
+ document.getElementById("colorsSelector").style.paddingRight = "3px";
+ setTimeout(() => {
+ document.getElementById("colorsSelector").style.width = "calc(100% - 55px - 10px)";
+ }, 250);
+ botData.colorsVisibility = true;
+ }
+ saveLocally();
+}
+
+function saveLocally() {
+ fs.writeFileSync(
+ "./AppData/data.json",
+ JSON.stringify(botData, null, 2)
+ );
+
+
+ document.getElementById("saveStatus").innerText = "Saved";
+ document.getElementById("saveIcon").style.transform = '';
+}
+
+let lastNotification;
+let handlingLastNotification = false;
+
+async function notify(text) {
+ if (lastNotification) {
+ await new Promise(res => {
+ lastNotification.style.opacity = '0'
+ lastNotification.style.scale = '2.2'
+ res();
+
+ setTimeout(() => {
+ lastNotification.remove();
+ }, 100);
+ })
+ }
+ let popup = document.createElement('div')
+ popup.style.position = 'fixed'
+ document.body.appendChild(popup);
+
+ popup.innerHTML = `${text}`;
+ popup.style.marginTop = ''
+ popup.style.marginRight = '-100vw'
+ popup.style.padding = '10px'
+ popup.style.borderRadius = '9px'
+ popup.style.transition = 'all 0.2s ease, margin-top 0.3s cubic-bezier(.4,.16,.14,1.4), margin-left 0.3s cubic-bezier(.4,.16,.14,1.4), height 0.3s ease, scale 0.4s cubic-bezier(.4,.16,.14,1.4)'
+ popup.style.backdropFilter = 'blur(12px)'
+ popup.style.background = '#ffffff10'
+ popup.style.scale = '0.2'
+
+ setTimeout(() => {
+ popup.style.scale = '1'
+ lastNotification = popup;
+ }, 100);
+
+
+ setTimeout(() => {
+ popup.style.opacity = '0'
+ popup.style.scale = '2.2'
+ setTimeout(() => {
+ popup.remove()
+ }, 300);
+ }, 4000);
+
+ return popup
+}
+
+let usedCustomIds = [];
+for (let command in botData.commands) {
+ if (botData.commands[command]) {
+ if (usedCustomIds.includes(botData.commands[command].customId)) {
+ botData.commands[command].customId =
+ parseFloat(new Date().getTime()) + parseFloat(usedCustomIds.length);
+ } else {
+ usedCustomIds.push(botData.commands[command].customId);
+ }
+ }
+}
+saveLocally();
+
+async function closeEditor() {
+ if (checkSaveStatus() == false) {
+ let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: strings.editor.exit_unsaved_confirmation }, 'deletionModalInteraction');
+ if (!keepGoing) return;
+ }
+ ipcRenderer.send("close");
+}
+
+
+async function uploadToWorkshop(content, type) {
+ if (type == 0) {
+ const customId = botData.commands[content].customId;
+ let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: `Are you sure you want to upload ${botData.commands[content].name} to the Steam Workshop?` }, 'deletionModalInteraction');
+ if (!keepGoing) return;
+
+ client.workshop.createItem(appID).then(e => {
+ client.workshop.updateItem(e.itemId, {
+ changeNote: "Add content",
+ title: `${botData.commands[lastObj].name} (${botData.commands[lastObj].type == 'action' ? "command" : "event"})`,
+ contentPath: "./Workshop_Items/Command"
+ }).then(e => {
+ console.log(e);
+ client.workshop.getItem(e.itemId).then(aaaaaaaaaa => {
+ console.log(aaaaaaaaaa)
+ })
+ })
+ }).catch(err => console.log(err));
+
+ const fse = require('fs-extra');
+
+ try {
+ if (!fs.existsSync(`./Workshop_Items/${customId}`)) {
+ fse.copySync('./Workshop_Items/Command', `./Workshop_Items/${customId}`)
+ }
+ } catch (error) {
+ return notify('Something went wrong, sorry!');
+ }
+
+ try {
+ client.workshop.createItem().then(workshopItem => {
+ console.log('created!')
+ client.workshop.updateItem(workshopItem.itemId, {
+ contentPath: `./Workshop_Items/${customId}`,
+ tags: ["383217"]
+ })
+ });
+ } catch (error) {
+ console.log(error);
+ notify('Upload Failed..');
+ }
+ }
+}
+
+function resizeCommands() {
+ let ids = ['commandbar', 'edutor', 'actionbar', 'toggleSizing'];
+ ids.forEach(id => {
+ document.getElementById(id).style.transition = `all 0.${editorSettings.commonAnimation}s cubic-bezier(.17,.67,0,1.38)`
+ })
+
+ if (!botData.collapsed) {
+ document.getElementById('commandbar').style.height = 'var(--collapsedCommandContainerHeight)'
+ document.getElementById('actionbar').style.height = 'var(--expandedActionContainerHeight)'
+ document.getElementById('toggleSizing').style.rotate = '90deg'
+ botData.collapsed = true;
+ } else {
+ document.getElementById('commandbar').style.height = 'var(--commandContainerHeight)'
+ document.getElementById('actionbar').style.height = 'var(--actionContainerHeight)'
+ document.getElementById('edutor').style.height = ''
+ document.getElementById('edutor').style.width = ''
+ document.getElementById('edutor').style.marginBottom = ''
+ botData.collapsed = false;
+ document.getElementById('toggleSizing').style.rotate = '-90deg'
+ }
+ saveLocally();
+ checkSaveStatus();
+}
+
+resizeCommands();
+resizeCommands();
+
+// document.getElementById('windowControls').appendBefore(document.getElementById('logo_toolbar'))
\ No newline at end of file
diff --git a/kits/EditorComponents.js b/kits/EditorComponents.js
new file mode 100644
index 0000000..2366b31
--- /dev/null
+++ b/kits/EditorComponents.js
@@ -0,0 +1,836 @@
+let lastHoveredContainer;
+let draggedOverMenu, draggedPosition, draggedOverPosition;
+let timing;
+let customIDsCalculated = 0;
+
+function addObjectToMenu(element, option, hlLast) {
+ setTimeout(() => {
+ document.getElementById(actionUI[element].storeAs).classList.remove('flexbox');
+ }, editorSettings.commonAnimation * 100);
+
+ if (actionUI[element].max > action.data[actionUI[element].storeAs].length) {
+ action.data[actionUI[element].storeAs].push({
+ type: option,
+ data: actionUI[element].UItypes[option].data,
+ });
+ }
+ refreshMenuItems(element, true, hlLast ? true : false);
+ document.getElementById(`${element}AddButton`).style.transition = `all 0.${editorSettings.commonAnimation}s ease`
+
+ if (actionUI[element].max != 1) {
+ document.getElementById(`${element}AddButton`).style.transform = "rotate(360deg)";
+ setTimeout(() => {
+ document.getElementById(`${element}AddButton`).style.transform = "rotate(0deg)";
+ document.getElementById(`${element}AddButton`).style.transition = `all 0s ease`
+ }, editorSettings.commonAnimation * 200);
+ }
+
+ if (editorSettings.editMenusOnCreation) {
+ openPopupOption(action.data[actionUI[element].storeAs].length - 1, element, { picker: true });
+ }
+}
+
+function recacheOwnVariables() {
+ let rescraped = scrapeForVariables(actionUI, action.data, true);
+
+ tempVars = rescraped.temp;
+ thisGlobal = rescraped.global;
+ thisServer = rescraped.server;
+}
+
+let scrapeForVariables = (UI, data, pullTemp) => {
+ let localGlobal = [];
+ let localServer = [];
+ let localTemp = [];
+
+ try {
+ for (let i in UI) {
+ let element = UI[i];
+ if (element.element == 'storageInput' || element.element == 'storage' || element.element == 'store') {
+ if (data[element.storeAs].type == 'global') {
+ localGlobal.push(data[element.storeAs].value);
+ } else if (data[element.storeAs].type == 'server') {
+ localServer.push(data[element.storeAs].value);
+ } else if (data[element.storeAs].type == 'temporary' && (pullTemp == undefined || pullTemp == true)) {
+ localTemp.push(data[element.storeAs].value);
+ }
+ }
+
+ if (element.element == 'menu') {
+ for (let menu in data[element.storeAs]) {
+ let scraped = scrapeForVariables(element.UItypes[data[element.storeAs][menu].type].UI, data[element.storeAs][menu].data, element.UItypes[data[element.storeAs][menu].type].pullVariables);
+ localTemp = [...localTemp, ...scraped.temp]
+ localServer = [...localServer, ...scraped.server]
+ localGlobal = [...localGlobal, ...scraped.global]
+ }
+ }
+
+ if (element.element == "case" || element.element == "condition") {
+ if (data[element.storeAs].type == "runActions") {
+ for (let i in data[element.storeActionsAs]) {
+ let action = data[element.storeActionsAs][i];
+ try {
+ let act = allActions[action.file];
+ let scraped = scrapeForVariables(act.UI, action.data);
+ localTemp = [...localTemp, ...scraped.temp]
+ localServer = [...localServer, ...scraped.server]
+ localGlobal = [...localGlobal, ...scraped.global]
+ } catch (err) { }
+ }
+ }
+ }
+
+ if (element.element == 'actions') {
+ for (let i in data[element.storeAs]) {
+ let action = data[element.storeAs][i];
+ try {
+ let act = allActions[action.file];
+ let scraped = scrapeForVariables(act.UI, action.data);
+ localTemp = [...localTemp, ...scraped.temp]
+ localServer = [...localServer, ...scraped.server]
+ localGlobal = [...localGlobal, ...scraped.global]
+ } catch (err) { }
+ }
+ }
+ }
+ } catch (err) { }
+ return { global: localGlobal, server: localServer, temp: localTemp }
+}
+
+
+function openPopupOption(object, index) {
+ let vars = scrapeForVariables(actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].UI, action.data[actionUI[index].storeAs][object].data, true);
+
+ let data = action.data[actionUI[index].storeAs][object].data;
+ if (actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].inheritData == true) {
+ data = action.data;
+ }
+
+ ipcRenderer.send(`${time}`, {
+ event: "openCustom",
+ data,
+ UI: actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].UI,
+ name: actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].name,
+ variables: {
+ commandVars: [...commandVars, ...tempVars],
+ temporary: vars.temp,
+ server: [...serverVars],
+ global: [...globalVars],
+ thisGlobal: vars.global,
+ thisServer: vars.server
+ },
+ actionType: actionType,
+ });
+
+ ipcRenderer.once("menuData", (event, data, copied) => {
+ if (actionUI[index].UItypes[action.data[actionUI[index].storeAs][object].type].inheritData) {
+ action.data = data;
+ } else {
+ action.data[actionUI[index].storeAs][object].data = data;
+ }
+ recacheOwnVariables();
+ refreshMenuItems(index);
+ });
+}
+
+
+function editAction(at, actionNumber, options) {
+ let vars = scrapeForVariables(ipcActionCache[action.data[at][actionNumber].file].UI, action.data[at][actionNumber]);
+ let customId = new Date().getTime();
+ ipcRenderer.send("editAction", {
+ event: "openAction",
+ variables: {
+ commandVars: vars.temp,
+ temporary: [...commandVars, ...tempVars],
+ server: [...thisServer, ...serverVars],
+ global: [...thisGlobal, ...globalVars],
+ thisGlobal: vars.global,
+ thisServer: vars.server
+ },
+ actionType: actionType,
+ customId: `${customId}`,
+ actions: action.data[at],
+ action: actionNumber,
+ options: (options || { picker: false })
+ });
+ function storeActionData() {
+ ipcRenderer.once(`childSave${customId}`, (event, data, copied) => {
+ action.data[at][actionNumber] = data;
+ storeActionData();
+ recacheOwnVariables();
+
+ refreshActions(at);
+ });
+ }
+ storeActionData();
+}
+
+recacheOwnVariables();
+
+
+function handleOptionDrag(position, menu) {
+ draggedPosition = position;
+ draggedOverMenu = menu;
+}
+
+function dragPositionOver(position, menu, event) {
+ if (draggedOverMenu == menu) event.preventDefault()
+
+ draggedOverPosition = position;
+}
+
+function handleDragOptionEnd() {
+ console.log(actionUI[draggedOverMenu], draggedOverMenu)
+ action.data[actionUI[draggedOverMenu].storeAs] = moveArrayElement(action.data[actionUI[draggedOverMenu].storeAs], draggedPosition, draggedOverPosition);
+ refreshMenuItems(draggedOverMenu)
+ draggedOverMenu = undefined;
+}
+
+
+async function refreshMenuItems(menu, fade, fadeLast) {
+
+ let leftSeparatorDisplay, rightSeparatorDisplay, subtitlePosition;
+
+ switch (editorSettings.subtitlePosition) {
+ case "left":
+ leftSeparatorDisplay = "none";
+ rightSeparatorDisplay = "inherit; margin-left: 5px !important;";
+ subtitlePosition = "margin-left: 5px !important; margin-right: auto;";
+ break;
+ case "right":
+ rightSeparatorDisplay = "none";
+ leftSeparatorDisplay =
+ "inherit; margin-right: 5px !important; margin-left: 10px !important;";
+ subtitlePosition = "margin-right: 0; margin-left: auto;";
+ deleteButtonStyling = "margin-left: 5px;";
+ break;
+ case "center":
+ rightSeparatorDisplay = "inherit";
+ leftSeparatorDisplay = "inherit; margin-left: 5px !important;";
+ subtitlePosition = "margin-right: 5px; margin-left: 5px;";
+ break;
+ }
+
+ if (editorSettings.focus) {
+ rightSeparatorDisplay = 'none'
+ leftSeparatorDisplay = 'none'
+ }
+
+
+ await new Promise(res => {
+ if (document.getElementById(`${actionUI[menu].storeAs}_Options`)) {
+ document.getElementById(`${actionUI[menu].storeAs}_Options`).style.opacity = '0'
+ setTimeout(() => {
+ res()
+ }, editorSettings.fastAnimation * 100);
+ } else {
+ res()
+ }
+ });
+
+ let menuObject = actionUI[menu];
+ let menuElement = document.getElementById(menuObject.storeAs);
+
+
+ if (menuObject.max != 1) {
+ if (!action.data[menuObject.storeAs].length) {
+ menuElement.style.height = "37px";
+ } else {
+ menuElement.style.height = "150px";
+ }
+
+ if (!highlights[menuObject.storeAs]) {
+ highlights[menuObject.storeAs] = { highlighted: 0, menu, selected: [], type: 2 }
+ }
+
+ if (!action.data[menuObject.storeAs][highlights[menuObject.storeAs].highlighted] && highlights[menuObject.storeAs].highlighted != 0) {
+ highlights[menuObject.storeAs].highlighted = 0;
+ }
+
+ let endOptions = ``;
+
+ for (let object in action.data[menuObject.storeAs]) {
+ let option = action.data[menuObject.storeAs][object];
+ let typeName = actionUI[menu].UItypes[option.type].name;
+
+ let preview = '';
+ try {
+ if (actionUI[menu].UItypes[option.type].preview) {
+ preview = eval(actionUI[menu].UItypes[option.type].preview)
+ }
+ } catch (err) { }
+
+ let previewText = '';
+ let previewLength = 0;
+
+ previewText.replaceAll('<', '<')
+
+ let deco = ``
+
+ if (action.data[menuObject.storeAs][Number(object) + 1] && actionUI[menu].path) {
+ deco = `
+
+ `
+ }
+
+ let additionalClass = ``
+ if (highlights[menuObject.storeAs]?.highlighted == object) {
+ additionalClass = `highlighted`
+ }
+
+ let fadeNow = false;
+
+ if (fade && !fadeLast) {
+ fadeNow = true;
+ } else if (fade && fadeLast) {
+ fadeNow = action.data[menuObject.storeAs].length - 1 == object;
+ }
+
+
+
+ endOptions += `
+
+ ${deco}
+ `
+ }
+ setTimeout(() => {
+ menuElement.innerHTML = `${endOptions}
`;
+ if (!endOptions) {
+ menuElement.innerHTML = `
+
+ No ${menuObject.name} Yet
+
+ `
+ }
+ }, editorSettings.commonAnimation * 50);
+ document.getElementById(`${menu}AddButton`).style.transform = "rotate(0deg)";
+
+ setTimeout(() => {
+ document.getElementById(`${menu}AddButton`).style.transition = "";
+ document.getElementById(`${menu}AddButton`).style.transition = `all 0.${editorSettings.commonAnimation}s cubic-bezier(.17,.67,.6,1.34)`
+ document.getElementById(`${menu}AddButton`).parentElement.onclick = () => {
+ addObjectToCustomMenu(menu, true);
+ };
+ }, editorSettings.commonAnimation * 50);
+ } else {
+ if (action.data[menuObject.storeAs][0]) {
+ let UItype = Object.keys(menuObject.UItypes)[0];
+ let previewText = ``
+
+ try {
+ let preview = '';
+ let data = action.data[menuObject.storeAs][0];
+
+
+ try {
+ if (actionUI[menu].UItypes[UItype].preview) {
+ let option = { data }
+ preview = eval(actionUI[menu].UItypes[UItype].preview);
+ }
+ } catch (err) { }
+
+ let previewLength = 0;
+
+ if (preview.length > 35) {
+ for (let character of preview.split('')) {
+ if (previewLength < 35) {
+ const opacity = 100 - (previewLength - 25) * 10;
+ previewText += `${character}`;
+ previewLength++
+ }
+ }
+ } else {
+ previewText = preview;
+ }
+
+ previewText.replaceAll('<', '<')
+ } catch (error) { }
+
+ menuElement.innerHTML = `
+
+ `
+ document.getElementById(`${menu}AddButton`).parentElement.onclick = () => {
+ deleteMenuOption(0, menu, true);
+ };
+ document.getElementById(`${menu}AddButton`).style.rotate = "225deg";
+ } else {
+ document.getElementById(`${menu}AddButton`).style.rotate = "0deg";
+
+ menuElement.innerHTML = `
+ `
+ document.getElementById(`${menu}AddButton`).parentElement.onclick = () => {
+ addObjectToCustomMenu(menu, true);
+ };
+ }
+ }
+}
+
+async function highlightMenu(menu, object) {
+ let rawMenu = actionUI[menu];
+ lastContainer = rawMenu.storeAs;
+
+ let currentSelection = [];
+ let skipBackgroundAddition = false;
+
+ if (highlights[rawMenu.storeAs]) {
+ currentSelection = highlights[rawMenu.storeAs].selected;
+ if (currentSelection.length != 0) {
+ if (!isHoldingCTRL) {
+ highlights[rawMenu.storeAs].highlighted = object;
+ currentSelection = [];
+ await refreshMenuItems(menu);
+ } else {
+ if (currentSelection.includes(object)) {
+ let lastHighlightedMenu = document.getElementById(`menu${menu}object${object}`);
+ lastHighlightedMenu.classList.remove('highlighted')
+ skipBackgroundAddition = true;
+ currentSelection.splice(currentSelection.indexOf(object), 1);
+ return
+ }
+ }
+ } else {
+ if (!isHoldingCTRL) {
+ let oldMenu = highlights[rawMenu.storeAs];
+ try {
+ let lastHighlightedMenu = document.getElementById(`menu${oldMenu.menu}object${oldMenu.highlighted}`);
+ lastHighlightedMenu.classList.remove('highlighted')
+ } catch (error) { }
+ }
+ }
+ }
+
+ if (isHoldingCTRL) {
+ if (currentSelection.length == 0 && highlights[rawMenu.storeAs].highlighted != object) {
+ currentSelection.push(highlights[rawMenu.storeAs].highlighted)
+ }
+ currentSelection.push(object)
+ }
+
+ if (!skipBackgroundAddition) {
+ let newMenu = document.getElementById(`menu${menu}object${object}`);
+ newMenu.classList.add('highlighted')
+ }
+
+
+ highlights[rawMenu.storeAs] = { highlighted: object, selected: currentSelection, type: 2, menu };
+}
+
+function createAction(at) {
+ customIDsCalculated++
+ let newAct = {
+ name: "Send Message",
+ file: "sendmessage.js",
+ data: {
+ "name": "Send Message",
+ "messageContent": "Hello World!",
+ "actionRows": [],
+ "embeds": [],
+ channel: {
+ type: "command",
+ value: ""
+ },
+ storeAs: {
+ value: "",
+ type: "temporary"
+ },
+ replyToInteraction: true
+ },
+ id: customIDsCalculated + new Date().getTime()
+ };
+
+ action.data[at].push(newAct);
+ refreshActions(at);
+
+ if (editorSettings.editActionsOnCreation) {
+ editAction(at, action.data[at].length - 1, { picker: true });
+ }
+}
+
+
+function refreshActions(at) {
+ if (!highlights[at]) {
+ highlights[at] = { highlighted: 0, selected: [], type: 1 };
+ }
+ action.data[at] = action.data[at].filter(action => action != null)
+
+ document.getElementById(at).innerHTML = "";
+ let endHTML = '';
+ let endActions = []
+
+ for (let a in action.data[at]) {
+ let Action = action.data[at][a];
+ let actionData;
+ let endAction = {
+ subtitle: '',
+ found: false,
+ file: Action.file,
+ borderType: 'bordercentere'
+ }
+ try {
+ actionData = require(`${processPath}/AppData/Actions/${Action.file}`);
+ } catch (err) { }
+
+ // if (action.data[at][parseFloat(a) - 1] == undefined) {
+ // endAction.borderType = "bordertop";
+ // } else if (action.data[at][parseFloat(a) + 1] == undefined) {
+ // endAction.borderType = "bordertop";
+ // }
+
+
+
+ if (actionData) {
+ endAction.found = true;
+ endAction.name = Action.name;
+ try {
+ if (actionData.subtitle) {
+ if (typeof actionData.subtitle == 'function') {
+ endAction.subtitle = actionData.subtitle(Action.data, {
+ user: (user) => {
+ let translations = {
+ author: "Command Author",
+ mentioned: "Mentioned User",
+ user: "Command User",
+ messageAuthor: "Message Author",
+
+ id: "ID",
+
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["mentioned", "author", "user", "messageAuthor"];
+ if (!disabledInputTypes.includes(user.type)) {
+ return `${translations[user.type]} (${user.value || "Blank"
+ })`;
+ } else {
+ return `${translations[user.type]}`;
+ }
+ },
+ channel: (channel) => {
+ let translations = {
+ id: "Channel ID",
+ userID: "User ID",
+ command: "Command Channel",
+ user: "Command User",
+ commandAuthor: "Command Author",
+ mentionedChannel: "Mentioned Channel",
+ mentionedUser: "Mentioned User",
+
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = [
+ "command",
+ "commandAuthor",
+ "mentionedUser",
+ "mentionedChannel",
+ "user"
+ ];
+ if (!disabledInputTypes.includes(channel.type)) {
+ return `${translations[channel.type]} (${channel.value || "Blank"
+ })`;
+ } else {
+ return `${translations[channel.type]}`;
+ }
+ },
+ role: (role) => {
+ let translations = {
+ id: "ID",
+ mentioned: "Mentioned Role",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["mentioned"];
+ if (!disabledInputTypes.includes(role.type)) {
+ return `${translations[role.type]} (${role.value || "Blank"
+ })`;
+ } else {
+ return `${translations[role.type]}`;
+ }
+ },
+ guild: (guild) => {
+ let translations = {
+ current: "Current",
+ id: "ID",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["current"];
+ if (!disabledInputTypes.includes(guild.type)) {
+ return `${translations[guild.type]} (${guild.value || "Blank"})`;
+ } else {
+ return `${translations[guild.type]}`;
+ }
+ },
+ message: (message) => {
+ let translations = {
+ commandMessage: "Command Message",
+ interactionReply: "Command Reply",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["commandMessage", "interactionReply"];
+ if (!disabledInputTypes.includes(message.type)) {
+ return `${translations[message.type]} (${message.value || "Blank"
+ })`;
+ } else {
+ return `${translations[message.type]}`;
+ }
+ },
+ interaction: (interaction) => {
+ let translations = {
+ commandInteraction: "Command Interaction",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = ["commandInteraction"];
+ if (!disabledInputTypes.includes(interaction.type)) {
+ return `${translations[interaction.type]} (${interaction.value || "Blank"
+ })`;
+ } else {
+ return `${translations[interaction.type]}`;
+ }
+ },
+ image: (image) => {
+ let translations = {
+ file: "File",
+ url: "URL",
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ };
+
+ let disabledInputTypes = [];
+ if (!disabledInputTypes.includes(image.type)) {
+ return `${translations[image.type]} (${image.value || "Blank"
+ })`;
+ } else {
+ return `${translations[image.type]}`;
+ }
+ },
+ variable: (variables) => {
+ let translations = {
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable",
+ temporary: "Temporary Variable",
+ server: "Server Variable",
+ global: "Global Variable",
+ };
+ return `${translations[variables.type]} (${variables.value || "Blank"
+ })`;
+ },
+ }, actionData);
+ } else {
+ let actionSubtitle = actionData.subtitle;
+ const subtitleRegex = /(\$\[.*?\]\$)/g;
+ endAction.subtitle = actionSubtitle.replace(
+ subtitleRegex,
+ (match, key) => {
+ let dataName = key
+ .split("$[")[1]
+ .split("]$")[0]
+ .replaceAll("*", "");
+ return Action.data[dataName];
+ },
+ );
+ }
+ }
+ } catch (err) { }
+ } else {
+ endAction.name = Action.name
+ }
+
+ endAction.subtitle = endAction.subtitle?.replaceAll('<', '<')
+
+ endActions.push(endAction)
+ }
+
+ let leftSeparatorDisplay, rightSeparatorDisplay, subtitlePosition;
+
+ switch (editorSettings.subtitlePosition) {
+ case "left":
+ leftSeparatorDisplay = "none";
+ rightSeparatorDisplay = "inherit; margin-left: 5px !important;";
+ subtitlePosition = "margin-left: 5px !important; margin-right: auto;";
+ break;
+ case "right":
+ rightSeparatorDisplay = "none";
+ leftSeparatorDisplay =
+ "inherit; margin-right: 5px !important; margin-left: 10px !important;";
+ subtitlePosition = "margin-right: 0; margin-left: auto;";
+ deleteButtonStyling = "margin-left: 5px;";
+ break;
+ case "center":
+ rightSeparatorDisplay = "inherit";
+ leftSeparatorDisplay = "inherit; margin-left: 5px !important;";
+ subtitlePosition = "margin-right: 5px; margin-left: 5px;";
+ break;
+ }
+
+ if (editorSettings.focus) {
+ rightSeparatorDisplay = 'none'
+ leftSeparatorDisplay = 'none'
+ }
+
+ endActions.forEach((Action, index) => {
+ let errors = ''
+
+ if (Action.found == false) {
+ errors = `
+ Action Not Found!
+ `
+ }
+ endHTML += `
+
+
+
${editorSettings.focus ? "" : "#"}${parseFloat(index) + 1}
+
${Action.name.substring(0, 256)}
+ ${errors}
+
+
+ ${Action.subtitle.replaceAll("", "")}
+
+
+
+
+
+ `
+ });
+
+ document.getElementById(at).innerHTML = endHTML;
+ highlights[at].selected = []
+}
+
+function highlightAction(container, index) {
+ lastContainer = container;
+ let selected = [];
+ if (highlights[container].selected) {
+ selected = highlights[container].selected;
+ }
+ if (!isHoldingCTRL && selected.length != 0) {
+ highlights[container].selected = [];
+ selected = [];
+ refreshActions(container);
+ }
+
+ let newAction = document.getElementById(`${container}Action${index}`)
+
+ try {
+ if (!isHoldingCTRL) {
+ let oldAction = document.getElementById(`${container}Action${highlights[container].highlighted}`)
+ oldAction.style.background = ''
+ } else {
+ if (selected.includes(index)) {
+ selected.splice(selected.indexOf(index), 1)
+ newAction.style.background = ''
+ return;
+ } else {
+ if (selected.length == 0) {
+ if (highlights[container].highlighted != index) {
+ selected.push(highlights[container].highlighted);
+ }
+ }
+ selected.push(index)
+ }
+ }
+ } catch (e) { }
+
+ highlights[container] = { highlighted: index, type: 1, selected };
+
+ newAction.style.background = `var(--accent)`
+}
+
+function deleteAction(at, number) {
+ action.data[at].splice(number, 1);
+ refreshActions(at);
+}
+var actionParent;
+var draggedAction;
+var draggedOverAction;
+function handleActionDrag(at, actionNumber) {
+ draggedAction = actionNumber;
+ actionParent = at;
+ timing = new Date().getTime();
+}
+function actionDragOverHandle(event, at, actionNumber) {
+ if (at != actionParent) return;
+ event.preventDefault();
+ draggedOverAction = actionNumber;
+}
+
+function handleActionDragEnd() { }
+
+function moveArrayElement(arr, old_index, new_index) {
+ const element = arr[old_index];
+ arr.splice(old_index, 1);
+ arr.splice(new_index, 0, element);
+
+ return arr;
+}
+function handleActionDrop(at) {
+ if (new Date().getTime() - timing < 100) return;
+
+ let oldPosition = parseFloat(draggedAction);
+ let newPosition = parseFloat(draggedOverAction);
+ lastType = 1;
+
+ let modifiedActions = moveArrayElement(
+ action.data[at],
+ oldPosition,
+ newPosition,
+ );
+
+ action.data[at] = modifiedActions;
+ refreshActions(at);
+}
\ No newline at end of file
diff --git a/kits/EditorScripts.js b/kits/EditorScripts.js
new file mode 100644
index 0000000..b9c0689
--- /dev/null
+++ b/kits/EditorScripts.js
@@ -0,0 +1,538 @@
+let kindOf;
+let highlights = {};
+let lastContainer;
+let lastHoveredMenu;
+let lastHovered;
+let isHoldingCTRL = false;
+let lastActionContainer;
+
+let lastOpenedMenu = {}
+
+let cancelMenu = false;
+
+(Element.prototype.appendBefore = function (element) {
+ element.parentNode.insertBefore(this, element);
+}),
+ false;
+(Element.prototype.appendAfter = function (element) {
+ element.parentNode.insertBefore(this, element.nextSibling);
+}),
+ false;
+
+window.oncontextmenu = function (event) {
+ if (menu) {
+ menu.style.transition = "all 0.2s ease";
+ }
+ showCustomMenu(event.clientX, event.clientY);
+ return false; // cancel default menu
+};
+
+async function addObjectToCustomMenu(element) {
+ if (document.getElementById(actionUI[element].storeAs)?.getElementsByClassName('backArrow').length) {
+ document.getElementById(actionUI[element].storeAs).getElementsByClassName('backArrow')[0].parentElement.style.opacity = '0'
+ }
+
+ if (document.getElementById(`addButtonOf${element}`)?.previousElementSibling.getElementsByClassName('backArrow').length) {
+ document.getElementById(`addButtonOf${element}`).previousElementSibling.getElementsByClassName('backArrow')[0].parentElement.style.opacity = '0'
+ }
+
+ let targetField = document.getElementById(actionUI[element].storeAs);
+ targetField.style.transition = `all 0.${editorSettings.fastAnimation}s ease`
+
+ let animationDelay = 0
+
+ if (actionUI[element].max > action.data[actionUI[element].storeAs].length) {
+ if (Object.keys(actionUI[element].types).length > 1) {
+ await new Promise(res => {
+ action.data[actionUI[element].storeAs].forEach((e, index) => {
+ try {
+ document.getElementById(`menu${element}object${index}`).style.transition = `all 0.${editorSettings.fastAnimation}s ease`
+ document.getElementById(`menu${element}object${index}`).style.opacity = '0'
+ } catch (error) { }
+ })
+
+ setTimeout(() => {
+ res()
+ }, editorSettings.fastAnimation * 100);
+ })
+ document.getElementById(`${element}AddButton`).style.transition = `all 0.${editorSettings.commonAnimation}s ease`
+
+ document.getElementById(`${element}AddButton`).style.transform =
+ "rotate(135deg)";
+ document.getElementById(`${element}AddButton`).parentElement.onclick = () => {
+ refreshMenuItems(`${element}`, true);
+
+ setTimeout(() => {
+ targetField.classList.remove('flexbox');
+ }, editorSettings.commonAnimation * 100);
+ };
+
+ let endHTML = "";
+ for (let option in actionUI[element].types) {
+ if (animationDelay != 9) {
+ animationDelay++
+ }
+ endHTML = `${endHTML}
+
+ ${actionUI[element].types[option]}
+
+ `;
+ }
+
+ targetField.classList.add('flexbox')
+ targetField.style.height = "170px";
+
+ setTimeout(() => {
+ targetField.innerHTML = `
+
+
${!editorSettings.focus ? `${actionUI[element].name} have different types, select one!` : `${actionUI[element].name} Types`}
+
+ ${endHTML}
+
+
+ `;
+ }, editorSettings.fastAnimation * 100);
+ } else {
+ addObjectToMenu(`${element}`, Object.keys(actionUI[element].types)[0], true);
+ }
+ }
+}
+
+function deleteMenuOption(position, menu, skipAnimations) {
+ action.data[actionUI[menu].storeAs].splice(position, 1);
+
+ document.getElementById(`menu${menu}object${position}`).style.transition = `all 0.${editorSettings.commonAnimation}s ease`
+ document.getElementById(`${menu}AddButton`).style.transition = `all 0.${editorSettings.commonAnimation}s ease`
+
+ setTimeout(() => {
+ refreshMenuItems(menu);
+ }, editorSettings.commonAnimation * 100);
+
+ setTimeout(() => {
+ document.getElementById(`menu${menu}object${position}`).style.opacity = '0%'
+
+ if (!skipAnimations) {
+ document.getElementById(`menu${menu}object${position}`).style.height = '0px'
+ document.getElementById(`menu${menu}object${position}`).style.paddingTop = '0px'
+ document.getElementById(`menu${menu}object${position}`).style.paddingBottom = '0px'
+ document.getElementById(`menu${menu}object${position}`).style.marginBottom = '0px'
+ document.getElementById(`menu${menu}object${position}`).style.marginTop = '0px'
+ }
+ }, editorSettings.commonAnimation);
+}
+
+function fuzzyMatch(str, pattern, accuracy) {
+ pattern = pattern.replace(/[-\\\/^$*+?.()|[\]{}]/g, "\\$&");
+ pattern = pattern.split("").reduce((a, b) => a + `.*${b}`, "");
+
+ const regex = new RegExp(pattern, "i");
+ const matchScore = str.match(regex) ? str.match(regex)[0].length : 0;
+ const requiredScore = str.length * accuracy;
+
+ return matchScore >= requiredScore;
+}
+
+let folders;
+
+async function viewAllActions() {
+ let ind = -1;
+ try {
+ document.getElementById('searchResults').innerHTML = ''
+ if (!folders) {
+ folders = {};
+ for (let action of cachedActions) {
+ ind++
+ if (!folders[action.category]) {
+ folders[action.category] = ''
+ }
+ folders[action.category] += `
+ ${action.name}${action.mod ? ` MOD` : ""}
+ `
+ };
+
+ folders = Object.fromEntries(Object.entries(folders).sort())
+ }
+
+ for (let f in folders) {
+ let folder = folders[f];
+ document.getElementById('searchResults').innerHTML += `
+
+
+ ${folder}
+
`
+ }
+ } catch (err) { console.log(err) }
+}
+
+let isSearchOpen = false;
+async function startSearch() {
+ if (isSearchOpen) return;
+ isSearchOpen = true;
+ let cache;
+ if (!Array.isArray(cachedActions)) {
+ cache = new Promise(resolve => {
+ ipcRenderer.send(`${time}`, {
+ event: "askForCache"
+ });
+
+ ipcRenderer.on('actionCache', (e, actionCache) => {
+ cachedActions = actionCache.cachedActions;
+ resolve()
+ })
+ });
+ }
+
+ document.getElementById('searchIcon').style.transition = `all 0.${editorSettings.commonAnimation}s ease`;
+
+ document.getElementById('searchIcon').style.rotate = '360deg';
+ document.getElementById('searchIcon').style.scale = '0.6';
+
+ setTimeout(() => {
+ document.getElementById('searchIcon').style.scale = '1'
+ }, editorSettings.commonAnimation * 30);
+
+ await cache;
+ document.getElementById('actionSearchButton').onclick = () => { closeSearch() }
+ const container = document.getElementById('editorContent');
+ container.style.transition = `all 0.${editorSettings.fastAnimation}s ease`;
+
+ const search = document.getElementById('search');
+ search.style.height = 'calc(100vh - var(--toolbar-height))'
+ search.style.transition = `all 0.${editorSettings.fastAnimation}s ease, opacity 0.${editorSettings.commonAnimation == '0' ? '1' : '5'}s ease`
+ search.style.opacity = '1'
+
+ if (!document.getElementById('searchResults')) {
+ search.innerHTML = `
+ `
+ viewAllActions();
+ };
+
+ container.style.borderRadius = 'var(--round-strong)'
+ container.style.scale = '0.9'
+ container.style.marginRight = '-296.475px';
+ search.style.width = '296.475px';
+ search.style.overflow = 'hidden';
+
+ document.getElementById('search').firstElementChild.firstElementChild.focus();
+}
+
+function actionSearch(query) {
+ cachedResults = undefined;
+ if (query == "") {
+ viewAllActions();
+ return;
+ }
+ query = query.replaceAll(' ', '')
+
+ let endFolders = {};
+ let overwrittenFolders = {};
+ let count = 0;
+
+ document.getElementById("searchResults").innerHTML = "";
+ for (let action in cachedActions) {
+ if (fuzzyMatch(cachedActions[action].name, query, 0.02)) {
+ count++
+ if (!endFolders[cachedActions[action].category]) {
+ endFolders[cachedActions[action].category] = ''
+ }
+ endFolders[cachedActions[action].category] += `
+ ${cachedActions[action].name}${cachedActions[action].mod ? ` MOD` : ""}
`
+ }
+ }
+
+ for (let folder in folders) {
+ if (fuzzyMatch(folder, query, 0.02)) {
+ overwrittenFolders[folder] = true;
+ endFolders[folder] = folders[folder];
+ }
+ }
+
+ endFolders = Object.fromEntries(Object.entries(endFolders).sort());
+
+ let initialKeys = [];
+ let leftoverKeys = [];
+ for (let folder in endFolders) {
+ if (overwrittenFolders[folder]) {
+ initialKeys.push([folder, endFolders[folder]])
+ } else {
+ leftoverKeys.push([folder, endFolders[folder]])
+ }
+ }
+ let endKeys = [...initialKeys, ...leftoverKeys]
+ endFolders = Object.fromEntries(endKeys)
+
+ for (let folderName in endFolders) {
+ let decoration = ``
+ if (overwrittenFolders[folderName]) {
+ decoration = `
+
+
+ `
+ } else {
+ decoration = `
+
+ `
+ }
+
+ document.getElementById("searchResults").innerHTML += `
+
+
+ ${decoration}
+ ${folderName}
+
+ ${endFolders[folderName]}
+
+ `
+ }
+}
+
+async function closeSearch() {
+ searchResultSelected = 0;
+ document.getElementById('searchIcon').style.rotate = '0deg'
+ document.getElementById('searchIcon').style.scale = '0.6';
+
+ setTimeout(() => {
+ document.getElementById('searchIcon').style.scale = '1'
+ isSearchOpen = false;
+ }, editorSettings.commonAnimation * 30);
+
+ document.getElementById('actionSearchButton').onclick = () => { startSearch() }
+
+ const container = document.getElementById('editorContent');
+ container.style.scale = '1'
+ container.style.borderRadius = '0px'
+ container.style.marginRight = '0';
+
+ const search = document.getElementById('search');
+ search.style.width = '0';
+ search.style.opacity = '0'
+}
+
+function switchOutAction(file) {
+ let newAction = require(`${processPath}/AppData/Actions/${file}`);
+ actionFile = newAction;
+ action.data = newAction.data;
+ action.name = newAction.data.name;
+ action.file = file;
+ actionUI = newAction.UI;
+ actions[actionNumber].data = action.data;
+ document.getElementById("editorContent").innerHTML = "";
+ document.getElementById("editorContent").innerHTML = getUIelements(newAction.UI);
+
+ closeSearch();
+ updateTopBarContent(`${action.name}`, 'action-name');
+
+ recacheThisVariables();
+}
+
+function openHalfDropdown(storedAs, index) {
+ document.getElementById(storedAs).onclick = () => {
+ closeHalfDropdown(storedAs, index)
+ }
+
+ document.getElementById(storedAs).style.zIndex = '1000'
+ document.getElementById(storedAs).parentElement.style.zIndex = '1000'
+
+ for (let choiceIndex in actionUI[index].choices) {
+ let choice = actionUI[index].choices[choiceIndex]
+ if (choice.name != action.data[storedAs]) {
+ document.getElementById(storedAs).innerHTML += `
+ ${choice.name}
+ `
+ }
+ }
+}
+
+function setHalfDropdownType(storedAs, choice, index) {
+ let foundChoice;
+ for (let option of actionUI[index].choices) {
+ if (option.name == action.data[actionUI[index].storeAs]) {
+ foundChoice = option;
+ }
+ }
+ if (foundChoice.placeholder) {
+ document.getElementById(`${storedAs}input`).ariaPlaceholder = foundChoice.placeholder
+ } else {
+ document.getElementById(`${storedAs}input`).ariaPlaceholder = ''
+ }
+
+ let input = document.getElementById(`${storedAs}input`)
+
+ if (foundChoice.field && !actionUI[index].choices[choice].field) {
+ let dropdown = document.getElementById(storedAs)
+
+ dropdown.parentElement.style.marginRight = '0'
+
+ dropdown.classList.remove('borderright');
+ dropdown.style.width = 'calc(var(--width-in-editor) - 12px)'
+
+ input.style.width = '0px'
+ input.style.setProperty('padding', '0px')
+ input.style.height = '0px'
+ } else if (!foundChoice.field && actionUI[index].choices[choice].field) {
+ let dropdown = document.getElementById(storedAs)
+
+ dropdown.parentElement.style.marginRight = 'var(--dropdown-paddingLeft)'
+
+ dropdown.classList.add('borderright');
+ dropdown.style.width = 'var(--width-in-otherhalf-dropdown)'
+
+ input.style.width = 'calc(var(--width-in-editor) - var(--width-in-half-dropdown))'
+ input.style.setProperty('padding', '')
+ input.style.height = '30.8px'
+ }
+
+ input.placeholder = actionUI[index].choices[choice].placeholder ? actionUI[index].choices[choice].placeholder : ''
+
+ action.data[storedAs] = actionUI[index].choices[choice].name;
+
+ emitChange(storedAs)
+}
+
+function closeHalfDropdown(s, i) {
+ let element = document.getElementById(s);
+ element.style.animationName = "";
+ const innerHeight = element.clientHeight;
+ element.style.animationDuration = "";
+ element.style.setProperty("--inner-height", innerHeight + "px");
+ element.style.animationName = "shrink";
+ element.style.animationDuration = "300ms";
+ element.style.zIndex = ''
+ element.parentElement.style.zIndex = ''
+
+
+ setTimeout(() => {
+ element.onclick = () => {
+ openHalfDropdown(s, i)
+ };
+ element.innerHTML = action.data[s];
+ }, 70);
+}
+
+function openTypedDropdown(storedAs, index, types, toRun) {
+ document.getElementById(storedAs).style.zIndex = '1000'
+ document.getElementById(storedAs).parentElement.style.zIndex = '1000'
+
+ document.getElementById(storedAs).onclick = () => {
+ closeTypedDropdown(storedAs, index, types, toRun)
+ }
+
+ for (let translation in types) {
+ if (translation != action.data[storedAs].type) {
+ let option = document.createElement('div')
+ option.className = 'dropdown_option'
+ option.onclick = () => {
+ setTypedType(storedAs, { ...types[translation], type: translation }, index)
+ }
+ option.innerHTML = types[translation].name;
+ document.getElementById(storedAs).appendChild(option)
+ }
+ }
+}
+
+function setTypedType(storedAs, translation, i, toRun) {
+ if (!translation.field) {
+ let dropdown = document.getElementById(storedAs)
+ let input = document.getElementById(`${storedAs}input`)
+
+ dropdown.parentElement.style.marginRight = '0'
+
+ dropdown.classList.remove('borderright');
+ dropdown.style.width = 'calc(var(--width-in-editor) - 12px)'
+
+ input.style.width = '0px'
+ input.style.setProperty('padding', '0px')
+ input.style.height = '0px'
+ } else {
+ let dropdown = document.getElementById(storedAs)
+ let input = document.getElementById(`${storedAs}input`)
+
+ dropdown.parentElement.style.marginRight = 'var(--dropdown-paddingLeft)'
+
+ dropdown.classList.add('borderright');
+ dropdown.style.width = 'var(--width-in-otherhalf-dropdown)'
+
+ input.style.width = 'calc(var(--width-in-editor) - var(--width-in-half-dropdown))'
+ input.style.setProperty('padding', '')
+ input.style.height = '30.8px'
+ }
+
+ action.data[storedAs].type = translation.type;
+}
+
+function closeTypedDropdown(s, i, types, toRun) {
+ let element = document.getElementById(s);
+ element.style.animationName = "";
+ const innerHeight = element.clientHeight;
+ element.style.animationDuration = "";
+ element.style.setProperty("--inner-height", innerHeight + "px");
+ element.style.animationName = "shrink";
+ element.style.animationDuration = "300ms";
+ element.style.zIndex = ''
+ element.parentElement.style.zIndex = ''
+
+ if (toRun) {
+ toRun(action.data[s], i);
+ }
+
+ setTimeout(() => {
+ element.onclick = () => {
+ openTypedDropdown(s, i, types, toRun)
+ };
+ element.innerHTML = types[action.data[s].type].name;
+ }, 70);
+}
+
+function openActionFolder(folder_bar) {
+ let element = folder_bar.nextElementSibling;
+ let heightGuesser = document.createElement('div');
+ heightGuesser.innerHTML = element.innerHTML;
+ heightGuesser.style.width = element.clientWidth;
+ heightGuesser.classList.add('search_action');
+ heightGuesser.style.padding = '0px'
+ element.style.marginTop = '4px';
+ document.body.appendChild(heightGuesser);
+ setTimeout(() => {
+ let height = heightGuesser.clientHeight;
+ element.style.paddingTop = '4px';
+ element.style.height = height;
+ folder_bar.classList.add('rounded_top');
+ element.classList.add('rounded_bottom');
+ heightGuesser.remove();
+ }, 10);
+
+ folder_bar.onclick = () => {
+ closeActionFolder(folder_bar)
+ }
+}
+
+function toggleDropdownContainer(dataset, i) {
+ let actionContainer = document.getElementById(actionUI[i].storeActionsAs);
+ if (dataset.type == 'runActions') {
+ actionContainer.classList.remove('closedActions');
+ actionContainer.previousElementSibling.classList.remove('closedActions');
+ } else {
+ actionContainer.classList.add('closedActions');
+ actionContainer.previousElementSibling.classList.add('closedActions');
+ }
+}
+
+function closeActionFolder(folder_bar) {
+ folder_bar.classList.remove('rounded_top');
+ let element = folder_bar.nextElementSibling;
+ element.classList.remove('rounded_bottom')
+ element.style.height = '0px'
+ element.style.paddingBottom = '0px';
+ element.style.paddingTop = '0px';
+ element.style.marginTop = '0px';
+ folder_bar.onclick = () => {
+ openActionFolder(folder_bar)
+ }
+}
\ No newline at end of file
diff --git a/kits/Loader.js b/kits/Loader.js
new file mode 100644
index 0000000..68c4863
--- /dev/null
+++ b/kits/Loader.js
@@ -0,0 +1,17 @@
+var fs = require("fs");
+let lastButton;
+let menu;
+
+function closeContextmenu() {
+ if (menu && !mOpened) {
+ menu.style.scale = "0";
+ setTimeout(() => {
+ menu.remove();
+ menu = undefined;
+ }, 200);
+ }
+}
+
+document.onclick = () => {
+ closeContextmenu()
+};
diff --git a/kits/MiscScripts.js b/kits/MiscScripts.js
new file mode 100644
index 0000000..36fecee
--- /dev/null
+++ b/kits/MiscScripts.js
@@ -0,0 +1,1080 @@
+let areSettingsOpen;
+let preventClose;
+function array_move(arr, old_index, new_index) {
+ if (new_index >= arr.length) {
+ var k = new_index - arr.length + 1;
+ while (k--) {
+ arr.push(undefined);
+ }
+ }
+ arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
+ return arr; // for testing
+}
+
+let settings;
+try {
+ settings = JSON.parse(
+ fs.readFileSync(path + "/EditorSettings.json", "utf8"),
+ );
+} catch (err) { }
+
+if (!settings) {
+ fs.writeFileSync(path + "/EditorSettings.json", "{}");
+ settings = JSON.parse(
+ fs.readFileSync(path + "/EditorSettings.json", "utf8"),
+ );
+}
+
+function saveLocally() {
+ fs.writeFileSync(
+ "./AppData/data.json",
+ JSON.stringify(botData, null, 2),
+ );
+}
+
+let lastRow;
+let lastDraggedComponent;
+
+window.oncontextmenu = function (event) {
+ showCustomMenu(event.clientX, event.clientY);
+ return false;
+};
+
+function copyAction(id) {
+ if (selectedActions.length == 0) {
+ ipcRenderer.send('copiedAction', botData.commands[lastObj].actions[id])
+ } else {
+ ipcRenderer.send('copiedAction', selectedActions.map(action => botData.commands[lastObj].actions[action]))
+ }
+}
+
+function toHex(rgb) {
+ try {
+ let parts = rgb.replace('rgb(', '').replace(')', '').split(',');
+
+ // Convert each part to an integer, then to a hex string and pad with zeros if necessary
+ let r = parseInt(parts[0]).toString(16).padStart(2, '0');
+ let g = parseInt(parts[1]).toString(16).padStart(2, '0');
+ let b = parseInt(parts[2]).toString(16).padStart(2, '0');
+
+ // Concatenate the hex strings and prepend with '#'
+ return `${r}${g}${b}`;
+ } catch (error) {
+ return `#000000`
+ }
+}
+
+
+
+
+/**
+ *
+ * @param {*} x
+ * @param {*} y
+ * @param {HTMLDivElement} target
+ */
+function showCustomMenu(x, y, target) {
+ if (!menu) {
+ menu = document.createElement("div");
+ document.body.appendChild(menu);
+ menu.className = 'right_click_menu'
+ menu.id = "customMenu";
+ }
+
+
+ // Calculate the maximum allowed coordinates based on window dimensions
+ const windowWidth = window.innerWidth;
+ const windowHeight = window.innerHeight;
+ const menuWidth = menu.offsetWidth;
+ const menuHeight = menu.offsetHeight;
+ const maxX = windowWidth - menuWidth;
+ const maxY = windowHeight - menuHeight;
+
+ let adjustedX = x;
+ let adjustedY = y;
+ if (x > maxX) {
+ adjustedX = maxX;
+ }
+ if (y > maxY) {
+ adjustedY = maxY - 48;
+ }
+
+ menu.style.top = adjustedY + "px";
+ menu.style.left = adjustedX + "px";
+ menu.style.width = "";
+
+ menu.style.position = 'relative';
+ menu.style.zIndex = '5000'
+ menu.style.scale = 1;
+ menu.style.opacity = 1;
+ menu.innerHTML = ``;
+ if (lastHovered) {
+ if (lastHovered.id.startsWith("Group")) {
+ menu.innerHTML += `
+
+
+
+
+
+
+
+
+
+
+
+ `;
+ }
+
+ if (lastHovered.id.startsWith("Action")) {
+ ipcRenderer.send('getCopiedAction');
+ ipcRenderer.once('copiedAction', (e, action) => {
+ menu.innerHTML += `
+
+ `
+ if (action) {
+ menu.innerHTML += ``
+ };
+ menu.innerHTML += `
+
+
+
+ `;
+ })
+
+ }
+ if (lastHovered.id == 'folder') {
+ let folderID = lastHovered.specifically;
+ menu.innerHTML += `
+
+
+
+
+
+ `;
+ }
+ }
+}
+function getCaretPosition(element) {
+ var caretPos = 0;
+ var sel;
+ var range;
+ var clonedRange;
+
+ if (window.getSelection) {
+ sel = window.getSelection();
+ if (sel.rangeCount) {
+ range = sel.getRangeAt(0);
+ clonedRange = range.cloneRange();
+ clonedRange.selectNodeContents(element);
+ clonedRange.setEnd(range.endContainer, range.endOffset);
+ caretPos = clonedRange.toString().length;
+ }
+ } else if (document.selection && document.selection.type !== "Control") {
+ range = document.selection.createRange();
+ clonedRange = range.duplicate();
+ clonedRange.moveToElementText(element);
+ clonedRange.setEndPoint("EndToEnd", range);
+ caretPos = clonedRange.text.length;
+ }
+
+ return caretPos;
+}
+
+function setCaretPosition(element, caretPos) {
+ let range;
+ let offset = caretPos;
+ let found = false;
+
+ if (document.createRange) {
+ range = document.createRange();
+ for (const node of element.childNodes) {
+ if (node.nodeType === Node.TEXT_NODE) {
+ if (offset <= node.textContent.length) {
+ range.setStart(node, offset);
+ found = true;
+ break;
+ } else {
+ offset -= node.textContent.length;
+ }
+ }
+ }
+
+ if (!found) {
+ range.setStart(element, element.childNodes.length);
+ }
+
+ range.collapse(true);
+
+ const sel = window.getSelection();
+ sel.removeAllRanges();
+ sel.addRange(range);
+ } else if (document.selection) {
+ range = document.body.createTextRange();
+ range.moveToElementText(element);
+ range.moveStart("character", caretPos);
+ range.collapse(true);
+ range.select();
+ }
+}
+
+function editRawData(group) {
+ if (areSettingsOpen) return
+ document.getElementById('titlebar1').style.transition = `all 0.${editorSettings.fastAnimation}s ease`
+
+ areSettingsOpen = true;
+ menu.remove();
+
+ setTimeout(() => {
+ document.getElementById('titlebar1').style.marginTop = '-37px'
+ }, 100);
+ document.body.innerHTML += `
+
+
+
+
+
+
${strings.dismissible_content.rawdata_editor_new}
+
Dismiss
+
+
${strings.dismissible_content.rawdata_editor_new_subtitle}
+
+
+
+
${getString(strings.editor.rawdata_editor.folder_id, [botData.commands[group].folder || "null"]?.join(', ') || "")}
+
+ ${strings.misc.copy}
+
+
+
${getString(strings.editor.rawdata_editor.id, [botData.commands[group].customId])}
+
+ ${strings.misc.copy}
+
+
+
+
${getString(strings.editor.rawdata_editor.description, [botData.commands[group].description])}
+
+
${getString(strings.editor.rawdata_editor.permissions, [botData.commands[group].boundary?.limits || "Unset"])}
+
+
${getString(strings.editor.rawdata_editor.nsfw, [botData.commands[group].boundary?.nsfw || "false"])}
+
+
${getString(strings.editor.rawdata_editor.installable, [botData.commands[group].boundary?.installable || "false"])}
+
+
+
+
${strings.misc.exit}
+
+
${strings.editor.rawdata_editor.serialized_upload}
+
${strings.editor.rawdata_editor.deserialized_upload}
+
+
+
+
+ `
+}
+
+function pasteActionTo(index) {
+ ipcRenderer.send('getCopiedAction')
+
+ ipcRenderer.once('copiedAction', (e, action) => {
+ if (action) {
+ createCheckpoint();
+ if (Array.isArray(action)) {
+ let pasteIndex = Number(index) + 1;
+ action.forEach(act => {
+ botData.commands[lastObj].actions.splice(pasteIndex, 0, act);
+ pasteIndex++
+ });
+ saveLocally();
+ refreshActions();
+ } else {
+ botData.commands[lastObj].actions.push(action);
+ botData.commands[lastObj].actions = moveArrayElement(
+ botData.commands[lastObj].actions,
+ botData.commands[lastObj].actions.length - 1,
+ parseFloat(index) + 1,
+ );
+ saveLocally();
+ refreshActions();
+ }
+ }
+ })
+
+}
+
+window.oncontextmenu = function (event) {
+ showCustomMenu(event.clientX, event.clientY, event.target);
+ return false;
+};
+
+window.addEventListener("click", function (event) {
+ if (menu && !preventClose) {
+ menu.style.scale = "var(--menu-initial-scale)";
+ menu.style.opacity = "var(--menu-initial-opacity)";
+ setTimeout(() => {
+ menu.remove();
+ menu = null;
+ }, editorSettings.commonAnimation * 100);
+ }
+});
+
+function getOffset(el) {
+ const rect = el.getBoundingClientRect();
+ return {
+ left: rect.left + window.scrollX,
+ top: rect.top + window.scrollY,
+ };
+}
+
+async function handleKeybind(keyEvent) {
+ if (keyEvent.key == 'Enter' && searchBar) {
+ document.getElementById('searchResults').firstElementChild.nextElementSibling.onclick()
+ }
+ if (keyEvent.key.toLowerCase() == keybinds.search.key && keyEvent[keybinds.modifier] == true && keyEvent.repeat == false) {
+ toggleSearch()
+ }
+
+ if (Number(keyEvent.key) != NaN && keyEvent[keybinds.modifier]) {
+ if (lastHighlightedType == 1) {
+ if (isHoldingCTRL && !keyEvent.shiftKey) {
+ isHoldingCTRL = false;
+ await highlight(document.getElementById(`Action${keyEvent.key - 1}`));
+ isHoldingCTRL = true;
+ }
+ }
+ }
+
+ if (keyEvent.key.toLowerCase() == keybinds.save.key && keyEvent[keybinds.modifier] == true) {
+ saveLocally();
+ savePrj();
+ }
+
+ if (keyEvent.key.toLowerCase() == keybinds.newAction.key && keyEvent[keybinds.modifier] == true) {
+ newObject(1)
+ }
+
+ if (keyEvent.key.toLowerCase() == keybinds.newCommand.key && keyEvent[keybinds.modifier] == true) {
+ newObject(0)
+ }
+
+
+
+ if (keyEvent.key == 'Escape') {
+ if (searchBar) {
+ toggleSearch();
+ }
+ }
+
+ if (document.activeElement.tagName != "BODY") return;
+
+ if (keyEvent.key.toLowerCase() == "d" && keyEvent[keybinds.modifier] == true) {
+ duplicateGroup(lastObj)
+ return
+ }
+
+ if (keyEvent.key == 'ArrowUp') {
+ if (lastHighlightedType == 1) {
+ highlight(document.getElementById(`Action${Number(lastAct) - 1}`));
+ }
+ if (lastHighlightedType == 0) {
+ await highlight(document.getElementById(`Group${Number(lastObj) - 1}`));
+ if (botData.folders[botData.commands[lastObj].folder].closed) {
+ toggleFolderVisibility(botData.commands[lastObj].folder, document.getElementById(`${botData.commands[lastObj].folder}closebutton`))
+ saveLocally();
+ recacheFolders();
+ }
+ }
+ }
+
+ if (keyEvent.key.toLowerCase() == 'a' && keyEvent[keybinds.modifier] && document.activeElement.tagName == 'BODY') {
+ if (lastHighlightedType == 1) {
+ selectedActions = [];
+
+ highlight(document.getElementById(`Action0`));
+ botData.commands[lastObj].actions.forEach((act, index) => {
+ if (index != 0) {
+ highlight(document.getElementById(`Action${index}`))
+ }
+ });
+ selectedActions.sort((a, b) => a - b)
+ }
+ }
+
+ let symbolsToNumbers = {
+ "!": "1",
+ "@": "2",
+ "#": "3",
+ "$": "4",
+ "%": "5",
+ "^": "6",
+ "&": "7",
+ "*": "8",
+ "(": "9",
+ ")": "10"
+ };
+
+ if (keyEvent.shiftKey && symbolsToNumbers[keyEvent.key] && !keyEvent[keybinds.modifier]) {
+ isHoldingCTRL = true;
+ await highlight(document.getElementById(`Action${Number(symbolsToNumbers[keyEvent.key]) - 1}`));
+ isHoldingCTRL = false;
+ }
+
+ if (keyEvent.key == 'ArrowDown') {
+ if (lastHighlightedType == 1) {
+ highlight(document.getElementById(`Action${Number(lastAct) + 1}`));
+ }
+ if (lastHighlightedType == 0) {
+ await highlight(document.getElementById(`Group${Number(lastObj) + 1}`));
+ if (botData.folders[botData.commands[lastObj].folder].closed) {
+ toggleFolderVisibility(botData.commands[lastObj].folder, document.getElementById(`${botData.commands[lastObj].folder}closebutton`))
+ saveLocally();
+ recacheFolders();
+ }
+ }
+ }
+
+ if (keyEvent.key == 'Enter') {
+ createCheckpoint({ recacheFolders: true });
+
+ if (lastHighlightedType == 1) {
+ highlight(document.getElementById(`Action${lastAct}`));
+ editAction(lastAct);
+ }
+ if (lastHighlightedType == 0) {
+ lastHighlightedType = 1;
+ }
+ if (lastHighlightedType == 2) {
+ toggleFolderVisibility(lastFolder, document.getElementById(`${lastFolder}closebutton`))
+ saveLocally();
+ recacheFolders();
+ }
+ }
+
+ if (keyEvent.key.toLowerCase() == 'c' && keyEvent[keybinds.modifier] == true && !keyEvent.repeat) {
+ if (lastHighlightedType == 0) {
+ document.getElementById(`Group${lastObj}`).style.rotate = '-2deg'
+ setTimeout(() => {
+ document.getElementById(`Group${lastObj}`).style.rotate = '2deg'
+ setTimeout(() => {
+ document.getElementById(`Group${lastObj}`).style.rotate = '0deg'
+ }, 100);
+ }, 100);
+
+ ipcRenderer.send('copiedAction', botData.commands[lastObj].actions);
+ notify('Copied ' + botData.commands[lastObj].actions.length + ' Actions!')
+ }
+
+ if (lastHighlightedType == 1) {
+ if (selectedActions.length != 0) {
+ notify('Copied ' + selectedActions.length + ` Action${selectedActions.length == 1 ? "" : "s"}`);
+
+ let toSend = [];
+
+ selectedActions.forEach(action => {
+ toSend.push(botData.commands[lastObj].actions[action])
+ })
+
+ ipcRenderer.send('copiedAction', toSend);
+ } else {
+ ipcRenderer.send('copiedAction', botData.commands[lastObj].actions[lastAct]);
+ }
+ }
+
+ if (lastHighlightedType == 2) {
+ document.getElementById(`${lastFolder}`).style.rotate = '-2deg'
+ setTimeout(() => {
+ document.getElementById(`${lastFolder}`).style.rotate = '2deg'
+ setTimeout(() => {
+ document.getElementById(`${lastFolder}`).style.rotate = ''
+ }, 100);
+ }, 100);
+
+ let copiedActions = [];
+ let totalActions = 0;
+
+ let folder = cachedFolders[lastFolder];
+ let commandsArray = [];
+
+ botData.commands.forEach((value, index) => {
+ if (index >= folder.first && index <= folder.last) {
+ commandsArray.push(value)
+ }
+ });
+
+ commandsArray.map(command => command.actions).forEach(actions => {
+ actions.forEach(action => {
+ copiedActions.push(action);
+ totalActions++
+ })
+ });
+
+ ipcRenderer.send('copiedAction', copiedActions);
+
+ notify('Copied ' + copiedActions.length + ` Action${totalActions == 1 ? "" : "s"}`);
+ }
+ }
+
+ if (keyEvent.key.toLowerCase() == 'v' && keyEvent[keybinds.modifier] == true && !keyEvent.repeat) {
+ if (lastHighlightedType != 2) {
+ let toInsertAt = lastAct;
+ toInsertAt++
+ ipcRenderer.send('getCopiedAction');
+
+ ipcRenderer.once('copiedAction', (event, actions) => {
+ createCheckpoint()
+ if (Array.isArray(actions)) {
+ actions.forEach(action => {
+ botData.commands[lastObj].actions.splice(toInsertAt, 0, action);
+ toInsertAt++
+ })
+ } else {
+ botData.commands[lastObj].actions.splice(Number(lastAct) + 1, 0, actions)
+ }
+ refreshGroups();
+ saveLocally();
+ })
+ }
+ }
+
+ if (keyEvent.key == 'Delete') {
+ if (document.activeElement.tagName != 'BODY') return
+ if (lastHighlightedType == 1 && (selectedActions.length != 0 || botData.commands[lastObj]?.actions[lastAct])) {
+ createCheckpoint({ recacheFolders: false });
+
+ if (selectedActions.length != 0) {
+ if (editorSettings.actionDeletionScreening) {
+ let keepGoing = await awaitIPCResponse({ channel: "deleteScreening", content: `Are you sure you want to delete ${selectedActions.length} actions?` }, 'deletionModalInteraction');
+ if (!keepGoing) return;
+ }
+
+ let endActions = [];
+ for (let action in botData.commands[lastObj].actions) {
+ if (!selectedActions.includes(`${action}`)) {
+ endActions.push(botData.commands[lastObj].actions[action])
+ }
+ }
+ botData.commands[lastObj].actions = endActions;
+ } else {
+ deleteAction(lastAct);
+ }
+ refreshActions();
+ saveLocally();
+ }
+
+ if (lastHighlightedType == 0) {
+ createCheckpoint({ recacheFolders: true });
+ deleteCommand(lastObj)
+ }
+
+ if (lastHighlightedType == 2) {
+ createCheckpoint({ recacheFolders: true });
+ deleteFolder(lastFolder)
+ }
+ }
+
+ if (keyEvent.key.toLowerCase() == 'z' && keyEvent[keybinds.modifier] == true) {
+ undo();
+ }
+
+ if (keyEvent.key.toLowerCase() == 'y' && keyEvent[keybinds.modifier] == true) {
+ redo();
+ }
+
+ if (keyEvent.key.toLowerCase() == 'q' && keyEvent[keybinds.modifier] == true) {
+ toggleBotStatus('shutdownBot');
+ }
+
+ if (keyEvent.key.toLowerCase() == keybinds.create.key && keyEvent[keybinds.modifier] == true) {
+ newAction();
+ }
+
+ if (keyEvent.key.toLowerCase() == keybinds.toggle.key && keyEvent[keybinds.modifier] == true) {
+ resizeCommands();
+ }
+}
+
+let searchBar;
+
+function fuzzyMatch(str, pattern, accuracy) {
+ pattern = pattern.replace(/[-\\\/^$*+?.()|[\]{}]/g, "\\$&");
+ pattern = pattern.split("").reduce((a, b) => a + `.*${b}`, "");
+
+ const regex = new RegExp(pattern, "i");
+ const matchScore = str.match(regex) ? str.match(regex)[0].length : 0;
+ const requiredScore = str.length * accuracy;
+
+ return matchScore >= requiredScore;
+}
+
+function toggleSearch(preview) {
+ if (searchBar == undefined) {
+ if (searchBar == undefined && areSettingsOpen) return;
+ document.getElementById('searchIcon').style.rotate = '360deg'
+ areSettingsOpen = true;
+ searchBar = document.createElement('div');
+ searchBar.className = 'search'
+ searchBar.style.zIndex = '2147483647'
+ searchBar.style.position = 'relative'
+
+ document.body.appendChild(searchBar);
+ searchBar.innerHTML = `
+
+
+ Start your search with : to search within ${botData.commands[lastObj]?.name || "nothing"}'s actions, ! to search for a(n) ${selectedGroupType} and / to search through available automations.
+ `
+
+ setTimeout(() => {
+ searchBar.firstElementChild.focus();
+ searchBar.style.opacity = '1';
+ searchBar.style.scale = '1';
+ searchBar.style.filter = 'unset'
+ }, 30);
+ } else {
+ document.getElementById('searchIcon').style.rotate = '0deg'
+ areSettingsOpen = false;
+ searchBar.style.scale = ''
+ searchBar.style.opacity = ''
+ searchBar.style.filter = ''
+ const cachedsearchbar = searchBar;
+ searchBar = undefined;
+ setTimeout(() => {
+ cachedsearchbar.remove();
+ }, editorSettings.commonAnimation * 100);
+ }
+}
+
+if (botData.openThemesAtLaunch) {
+ botData.openThemesAtLaunch = false;
+ saveLocally();
+
+ toggleSearch();
+
+ let themes = [];
+
+ fs.readdirSync('./Themes').forEach(themeFolder => {
+ try {
+ let themeData = require(`${processPath}/Themes/${themeFolder}/data.json`);
+ themes.push({ ...themeData, folder: themeFolder })
+ } catch (error) { }
+ })
+
+ searchBar.style.height = 'fit-content'
+ searchBar.style.paddingBottom = '5px'
+ searchBar.style.maxHeight = '500px'
+ searchBar.innerHTML = `
+ ${studioUI.dropdown({
+ name: 'Theme',
+ options: [{ name: "Default", value: "default" }, ...themes.map((theme) => { return { name: theme.name, value: theme.folder } })],
+ currentChoice: settings.theme,
+ onclick: "pickTheme(this.parentElement.dataset.chosen)",
+ forcePush: true,
+ style: "width: 98.5% !important;"
+ })}
+
+ ${strings.misc.done}
+ `
+}
+
+function pickTheme(theme) {
+ settings.theme = theme;
+ saveSettings();
+
+ try {
+ let themeCss = fs.readFileSync(`./Themes/${theme}/theme.css`, 'utf8');
+
+ if (document.getElementById('theme_container')) {
+ document.getElementById('theme_container').innerHTML = themeCss
+ } else {
+ let styleSheet = document.createElement('style');
+ styleSheet.id = 'theme_container';
+ styleSheet.innerHTML = themeCss;
+ document.body.appendChild(styleSheet)
+ }
+ document.body.style.background = 'var(--editor-background)'
+ } catch (error) {
+ document.getElementById('theme_container').innerHTML = ''
+ setColor({ style: { background: botData.color || "rgb(0, 0, 0)" } });
+ }
+}
+
+
+try {
+ pickTheme(settings.theme)
+} catch (error) {
+ pickTheme('default')
+}
+
+async function search(query) {
+ await new Promise(res => {
+ res()
+ if (loadedAutomations.length == 0) {
+ fs.readdirSync('./Automations').forEach((folderName) => {
+ try {
+ loadedAutomations.push({
+ ...require(`${process.cwd()}/Automations/${folderName}/data.json`), ...{
+ id: folderName
+ }
+ });
+ } catch (error) { }
+ })
+ }
+ })
+
+
+ let results = document.getElementById('searchResults')
+ results.innerHTML = ''
+ if (query == '') {
+ searchBar.style.marginTop = ''
+ setTimeout(() => {
+ results.style.height = '0px'
+ }, 10);
+ return
+ } else {
+ searchBar.style.marginTop = '2vh'
+ }
+
+ let queryTypes = {
+ '/': "automations",
+ '!': "commands",
+ ':': "actions",
+ }
+
+ let queryType = [queryTypes[query[0]]];
+ if (!queryType[0]) {
+ queryType = ["actions", "automations", "commands"];
+ } else {
+ query = query.substring(1)
+ }
+
+
+ let actions = botData.commands[lastObj].actions;
+
+ let resultsFound = 0;
+
+ let endResults = {
+ actions: [],
+ automations: [],
+ commands: []
+ }
+
+ queryType.forEach((type) => {
+ if (type == 'actions') {
+ actions.forEach((action, index) => {
+ if (fuzzyMatch(action.name.toLowerCase().replaceAll(' ', ''), query.toLowerCase().replaceAll(' ', ''), 0.12) || Number(query.replaceAll('#', '')) - 1 == index) {
+ endResults[type].push({
+ indicator: `#${index + 1}`,
+ label: action.name,
+ actions: [
+ { label: "Higlight", onclick: `highlight(document.getElementById('Action${index}'))` },
+ { label: "Edit", onclick: `editAction(${index})` },
+ ]
+ })
+ }
+ });
+ } else if (type == 'commands') {
+ botData.commands.forEach((command, index) => {
+ if (!((command.type == (selectedGroupType == "command" ? "action" : "event")) && command.name.replaceAll(' ', '') != '')) return;
+ if (!editorSettings.hideCommandInvokers) {
+ let commandTriggerMap = {
+ textCommand: botData.prefix,
+ slashCommand: "/",
+ }
+
+ preDeco = commandTriggerMap[command.trigger] || ``;
+ }
+
+ if (fuzzyMatch(command.name.toLowerCase().replaceAll(' ', ''), query.toLowerCase().replaceAll(' ', ''), 0.12)) {
+ endResults[type].push({
+ label: command.name,
+ indicator: preDeco,
+ actions: [
+ { label: "Higlight", onclick: `highlight(document.getElementById('Group${index}'))` }
+ ]
+ })
+ }
+ })
+ } else if (type == 'automations') {
+ loadedAutomations.forEach((automation) => {
+ if (fuzzyMatch(automation.name, query.toLowerCase().replaceAll(' ', ''), 0.12)) {
+ endResults[type].push({
+ label: automation.name,
+ indicator: ``,
+ onclick: 0,
+ actions: [
+ { label: "Run", onclick: `runAutomation('${automation.id}')` }
+ ]
+ })
+ }
+ })
+ }
+ })
+
+
+ let leftSeparatorDisplay, rightSeparatorDisplay, subtitlePosition;
+
+ switch (editorSettings.subtitlePosition) {
+ case "left":
+ leftSeparatorDisplay = "none";
+ rightSeparatorDisplay = "inherit; margin-left: 5px !important;";
+ subtitlePosition = "margin-left: 5px !important; margin-right: auto;";
+ break;
+ case "right":
+ rightSeparatorDisplay = "none";
+ leftSeparatorDisplay =
+ "inherit; margin-right: 5px !important; margin-left: 10px !important;";
+ subtitlePosition = "margin-right: 0; margin-left: auto;";
+ deleteButtonStyling = "margin-left: 5px;";
+ break;
+ case "center":
+ rightSeparatorDisplay = "inherit";
+ leftSeparatorDisplay = "inherit; margin-left: 5px !important;";
+ subtitlePosition = "margin-right: 5px; margin-left: 5px;";
+ break;
+ }
+
+ if (editorSettings.focus) {
+ rightSeparatorDisplay = 'none'
+ leftSeparatorDisplay = 'none'
+ }
+
+ let toHTML = (data) => {
+ return `
+
+ ${data.indicator ? `
${data.indicator}` : ""}
+
${data.label}
+
+
+ ${data.subtitle ? `
${data.subtitle}` : ""}
+
+ ${data.actions?.map((i) => {
+ return `
+
${i.label}
+ `
+ }).join('')}
+
+ `
+ }
+
+ queryType.forEach((type) => {
+ if (!endResults[type]?.length) return
+ resultsFound++
+ results.innerHTML += `
+ Results for ${type}
+ ${endResults[type].map(i => toHTML(i)).join('')}
+
+ `
+ })
+
+ if (resultsFound == 0) {
+ results.innerHTML = `
+ Oof.. nothing to see here
+ `
+ }
+ setTimeout(() => {
+ results.style.height = '270px'
+ }, 30);
+}
+
+
+function refreshIntents() {
+ return
+ if (!botData.intents) {
+ botData.intents = ["all"]
+ saveLocally()
+ }
+
+ document.getElementById('intents').innerHTML = ''
+
+ let intents = {
+ all: "All",
+ guildMessages: "Guild Messages",
+ messageContent: "Messages Content",
+ guilds: "Guilds",
+ guildExpressions: "Guild Expressions",
+ directMessages: "Direct Messages",
+ guildIntegrations: "Guild Integrations",
+ guildMembers: "Guild Members",
+ guildInvites: "Guild Invites",
+ guildPresence: "Guild Presences",
+ guildModeration: "Guild Moderation",
+ typingMessages: "Guild Message Typing",
+ }
+
+ for (let i in intents) {
+ let intent = intents[i]
+ document.getElementById('intents').innerHTML += `${intent}
`
+ }
+}
+
+function toggleIntent(intent, e) {
+ if (botData.intents.includes(intent)) {
+ e.style.background = ''
+ for (let i in botData.intents) {
+ if (botData.intents[i] == intent) {
+ botData.intents.splice(i, 1)
+ saveLocally()
+ }
+ }
+ } else {
+ botData.intents.push(intent)
+ e.style.background = 'var(--accent)'
+ saveLocally()
+ }
+}
+
+function dupe(from, target) {
+ fs.writeFileSync(from, fs.readFileSync(target, 'utf8'))
+}
+
+function saveSettings() {
+ fs.writeFileSync(
+ path + "/EditorSettings.json",
+ JSON.stringify(settings),
+ );
+}
+
+
+
+if (settings.lastVersionOpened != version) {
+ // toggleSearch();
+ // searchBar.style.height = '500px'
+ // searchBar.style.padding = '12px'
+
+ // let endHTML = ``
+
+ // if (changelog.actions) {
+ // let end = `
+ // New Actions
+ // `
+ // changelog.actions.forEach(act => {
+ // let action = require(`${process.cwd()}/AppData/Actions/${act}`);
+ // end += `
+ //
+ //
See In Action
+ //
${action.data.name}
+ //
+ //
${action.category || "Uncategorized"}
+ //
+ // `
+ // });
+
+ // endHTML += `${end}`
+ // }
+
+ // if (changelog.updatedActions) {
+ // let end = `
+ // Updated Actions
+ // `
+ // changelog.updatedActions.forEach(act => {
+ // let action = require(`${process.cwd()}/AppData/Actions/${act.action}`);
+ // end += `
+ //
+ // ${action.data.name}
+ //
+ // ${act.update}
+ //
+ // `
+ // });
+
+ // endHTML += `${end}`
+ // }
+
+ // if (changelog.updatedEditor) {
+ // let end = `
+ // Editor Updates
+ // `
+ // changelog.updatedEditor.forEach(update => {
+ // end += `
+ //
+ // ${update.type.toUpperCase()}
+ // ${update.name}
+ // ${update.description}
+ //
+ // `
+ // });
+
+ // endHTML += `${end}`
+ // }
+
+ // searchBar.innerHTML = `
+ // Just Updated - What's New? Dismiss
+ //
+ //
+ // ${endHTML}
+ //
+ // `
+}
+
+function countUppercaseLetters(str) {
+ let count = 0;
+
+ for (let i = 0; i < str.length; i++) {
+ if (str[i] >= 'A' && str[i] <= 'Z') {
+ count++;
+ }
+ }
+ return count;
+}
+
+function runAutomation(automationID) {
+ let search = document.getElementsByClassName('search')[0];
+
+ let automation = require(`./Automations/${automationID}/main.js`);
+ let automationData = require(`./Automations/${automationID}/data.json`);
+
+ automation.run({
+ showInterface: (UI, data) => {
+ ipcRenderer.send(`openCustom`, {
+ data: data || { name: automationData.name },
+ UI,
+ name: automationData.name,
+ actionType: 'text',
+ });
+
+ return new Promise((res) => {
+ ipcRenderer.once('menuData', (event, data) => {
+ setTimeout(() => {
+ res(data);
+ }, 10);
+ })
+ })
+ },
+ eval,
+ burstInform: (message) => {
+ search.innerHTML = `
+ ${message}
+ `
+ },
+ result: (message) => {
+ search.style.opacity = 0;
+ search.style.padding = '0px'
+ setTimeout(() => {
+ search.style.padding = '15px'
+ search.innerHTML = `
+ ${message}
+ `
+ setTimeout(() => {
+ if (searchBar) {
+ toggleSearch()
+ }
+ }, 3000);
+
+ search.style.opacity = 1;
+ }, editorSettings.commonAnimation * 100);
+
+ }
+ });
+
+ search.style.opacity = 0;
+ setTimeout(() => {
+ search.style.padding = '15px'
+ search.innerHTML = `
+ ${automationData.name} is running...
+ `
+ search.style.opacity = 1;
+ }, editorSettings.commonAnimation * 100);
+}
\ No newline at end of file
diff --git a/kits/PopupModalHandler.js b/kits/PopupModalHandler.js
new file mode 100644
index 0000000..5281d8e
--- /dev/null
+++ b/kits/PopupModalHandler.js
@@ -0,0 +1 @@
+// don't ask what this is
\ No newline at end of file
diff --git a/kits/Toolkit/botInit.js b/kits/Toolkit/botInit.js
new file mode 100644
index 0000000..cbd4850
--- /dev/null
+++ b/kits/Toolkit/botInit.js
@@ -0,0 +1,78 @@
+const runCmd = require("node-run-cmd");
+const customFs = require("fs");
+
+const filePath = "./bot.js";
+function consoleLog(log) {
+ document.getElementById(
+ "console",
+ ).innerHTML += `${ansiToHtml(
+ log,
+ )}
`;
+}
+
+let ranbot = false;
+
+const fs = require("fs");
+const { exec } = require("child_process");
+const os = require("os");
+
+exec("node -v", (error, stdout, stderr) => {
+ if (error) {
+ consoleLog(
+ "Node.js is not installed. Downloading now... (This will take a while..)",
+ );
+ const platform = os.platform();
+
+ if (platform === "win32") {
+ exec(
+ "winget install --accept-source-agreements --accept-package-agreements nodeJS",
+ (error, stdout, stderr) => {
+ if (error) {
+ consoleLog(
+ `Error occured whilst downloading Node.JS, please visit the support guild or download Node.JS manually`,
+ );
+ return;
+ }
+ consoleLog(
+ `Finished downloading Node.js! Studio Bot Maker will close in order to comply with the new changes. Please reopen it afterwards!`,
+ );
+
+ setTimeout(() => {
+ require("electron").ipcRenderer.send("restart", true);
+ }, 7500);
+ },
+ );
+ } else {
+ consoleLog(
+ "winget is only available on Windows. Please download it manually",
+ );
+ }
+ } else {
+ consoleLog(`Node.JS ${stdout} is already installed, jumping directly to Startup.`);
+ consoleLog(`Checking NPM modules.. This might take a bit`);
+
+ exec("npm i oceanic.js@1.8.0", (err) => {
+ runBot()
+ });
+ exec("npm i @oceanicjs/builders");
+ exec("npm i discord-api-types");
+ }
+});
+
+async function runBot() {
+ if (ranbot == true) return;
+ ranbot = true;
+ customFs.writeFileSync(
+ "bot.js",
+ customFs.readFileSync("./AppData/bot.js", "utf8"),
+ );
+ runCmd
+ .run(`node ${filePath}`, { onData: consoleLog, onError: consoleLog, oncancel: cancelWindow })
+ .catch((error) => {
+ consoleLog(`Error executing bot.js: ${error}`);
+ });
+}
+
+let cancelWindow = () => {
+ ipcRenderer.send('')
+}
\ No newline at end of file
diff --git a/kits/Toolkit/interactionTools.js b/kits/Toolkit/interactionTools.js
new file mode 100644
index 0000000..79a37d9
--- /dev/null
+++ b/kits/Toolkit/interactionTools.js
@@ -0,0 +1,22 @@
+module.exports = {
+ stopExecution(uID) {
+ var tempVars = JSON.parse(fs.readFileSync("./tempVars.json", "utf8"));
+
+ tempVars[uID][`${uID}_stop`] = true;
+ fs.writeFileSync("./tempVars.json", JSON.stringify(tempVars));
+ },
+ async runCommand(id, actionRunner, uID, client, message) {
+ const datjson = require("../data.json");
+ for (let command in datjson.commands) {
+ if (datjson.commands[command].customId == id) {
+ await actionRunner(command, message, client, uID);
+ }
+ }
+ },
+ preventDeletion(uID) {
+ return;
+ },
+ leak(uID, customTimestamp) {
+ return;
+ },
+};
diff --git a/kits/Toolkit/storedData.json b/kits/Toolkit/storedData.json
new file mode 100644
index 0000000..08ae05c
--- /dev/null
+++ b/kits/Toolkit/storedData.json
@@ -0,0 +1,7 @@
+{
+ "users": { },
+ "guilds": {},
+ "members": {},
+ "channels": {},
+ "lists": {}
+}
diff --git a/kits/Toolkit/variableTools.js b/kits/Toolkit/variableTools.js
new file mode 100644
index 0000000..1ff2962
--- /dev/null
+++ b/kits/Toolkit/variableTools.js
@@ -0,0 +1,31 @@
+module.exports = {
+ transf(text, variables) {
+ try {
+ const tempVars = (variable) => {
+ if (typeof variables[variable] == 'string' || variables[variable] == undefined || typeof variables[variable] == 'number') {
+ return variables[variable];
+ } else {
+ try {
+ if (variables[variable].userID) {
+ return `<@${variables[variable].user.id}>`
+ } else if (variables[variable].topic && variables[variable].guildID) {
+ return `<#${variables[variable].id}>`
+ } else if (variables[variable].publicFlags) {
+ return `<@${variables[variable].id}>`
+ } else if (typeof variables[variable].hoist == "boolean") {
+ return `<@&${variables[variable].id}>`
+ }
+ } catch (err) {return variables[variable]}
+ }
+ };
+
+ let formattedText = text;
+ if (formattedText.includes("`")) {
+ formattedText = formattedText.replace(/`/g, "/`");
+ }
+
+ const evaluatedText = eval("`" + formattedText + "`");
+ return evaluatedText;
+ } catch (err) {return ''}
+ },
+};
\ No newline at end of file
diff --git a/kits/botLoader.js b/kits/botLoader.js
new file mode 100644
index 0000000..8fe72f3
--- /dev/null
+++ b/kits/botLoader.js
@@ -0,0 +1,2 @@
+var Convert = require("ansi-to-html");
+var convert = new Convert();
diff --git a/kits/flex.js b/kits/flex.js
new file mode 100644
index 0000000..da9e4d7
--- /dev/null
+++ b/kits/flex.js
@@ -0,0 +1,814 @@
+let variableInsertionData = {}
+
+const EventEmitter = require('events');
+
+let actionEvents = new EventEmitter();
+
+function refreshUI() {
+ document.getElementById('editorContent').innerHTML = getUIelements(actionUI, false, true)
+}
+
+function emitChange(changed) {
+ actionEvents.emit('change', {
+ data: action.data,
+ type: actionType,
+ UI: actionUI,
+ document: document,
+ events: actionEvents,
+ changed,
+ extra: globalData || null,
+ updateUI: refreshUI
+ })
+}
+
+function createDropdown(element, hasField, translations, index, defaultName, toRun) {
+ return `
+ ${element.name ? element.name : defaultName}
+
+
+
${translations[action.data[element.storeAs].type].name}
+
+
+
+ `
+}
+
+function getUIelements(UI, excludeTitle, excludeScript, options) {
+ let additional = ''
+ let indexOffset = 0;
+
+ let endHTML = `
+
+ ${action.name}
+ ${additional}
+
+
+ `;
+
+ if (excludeTitle == true) {
+ endHTML = ''
+ } else {
+ endHTML += ''
+ }
+ let pendingMenus = [];
+ let pendingActions = [];
+ let pendingTabs = [];
+
+ for (let index in UI) {
+ let realIndex = Number(index)
+ let element = UI[index];
+
+ if (typeof UI[index] == 'string') {
+ if (UI[index] == '' || UI[index] == 'sep' || UI[index] == 'sepbar' || UI[index] == '-') {
+ endHTML += ''
+ }
+ if (UI[index] == '_') {
+ endHTML += ``
+ }
+ } else {
+ if (options?.starterIndex) {
+ index = index + (options.starterIndex || 0);
+ }
+
+ index = Number(index) + indexOffset;
+
+ try {
+ if (element.element == 'input') {
+ element.type = undefined;
+ if (!action.data[element.storeAs]) {
+ action.data[element.storeAs] = ''
+ }
+
+ endHTML += `${element.name}`
+ }
+
+ if (element.element == 'largeInput') {
+ if (!action.data[element.storeAs]) {
+ action.data[element.storeAs] = ''
+ }
+ endHTML += `${element.name}`
+ }
+
+
+ if (element.element == 'inputGroup') {
+ if (!action.data[element.storeAs[0]]) {
+ action.data[element.storeAs[0]] = ''
+ }
+
+ if (!action.data[element.storeAs[1]]) {
+ action.data[element.storeAs[1]] = ''
+ }
+
+ endHTML += `
+
+ `
+ }
+
+ if (element.element == 'toggle') {
+ if (!action.data[element.storeAs]) {
+ action.data[element.storeAs] = false
+ }
+
+ endHTML += studioUI.toggle({ state: (action.data[element.storeAs] == true || action.data[element.storeAs] == 'true') ? true : false, true: element.true, false: element.false, name: element.name }, `action.data['${element.storeAs}'] = (this.dataset.state == 'true')`)
+ }
+
+ if (element.element == 'toggleGroup') {
+ if (!action.data[element.storeAs[0]]) {
+ action.data[element.storeAs[0]] = false
+ }
+ if (!action.data[element.storeAs[1]]) {
+ action.data[element.storeAs[1]] = false
+ }
+
+ let leftWidth = `(var(--width-in-editor) / 2 + 4px)`;
+ let rightWidth = `(var(--width-in-editor) / 2 + 4px)`;
+
+ if (element.prefer == 0) {
+ leftWidth = `((var(--width-in-editor) / 1.6) - 13.5px)`
+ rightWidth = `((var(--width-in-editor) / 2.4) - 13.5px)`
+ }
+ if (element.prefer == 1) {
+ rightWidth = `((var(--width-in-editor) / 1.6) - 13.5px)`
+ leftWidth = `((var(--width-in-editor) / 2.4) - 13.5px)`
+ }
+
+ endHTML += `
+
+ ${studioUI.toggle({ style: `width: calc(${leftWidth} - var(--padding-super)); margin-right: 2px !important; margin-bottom: 0px; margin-top: 0px !important;`, state: (action.data[element.storeAs[0]] == true || action.data[element.storeAs[0]] == 'true') ? true : false, true: element.true ? element?.true[0] : null, false: element.false ? element?.false[0] : null, name: element?.nameSchemes[0] }, `action.data['${element.storeAs[0]}'] = (this.dataset.state == 'true')`)}
+ ${studioUI.toggle({ style: `width: calc(${rightWidth} - var(--padding-super)); margin-left: 2px !important; margin-bottom: 0px; margin-top: 0px !important;`, state: (action.data[element.storeAs[1]] == true || action.data[element.storeAs[1]] == 'true') ? true : false, true: element.true ? element?.true[1] : null, false: element.false ? element?.false[1] : null, name: element?.nameSchemes[1] }, `action.data['${element.storeAs[1]}'] = (this.dataset.state == 'true')`)}
+
`
+ }
+
+ if (element.element == 'storageInput' || element.element == 'storage' || element.element == 'store') {
+ let translations = {
+ temporary: { name: "Temporary Variable", field: true },
+ server: { name: "Server Variable", field: true },
+ global: { name: "Global Variable", field: true }
+ }
+
+ if (element.optional) {
+ translations.none = { name: "None", field: false }
+ }
+
+ if (!action.data[element.storeAs]) {
+ if (element.optional) {
+ action.data[element.storeAs] = { type: "none", value: "" }
+ } else {
+ action.data[element.storeAs] = { type: "temporary", value: "" }
+ }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ if (element.optional) {
+ action.data[element.storeAs].type = 'none'
+ } else {
+ action.data[element.storeAs].type = 'temporary'
+ }
+ }
+
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, 'Store As', { onblur: "recacheOwnVariables()" })
+ }
+
+ if (element.element == 'memberInput' || element.element == 'userInput' || element.element == 'member' || element.element == 'user') {
+ let translations = {}
+
+ if (actionType == 'text') {
+ translations.mentioned = { name: "Mentioned User", field: false }
+ translations.author = { name: "Command Author", field: false }
+ } else if (actionType == 'slash') {
+ translations.author = { name: "Command Author", field: false }
+ } else if (actionType == 'message') {
+ translations.author = { name: "Command Author", field: false }
+ translations.messageAuthor = { name: "Message Author", field: false }
+ } else if (actionType == 'user') {
+ translations.author = { name: "Command Author", field: false }
+ translations.user = { name: "Command User", field: false }
+ }
+
+ translations.id = { name: "User ID", field: true };
+
+ if (element.also) {
+ for (let o in element.also) {
+ let also = element.also[o];
+ translations[o] = { name: also, field: true }
+ }
+ }
+
+ if (element.and) {
+ for (let o in element.and) {
+ if (translations[o]) {
+ let and = element.and[o];
+ translations[o].field = and;
+ }
+ }
+ }
+
+ if (element.additionalOptions) {
+ translations = {
+ ...element.additionalOptions,
+ ...translations
+ }
+ }
+
+ translations.tempVar = { name: "Temporary Variable", field: true }
+ translations.serverVar = { name: "Server Variable", field: true }
+ translations.globVar = { name: "Global Variable", field: true }
+
+ if (!action.data[element.storeAs]) {
+ let type = 'id';
+
+ if (actionType == 'text' || actionType == 'slash' || actionType == 'message' || actionType == 'user') {
+ type = 'author'
+ }
+
+ action.data[element.storeAs] = {
+ type,
+ value: ""
+ }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ action.data[element.storeAs].type = 'id'
+ }
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, 'User')
+ }
+
+ if (element.element == 'halfDropdown' || element.element == 'dropdown') {
+ let foundChoice;
+
+ if (!element.preventRecovery) {
+ if (!action.data[element.storeAs]) {
+ action.data[element.storeAs] = element.choices[0].name;
+ }
+
+ if (!action.data[element.extraField] && element.extraField) {
+ action.data[element.extraField] = '';
+ }
+
+ for (let choice of element.choices) {
+ if (choice.name == action.data[element.storeAs]) {
+ foundChoice = choice;
+ }
+ }
+
+ if (!foundChoice) {
+ action.data[element.storeAs] = element.choices[0].name
+ foundChoice = element.choices[0]
+ }
+ } else {
+ foundChoice = {
+ name: action.data[element.storeAs] || element.choices[0].name
+ }
+ }
+
+ let text = `${element.name}`
+ if (!element.name) {
+ text = ''
+ }
+ endHTML += `
+ ${text}
+
+ `
+ }
+
+ if (element.element == 'typedDropdown' || element.element == 'typed') {
+ let translations = element.choices;
+
+ if (!action.data[element.storeAs]) {
+ let type = translations[0];
+
+ action.data[element.storeAs] = {
+ type,
+ value: ""
+ }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ action.data[element.storeAs].type = Object.keys(translations)[0];
+ }
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, element.name || "")
+ }
+
+ if (element.element == 'channelInput' || element.element == 'channel') {
+ let translations = {}
+
+ if (element.optional) {
+ translations.none = { name: "None", field: false }
+ }
+
+ if (actionType == 'text' || actionType == 'message') {
+ translations.command = { name: "Command Channel", field: false }
+ translations.mentionedChannel = { name: "Mentioned Channel", field: false }
+
+
+ if (!element.excludeUsers) {
+ translations.commandAuthor = { name: "Command Author", field: false }
+ translations.mentionedChannel = { name: "Mentioned User", field: false }
+ if (actionType == 'message') {
+ translations.user = { name: "Message Author", field: false }
+ }
+ }
+ } else if (actionType == 'slash') {
+ translations.command = { name: "Command Channel", field: false }
+
+ if (!element.excludeUsers) {
+ translations.commandAuthor = { name: "Command Author", field: false }
+ }
+ } else if (actionType == 'user') {
+ if (!element.excludeUsers) {
+ translations.commandAuthor = { name: "Command Author", field: false }
+ translations.user = { name: "Command User", field: false }
+ }
+ }
+
+ translations.id = { name: "Channel ID", field: true }
+
+ if (!element.excludeUsers) {
+ translations.userID = { name: "User ID", field: true }
+ }
+
+ if (element.also) {
+ for (let o in element.also) {
+ let also = element.also[o];
+ translations[o] = { name: also, field: true }
+ }
+ }
+
+ if (element.and) {
+ for (let o in element.and) {
+ if (translations[o]) {
+ let and = element.and[o];
+ translations[o].field = and;
+ }
+ }
+ }
+
+ if (element.additionalOptions) {
+ translations = {
+ ...element.additionalOptions,
+ ...translations
+ }
+ }
+
+ translations.tempVar = { name: "Temporary Variable", field: true }
+ translations.serverVar = { name: "Server Variable", field: true }
+ translations.globVar = { name: "Global Variable", field: true }
+
+ if (!action.data[element.storeAs]) {
+ if (element.optional) {
+ action.data[element.storeAs] = {
+ type: "none",
+ value: ""
+ }
+ } else {
+ let type = 'id';
+
+ if (actionType == 'text' || actionType == 'slash' || actionType == 'message') {
+ type = 'command'
+ }
+
+ action.data[element.storeAs] = {
+ type,
+ value: ""
+ }
+ }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ if (element.optional) {
+ action.data[element.storeAs].type = 'none'
+ } else {
+ action.data[element.storeAs].type = 'id'
+ }
+ }
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, 'Channel')
+ }
+
+ if (element.element == 'image' || element.element == 'imageInput') {
+ let translations = {
+ none: { name: "None", field: false },
+ file: { name: "File", field: true },
+ url: { name: "URL", field: true },
+ }
+
+ if (!action.data[element.storeAs]) {
+ if (element.optional) {
+ action.data[element.storeAs] = { type: 'none', value: '' }
+ } else {
+ action.data[element.storeAs] = { type: 'file', value: '' }
+ }
+ }
+
+ if (element.also) {
+ for (let o in element.also) {
+ let also = element.also[o];
+ translations[o] = { name: also, field: true }
+ }
+ }
+
+ if (element.and) {
+ for (let o in element.and) {
+ if (translations[o]) {
+ let and = element.and[o];
+ translations[o].field = and;
+ }
+ }
+ }
+
+ if (element.additionalOptions) {
+ translations = {
+ ...element.additionalOptions,
+ ...translations
+ }
+ }
+
+ translations = {
+ ...translations,
+ tempVar: { name: "Temporary Variable", field: true },
+ serverVar: { name: "Server Variable", field: true },
+ globVar: { name: "Global Variable", field: true }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ if (element.optional) {
+ action.data[element.storeAs].type = 'none'
+ } else {
+ action.data[element.storeAs].type = 'file'
+ }
+ }
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, 'Image')
+ }
+
+ if (element.element == 'actions') {
+ pendingActions.push(element);
+ if (action.data[element.storeAs] == undefined || (typeof action.data[element.storeAs] == 'object' && !Array.isArray(action.data[element.storeAs]))) {
+ action.data[element.storeAs] = [];
+ }
+
+ endHTML = `${endHTML}
+
+
+
+
`;
+ }
+
+ if (element.element == 'menu') {
+ if (action.data[element.storeAs] == undefined) {
+ action.data[element.storeAs] = [];
+ if (element.required) {
+ action.data[element.storeAs].push({
+ type: Object.keys(element.UItypes)[0],
+ data: undefined
+ })
+ }
+ }
+
+ if (element.max == 1) {
+ endHTML += `
+
+
+
+ `
+ } else {
+ endHTML = `${endHTML}
+
+
+
+
+
+
+ `;
+ }
+
+ pendingMenus.push(index);
+ }
+
+ if (element.element == 'text') {
+ endHTML += `${element.text}`
+ }
+
+ if (element.element == 'case' || element.element == 'condition') {
+ if (action.data[element.storeAs] == undefined) {
+ action.data[element.storeAs] = {
+ type: 'continue',
+ value: ''
+ }
+ action.data[element.storeActionsAs] = []
+ }
+
+ let translations = {
+ continue: { name: "Continue Actions", field: false },
+ stop: { name: "Stop Actions", field: false },
+ runActions: { name: "Run Actions", field: false },
+ skip: { name: "Skip # Actions", field: true },
+ jump: { name: "Jump To Action #", field: true },
+ anchorJump: { name: "Jump To Anchor", field: true },
+ callAnchor: { name: "Call Anchor", field: true },
+ }
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, '', 'toggleDropdownContainer')
+
+ pendingActions.push({ storeAs: element.storeActionsAs });
+ endHTML += `
+
+
+
+ `
+ }
+
+ if (element.element == 'variableInsertion' || element.element == 'var' || element.element == 'variable') {
+ let translations = {
+ tempVar: { name: "Temporary Variable", field: true },
+ serverVar: { name: "Server Variable", field: true },
+ globVar: { name: "Global Variable", field: true }
+ }
+
+ if (element.optional) {
+ translations.none = { name: "None", field: false }
+ }
+
+ if (element.also) {
+ for (let o in element.also) {
+ let also = element.also[o];
+ translations[o] = { name: also, field: true }
+ }
+ }
+
+ if (element.and) {
+ for (let o in element.and) {
+ let and = element.and[o];
+ translations[o].field = and;
+ }
+ }
+
+ if (element.additionalOptions) {
+ translations = {
+ ...element.additionalOptions,
+ ...translations
+ }
+ }
+
+ if (!action.data[element.storeAs]) {
+ if (element.optional) {
+ action.data[element.storeAs] = { type: "none", value: "" }
+ } else {
+ action.data[element.storeAs] = { type: 'tempVar', value: '' }
+ }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ if (element.optional) {
+ action.data[element.storeAs].type = 'none'
+ } else {
+ action.data[element.storeAs].type = 'tempVar'
+ }
+ }
+
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, 'Variable')
+ }
+
+ if (element.element == 'interaction') {
+ let translations = {}
+
+ if (actionType == 'slash' || actionType == 'message' || actionType == 'user') {
+ translations.commandInteraction = { name: "Command Interaction", field: false };
+ }
+
+ if (!action.data[element.storeAs]) {
+ if (actionType == 'slash' || actionType == 'message' || actionType == 'user') {
+ action.data[element.storeAs] = { type: "commandInteraction", value: "" }
+ } else {
+ action.data[element.storeAs] = { type: "tempVar", value: "" }
+ }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ action.data[element.storeAs].type = 'tempVar'
+ }
+
+ translations = {
+ ...translations,
+ tempVar: { name: "Temporary Variable", field: true },
+ serverVar: { name: "Server Variable", field: true },
+ globVar: { name: "Global Variable", field: true }
+ }
+
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, 'Interaction')
+ }
+
+ if (element.element == 'message' || element.element == 'messageDropdown') {
+ let translations = {};
+ if (element.optional) {
+ translations.none = { name: "None", field: false }
+ }
+
+ translations = {
+ ...translations,
+ tempVar: { name: "Temporary Variable", field: true },
+ serverVar: { name: "Server Variable", field: true },
+ globVar: { name: "Global Variable", field: true }
+ }
+
+ if (actionType == 'text' || actionType == 'message') {
+ translations.commandMessage = { name: "Command Message", field: false }
+ } else if (actionType == 'slash') {
+ translations.interactionReply = { name: "Command Reply", field: false }
+ }
+
+ if (!action.data[element.storeAs]) {
+ if (element.optional) {
+ action.data[element.storeAs] = { type: 'none', value: "" }
+ } else if (actionType == 'text' || actionType == 'message') {
+ action.data[element.storeAs] = { type: "commandMessage", value: "" }
+ } else if (actionType == 'slash') {
+ action.data[element.storeAs] = { type: "interactionReply", value: "" }
+ } else {
+ action.data[element.storeAs] = { type: "tempVar", value: "" }
+ }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ action.data[element.storeAs].type = element.optional ? 'none' : 'tempVar'
+ }
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, 'Message')
+ }
+
+ if (element.element == 'role' || element.element == 'roleInput') {
+ let translations = {
+ id: { name: "ID", field: true },
+ }
+
+ if (actionType == 'text' || actionType == 'message') {
+ translations.mentioned = { name: "Mentioned Role", field: false }
+ }
+
+ if (!action.data[element.storeAs]) {
+ action.data[element.storeAs] = { type: "id", value: "" }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ action.data[element.storeAs].type = 'tempVar'
+ }
+
+ translations = {
+ ...translations,
+ tempVar: { name: "Temporary Variable", field: true },
+ serverVar: { name: "Server Variable", field: true },
+ globVar: { name: "Global Variable", field: true }
+ }
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, 'Role')
+ }
+
+ if (element.element == 'html') {
+ endHTML += element.html
+ }
+
+ if (element.element == 'category' || element.element == 'guild') {
+ let translations = {
+ id: { name: "ID", field: true }
+ }
+
+ if (element.element == 'guild') {
+ translations.current = { name: "Current", field: false }
+ }
+
+
+ if (element.optional) {
+ translations.none = { name: "None", field: false }
+ }
+
+ if (!action.data[element.storeAs]) {
+ if (!element.optional) {
+ if (translations.current) {
+ action.data[element.storeAs] = { type: "current", value: "" }
+ } else {
+ action.data[element.storeAs] = { type: "id", value: "" }
+ }
+ } else {
+ action.data[element.storeAs] = { type: "none", value: "" }
+ }
+ }
+
+ translations = {
+ ...translations,
+ tempVar: { name: "Temporary Variable", field: true },
+ serverVar: { name: "Server Variable", field: true },
+ globVar: { name: "Global Variable", field: true }
+ }
+
+ if (!translations[action.data[element.storeAs].type]) {
+ if (!element.optional) {
+ action.data[element.storeAs].type = 'tempVar'
+ } else {
+ action.data[element.storeAs].type = 'none'
+ }
+ }
+
+ let hasField = translations[action.data[element.storeAs].type].field;
+
+ endHTML += createDropdown(element, hasField, translations, index, element.element == 'category' ? "Category" : "Server")
+ }
+ } catch (err) { console.log(err) }
+ }
+ }
+
+ if (options?.returnInstead) {
+ return endHTML
+ }
+
+ try {
+ return endHTML + "";
+ } finally {
+ setTimeout(() => {
+ for (let menu in pendingMenus) {
+ refreshMenuItems(pendingMenus[menu], true);
+ }
+ for (let action in pendingActions) {
+ refreshActions(pendingActions[action].storeAs);
+ }
+
+ if (actionFile.script && !excludeScript) {
+ actionFile.script({
+ data: action.data,
+ type: actionType,
+ UI: actionUI,
+ document: document,
+ events: actionEvents,
+ extra: globalData || null,
+ updateUI: refreshUI
+ })
+
+ emitChange(null);
+ }
+ }, 15);
+ }
+}
\ No newline at end of file
diff --git a/kits/settings.js b/kits/settings.js
new file mode 100644
index 0000000..9050583
--- /dev/null
+++ b/kits/settings.js
@@ -0,0 +1,619 @@
+let settingsFS = require('fs');
+const appID = Number('2592170');
+
+let path = 'C:/ProgramData/Bot-Maker-For-Discord'
+
+if (require('os').platform == 'linux') {
+ path = './linux-data'
+}
+if (require('os').platform == 'darwin') {
+ path = './mac-data'
+}
+
+let ownSettings = { theme: "default", translation: "default" };
+try {
+ ownSettings = JSON.parse(
+ settingsFS.readFileSync(path + "/EditorSettings.json", "utf8"),
+ );
+} catch (err) {
+ console.log(err);
+}
+
+let editorSettings = {
+ deletionScreening: true,
+ focus: ownSettings.focus == 'On' ? true : false,
+};
+
+switch (ownSettings.bigBrain) {
+ case 'On':
+ var sheet = document.styleSheets[1];
+ sheet.insertRule(":root{--smallBrainDisplay: none}");
+ editorSettings.bigBrain = true;
+ break
+ default:
+ var sheet = document.styleSheets[1];
+ editorSettings.bigBrain = false;
+ sheet.insertRule(":root{--bigBrainDisplay: none}");
+ break
+}
+
+switch (ownSettings.preffered) {
+ default:
+ editorSettings.groupPaneHeight = "inherit";
+ editorSettings.actionPaneHeight = "inherit";
+ break;
+ case "Group Pane":
+ editorSettings.actionPaneHeight = "calc(35.5vh - 12px)";
+ editorSettings.groupPaneHeight = "calc(44.5vh - 12px)";
+ break;
+ case "Action Pane":
+ editorSettings.groupPaneHeight = "calc(35vh - 12px)";
+ editorSettings.actionPaneHeight = "calc(45vh - 12px)";
+ break;
+}
+switch (ownSettings.actionPreviewPosition) {
+ default:
+ editorSettings.subtitlePosition = "center";
+ break;
+ case "Right":
+ editorSettings.subtitlePosition = "right";
+ break;
+ case "Left":
+ editorSettings.subtitlePosition = "left";
+ break;
+}
+switch (ownSettings.animations) {
+ case "Slow":
+ editorSettings.commonAnimation = 6;
+ editorSettings.fastAnimation = 4;
+ editorSettings.reallyFast = 1;
+ break;
+ case "Relaxed":
+ editorSettings.commonAnimation = 4;
+ editorSettings.fastAnimation = 3;
+ editorSettings.reallyFast = 0.5;
+ break;
+ case "Fast":
+ editorSettings.commonAnimation = 2;
+ editorSettings.fastAnimation = 1;
+ editorSettings.reallyFast = 0.01;
+ break;
+ case "Off":
+ editorSettings.commonAnimation = 0;
+ editorSettings.fastAnimation = 0;
+ editorSettings.reallyFast = 0;
+ break;
+ default:
+ editorSettings.commonAnimation = 3;
+ editorSettings.fastAnimation = 2;
+ editorSettings.reallyFast = 0.16;
+ break;
+}
+var sheet = document.styleSheets[0];
+sheet.insertRule(`:root{--commonAnimation: 0.${editorSettings.commonAnimation}s}`);
+sheet.insertRule(`:root{--fastAnimation: 0.${editorSettings.fastAnimation}s}`);
+sheet.insertRule(`:root{--reallyFast: ${editorSettings.reallyFast}s}`);
+
+
+switch (ownSettings.scaleEffects) {
+ case '1.2':
+ var sheet = document.styleSheets[0];
+ sheet.insertRule(":root{--scale: 1.1}");
+ break
+
+ case '0.8':
+ var sheet = document.styleSheets[0];
+ sheet.insertRule(":root{--scale: 0.95}");
+ break
+}
+
+switch (ownSettings.varStyle) {
+ case "Floating Window":
+ editorSettings.oldVariableInsertion = true;
+}
+
+switch (ownSettings.scrolling) {
+ default:
+ var sheet = document.styleSheets[0];
+ window.addEventListener("mousedown", function (event) {
+ if (event.button === 1) {
+ event.preventDefault();
+ }
+ });
+ sheet.insertRule(":root{--scrollbar: hidden}");
+ sheet.insertRule(":root{--scrw: 0px}");
+ break
+
+ case "On":
+ var sheet = document.styleSheets[document.styleSheets.length - 1];
+ sheet.insertRule(":root{--scrollbar: overlay}");
+ sheet.insertRule(":root{--scrw: 7px}");
+ break
+}
+
+switch (ownSettings.pointer) {
+ default:
+ var sheet = document.styleSheets[0];
+ sheet.insertRule(":root{--pointer: pointer}");
+ break
+
+ case 'Arrow':
+ var sheet = document.styleSheets[0];
+ sheet.insertRule(":root{--pointer: default}");
+ break
+}
+
+switch (ownSettings.deletionScreening) {
+ default:
+ editorSettings.actionDeletionScreening = true;
+ editorSettings.commandDeletionScreening = true;
+ break
+
+ case 'Off':
+ break
+
+ case 'Commands Only':
+ editorSettings.commandDeletionScreening = true;
+ break
+
+ case 'Actions Only':
+ editorSettings.actionDeletionScreening = true;
+ break
+}
+
+switch (ownSettings.actionButtons) {
+ case "Left":
+ editorSettings.leftActionPlacement = false;
+ break;
+ default:
+ editorSettings.leftActionPlacement = true;
+ break
+}
+
+
+switch (ownSettings.editOnCreation) {
+ case "Just Actions":
+ editorSettings.editActionsOnCreation = true;
+ break;
+ case "Just Menus":
+ editorSettings.editMenusOnCreation = true;
+ break;
+ case "On":
+ editorSettings.editMenusOnCreation = true;
+ editorSettings.editActionsOnCreation = true;
+ break;
+}
+
+editorSettings.animation = ownSettings.windowAnimation
+
+if (ownSettings.theme == undefined) {
+ ownSettings.theme = 'default';
+}
+
+// window.addEventListener('keydown', function(event) {
+// if ((event.ctrlKey || event.metaKey) && (event.key === '+' || event.key === '-')) {
+// event.preventDefault();
+// }
+// });
+
+
+/**
+ * @type {{ button: (options: any) => string; toggle: (options: any, onclick: any) => string; toggleSwitch: (element: HTMLDivElement) => void; }}
+ */
+let studioUI = {
+ toggle: (options, onclick) => {
+ return `
+
+
${options.name}
+
${options.false ? options.false : "No"}
+
+
${options.true ? options.true : "Yes"}
+
+ `
+ },
+
+
+ toggleSwitch: (element) => {
+ let toggle = element.getElementsByClassName('toggle_bar')[0].getElementsByClassName('toggle_tail')[0]
+ toggle.style.transition = `all 0.${editorSettings.commonAnimation}s ease`;
+ toggle.parentElement.style.transition = `all 0.${editorSettings.commonAnimation}s ease`;
+
+ if (element.dataset.state == 'false') {
+ element.dataset.state = 'true'
+
+ if (ownSettings.highlightToggles == 'On') {
+ element.classList.add('selected')
+ }
+
+ toggle.classList.add('toggle_button_animation_false_to_true');
+ toggle.classList.add('toggle_button_false_pre');
+ toggle.classList.remove('toggle_button_true_pre');
+ toggle.classList.remove('toggle_button_true');
+ toggle.parentElement.classList.add('toggle_tail_animation_true_to_false');
+
+ setTimeout(() => {
+ toggle.classList.remove('toggle_button_animation_false_to_true');
+ toggle.parentElement.classList.remove('toggle_tail_animation_true_to_false');
+ toggle.classList.add('toggle_button_false');
+ }, editorSettings.commonAnimation * 50);
+
+ } else {
+ element.dataset.state = 'false'
+
+ toggle.classList.remove('toggle_button_false_pre');
+ toggle.classList.remove('toggle_button_false');
+ toggle.classList.add('toggle_button_true_pre');
+ toggle.parentElement.classList.add('toggle_tail_animation_false_to_true');
+ element.classList.remove('selected');
+
+ toggle.classList.add('toggle_button_animation_true_to_false');
+
+ setTimeout(() => {
+ toggle.classList.remove('toggle_button_animation_true_to_false');
+ toggle.classList.add('toggle_button_true');
+ toggle.parentElement.classList.remove('toggle_tail_animation_false_to_true');
+ }, editorSettings.commonAnimation * 50);
+ }
+ },
+
+ dropdown: (options) => {
+ let choices = options.options;
+ let foundChoice;
+ choices.forEach(choice => {
+ if (choice.value == options.currentChoice) {
+ foundChoice = choice;
+ }
+ });
+
+ if (!foundChoice) {
+ foundChoice = choices[0];
+ }
+
+ return ``
+ },
+
+ openDropdown: (element, bound) => {
+ element.style.zIndex = '1000'
+ element.parentElement.style.zIndex = '1000'
+
+ element.onclick = () => {
+ studioUI.closeTypedDropdown(element, bound)
+ }
+
+ let types = JSON.parse(element.parentElement.dataset.options)
+
+ for (let translation of types) {
+ if (translation.value != element.parentElement.dataset.chosen) {
+ let option = document.createElement('div')
+ option.style = ''
+ option.className = 'dropdown_option'
+ option.onclick = () => {
+ studioUI.selectDropdownOption(element, bound, translation);
+ }
+ option.innerHTML = translation.name;
+ element.appendChild(option);
+ }
+ }
+ },
+
+ selectDropdownOption: (element, bound, translation) => {
+ element.parentElement.dataset.chosen = translation.value;
+
+ bound();
+ },
+
+ closeTypedDropdown: (element, bound) => {
+ element.style.animationName = "";
+ const innerHeight = element.clientHeight;
+ element.style.animationDuration = "";
+ element.style.setProperty("--inner-height", innerHeight + "px");
+ element.style.animationName = "shrink";
+ element.style.animationDuration = "300ms";
+ element.style.zIndex = ''
+ element.parentElement.style.zIndex = ''
+
+ setTimeout(() => {
+ element.onclick = () => {
+ studioUI.openDropdown(element, bound)
+ };
+ element.innerHTML = JSON.parse(element.parentElement.dataset.options).find(opt => opt.value == element.parentElement.dataset.chosen).name;
+ }, 70);
+ },
+
+ getColors: () => {
+ return ["rgb(255, 255, 255)", "rgb(255, 0, 0)", "rgb(255, 106, 0)", "rgb(255, 200, 0)", "rgb(187, 255, 0)", "rgb(51, 255, 0)", "rgb(0, 255, 213)", "rgb(0, 132, 255)", "rgb(0, 90, 255)", "rgb(72, 0, 255)", "rgb(119, 0, 255)", "rgb(195, 0, 255)", "rgb(255, 0, 225)"]
+ },
+
+ colorPicker: (style, onclick, rgb, realStyle) => {
+ return `
+
+
+
+
+
+
+ ${studioUI.getColors().map((color) => {
+ return `
`
+ }).join('')}
+
+ `
+ },
+
+ colorSlider: (options, style) => {
+ return `
+
+ ${options.inbetween || ""}
+
+ `
+ },
+
+
+ colorChange: (slider) => {
+ var val = slider.value;
+ var val2 = slider.nextElementSibling.value;
+ slider.style.setProperty('--chosenColor', `hsl(${val}, 100%, ${val2 * 100}%)`)
+ slider.nextElementSibling.style.setProperty('--chosenColor', `rgb(${opposite(val2) * 255}, ${opposite(val2) * 255}, ${opposite(val2) * 255})`)
+ },
+
+ togglePicker: (element) => {
+ let sibling = element;
+ if (sibling.style.width == '33px') {
+ sibling.style.width = '518.4px'
+ setTimeout(() => {
+ sibling.style.overflow = 'visible'
+ }, editorSettings.commonAnimation * 100);
+ } else {
+ sibling.style.width = '33px'
+ sibling.style.overflow = 'hidden'
+ }
+ },
+
+ colorPickerToggle: (id, constant) => {
+ document.getElementById(`${constant}red`).style.width = '0%'
+ document.getElementById(`${constant}red`).style.opacity = '0%'
+ document.getElementById(`${constant}red`).style.height = '0px'
+ document.getElementById(`${constant}green`).style.width = '0%'
+ document.getElementById(`${constant}green`).style.opacity = '0%'
+ document.getElementById(`${constant}green`).style.height = '0px'
+ document.getElementById(`${constant}blue`).style.width = '0%'
+ document.getElementById(`${constant}blue`).style.opacity = '0%'
+ document.getElementById(`${constant}blue`).style.height = '0px'
+
+ setTimeout(() => {
+ if (resolvedToggles[constant] != id) {
+ document.getElementById(id).style.width = '100%'
+ document.getElementById(id).style.opacity = '1'
+ document.getElementById(id).style.height = '30px'
+ resolvedToggles[constant] = id;
+ } else {
+ resolvedToggles[constant] = undefined;
+ }
+ }, resolvedToggles[constant] ? editorSettings.commonAnimation * 100 : 1);
+ },
+}
+
+function opposite(number) {
+ return (-number) + 1;
+}
+
+
+
+let resolvedToggles = {};
+
+async function awaitIPCResponse(send, receive) {
+ return new Promise(resolve => {
+ ipcRenderer.send(send.channel, send.content);
+
+ ipcRenderer.once(receive, (event, data) => {
+ resolve(data)
+ })
+ })
+}
+
+let keybindOverwrites = {}
+
+
+if (ownSettings.keybindOverwrites) {
+ for (let key in ownSettings.keybindOverwrites) {
+ let kbd = ownSettings.keybindOverwrites[key];
+ keybindOverwrites[key] = kbd;
+ }
+}
+
+let keybinds = {
+ save: { display: `CTRL+${(keybindOverwrites.save || "s").toUpperCase()}`, key: (keybindOverwrites.save || "s") },
+ save_exit: { display: `CTRL+${(keybindOverwrites.save_exit || "q").toUpperCase()}`, key: (keybindOverwrites.save_exit || "q") },
+ search: { display: `CTRL+${(keybindOverwrites.search || "k").toUpperCase()}`, key: (keybindOverwrites.search || "k") },
+ done: { display: `CTRL+${(keybindOverwrites.done || "q").toUpperCase()}`, key: (keybindOverwrites.done || "q") },
+ create: { display: `CTRL+${(keybindOverwrites.create || "d").toUpperCase()}`, key: (keybindOverwrites.create || "d") },
+ toggle: { display: `CTRL+${(keybindOverwrites.resize || "`").toUpperCase()}`, key: (keybindOverwrites.resize || "`") },
+ toggleState: { display: `CTRL+${(keybindOverwrites.resize || "`").toUpperCase()}`, key: (keybindOverwrites.resize || "`") },
+ newAction: { display: `CTRL+${(keybindOverwrites.newAction || "n").toUpperCase()}`, key: (keybindOverwrites.resize || "n") },
+ newCommand: { display: `CTRL+${(keybindOverwrites.newCommand || "j").toUpperCase()}`, key: (keybindOverwrites.resize || "j") },
+ exit: { display: `CTRL+TAB`, key: "tab" },
+ modifier: "ctrlKey",
+ modifier_readable: "CTRL",
+}
+
+const keybindElements = {
+ 'keybind-save': keybinds.save.display,
+ 'keybind-save-exit': keybinds.save_exit.display,
+ 'keybind-exit': keybinds.exit.display,
+ 'keybind-search': keybinds.search.display,
+ 'keybind-done': keybinds.done.display,
+ 'keybind-create': keybinds.create.display
+};
+
+for (const [className, displayText] of Object.entries(keybindElements)) {
+ for (const element of document.getElementsByClassName(className)) {
+ element.innerHTML = displayText;
+ }
+}
+
+
+try {
+ var datjson = JSON.parse(settingsFS.readFileSync("./AppData/data.json"));
+} catch (error) {
+ var datjson = {}
+}
+function finishEverything(cb) {
+ if (ownSettings.theme == 'default' || ownSettings.theme == undefined) {
+ document.getElementById("everything_container").style.background = `linear-gradient(130deg, ${ownSettings.firstColor || `rgb(0, 0, 0)`}, ${ownSettings.secondColor || `rgb(18, 18, 18)`})`;
+ } else {
+ document.getElementById("everything_container").style.background = `var(--window-background)`;
+ try {
+ document.getElementById('everything_container_2').style.backgroundColor = 'unset'
+ } catch (error) { }
+ }
+
+ let easingFunction = 'ease'
+
+ if (editorSettings.animation == 'Push' || !editorSettings.animation) {
+ document.getElementById("everything_container").style.transform = "rotate3d(12, 0, 0, -90deg)";
+ document.getElementById("everything_container").style.scale = "0";
+ // easingFunction = 'ease-in-out'
+ } else if (editorSettings.animation == 'Simple') {
+ document.getElementById("everything_container").style.scale = "1";
+ document.getElementById("everything_container").style.opacity = "0";
+ document.getElementById("everything_container").style.filter = "blur(0px)";
+ }
+
+
+ setTimeout(() => {
+ document.body.style.transition = `all 0.${editorSettings.commonAnimation}s ${easingFunction}`;
+ document.body.style.backgroundColor = "#FFFFFF00";
+ document.getElementById("everything_container").style.transition = `all 0.${editorSettings.commonAnimation}s ${easingFunction}`;
+ document.getElementById("everything_container").style.transform = "rotate3d(12, 0, 0, 0deg)";
+ document.getElementById("everything_container").style.scale = "1";
+ document.getElementById("everything_container").style.opacity = "1";
+ document.getElementById("everything_container").style.filter = "blur(0px)";
+ if (cb) {
+ setTimeout(() => {
+ cb()
+ }, editorSettings.commonAnimation * 100);
+ }
+ }, 20);
+}
+
+async function unfinishEverything(callback) {
+ if (editorSettings.animation == 'Simple') {
+ document.getElementById("everything_container").style.opacity = "0";
+ } else if (editorSettings.animation == 'Expand') {
+ document.getElementById("everything_container").style.scale = "0";
+ document.getElementById("everything_container").style.filter = "blur(40px)";
+ } else {
+ document.getElementById("everything_container").style.transform = "rotate3d(100, 0, 0, 90deg)";
+ document.getElementById("everything_container").style.scale = "0";
+ document.getElementById("everything_container").style.filter = "blur(40px)";
+ }
+
+ setTimeout(() => {
+ callback();
+ }, editorSettings.commonAnimation * 100);
+}
+
+try {
+ let themeCss = settingsFS.readFileSync(`./Themes/${ownSettings.theme}/theme.css`, 'utf8');
+
+ let styleSheet = document.createElement('style');
+ styleSheet.id = 'theme_container';
+ styleSheet.innerHTML = themeCss;
+ document.body.appendChild(styleSheet);
+} catch (error) {
+ let styleSheet = document.createElement('style');
+ styleSheet.id = 'theme_container';
+ styleSheet.innerHTML = '';
+ document.body.appendChild(styleSheet);
+}
+
+
+let cachedStrings;
+
+function getStrings() {
+ try {
+ if (cachedStrings) return cachedStrings;
+ let result;
+ let strings = require(`${process.cwd()}/cachedStrings.json`);
+ cachedStrings = strings;
+ return result;
+ } catch (error) { }
+}
+getStrings()
+
+
+function getString(string, replacements) {
+ for (let i in replacements) {
+ string = string.replace(`+${Number(i) + 1}`, replacements[i])
+ }
+
+ return string;
+}
+
+function dismissContent(content) {
+ if (!settingsFS.existsSync('./Dismissed Content')) {
+ settingsFS.mkdirSync('./Dismissed Content')
+ }
+
+ settingsFS.writeFileSync(`./Dismissed Content/${content}`, '1')
+}
+function isDismissed(content) {
+ return settingsFS.existsSync(`./Dismissed Content/${content}`, () => { })
+}
+
+function clipboardCopy(toCopy) {
+ navigator.clipboard.writeText(toCopy)
+}
+
+function updateTopBarContent(updated, specifity) {
+ let element = specifity ? document.getElementById(specifity) : document.getElementsByClassName('editor_toolbar')[0].getElementsByTagName('btext')[0]
+ element.style.transition = `all 0.${editorSettings.commonAnimation}s cubic-bezier(.47,.75,.36,1.54), blur ease var(--commonAnimation), var(--ease-strong) var(--commonAnimation)`
+
+ setTimeout(() => {
+ element.style.scale = '0.7';
+ element.style.opacity = '0';
+ element.style.filter = 'blur(12px)';
+ setTimeout(() => {
+ element.innerHTML = updated;
+ }, editorSettings.commonAnimation * 100);
+ setTimeout(() => {
+ element.style.scale = '1';
+ element.style.opacity = '1';
+ element.style.filter = '';
+ }, editorSettings.commonAnimation * 110);
+ }, 10);
+}
+
+var processPath = require('process').cwd();
+
+if (datjson.structureType != '1') {
+ processPath = processPath + `/Legacy`;
+}
+
+for (let i in document.getElementsByTagName('translation')) {
+ let element = document.getElementsByTagName('translation')[i];
+ element.innerHTML = eval(`cachedStrings.${element.id}`);
+}
+
+const hexToRGB = (hex) => {
+ const r = parseInt(hex.slice(1, 3), 16);
+ const g = parseInt(hex.slice(3, 5), 16);
+ const b = parseInt(hex.slice(5, 7), 16);
+
+ return `rgb(${r}, ${g}, ${b})`;
+}
+
+function componentToHex(c) {
+ var hex = c.toString(16);
+ return hex.length == 1 ? "0" + hex : hex;
+}
+
+function rgbToHEX(rgb) {
+ let rgbSeparated = rgb.replaceAll('rgb(', '').replaceAll(')', '').split(', ');
+ let r = rgbSeparated[0];
+ let g = rgbSeparated[1];
+ let b = rgbSeparated[2];
+ console.log(r, g, b, rgbSeparated)
+ return "#" + componentToHex(r) + componentToHex(g) + componentToHex(b);
+}
diff --git a/kits/temp.js b/kits/temp.js
new file mode 100644
index 0000000..e69de29
diff --git a/kits/variableInsertion.js b/kits/variableInsertion.js
new file mode 100644
index 0000000..fc8bcbd
--- /dev/null
+++ b/kits/variableInsertion.js
@@ -0,0 +1,530 @@
+window.oncontextmenu = function (event) {
+ if (!menu) {
+ setTimeout(() => {
+ showCustomMenu(event.clientX, event.clientY);
+ }, 200);
+ }
+ showCustomMenu(event.clientX, event.clientY);
+ return false;
+};
+let mOpened = false;
+
+function getVars(type, eID) {
+ foundVarType = [...commandVars, ...tempVars]
+ if (type == 'server') {
+ foundVarType = [...thisServer, ...serverVars]
+ } else if (type == 'global') {
+ foundVarType = [...thisGlobal, ...globalVars]
+ }
+
+ let used = [];
+ let endHTML = ''
+ if (type == 'command') {
+ let rawVariables = ownSettings.commandVariables;
+ let variables = {}
+
+ for (let variable in rawVariables) {
+ if (!rawVariables[variable].commandTypeLimits.length || rawVariables[variable].commandTypeLimits.includes(actionType)) {
+ variables[variable] = rawVariables[variable]
+ }
+ }
+
+ for (let type in variables) {
+ endHTML += `
+
+ `;
+ }
+ } else {
+ for (let variable in foundVarType) {
+ try {
+ if (foundVarType[variable].trim() != "" && !used.includes(foundVarType[variable])) {
+ used.push(foundVarType[variable])
+ endHTML += `
+
+ `;
+ }
+ } catch (err) { console.error(err) }
+ }
+ }
+
+ setTimeout(() => {
+ document.getElementById('vars-temporary').classList.remove('highlighted')
+ document.getElementById('vars-server').classList.remove('highlighted')
+ document.getElementById('vars-global').classList.remove('highlighted')
+ try {
+ document.getElementById('vars-command').classList.remove('highlighted')
+ } catch (error) { }
+ document.getElementById(`vars-${type}`).classList.add('highlighted')
+ }, 100);
+
+ return (endHTML || `
Your variables will appear here!`)
+}
+
+function showCustomMenu(x, y) {
+ let computedHeight = 'auto'
+ if (!menu) {
+ menu = document.createElement("div");
+ document.body.appendChild(menu);
+ menu.className = "right_click_menu";
+ }
+ // Calculate the maximum allowed coordinates based on window dimensions
+ const windowWidth = window.innerWidth;
+ const windowHeight = window.innerHeight;
+ const menuWidth = menu.offsetWidth;
+ const menuHeight = menu.offsetHeight;
+ const maxX = windowWidth - menuWidth;
+ const maxY = windowHeight - menuHeight;
+ let adjustedScale = 1;
+ // Adjust the menu position if it exceeds the window boundaries
+ let adjustedX = x;
+ let adjustedY = y;
+ if (x > maxX) {
+ adjustedX = maxX;
+ }
+ if (y > maxY) {
+ adjustedY = maxY - 48;
+ }
+
+ menu.style.top = adjustedY + "px";
+ menu.style.left = adjustedX + "px";
+ menu.style.maxHeight = '400px'
+
+ menu.style.scale = adjustedScale;
+ menu.style.opacity = `1`;
+
+ let type = 'indirect'
+ menu.onmouseenter = () => {
+ mOpened = true;
+ }
+ menu.onmouseleave = () => {
+ setTimeout(() => {
+ mOpened = false;
+ }, 20);
+ }
+
+ if (actionType != 'event') {
+ menu.innerHTML = `
+
+
Command
+
Temporary
+
Server
+
Global
+
+
+
+
+ `;
+ } else {
+ menu.innerHTML = `
+
+
Temporary
+
Server
+
Global
+
+
+
+
+ `;
+ }
+
+
+ setTimeout(() => {
+ document.getElementById('VARINSMENU').innerHTML = getVars('temporary', `${document.activeElement.id}`)
+ }, 10);
+
+ if (document.activeElement.tagName.toLowerCase() == 'input' || document.activeElement.tagName.toLowerCase() == 'textarea') {
+ menu.style.width = '348px'
+ if (variableInsertionData.type) {
+ type = variableInsertionData.type;
+ } else if (variableInsertionData.accept == false || variableInsertionData.accept) {
+ type = variableInsertionData.accept ? 'indirect' : 'off'
+ } else if (variableInsertionData.direct) {
+ type = 'direct'
+ } else if (variableInsertionData.custom) {
+ let direct = ['tempVar', 'cmdVar', 'serverVar', 'globVar'];
+
+ let UIelement = actionUI[variableInsertionData.elementIndex];
+ if (direct.includes(action.data[UIelement.storeAs].type)) {
+ type = action.data[UIelement.storeAs].type
+ }
+ }
+ } else {
+ menu.style.width = ''
+ menu.innerHTML = ``;
+ if (lastHovered != undefined) {
+ menu.innerHTML += `
+
+ `;
+ }
+
+ if (lastActionContainer) {
+ ipcRenderer.send('getCopiedAction');
+ ipcRenderer.once('copiedAction', (event, Action) => {
+ if (Action) {
+ menu.innerHTML += `
+
+ `;
+ }
+
+ menu.innerHTML += `
+
+
+
+ `
+ });
+ }
+
+ if (lastHoveredContainer) {
+ if (highlights[lastHoveredContainer].type == 2) {
+ if (lastHoveredMenu) {
+ menu.innerHTML += `
+
+ `
+ }
+ ipcRenderer.send('getCopiedMenu');
+ ipcRenderer.once('copiedMenu', (event, Menu) => {
+ if (Menu) {
+ menu.innerHTML += `
+ `
+ if (action.data[highlights[lastHoveredContainer].menu]) {
+ menu.innerHTML += `
+ `
+ }
+ }
+ if (lastHoveredMenu) {
+ if (actionUI[lastHoveredMenu.menu].max != action.data[actionUI[lastHoveredMenu.menu].storeAs].length) {
+ menu.innerHTML += `
+
+ `
+
+ }
+ }
+ })
+ }
+ }
+
+ }
+}
+
+function closeContextmenu(force) {
+ if (menu && !mOpened || force) {
+ menu.style.scale = "";
+ menu.style.opacity = "";
+ setTimeout(() => {
+ menu.remove();
+ menu = undefined;
+ }, 200);
+ }
+}
+
+function copyAction(Action, container) {
+ if (highlights[container].selected.length != 0) {
+ ipcRenderer.send('copiedAction', highlights[container].selected.map((value) => action.data[container][value]));
+ } else {
+ ipcRenderer.send('copiedAction', action.data[`${container}`][`${Action}`]);
+ }
+ closeContextmenu(true)
+}
+
+function pasteCopiedIn(container, Action) {
+ ipcRenderer.send('getCopiedAction');
+ ipcRenderer.once('copiedAction', (event, _Action) => {
+ let pasteIndex = action.data[container].length - 1;
+ if (action.data[container][Action]) {
+ pasteIndex = Number(Action) + 1;
+ }
+
+ if (_Action) {
+ if (Array.isArray(_Action)) {
+ _Action.forEach(act => {
+ action.data[container].splice(pasteIndex, 0, act);
+ pasteIndex++
+ });
+ } else {
+ action.data[container].splice(Number(highlights[container].highlighted) + 1, 0, _Action)
+ }
+ }
+ refreshActions(container)
+ });
+
+ closeContextmenu(true)
+}
+
+function pasteMenuIn(container, menu) {
+ ipcRenderer.send('getCopiedMenu');
+ ipcRenderer.once('copiedMenu', (event, unhandledMenu) => {
+ if (!unhandledMenu) return
+ if (document.getElementById(actionUI[highlights[container].menu].storeAs).getElementsByClassName('backArrow').length) {
+ document.getElementById(actionUI[highlights[container].menu].storeAs).getElementsByClassName('backArrow')[0].parentElement.style.opacity = '0'
+ }
+
+ let Menu;
+
+ let menuObject = actionUI[highlights[container].menu]
+ let max = menuObject.max;
+ let current = action.data[container].length;
+
+ if (Array.isArray(unhandledMenu)) {
+ Menu = []
+
+ unhandledMenu.forEach(item => {
+ if (Object.keys(menuObject.types).includes(item.type)) {
+ current++
+ if (current < max) {
+ Menu.push(item)
+ }
+ }
+ })
+ } else {
+ if (Object.keys(menuObject.types).includes(unhandledMenu.type)) {
+ Menu = unhandledMenu;
+ }
+ }
+
+ let pasteIndex = action.data[container].length - 1;
+ if (action.data[container][menu]) {
+ pasteIndex = Number(menu) + 1;
+ }
+
+ if (Menu) {
+ if (Array.isArray(Menu)) {
+ Menu.forEach(_menu => {
+ action.data[container].splice(pasteIndex, 0, _menu);
+ pasteIndex++
+ });
+ } else {
+ if (current != max) {
+ action.data[container].push(Menu)
+ }
+ }
+ }
+
+ refreshMenuItems(highlights[container].menu, action.data[container].length != 1, action.data[container].length == 1)
+ });
+
+ closeContextmenu(true)
+}
+
+
+document.addEventListener('keydown', (key) => {
+ if (document.activeElement.tagName != "BODY") return;
+
+ if (key.ctrlKey) {
+ isHoldingCTRL = true;
+ let offListener = (key) => {
+ if (key.ctrlKey) return;
+ isHoldingCTRL = false;
+ document.removeEventListener('keyup', offListener)
+ };
+ document.addEventListener('keyup', offListener)
+ }
+
+ if (key.key.toLowerCase() == 'a' && key.ctrlKey) {
+ if (document.activeElement.tagName != 'BODY') return;
+ if (highlights[lastContainer].type == 1) {
+ refreshActions(lastContainer);
+
+ setTimeout(() => {
+ const initiallySelected = highlights[lastContainer].highlighted
+ action.data[lastContainer].forEach((value, index) => {
+ if (index == initiallySelected) return;
+ isHoldingCTRL = true;
+ highlightAction(lastContainer, index);
+ });
+ isHoldingCTRL = false;
+ highlights[lastContainer].selected = highlights[lastContainer].selected.sort((a, b) => a - b)
+ }, 10);
+ }
+ }
+
+ if (key.key.toLowerCase() == 'c' && key.ctrlKey == true) {
+ let highlighted = highlights[lastContainer];
+
+ let sendChannel = highlighted.type == 1 ? "copiedAction" : "copiedMenu"
+ ipcRenderer.send(sendChannel, highlighted.selected.length != 0 ? highlighted.selected.map((value) => action.data[lastContainer][value]) : action.data[lastContainer][highlighted.highlighted])
+ }
+
+ if (key.key.toLowerCase() == 'v' && key.ctrlKey == true) {
+ if (lastContainer) {
+ if (highlights[lastContainer].type == 1) {
+ pasteCopiedIn(lastContainer)
+ } else {
+ pasteMenuIn(lastContainer)
+ }
+ }
+ else {
+ if (!editorSettings.experiments) return;
+ ipcRenderer.send('getCopiedAction');
+ ipcRenderer.once('copiedAction', (event, Action) => {
+ let containers = 0;
+ actionUI.forEach(element => {
+ let container;
+ if (element.element == 'actions') {
+ container = document.getElementById(element.storeAs)
+ containers++
+ } else if (element.element == 'case' || element.element == 'condition') {
+ if (action.data[element.storeAs].type == 'runActions') {
+ container = document.getElementById(element.storeActionsAs)
+ containers++
+ }
+ }
+
+ if (container) {
+ container.previousElementSibling.style.scale = 0
+ setTimeout(() => {
+ container.style.height = '14vh'
+ container.style.filter = 'blur(12px)'
+ setTimeout(() => {
+ container.innerHTML = `
+
+
Pasting ${Action.name}
+
+
Paste Here
+
CTRL+${containers}
+
+
+
+ `
+ }, 100);
+ setTimeout(() => {
+ container.style.filter = 'blur(0px)'
+ }, 200);
+ }, 200);
+ }
+ });
+ });
+ }
+ }
+})
+
+
+function setVariableIn(type, varName, elementId) {
+ closeContextmenu()
+
+ if (type == 'temporary') {
+ insertTextAtCaret("${tempVars('" + varName + "')}", elementId);
+ } else if (type == 'server') {
+ insertTextAtCaret("${serverVars('" + varName + "')}", elementId);
+ } else if (type == 'global') {
+ insertTextAtCaret("${globalVars('" + varName + "')}", elementId);
+ } else {
+ insertTextAtCaret(varName, elementId);
+ }
+
+ setTimeout(() => {
+ mOpened = false;
+ closeContextmenu()
+ }, 150)
+}
+
+function insertTextAtCaret(text, elementId) {
+ var element = document.getElementById(elementId);
+ element.blur()
+ if (element && (element.tagName.toLowerCase() === 'textarea' || element.tagName.toLowerCase() === 'input')) {
+ var start = element.selectionStart;
+ var end = element.selectionEnd;
+ var newValue = element.value.substring(0, start) + text + element.value.substring(end);
+ element.value = newValue;
+ }
+ element.blur()
+ element.focus()
+}
+
+function varTool(elm, index) {
+ let element = actionUI[index]
+ let validTypes = {
+ tempVar: "Temporary Variable",
+ serverVar: "Server Variable",
+ globVar: "Global Variable"
+ }
+ if (!validTypes[action.data[element.storeAs].type]) {
+ return
+ }
+ let parent = elm;
+ if (elm?.parentElement?.id) {
+ parent = elm.parentElement
+ }
+
+ let selectorParent = document.createElement('div');
+ selectorParent.style.width = '100%';
+ selectorParent.style.height = '0px';
+ selectorParent.style.transition = 'height 0.2s ease'
+
+ let selector = document.createElement('div');
+ selectorParent.appendChild(selector);
+ selector.classList.add('variableInsertion')
+
+ setTimeout(() => {
+ selector.style.scale = '1'
+ selector.style.opacity = '1'
+ elm.style.borderBottomRightRadius = '0px'
+ }, 10);
+ elm.onblur = () => {
+ elm.style.borderBottomRightRadius = ''
+ action.data[actionUI[index].storeAs].value = elm.value;
+ selector.style.opacity = ''
+ selector.style.scale = ''
+
+ setTimeout(() => {
+ selector.style.height = '0vh'
+ selector.style.padding = '0px'
+ }, editorSettings.commonAnimation * 100);
+ setTimeout(() => {
+ selector.remove()
+ selectorParent.remove()
+ }, editorSettings.commonAnimation * 200);
+ }
+ selectorParent.appendAfter(parent);
+
+ let displayType = 'Temporary';
+
+ let localVariables = [...commandVars, ...tempVars];
+
+ switch (action.data[element.storeAs].type) {
+ case 'serverVar':
+ localVariables = [...thisServer, ...serverVars];
+ displayType = 'Server'
+ break
+ case 'globVar':
+ localVariables = [...thisGlobal, ...globalVars];
+ displayType = 'Global'
+ break
+ }
+
+ elm.oninput = () => {
+ var endVars = ''
+ var includedVars = [];
+
+ let query = elm.value;
+ let results = 0;
+ for (var varIndex in localVariables) {
+ var variable = localVariables[varIndex];
+ if (variable.trim() != '' && !includedVars.includes(variable) && (fuzzyMatch(variable.toLowerCase().replaceAll('', ' '), query.toLowerCase().replaceAll(' ', ''), 0.01) || variable.toLowerCase().replaceAll(' ', '').includes(query.toLowerCase().replaceAll(' ', '')))) {
+ results++
+ includedVars.push(variable)
+ endVars += `
+
+
${displayType}
+
+ ${variable}
+
+
+ `
+ }
+ };
+
+ selector.innerHTML = endVars;
+ }
+
+ elm.oninput()
+}
\ No newline at end of file