diff --git a/.env b/.env index 2ac9c8ef1..070f91cae 100644 --- a/.env +++ b/.env @@ -11,10 +11,8 @@ TASK_SERVER_PATH=./TaskServer # TASK SERVER VARIABLES: STORAGE_PATH=./Data-Storage -PLOTTERS_PATH=./Legacy-Code WRITE_LOGS_TO_FILES=true -BOTS_PATH=./Legacy-Code LOG_PATH=./Log-Files WEB_SERVER_URL=localhost diff --git a/Client/.env b/Client/.env index be63a0e1b..ccfd1e3ba 100644 --- a/Client/.env +++ b/Client/.env @@ -1,11 +1,9 @@ INTER_PROCESS_FILES_PATH=../Inter-Process-Files STORAGE_PATH=../Data-Storage -PLOTTERS_PATH=../Legacy-Code USE_KEYVAULT=false WRITE_LOGS_TO_FILES=true -BOTS_PATH=../Legacy-Code LOG_PATH=../Log-Files WEB_SOCKETS_INTERFACE_PORT=18041 diff --git a/Client/httpInterface.js b/Client/httpInterface.js index 2e7d61891..aa2ce7cb1 100644 --- a/Client/httpInterface.js +++ b/Client/httpInterface.js @@ -404,20 +404,11 @@ exports.newHttpInterface = function newHttpInterface(WEB_SERVER, DATA_FILE_SERVE case 'Plotters': // This means the plotter folder, not to be confused with the Plotters script! { - let dataMine = requestParameters[2] - let codeName = requestParameters[3] - let moduleName = requestParameters[4] - let filePath = process.env.PLOTTERS_PATH + '/' + dataMine + '/plotters/' + codeName + '/' + moduleName - respondWithFile(filePath, httpResponse) - } - break - - case 'PlotterPanels': // This means the PlotterPanels folder, not to be confused with the Plotter Panels scripts! - { - let dataMine = requestParameters[2] - let codeName = requestParameters[3] - let moduleName = requestParameters[4] - let filePath = process.env.PLOTTERS_PATH + '/' + dataMine + '/plotters/' + codeName + '/' + moduleName + let project = requestParameters[2] + let dataMine = requestParameters[3] + let codeName = requestParameters[4] + let moduleName = requestParameters[5] + let filePath = process.env.PROJECTS_PATH + '/' + project + '/' + 'Bots-Plotters-Code' + '/' + dataMine + '/plotters/' + codeName + '/' + moduleName respondWithFile(filePath, httpResponse) } break diff --git a/Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Commons.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Commons.js similarity index 100% rename from Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Commons.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Commons.js diff --git a/Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Multi-Period-Daily/User.Bot.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Multi-Period-Daily/User.Bot.js similarity index 100% rename from Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Multi-Period-Daily/User.Bot.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Multi-Period-Daily/User.Bot.js diff --git a/Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Multi-Period-Market/User.Bot.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Multi-Period-Market/User.Bot.js similarity index 100% rename from Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Multi-Period-Market/User.Bot.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/Multi-Period-Market/User.Bot.js diff --git a/Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/package.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/package.json similarity index 100% rename from Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/package.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/package.json diff --git a/Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/this.bot.config.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/this.bot.config.json similarity index 100% rename from Legacy-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/this.bot.config.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Bollinger-Bands-Indicator-Bot/this.bot.config.json diff --git a/Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Commons.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Commons.js similarity index 100% rename from Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Commons.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Commons.js diff --git a/Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Multi-Period-Daily/User.Bot.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Multi-Period-Daily/User.Bot.js similarity index 100% rename from Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Multi-Period-Daily/User.Bot.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Multi-Period-Daily/User.Bot.js diff --git a/Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Multi-Period-Market/User.Bot.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Multi-Period-Market/User.Bot.js similarity index 100% rename from Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Multi-Period-Market/User.Bot.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/Multi-Period-Market/User.Bot.js diff --git a/Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/package.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/package.json similarity index 100% rename from Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/package.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/package.json diff --git a/Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/this.bot.config.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/this.bot.config.json similarity index 100% rename from Legacy-Code/Masters/bots/Candles-Volumes-Indicator-Bot/this.bot.config.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Candles-Volumes-Indicator-Bot/this.bot.config.json diff --git a/Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Commons.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Commons.js similarity index 100% rename from Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Commons.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Commons.js diff --git a/Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Historic-OHLCVs/User.Bot.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Historic-OHLCVs/User.Bot.js similarity index 100% rename from Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Historic-OHLCVs/User.Bot.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Historic-OHLCVs/User.Bot.js diff --git a/Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Historic-Trades/User.Bot.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Historic-Trades/User.Bot.js similarity index 100% rename from Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Historic-Trades/User.Bot.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/Historic-Trades/User.Bot.js diff --git a/Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/package-lock.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/package-lock.json similarity index 100% rename from Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/package-lock.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/package-lock.json diff --git a/Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/package.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/package.json similarity index 100% rename from Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/package.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/package.json diff --git a/Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/this.bot.config.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/this.bot.config.json similarity index 100% rename from Legacy-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/this.bot.config.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Exchange-Raw-Data-Sensor-Bot/this.bot.config.json diff --git a/Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/Check-Webhook/User.Bot.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/Check-Webhook/User.Bot.js similarity index 100% rename from Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/Check-Webhook/User.Bot.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/Check-Webhook/User.Bot.js diff --git a/Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/Commons.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/Commons.js similarity index 100% rename from Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/Commons.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/Commons.js diff --git a/Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/package-lock.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/package-lock.json similarity index 100% rename from Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/package-lock.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/package-lock.json diff --git a/Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/package.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/package.json similarity index 100% rename from Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/package.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/package.json diff --git a/Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/this.bot.config.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/this.bot.config.json similarity index 100% rename from Legacy-Code/Masters/bots/Webhooks-Sensor-Bot/this.bot.config.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/bots/Webhooks-Sensor-Bot/this.bot.config.json diff --git a/Legacy-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBands.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBands.js similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBands.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBands.js diff --git a/Legacy-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBandsPanel.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBandsPanel.js similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBandsPanel.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/BollingerBandsPanel.js diff --git a/Legacy-Code/Masters/plotters/Plotters-Bollinger-Bands/PercentageBandwidth.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/PercentageBandwidth.js similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Bollinger-Bands/PercentageBandwidth.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/PercentageBandwidth.js diff --git a/Legacy-Code/Masters/plotters/Plotters-Bollinger-Bands/this.plotter.config.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/this.plotter.config.json similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Bollinger-Bands/this.plotter.config.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Bollinger-Bands/this.plotter.config.json diff --git a/Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/CandlePanel.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/CandlePanel.js similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/CandlePanel.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/CandlePanel.js diff --git a/Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/Candles.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/Candles.js similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/Candles.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/Candles.js diff --git a/Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/VolumePanel.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/VolumePanel.js similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/VolumePanel.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/VolumePanel.js diff --git a/Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/Volumes.js b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/Volumes.js similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/Volumes.js rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/Volumes.js diff --git a/Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/this.plotter.config.json b/Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/this.plotter.config.json similarity index 100% rename from Legacy-Code/Masters/plotters/Plotters-Candles-Volumes/this.plotter.config.json rename to Projects/Superalgos/Bots-Plotters-Code/Masters/plotters/Plotters-Candles-Volumes/this.plotter.config.json diff --git a/TaskServer/.env b/TaskServer/.env index be63a0e1b..ccfd1e3ba 100644 --- a/TaskServer/.env +++ b/TaskServer/.env @@ -1,11 +1,9 @@ INTER_PROCESS_FILES_PATH=../Inter-Process-Files STORAGE_PATH=../Data-Storage -PLOTTERS_PATH=../Legacy-Code USE_KEYVAULT=false WRITE_LOGS_TO_FILES=true -BOTS_PATH=../Legacy-Code LOG_PATH=../Log-Files WEB_SOCKETS_INTERFACE_PORT=18041 diff --git a/TaskServer/FileStorage.js b/TaskServer/FileStorage.js index 680037361..39715642a 100644 --- a/TaskServer/FileStorage.js +++ b/TaskServer/FileStorage.js @@ -74,7 +74,7 @@ exports.newFileStorage = function newFileStorage(logger, host, port) { let fileLocation let mustBeJason if (filePath.indexOf("/bots/") > 0) { - fileLocation = process.env.BOTS_PATH + '/' + filePath + fileLocation = process.env.PROJECTS_PATH + '/' + filePath mustBeJason = false } else { fileLocation = process.env.STORAGE_PATH + '/' + filePath diff --git a/TaskServer/IndicatorBot.js b/TaskServer/IndicatorBot.js index 2f55a1daa..40fb0b36a 100644 --- a/TaskServer/IndicatorBot.js +++ b/TaskServer/IndicatorBot.js @@ -36,7 +36,13 @@ } /* This bot is not ready for taking its code from the UI, then we need to load it from its repo. */ - let filePath = bot.dataMine + "/" + "bots" + "/" + bot.processNode.referenceParent.parentNode.config.repo + "/" + pProcessConfig.codeName + let filePath = + bot.processNode.referenceParent.parentNode.parentNode.project + // project + '/Bots-Plotters-Code/' + + bot.dataMine + + "/" + "bots" + "/" + + bot.processNode.referenceParent.parentNode.config.repo + "/" + + pProcessConfig.codeName filePath += "/User.Bot.js" fileStorage.getTextFile(filePath, onBotDownloaded); @@ -54,7 +60,7 @@ USER_BOT_MODULE = {} USER_BOT_MODULE.newUserBot = eval(text); // TODO This needs to be changed function - filePath = bot.dataMine + "/" + "bots" + "/" + bot.processNode.referenceParent.parentNode.config.repo + filePath = bot.dataMine + "/" + "bots" + "/" + bot.processNode.referenceParent.parentNode.config.repo filePath += "/Commons.js" fileStorage.getTextFile(filePath, onCommonsDownloaded); diff --git a/TaskServer/Root.js b/TaskServer/Root.js index 09cc407de..3b24f49c8 100644 --- a/TaskServer/Root.js +++ b/TaskServer/Root.js @@ -140,7 +140,13 @@ const FILE_STORAGE = require('./FileStorage.js'); let fileStorage = FILE_STORAGE.newFileStorage(); - let filePath = global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + '/bots/' + processInstance.referenceParent.parentNode.config.repo + '/this.bot.config.json'; + let filePath = + global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.project + // project + '/Bots-Plotters-Code/' + + global.TASK_NODE.bot.processes[processIndex].referenceParent.parentNode.parentNode.config.codeName + // mine + '/bots/' + + processInstance.referenceParent.parentNode.config.repo + // bot + '/this.bot.config.json' fileStorage.getTextFile(filePath, onFileReceived); @@ -554,7 +560,7 @@ setTimeout(exitProcessInstance, WAIT_TIME_FOR_ALL_PROCESS_INSTANCES_TO_START) } } - + function runLearningBot(pBotConfig, pProcessConfig) { global.TOTAL_PROCESS_INSTANCES_CREATED++ diff --git a/TaskServer/SensorBot.js b/TaskServer/SensorBot.js index e4c1f6a70..15eed811f 100644 --- a/TaskServer/SensorBot.js +++ b/TaskServer/SensorBot.js @@ -34,7 +34,13 @@ return } - let filePath = bot.dataMine + "/" + "bots" + "/" + bot.processNode.referenceParent.parentNode.config.repo + "/" + pProcessConfig.codeName + let filePath = + bot.processNode.referenceParent.parentNode.parentNode.project + // project + '/Bots-Plotters-Code/' + + bot.dataMine + + "/" + "bots" + "/" + + bot.processNode.referenceParent.parentNode.config.repo + "/" + + pProcessConfig.codeName filePath += "/User.Bot.js" fileStorage.getTextFile(filePath, onBotDownloaded); @@ -63,7 +69,7 @@ function onCommonsDownloaded(err, text) { if (err.result !== global.DEFAULT_OK_RESPONSE.result) { - parentLogger.write(MODULE_NAME, "[WARN] initialize -> onBotDownloaded -> onCommonsDownloaded -> Commons not found: " + err.message); + parentLogger.write(MODULE_NAME, "[WARN] initialize -> onBotDownloaded -> onCommonsDownloaded -> Commons not found: " + err.message); callBackFunction(global.DEFAULT_OK_RESPONSE); return; } diff --git a/UI/AppLoader.js b/UI/AppLoader.js index ac4543db4..90c0a0a70 100644 --- a/UI/AppLoader.js +++ b/UI/AppLoader.js @@ -177,13 +177,13 @@ function newAppLoader() { function defaultPlotters() { return [ - 'Plotters/Masters/Plotters-Candles-Volumes/Candles.js', - 'Plotters/Masters/Plotters-Candles-Volumes/CandlePanel.js', - 'Plotters/Masters/Plotters-Candles-Volumes/Volumes.js', - 'Plotters/Masters/Plotters-Candles-Volumes/VolumePanel.js', - 'Plotters/Masters/Plotters-Bollinger-Bands/BollingerBands.js', - 'Plotters/Masters/Plotters-Bollinger-Bands/BollingerBandsPanel.js', - 'Plotters/Masters/Plotters-Bollinger-Bands/PercentageBandwidth.js' + 'Plotters/Superalgos/Masters/Plotters-Candles-Volumes/Candles.js', + 'Plotters/Superalgos/Masters/Plotters-Candles-Volumes/CandlePanel.js', + 'Plotters/Superalgos/Masters/Plotters-Candles-Volumes/Volumes.js', + 'Plotters/Superalgos/Masters/Plotters-Candles-Volumes/VolumePanel.js', + 'Plotters/Superalgos/Masters/Plotters-Bollinger-Bands/BollingerBands.js', + 'Plotters/Superalgos/Masters/Plotters-Bollinger-Bands/BollingerBandsPanel.js', + 'Plotters/Superalgos/Masters/Plotters-Bollinger-Bands/PercentageBandwidth.js' ] } }