diff --git a/.gitignore b/.gitignore index d3a984f49..5471caae2 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,5 @@ bin/* /.nyc_output /coverage debug.log -Windows-Superalgos-Desktop.exe package-lock.json -MacOs-Superalgos-Desktop.app + diff --git a/BackendServers.njsproj b/BackendServers.njsproj index d19babbd5..6abd252b5 100644 --- a/BackendServers.njsproj +++ b/BackendServers.njsproj @@ -36,11 +36,270 @@ Code + + + + + + + + Code + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/WebServer/AppLoader.js b/WebServer/AppLoader.js new file mode 100644 index 000000000..e11ac4c3c --- /dev/null +++ b/WebServer/AppLoader.js @@ -0,0 +1,249 @@ +let dashboard + +function newAppLoader() { + const MODULE_NAME = 'App Loader' + const INFO_LOG = false + const ERROR_LOG = true + const logger = newWebDebugLog() + logger.fileName = MODULE_NAME + + let thisObject = { + loadModules: loadModules + } + + return thisObject + + async function loadModules() { + try { + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> Entering function.') } + + let plotters + let modulesArray = [] + + plotters = defaultPlotters() + + modulesArray = modulesArray.concat([ + 'ChartingSpace/Viewport.js', + + 'Globals.js', + + 'AppSchema.js', + 'Workspace.js', + + 'ChartingSpace/EdgeEditor.js', + 'ChartingSpace/ChartUtilities.js', + 'ChartingSpace/PlottersManager.js', + 'ChartingSpace/TimelineChart.js', + 'ChartingSpace/TimeMachine.js', + 'ChartingSpace/CoordinateSystem.js', + + 'DesignSpace/Workspace/Workspace.js', + 'DesignSpace/Workspace/FunctionLibraries/UiObjectsFromNodes.js', + 'DesignSpace/Workspace/FunctionLibraries/ChainAttachDetach.js', + 'DesignSpace/Workspace/FunctionLibraries/ReferenceAttachDetach.js', + 'DesignSpace/Workspace/FunctionLibraries/NodeDeleter.js', + 'DesignSpace/Workspace/FunctionLibraries/ProtocolNode.js', + 'DesignSpace/Workspace/FunctionLibraries/NodeCloning.js', + 'DesignSpace/Workspace/FunctionLibraries/NodeChildren.js', + 'DesignSpace/Workspace/FunctionLibraries/TaskFunctions.js', + 'DesignSpace/Workspace/FunctionLibraries/SessionFunctions.js', + 'DesignSpace/Workspace/FunctionLibraries/ShortcutKeys.js', + 'DesignSpace/Workspace/FunctionLibraries/OnFocus.js', + 'DesignSpace/Workspace/FunctionLibraries/SuperScripts.js', + 'DesignSpace/Workspace/FunctionLibraries/CCXTFunctions.js', + + 'Utilities/RoundedCornersBackground.js', + + 'Panels/LayersPanel.js', + 'Panels/UpDownButton.js', + 'Panels/LeftRightButton.js', + 'Panels/Layer.js', + 'Panels/PlotterPanel.js', + 'Panels/PanelsVisibleButton.js', + + 'ControlsToolBox/SidePanel.js', + 'ControlsToolBox/SidePanelTab.js', + + 'Spaces/CockpitSpace.js', + 'Spaces/TopSpace.js', + 'Spaces/PanelsSpace.js', + 'Spaces/ChartingSpace.js', + 'Spaces/FloatingSpace.js', + 'Spaces/DesignSpace.js', + + 'Files/SingleFile.js', + 'Files/FileCloud.js', + 'Files/MarketFiles.js', + 'Files/DailyFiles.js', + 'Files/FileCursor.js', + 'Files/FileSequence.js', + 'Files/FileStorage.js', + + 'FloatingSpace/FloatingObject.js', + 'FloatingSpace/FloatingLayer.js', + 'FloatingSpace/UiObjectConstructor.js', + 'FloatingSpace/UiObject.js', + 'FloatingSpace/UiObjectTitle.js', + 'FloatingSpace/CircularMenu.js', + 'FloatingSpace/CircularMenuItem.js', + 'FloatingSpace/CircularProgressBar.js', + 'FloatingSpace/BusyProgressBar.js', + 'FloatingSpace/CodeEditor.js', + 'FloatingSpace/ConfigEditor.js', + 'FloatingSpace/ConditionEditor.js', + 'FloatingSpace/FormulaEditor.js', + + 'Scales/RateScale.js', + 'Scales/TimeScale.js', + 'Scales/TimeFrameScale.js', + 'Scales/Commons.js', + 'Scales/AutoScaleButton.js', + + 'CockpitSpace/AssetBalances.js', + 'CockpitSpace/Speedometer.js', + 'CockpitSpace/FullScreen.js', + + 'EventsServerClient.js', + + 'VideoRecorder.js', + 'Plotter.js', + 'LegacyPlotter.js', + 'PlotterPanel.js', + + 'ProductStorage.js', + + 'SplashScreen.js', + 'Canvas.js', + 'EventHandler.js', + 'Frame.js', + + 'Animation.js', + + 'Container.js', + + 'Utilities.js', + 'PostLoader.js' + ]) + + modulesArray = modulesArray.concat(plotters) + + let downloadedCounter = 0 + let versionParam = window.canvasApp.version + if (versionParam === undefined) { versionParam = '' } else { + versionParam = '?' + versionParam + } + + for (let i = 0; i < modulesArray.length; i++) { + let path = window.canvasApp.urlPrefix + modulesArray[i] + versionParam + + REQUIREJS([path], onRequired) + + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> Module Requested.') } + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> path = ' + path) } + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> total requested = ' + (i + 1)) } + + function onRequired(pModule) { + try { + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> onRequired -> Entering function.') } + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> onRequired -> Module Downloaded.') } + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> onRequired -> path = ' + path) } + + downloadedCounter++ + + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> onRequired -> downloadedCounter = ' + downloadedCounter) } + + if (downloadedCounter === modulesArray.length) { + if (INFO_LOG === true) { logger.write('[INFO] loadModules -> onRequired -> Starting Advanced Algos Platform.') } + setTimeout(() => { + dashboard = newDashboard() + dashboard.start() + }, 500) + + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] loadModules -> onRequired -> err = ' + err.stack) } + } + } + } + } catch (err) { + if (ERROR_LOG === true) { logger.write('[ERROR] loadModules -> err = ' + err.stack) } + } + } + + 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/TradingEngines/Plotters-Trading-Simulation/TradingSimulation.js', + 'Plotters/TradingEngines/Plotters-Trading-Simulation/TradingSimulationAssetBalancesPanel.js', + 'Plotters/TradingEngines/Plotters-Trading-Simulation/TradingSimulationCurrentPositionPanel.js', + 'Plotters/TradingEngines/Plotters-Trading-Simulation/TradingSimulationPartialResultsPanel.js', + 'Plotters/TradingEngines/Plotters-Trading-Simulation/Conditions.js', + 'Plotters/TradingEngines/Plotters-Trading-Simulation/Strategies.js', + 'Plotters/TradingEngines/Plotters-Trading-Simulation/Trades.js', + 'Plotters/TradingEngines/Plotters-Trading-Simulation/SimulationExecution.js', + 'Plotters/TradingEngines/Plotters-Trading-Simulation/SimulationExecutionPanel.js' + ] + } + + function getPlotters(ecosystem) { + if (INFO_LOG === true) { console.log('[INFO] server -> onBrowserRequest -> onFileRead -> addPlotters -> Entering function.') } + + let plotters = [] + let dataMines = ecosystem.dataMines + let hosts = ecosystem.hosts + + plotters = plotters.concat(addScript(dataMines)) + plotters = plotters.concat(addScript(hosts)) + + return plotters + } + + function addScript(pDataMinesOrHosts) { + if (INFO_LOG === true) { console.log('[INFO] server -> onBrowserRequest -> onFileRead -> addPlotters -> addScript -> Entering function.') } + const htmlLinePlotter = 'Plotters/@dataMine@/@repo@/@module@.js' + const htmlLinePlotterPanel = 'PlotterPanels/@dataMine@/@repo@/@module@.js' + let plotters = [] + + for (let i = 0; i < pDataMinesOrHosts.length; i++) { + let dataMine = pDataMinesOrHosts[i] + for (let j = 0; j < dataMine.plotters.length; j++) { + let plotter = dataMine.plotters[j] + if (plotter.modules !== undefined) { + for (let k = 0; k < plotter.modules.length; k++) { + let module = plotter.modules[k] + let htmlLineCopy = htmlLinePlotter + + let stringToInsert + stringToInsert = htmlLineCopy.replace('@dataMine@', dataMine.codeName) + stringToInsert = stringToInsert.replace('@repo@', plotter.repo) + stringToInsert = stringToInsert.replace('@module@', module.moduleName) + + plotters.push(stringToInsert) + + if (module.panels !== undefined) { + for (let l = 0; l < module.panels.length; l++) { + let panel = module.panels[l] + let htmlLineCopy = htmlLinePlotterPanel + + let stringToInsert + stringToInsert = htmlLineCopy.replace('@dataMine@', dataMine.codeName) + stringToInsert = stringToInsert.replace('@repo@', plotter.repo) + stringToInsert = stringToInsert.replace('@module@', panel.moduleName) + + plotters.push(stringToInsert) + } + } + } + } + } + } + return plotters + } +} + diff --git a/WebServer/AppPreLoader.js b/WebServer/AppPreLoader.js new file mode 100644 index 000000000..2e150a408 --- /dev/null +++ b/WebServer/AppPreLoader.js @@ -0,0 +1,174 @@ + +/* Callbacks default responses. */ + +let GLOBAL = {}; + +GLOBAL.DEFAULT_OK_RESPONSE = { + result: "Ok", + message: "Operation Succeeded" +}; + +GLOBAL.DEFAULT_FAIL_RESPONSE = { + result: "Fail", + message: "Operation Failed" +}; + +GLOBAL.DEFAULT_RETRY_RESPONSE = { + result: "Retry", + message: "Retry Later" +}; + +GLOBAL.CUSTOM_OK_RESPONSE = { + result: "Ok, but check Message", + message: "Custom Message" +}; + +GLOBAL.CUSTOM_FAIL_RESPONSE = { + result: "Fail Because", + message: "Custom Message" +}; + +let browserCanvas; // This is the canvas object of the browser. + +function spacePad(str, max) { + str = str.toString(); + return str.length < max ? spacePad(" " + str, max) : str; +} + +function loadSuperalgos() { + + const MODULE_NAME = "App Pre-Loader"; + const INFO_LOG = false; + const ERROR_LOG = true; + + if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] loadSuperalgos -> Entering function."); } + + /* The first thing to do here is to add the canvas where all the action is going to happen. */ + + + let textArea = document.createElement('textarea'); + textArea.id = "textArea"; + textArea.spellcheck = false; + textArea.style = 'resize: none;' + + ' border: none;' + + ' outline: none;' + + 'box-shadow: none;' + + 'overflow:hidden;' + + 'font-family: ' + 'Saira' + ';' + + 'font-size: 12px;' + + 'background-color: rgb(255, 255, 255);' + + 'color:rgb(255, 255, 255);' + + 'width: ' + 800 + 'px;' + + 'height: ' + 600 + 'px' + + let textAreaDiv = document.getElementById('textAreaDiv'); + textAreaDiv.appendChild(textArea); + textAreaDiv.style = 'position:fixed; top:' + -1500 + 'px; left:' + 500 + 'px; z-index:10; ' + + let input = document.createElement('input'); + input.id = "input"; + input.spellcheck = false; + input.style = "border: none; outline: none; box-shadow: none; overflow:hidden; width: 0px; height: 0px;"; + + let inputDiv = document.getElementById('inputDiv'); + inputDiv.appendChild(input); + + + let canvas = document.createElement('canvas'); + + canvas.id = "canvas"; + canvas.width = 1400; + canvas.height = 600; + canvas.style.border = "0"; + canvas.style = "position:absolute; top:0px; left:0px; z-index:1"; + + let canvasApp = document.getElementById('canvasApp'); + canvasApp.appendChild(canvas); + + browserCanvas = document.getElementById('canvas'); + + browserCanvas.width = window.innerWidth; + browserCanvas.height = window.innerHeight - window.canvasApp.topMargin; + browserCanvas.style.border = "none"; + + browserCanvas.style.top = window.canvasApp.topMargin + 'px'; + + + + loadDebugModule(); + + function loadDebugModule() { + + try { + if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] loadDebugModule -> Entering function."); } + + let path = window.canvasApp.urlPrefix + "WebDebugLog.js"; + + REQUIREJS([path], onRequired); + + function onRequired(pModule) { + + if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] " + path + " downloaded."); } + + loadModules(); + + } + } + catch (err) { + console.log(spacePad(MODULE_NAME, 50) + " : " + "[ERROR] loadDebugModule --> " + path + " --> err = " + err.stack); + } + } + + /* And Finally, we start loading all the scripts we will inmediatelly need. */ + + function loadModules() { + + try { + + if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] loadModules -> Entering function."); } + + let path = window.canvasApp.urlPrefix + "WebServer/AppLoader.js"; + + REQUIREJS([path], onRequired); + + function onRequired(pModule) { + + if (INFO_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[INFO] " + path + " downloaded."); } + + let APP_LOADER_MODULE = newAppLoader(); + APP_LOADER_MODULE.loadModules(); + + } + } + catch (err) { + console.log(spacePad(MODULE_NAME, 50) + " : " + "[ERROR] loadModules --> " + path + " --> err = " + err.stack); + } + } +} + +function callServer(pContentToSend, pPath, callBackFunction) { + let xhttp = new XMLHttpRequest(); + xhttp.onreadystatechange = function () { + if (this.readyState === 4 && this.status === 200) { + callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE, xhttp.responseText); + return; + } else if (this.readyState === 4 && this.status === 404) { + callBackFunction({ result: "Fail", message: xhttp.responseText.trim(), code: xhttp.responseText.trim() }); + return; + } + }; + + if (pContentToSend === undefined) { + xhttp.open("GET", pPath, true); + xhttp.send(); + } else { + try { + let blob = new Blob([pContentToSend], { type: 'text/plain' }); + xhttp.open("POST", pPath, true); + xhttp.send(blob); + } catch (err) { + if (ERROR_LOG === true) { console.log(spacePad(MODULE_NAME, 50) + " : " + "[ERROR] callServer -> err.message = " & err.message); } + callBackFunction({ result: "Fail", message: err.message }) + } + } +} diff --git a/WebServer/Images/Icons/style-01/150-next-phase-event.png b/WebServer/Images/Icons/style-01/150-next-phase-event.png new file mode 100644 index 000000000..fe469f85f Binary files /dev/null and b/WebServer/Images/Icons/style-01/150-next-phase-event.png differ diff --git a/WebServer/Images/Icons/style-01/analysis-1.png b/WebServer/Images/Icons/style-01/analysis-1.png new file mode 100644 index 000000000..8b3d61b9e Binary files /dev/null and b/WebServer/Images/Icons/style-01/analysis-1.png differ diff --git a/WebServer/Images/Icons/style-01/analysis.png b/WebServer/Images/Icons/style-01/analysis.png new file mode 100644 index 000000000..80ede07af Binary files /dev/null and b/WebServer/Images/Icons/style-01/analysis.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-000.png b/WebServer/Images/Icons/style-01/angle-to-parent-000.png new file mode 100644 index 000000000..23b3aee31 Binary files /dev/null and b/WebServer/Images/Icons/style-01/angle-to-parent-000.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-045.png b/WebServer/Images/Icons/style-01/angle-to-parent-045.png new file mode 100644 index 000000000..cd495d5bd Binary files /dev/null and b/WebServer/Images/Icons/style-01/angle-to-parent-045.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-090.png b/WebServer/Images/Icons/style-01/angle-to-parent-090.png new file mode 100644 index 000000000..6c94bc491 Binary files /dev/null and b/WebServer/Images/Icons/style-01/angle-to-parent-090.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-180.png b/WebServer/Images/Icons/style-01/angle-to-parent-180.png new file mode 100644 index 000000000..b04398af2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/angle-to-parent-180.png differ diff --git a/WebServer/Images/Icons/style-01/angle-to-parent-360.png b/WebServer/Images/Icons/style-01/angle-to-parent-360.png new file mode 100644 index 000000000..d66118a75 Binary files /dev/null and b/WebServer/Images/Icons/style-01/angle-to-parent-360.png differ diff --git a/WebServer/Images/Icons/style-01/approve.png b/WebServer/Images/Icons/style-01/approve.png new file mode 100644 index 000000000..2145a1626 Binary files /dev/null and b/WebServer/Images/Icons/style-01/approve.png differ diff --git a/WebServer/Images/Icons/style-01/arrangement-concave.png b/WebServer/Images/Icons/style-01/arrangement-concave.png new file mode 100644 index 000000000..4c6cc7854 Binary files /dev/null and b/WebServer/Images/Icons/style-01/arrangement-concave.png differ diff --git a/WebServer/Images/Icons/style-01/arrangement-convex.png b/WebServer/Images/Icons/style-01/arrangement-convex.png new file mode 100644 index 000000000..217eae0bd Binary files /dev/null and b/WebServer/Images/Icons/style-01/arrangement-convex.png differ diff --git a/WebServer/Images/Icons/style-01/arrangement-horizontal-bottom.png b/WebServer/Images/Icons/style-01/arrangement-horizontal-bottom.png new file mode 100644 index 000000000..8400c2249 Binary files /dev/null and b/WebServer/Images/Icons/style-01/arrangement-horizontal-bottom.png differ diff --git a/WebServer/Images/Icons/style-01/arrangement-horizontal-top.png b/WebServer/Images/Icons/style-01/arrangement-horizontal-top.png new file mode 100644 index 000000000..37111540e Binary files /dev/null and b/WebServer/Images/Icons/style-01/arrangement-horizontal-top.png differ diff --git a/WebServer/Images/Icons/style-01/arrangement-vertical-left.png b/WebServer/Images/Icons/style-01/arrangement-vertical-left.png new file mode 100644 index 000000000..9e8316511 Binary files /dev/null and b/WebServer/Images/Icons/style-01/arrangement-vertical-left.png differ diff --git a/WebServer/Images/Icons/style-01/arrangement-vertical-right.png b/WebServer/Images/Icons/style-01/arrangement-vertical-right.png new file mode 100644 index 000000000..ff70010bd Binary files /dev/null and b/WebServer/Images/Icons/style-01/arrangement-vertical-right.png differ diff --git a/WebServer/Images/Icons/style-01/asset.png b/WebServer/Images/Icons/style-01/asset.png new file mode 100644 index 000000000..ce6d5b5d8 Binary files /dev/null and b/WebServer/Images/Icons/style-01/asset.png differ diff --git a/WebServer/Images/Icons/style-01/attach.png b/WebServer/Images/Icons/style-01/attach.png new file mode 100644 index 000000000..678806e32 Binary files /dev/null and b/WebServer/Images/Icons/style-01/attach.png differ diff --git a/WebServer/Images/Icons/style-01/attractive.png b/WebServer/Images/Icons/style-01/attractive.png new file mode 100644 index 000000000..62e6fe2e7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/attractive.png differ diff --git a/WebServer/Images/Icons/style-01/band.png b/WebServer/Images/Icons/style-01/band.png new file mode 100644 index 000000000..de6aa8c55 Binary files /dev/null and b/WebServer/Images/Icons/style-01/band.png differ diff --git a/WebServer/Images/Icons/style-01/binance-coin.png b/WebServer/Images/Icons/style-01/binance-coin.png new file mode 100644 index 000000000..60e7bd4c2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/binance-coin.png differ diff --git a/WebServer/Images/Icons/style-01/binance.png b/WebServer/Images/Icons/style-01/binance.png new file mode 100644 index 000000000..8f4f71952 Binary files /dev/null and b/WebServer/Images/Icons/style-01/binance.png differ diff --git a/WebServer/Images/Icons/style-01/bitcoin-cash.png b/WebServer/Images/Icons/style-01/bitcoin-cash.png new file mode 100644 index 000000000..a1fdc4f69 Binary files /dev/null and b/WebServer/Images/Icons/style-01/bitcoin-cash.png differ diff --git a/WebServer/Images/Icons/style-01/bitcoin.png b/WebServer/Images/Icons/style-01/bitcoin.png new file mode 100644 index 000000000..a4ee2a209 Binary files /dev/null and b/WebServer/Images/Icons/style-01/bitcoin.png differ diff --git a/WebServer/Images/Icons/style-01/bitfinex.png b/WebServer/Images/Icons/style-01/bitfinex.png new file mode 100644 index 000000000..d5d3db0e2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/bitfinex.png differ diff --git a/WebServer/Images/Icons/style-01/bitmex.png b/WebServer/Images/Icons/style-01/bitmex.png new file mode 100644 index 000000000..4ae5662db Binary files /dev/null and b/WebServer/Images/Icons/style-01/bitmex.png differ diff --git a/WebServer/Images/Icons/style-01/bittrex.png b/WebServer/Images/Icons/style-01/bittrex.png new file mode 100644 index 000000000..b11a8e692 Binary files /dev/null and b/WebServer/Images/Icons/style-01/bittrex.png differ diff --git a/WebServer/Images/Icons/style-01/bot-indicator.png b/WebServer/Images/Icons/style-01/bot-indicator.png new file mode 100644 index 000000000..96a7d7fd1 Binary files /dev/null and b/WebServer/Images/Icons/style-01/bot-indicator.png differ diff --git a/WebServer/Images/Icons/style-01/bot-sensor.png b/WebServer/Images/Icons/style-01/bot-sensor.png new file mode 100644 index 000000000..650a239d6 Binary files /dev/null and b/WebServer/Images/Icons/style-01/bot-sensor.png differ diff --git a/WebServer/Images/Icons/style-01/bot-trading.png b/WebServer/Images/Icons/style-01/bot-trading.png new file mode 100644 index 000000000..8ba2a5668 Binary files /dev/null and b/WebServer/Images/Icons/style-01/bot-trading.png differ diff --git a/WebServer/Images/Icons/style-01/brainstorming.png b/WebServer/Images/Icons/style-01/brainstorming.png new file mode 100644 index 000000000..993bf0ec2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/brainstorming.png differ diff --git a/WebServer/Images/Icons/style-01/broken-link.png b/WebServer/Images/Icons/style-01/broken-link.png new file mode 100644 index 000000000..1d13ad8ac Binary files /dev/null and b/WebServer/Images/Icons/style-01/broken-link.png differ diff --git a/WebServer/Images/Icons/style-01/calculations-procedure.png b/WebServer/Images/Icons/style-01/calculations-procedure.png new file mode 100644 index 000000000..0883d961e Binary files /dev/null and b/WebServer/Images/Icons/style-01/calculations-procedure.png differ diff --git a/WebServer/Images/Icons/style-01/candles.png b/WebServer/Images/Icons/style-01/candles.png new file mode 100644 index 000000000..8db4abd30 Binary files /dev/null and b/WebServer/Images/Icons/style-01/candles.png differ diff --git a/WebServer/Images/Icons/style-01/cardano.png b/WebServer/Images/Icons/style-01/cardano.png new file mode 100644 index 000000000..68b542366 Binary files /dev/null and b/WebServer/Images/Icons/style-01/cardano.png differ diff --git a/WebServer/Images/Icons/style-01/chart-point-formula.png b/WebServer/Images/Icons/style-01/chart-point-formula.png new file mode 100644 index 000000000..c1ebd1072 Binary files /dev/null and b/WebServer/Images/Icons/style-01/chart-point-formula.png differ diff --git a/WebServer/Images/Icons/style-01/chart-point.png b/WebServer/Images/Icons/style-01/chart-point.png new file mode 100644 index 000000000..9069eee60 Binary files /dev/null and b/WebServer/Images/Icons/style-01/chart-point.png differ diff --git a/WebServer/Images/Icons/style-01/chart-points.png b/WebServer/Images/Icons/style-01/chart-points.png new file mode 100644 index 000000000..7ad931273 Binary files /dev/null and b/WebServer/Images/Icons/style-01/chart-points.png differ diff --git a/WebServer/Images/Icons/style-01/charting-space.png b/WebServer/Images/Icons/style-01/charting-space.png new file mode 100644 index 000000000..b3e320916 Binary files /dev/null and b/WebServer/Images/Icons/style-01/charting-space.png differ diff --git a/WebServer/Images/Icons/style-01/chat.png b/WebServer/Images/Icons/style-01/chat.png new file mode 100644 index 000000000..0b424a267 Binary files /dev/null and b/WebServer/Images/Icons/style-01/chat.png differ diff --git a/WebServer/Images/Icons/style-01/chronometer.png b/WebServer/Images/Icons/style-01/chronometer.png new file mode 100644 index 000000000..9f4821359 Binary files /dev/null and b/WebServer/Images/Icons/style-01/chronometer.png differ diff --git a/WebServer/Images/Icons/style-01/clone.png b/WebServer/Images/Icons/style-01/clone.png new file mode 100644 index 000000000..9b3b41696 Binary files /dev/null and b/WebServer/Images/Icons/style-01/clone.png differ diff --git a/WebServer/Images/Icons/style-01/compass.png b/WebServer/Images/Icons/style-01/compass.png new file mode 100644 index 000000000..e9b80e7b7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/compass.png differ diff --git a/WebServer/Images/Icons/style-01/competition.png b/WebServer/Images/Icons/style-01/competition.png new file mode 100644 index 000000000..96082a10d Binary files /dev/null and b/WebServer/Images/Icons/style-01/competition.png differ diff --git a/WebServer/Images/Icons/style-01/content.png b/WebServer/Images/Icons/style-01/content.png new file mode 100644 index 000000000..b46362501 Binary files /dev/null and b/WebServer/Images/Icons/style-01/content.png differ diff --git a/WebServer/Images/Icons/style-01/crypto-exchange.png b/WebServer/Images/Icons/style-01/crypto-exchange.png new file mode 100644 index 000000000..8c3dc3f12 Binary files /dev/null and b/WebServer/Images/Icons/style-01/crypto-exchange.png differ diff --git a/WebServer/Images/Icons/style-01/crypto-exchanges.png b/WebServer/Images/Icons/style-01/crypto-exchanges.png new file mode 100644 index 000000000..e94ca97b7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/crypto-exchanges.png differ diff --git a/WebServer/Images/Icons/style-01/dash.png b/WebServer/Images/Icons/style-01/dash.png new file mode 100644 index 000000000..755214b1e Binary files /dev/null and b/WebServer/Images/Icons/style-01/dash.png differ diff --git a/WebServer/Images/Icons/style-01/dashboard.png b/WebServer/Images/Icons/style-01/dashboard.png new file mode 100644 index 000000000..9e579ab06 Binary files /dev/null and b/WebServer/Images/Icons/style-01/dashboard.png differ diff --git a/WebServer/Images/Icons/style-01/data-building-procedure.png b/WebServer/Images/Icons/style-01/data-building-procedure.png new file mode 100644 index 000000000..63de055e5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-building-procedure.png differ diff --git a/WebServer/Images/Icons/style-01/data-dependency.png b/WebServer/Images/Icons/style-01/data-dependency.png new file mode 100644 index 000000000..822adf1fd Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-dependency.png differ diff --git a/WebServer/Images/Icons/style-01/data-entry.png b/WebServer/Images/Icons/style-01/data-entry.png new file mode 100644 index 000000000..47f1740f8 Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-entry.png differ diff --git a/WebServer/Images/Icons/style-01/data-formula.png b/WebServer/Images/Icons/style-01/data-formula.png new file mode 100644 index 000000000..58eca845b Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-formula.png differ diff --git a/WebServer/Images/Icons/style-01/data-mine.png b/WebServer/Images/Icons/style-01/data-mine.png new file mode 100644 index 000000000..5987d984c Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-mine.png differ diff --git a/WebServer/Images/Icons/style-01/data-mining.png b/WebServer/Images/Icons/style-01/data-mining.png new file mode 100644 index 000000000..069479644 Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-mining.png differ diff --git a/WebServer/Images/Icons/style-01/data-product.png b/WebServer/Images/Icons/style-01/data-product.png new file mode 100644 index 000000000..a56737af4 Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-product.png differ diff --git a/WebServer/Images/Icons/style-01/data-storage.png b/WebServer/Images/Icons/style-01/data-storage.png new file mode 100644 index 000000000..0371317db Binary files /dev/null and b/WebServer/Images/Icons/style-01/data-storage.png differ diff --git a/WebServer/Images/Icons/style-01/dataset-definition.png b/WebServer/Images/Icons/style-01/dataset-definition.png new file mode 100644 index 000000000..0f4735f92 Binary files /dev/null and b/WebServer/Images/Icons/style-01/dataset-definition.png differ diff --git a/WebServer/Images/Icons/style-01/dataset.png b/WebServer/Images/Icons/style-01/dataset.png new file mode 100644 index 000000000..8059cb8b5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/dataset.png differ diff --git a/WebServer/Images/Icons/style-01/delete.png b/WebServer/Images/Icons/style-01/delete.png new file mode 100644 index 000000000..a26ebea98 Binary files /dev/null and b/WebServer/Images/Icons/style-01/delete.png differ diff --git a/WebServer/Images/Icons/style-01/delink.png b/WebServer/Images/Icons/style-01/delink.png new file mode 100644 index 000000000..47f06ff61 Binary files /dev/null and b/WebServer/Images/Icons/style-01/delink.png differ diff --git a/WebServer/Images/Icons/style-01/design-tool.png b/WebServer/Images/Icons/style-01/design-tool.png new file mode 100644 index 000000000..7eb24f192 Binary files /dev/null and b/WebServer/Images/Icons/style-01/design-tool.png differ diff --git a/WebServer/Images/Icons/style-01/detach.png b/WebServer/Images/Icons/style-01/detach.png new file mode 100644 index 000000000..31aa781a3 Binary files /dev/null and b/WebServer/Images/Icons/style-01/detach.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-000.png b/WebServer/Images/Icons/style-01/distance-to-parent-000.png new file mode 100644 index 000000000..65e87718a Binary files /dev/null and b/WebServer/Images/Icons/style-01/distance-to-parent-000.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-025.png b/WebServer/Images/Icons/style-01/distance-to-parent-025.png new file mode 100644 index 000000000..bf08c48ac Binary files /dev/null and b/WebServer/Images/Icons/style-01/distance-to-parent-025.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-050.png b/WebServer/Images/Icons/style-01/distance-to-parent-050.png new file mode 100644 index 000000000..b5553349c Binary files /dev/null and b/WebServer/Images/Icons/style-01/distance-to-parent-050.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-100.png b/WebServer/Images/Icons/style-01/distance-to-parent-100.png new file mode 100644 index 000000000..44ad9bb60 Binary files /dev/null and b/WebServer/Images/Icons/style-01/distance-to-parent-100.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-150.png b/WebServer/Images/Icons/style-01/distance-to-parent-150.png new file mode 100644 index 000000000..c83632189 Binary files /dev/null and b/WebServer/Images/Icons/style-01/distance-to-parent-150.png differ diff --git a/WebServer/Images/Icons/style-01/distance-to-parent-200.png b/WebServer/Images/Icons/style-01/distance-to-parent-200.png new file mode 100644 index 000000000..537db0065 Binary files /dev/null and b/WebServer/Images/Icons/style-01/distance-to-parent-200.png differ diff --git a/WebServer/Images/Icons/style-01/eos.png b/WebServer/Images/Icons/style-01/eos.png new file mode 100644 index 000000000..d78e25ddd Binary files /dev/null and b/WebServer/Images/Icons/style-01/eos.png differ diff --git a/WebServer/Images/Icons/style-01/ethereum-classic.png b/WebServer/Images/Icons/style-01/ethereum-classic.png new file mode 100644 index 000000000..dc7089844 Binary files /dev/null and b/WebServer/Images/Icons/style-01/ethereum-classic.png differ diff --git a/WebServer/Images/Icons/style-01/ethereum.png b/WebServer/Images/Icons/style-01/ethereum.png new file mode 100644 index 000000000..33b2853a1 Binary files /dev/null and b/WebServer/Images/Icons/style-01/ethereum.png differ diff --git a/WebServer/Images/Icons/style-01/exchange-account-asset.png b/WebServer/Images/Icons/style-01/exchange-account-asset.png new file mode 100644 index 000000000..083125690 Binary files /dev/null and b/WebServer/Images/Icons/style-01/exchange-account-asset.png differ diff --git a/WebServer/Images/Icons/style-01/exchange-account-key.png b/WebServer/Images/Icons/style-01/exchange-account-key.png new file mode 100644 index 000000000..2df386906 Binary files /dev/null and b/WebServer/Images/Icons/style-01/exchange-account-key.png differ diff --git a/WebServer/Images/Icons/style-01/exchange-accounts.png b/WebServer/Images/Icons/style-01/exchange-accounts.png new file mode 100644 index 000000000..3ac313f88 Binary files /dev/null and b/WebServer/Images/Icons/style-01/exchange-accounts.png differ diff --git a/WebServer/Images/Icons/style-01/exchange-assets.png b/WebServer/Images/Icons/style-01/exchange-assets.png new file mode 100644 index 000000000..e5131939d Binary files /dev/null and b/WebServer/Images/Icons/style-01/exchange-assets.png differ diff --git a/WebServer/Images/Icons/style-01/exchange-markets.png b/WebServer/Images/Icons/style-01/exchange-markets.png new file mode 100644 index 000000000..98e70efc1 Binary files /dev/null and b/WebServer/Images/Icons/style-01/exchange-markets.png differ diff --git a/WebServer/Images/Icons/style-01/execution-finished-event.png b/WebServer/Images/Icons/style-01/execution-finished-event.png new file mode 100644 index 000000000..a50061daf Binary files /dev/null and b/WebServer/Images/Icons/style-01/execution-finished-event.png differ diff --git a/WebServer/Images/Icons/style-01/execution-started-event.png b/WebServer/Images/Icons/style-01/execution-started-event.png new file mode 100644 index 000000000..4389a6f16 Binary files /dev/null and b/WebServer/Images/Icons/style-01/execution-started-event.png differ diff --git a/WebServer/Images/Icons/style-01/grid.png b/WebServer/Images/Icons/style-01/grid.png new file mode 100644 index 000000000..b68f70a44 Binary files /dev/null and b/WebServer/Images/Icons/style-01/grid.png differ diff --git a/WebServer/Images/Icons/style-01/hand-drag.png b/WebServer/Images/Icons/style-01/hand-drag.png new file mode 100644 index 000000000..44f0683e2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/hand-drag.png differ diff --git a/WebServer/Images/Icons/style-01/headphones.png b/WebServer/Images/Icons/style-01/headphones.png new file mode 100644 index 000000000..d7c099510 Binary files /dev/null and b/WebServer/Images/Icons/style-01/headphones.png differ diff --git a/WebServer/Images/Icons/style-01/help.png b/WebServer/Images/Icons/style-01/help.png new file mode 100644 index 000000000..1fe2a4b34 Binary files /dev/null and b/WebServer/Images/Icons/style-01/help.png differ diff --git a/WebServer/Images/Icons/style-01/histogram.png b/WebServer/Images/Icons/style-01/histogram.png new file mode 100644 index 000000000..6c5711764 Binary files /dev/null and b/WebServer/Images/Icons/style-01/histogram.png differ diff --git a/WebServer/Images/Icons/style-01/hitbtc.png b/WebServer/Images/Icons/style-01/hitbtc.png new file mode 100644 index 000000000..0a2f39624 Binary files /dev/null and b/WebServer/Images/Icons/style-01/hitbtc.png differ diff --git a/WebServer/Images/Icons/style-01/html.png b/WebServer/Images/Icons/style-01/html.png new file mode 100644 index 000000000..fa46b2b7b Binary files /dev/null and b/WebServer/Images/Icons/style-01/html.png differ diff --git a/WebServer/Images/Icons/style-01/image.png b/WebServer/Images/Icons/style-01/image.png new file mode 100644 index 000000000..60b436b12 Binary files /dev/null and b/WebServer/Images/Icons/style-01/image.png differ diff --git a/WebServer/Images/Icons/style-01/initial-definition.png b/WebServer/Images/Icons/style-01/initial-definition.png new file mode 100644 index 000000000..d6e3db3d5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/initial-definition.png differ diff --git a/WebServer/Images/Icons/style-01/key-a.png b/WebServer/Images/Icons/style-01/key-a.png new file mode 100644 index 000000000..8809841e7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-a.png differ diff --git a/WebServer/Images/Icons/style-01/key-alt.png b/WebServer/Images/Icons/style-01/key-alt.png new file mode 100644 index 000000000..b5ad38990 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-alt.png differ diff --git a/WebServer/Images/Icons/style-01/key-ctrl.png b/WebServer/Images/Icons/style-01/key-ctrl.png new file mode 100644 index 000000000..95a97ba22 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-ctrl.png differ diff --git a/WebServer/Images/Icons/style-01/key-down.png b/WebServer/Images/Icons/style-01/key-down.png new file mode 100644 index 000000000..cea62f2c6 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-down.png differ diff --git a/WebServer/Images/Icons/style-01/key-left.png b/WebServer/Images/Icons/style-01/key-left.png new file mode 100644 index 000000000..d359dc5a9 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-left.png differ diff --git a/WebServer/Images/Icons/style-01/key-m.png b/WebServer/Images/Icons/style-01/key-m.png new file mode 100644 index 000000000..9415cb746 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-m.png differ diff --git a/WebServer/Images/Icons/style-01/key-r.png b/WebServer/Images/Icons/style-01/key-r.png new file mode 100644 index 000000000..3079372a7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-r.png differ diff --git a/WebServer/Images/Icons/style-01/key-right.png b/WebServer/Images/Icons/style-01/key-right.png new file mode 100644 index 000000000..9bb0c39c2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-right.png differ diff --git a/WebServer/Images/Icons/style-01/key-shift.png b/WebServer/Images/Icons/style-01/key-shift.png new file mode 100644 index 000000000..2d0f76800 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-shift.png differ diff --git a/WebServer/Images/Icons/style-01/key-up.png b/WebServer/Images/Icons/style-01/key-up.png new file mode 100644 index 000000000..0442350e0 Binary files /dev/null and b/WebServer/Images/Icons/style-01/key-up.png differ diff --git a/WebServer/Images/Icons/style-01/kraken.png b/WebServer/Images/Icons/style-01/kraken.png new file mode 100644 index 000000000..cf7e2d59e Binary files /dev/null and b/WebServer/Images/Icons/style-01/kraken.png differ diff --git a/WebServer/Images/Icons/style-01/kucoin.png b/WebServer/Images/Icons/style-01/kucoin.png new file mode 100644 index 000000000..c24a5e5c8 Binary files /dev/null and b/WebServer/Images/Icons/style-01/kucoin.png differ diff --git a/WebServer/Images/Icons/style-01/layer-manager.png b/WebServer/Images/Icons/style-01/layer-manager.png new file mode 100644 index 000000000..831267126 Binary files /dev/null and b/WebServer/Images/Icons/style-01/layer-manager.png differ diff --git a/WebServer/Images/Icons/style-01/layout.png b/WebServer/Images/Icons/style-01/layout.png new file mode 100644 index 000000000..eb93ce845 Binary files /dev/null and b/WebServer/Images/Icons/style-01/layout.png differ diff --git a/WebServer/Images/Icons/style-01/liquid.png b/WebServer/Images/Icons/style-01/liquid.png new file mode 100644 index 000000000..4dac18e6b Binary files /dev/null and b/WebServer/Images/Icons/style-01/liquid.png differ diff --git a/WebServer/Images/Icons/style-01/litecoin.png b/WebServer/Images/Icons/style-01/litecoin.png new file mode 100644 index 000000000..27080fd75 Binary files /dev/null and b/WebServer/Images/Icons/style-01/litecoin.png differ diff --git a/WebServer/Images/Icons/style-01/loading.png b/WebServer/Images/Icons/style-01/loading.png new file mode 100644 index 000000000..845c02cbd Binary files /dev/null and b/WebServer/Images/Icons/style-01/loading.png differ diff --git a/WebServer/Images/Icons/style-01/login.png b/WebServer/Images/Icons/style-01/login.png new file mode 100644 index 000000000..16a99c7b1 Binary files /dev/null and b/WebServer/Images/Icons/style-01/login.png differ diff --git a/WebServer/Images/Icons/style-01/market.png b/WebServer/Images/Icons/style-01/market.png new file mode 100644 index 000000000..ba224734d Binary files /dev/null and b/WebServer/Images/Icons/style-01/market.png differ diff --git a/WebServer/Images/Icons/style-01/master-script.png b/WebServer/Images/Icons/style-01/master-script.png new file mode 100644 index 000000000..9afac1eb8 Binary files /dev/null and b/WebServer/Images/Icons/style-01/master-script.png differ diff --git a/WebServer/Images/Icons/style-01/menu-backup.png b/WebServer/Images/Icons/style-01/menu-backup.png new file mode 100644 index 000000000..142a2fa80 Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-backup.png differ diff --git a/WebServer/Images/Icons/style-01/menu-fix-pinned.png b/WebServer/Images/Icons/style-01/menu-fix-pinned.png new file mode 100644 index 000000000..ba637d28d Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-fix-pinned.png differ diff --git a/WebServer/Images/Icons/style-01/menu-fix-unpinned.png b/WebServer/Images/Icons/style-01/menu-fix-unpinned.png new file mode 100644 index 000000000..c574c5b19 Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-fix-unpinned.png differ diff --git a/WebServer/Images/Icons/style-01/menu-mobility-freeze.png b/WebServer/Images/Icons/style-01/menu-mobility-freeze.png new file mode 100644 index 000000000..fd89c6208 Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-mobility-freeze.png differ diff --git a/WebServer/Images/Icons/style-01/menu-mobility-unfreeze.png b/WebServer/Images/Icons/style-01/menu-mobility-unfreeze.png new file mode 100644 index 000000000..df97739ca Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-mobility-unfreeze.png differ diff --git a/WebServer/Images/Icons/style-01/menu-share.png b/WebServer/Images/Icons/style-01/menu-share.png new file mode 100644 index 000000000..c4998af5e Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-share.png differ diff --git a/WebServer/Images/Icons/style-01/menu-tensor-fixed-angles.png b/WebServer/Images/Icons/style-01/menu-tensor-fixed-angles.png new file mode 100644 index 000000000..9fe32b7a2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-tensor-fixed-angles.png differ diff --git a/WebServer/Images/Icons/style-01/menu-tensor-free-angles.png b/WebServer/Images/Icons/style-01/menu-tensor-free-angles.png new file mode 100644 index 000000000..2fdd02cca Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-tensor-free-angles.png differ diff --git a/WebServer/Images/Icons/style-01/menu-tree-minus.png b/WebServer/Images/Icons/style-01/menu-tree-minus.png new file mode 100644 index 000000000..2a8158670 Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-tree-minus.png differ diff --git a/WebServer/Images/Icons/style-01/menu-tree-plus.png b/WebServer/Images/Icons/style-01/menu-tree-plus.png new file mode 100644 index 000000000..637282507 Binary files /dev/null and b/WebServer/Images/Icons/style-01/menu-tree-plus.png differ diff --git a/WebServer/Images/Icons/style-01/monero.png b/WebServer/Images/Icons/style-01/monero.png new file mode 100644 index 000000000..eb938c3f7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/monero.png differ diff --git a/WebServer/Images/Icons/style-01/mouse-left-click.png b/WebServer/Images/Icons/style-01/mouse-left-click.png new file mode 100644 index 000000000..be3e72840 Binary files /dev/null and b/WebServer/Images/Icons/style-01/mouse-left-click.png differ diff --git a/WebServer/Images/Icons/style-01/mouse-pointer.png b/WebServer/Images/Icons/style-01/mouse-pointer.png new file mode 100644 index 000000000..08b2ead5e Binary files /dev/null and b/WebServer/Images/Icons/style-01/mouse-pointer.png differ diff --git a/WebServer/Images/Icons/style-01/mouse-right-click.png b/WebServer/Images/Icons/style-01/mouse-right-click.png new file mode 100644 index 000000000..0e1a287b3 Binary files /dev/null and b/WebServer/Images/Icons/style-01/mouse-right-click.png differ diff --git a/WebServer/Images/Icons/style-01/mouse-wheel-click.png b/WebServer/Images/Icons/style-01/mouse-wheel-click.png new file mode 100644 index 000000000..6dab9a4ff Binary files /dev/null and b/WebServer/Images/Icons/style-01/mouse-wheel-click.png differ diff --git a/WebServer/Images/Icons/style-01/mouse-wheel-down.png b/WebServer/Images/Icons/style-01/mouse-wheel-down.png new file mode 100644 index 000000000..58386b47d Binary files /dev/null and b/WebServer/Images/Icons/style-01/mouse-wheel-down.png differ diff --git a/WebServer/Images/Icons/style-01/mouse-wheel-up.png b/WebServer/Images/Icons/style-01/mouse-wheel-up.png new file mode 100644 index 000000000..a11479633 Binary files /dev/null and b/WebServer/Images/Icons/style-01/mouse-wheel-up.png differ diff --git a/WebServer/Images/Icons/style-01/mouse-wheel.png b/WebServer/Images/Icons/style-01/mouse-wheel.png new file mode 100644 index 000000000..c26a3517a Binary files /dev/null and b/WebServer/Images/Icons/style-01/mouse-wheel.png differ diff --git a/WebServer/Images/Icons/style-01/moving-average.png b/WebServer/Images/Icons/style-01/moving-average.png new file mode 100644 index 000000000..5d62c67e3 Binary files /dev/null and b/WebServer/Images/Icons/style-01/moving-average.png differ diff --git a/WebServer/Images/Icons/style-01/neo.png b/WebServer/Images/Icons/style-01/neo.png new file mode 100644 index 000000000..ab608f9f9 Binary files /dev/null and b/WebServer/Images/Icons/style-01/neo.png differ diff --git a/WebServer/Images/Icons/style-01/network-node.png b/WebServer/Images/Icons/style-01/network-node.png new file mode 100644 index 000000000..30782f8e3 Binary files /dev/null and b/WebServer/Images/Icons/style-01/network-node.png differ diff --git a/WebServer/Images/Icons/style-01/network.png b/WebServer/Images/Icons/style-01/network.png new file mode 100644 index 000000000..0880e7e8d Binary files /dev/null and b/WebServer/Images/Icons/style-01/network.png differ diff --git a/WebServer/Images/Icons/style-01/next-phase-event.png b/WebServer/Images/Icons/style-01/next-phase-event.png new file mode 100644 index 000000000..efc14dbd0 Binary files /dev/null and b/WebServer/Images/Icons/style-01/next-phase-event.png differ diff --git a/WebServer/Images/Icons/style-01/oscillator.png b/WebServer/Images/Icons/style-01/oscillator.png new file mode 100644 index 000000000..7c4f9445a Binary files /dev/null and b/WebServer/Images/Icons/style-01/oscillator.png differ diff --git a/WebServer/Images/Icons/style-01/output-dataset.png b/WebServer/Images/Icons/style-01/output-dataset.png new file mode 100644 index 000000000..a8a34710a Binary files /dev/null and b/WebServer/Images/Icons/style-01/output-dataset.png differ diff --git a/WebServer/Images/Icons/style-01/pantone.png b/WebServer/Images/Icons/style-01/pantone.png new file mode 100644 index 000000000..0ea9cae40 Binary files /dev/null and b/WebServer/Images/Icons/style-01/pantone.png differ diff --git a/WebServer/Images/Icons/style-01/paper-plane.png b/WebServer/Images/Icons/style-01/paper-plane.png new file mode 100644 index 000000000..b61292bbc Binary files /dev/null and b/WebServer/Images/Icons/style-01/paper-plane.png differ diff --git a/WebServer/Images/Icons/style-01/photo-camera.png b/WebServer/Images/Icons/style-01/photo-camera.png new file mode 100644 index 000000000..77336bdff Binary files /dev/null and b/WebServer/Images/Icons/style-01/photo-camera.png differ diff --git a/WebServer/Images/Icons/style-01/piggy-bank.png b/WebServer/Images/Icons/style-01/piggy-bank.png new file mode 100644 index 000000000..5fe9f5062 Binary files /dev/null and b/WebServer/Images/Icons/style-01/piggy-bank.png differ diff --git a/WebServer/Images/Icons/style-01/pipette.png b/WebServer/Images/Icons/style-01/pipette.png new file mode 100644 index 000000000..5d854018c Binary files /dev/null and b/WebServer/Images/Icons/style-01/pipette.png differ diff --git a/WebServer/Images/Icons/style-01/pixel.png b/WebServer/Images/Icons/style-01/pixel.png new file mode 100644 index 000000000..0dd36069e Binary files /dev/null and b/WebServer/Images/Icons/style-01/pixel.png differ diff --git a/WebServer/Images/Icons/style-01/placeholder.png b/WebServer/Images/Icons/style-01/placeholder.png new file mode 100644 index 000000000..b9d3765cf Binary files /dev/null and b/WebServer/Images/Icons/style-01/placeholder.png differ diff --git a/WebServer/Images/Icons/style-01/planning.png b/WebServer/Images/Icons/style-01/planning.png new file mode 100644 index 000000000..d6e3db3d5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/planning.png differ diff --git a/WebServer/Images/Icons/style-01/plotter-module.png b/WebServer/Images/Icons/style-01/plotter-module.png new file mode 100644 index 000000000..476f02301 Binary files /dev/null and b/WebServer/Images/Icons/style-01/plotter-module.png differ diff --git a/WebServer/Images/Icons/style-01/plotter-panel.png b/WebServer/Images/Icons/style-01/plotter-panel.png new file mode 100644 index 000000000..001875359 Binary files /dev/null and b/WebServer/Images/Icons/style-01/plotter-panel.png differ diff --git a/WebServer/Images/Icons/style-01/plotter.png b/WebServer/Images/Icons/style-01/plotter.png new file mode 100644 index 000000000..5b1a23445 Binary files /dev/null and b/WebServer/Images/Icons/style-01/plotter.png differ diff --git a/WebServer/Images/Icons/style-01/poloniex.png b/WebServer/Images/Icons/style-01/poloniex.png new file mode 100644 index 000000000..2e29586a3 Binary files /dev/null and b/WebServer/Images/Icons/style-01/poloniex.png differ diff --git a/WebServer/Images/Icons/style-01/procedure-initialization.png b/WebServer/Images/Icons/style-01/procedure-initialization.png new file mode 100644 index 000000000..9adc971cf Binary files /dev/null and b/WebServer/Images/Icons/style-01/procedure-initialization.png differ diff --git a/WebServer/Images/Icons/style-01/procedure-loop.png b/WebServer/Images/Icons/style-01/procedure-loop.png new file mode 100644 index 000000000..bd5b5990a Binary files /dev/null and b/WebServer/Images/Icons/style-01/procedure-loop.png differ diff --git a/WebServer/Images/Icons/style-01/process-definition.png b/WebServer/Images/Icons/style-01/process-definition.png new file mode 100644 index 000000000..bd89e9373 Binary files /dev/null and b/WebServer/Images/Icons/style-01/process-definition.png differ diff --git a/WebServer/Images/Icons/style-01/process-dependencies.png b/WebServer/Images/Icons/style-01/process-dependencies.png new file mode 100644 index 000000000..dc000d321 Binary files /dev/null and b/WebServer/Images/Icons/style-01/process-dependencies.png differ diff --git a/WebServer/Images/Icons/style-01/process-output.png b/WebServer/Images/Icons/style-01/process-output.png new file mode 100644 index 000000000..f415f81a7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/process-output.png differ diff --git a/WebServer/Images/Icons/style-01/process.png b/WebServer/Images/Icons/style-01/process.png new file mode 100644 index 000000000..bf6e71161 Binary files /dev/null and b/WebServer/Images/Icons/style-01/process.png differ diff --git a/WebServer/Images/Icons/style-01/product-definition.png b/WebServer/Images/Icons/style-01/product-definition.png new file mode 100644 index 000000000..80ef1048d Binary files /dev/null and b/WebServer/Images/Icons/style-01/product-definition.png differ diff --git a/WebServer/Images/Icons/style-01/production-environment.png b/WebServer/Images/Icons/style-01/production-environment.png new file mode 100644 index 000000000..75c356de6 Binary files /dev/null and b/WebServer/Images/Icons/style-01/production-environment.png differ diff --git a/WebServer/Images/Icons/style-01/promotion.png b/WebServer/Images/Icons/style-01/promotion.png new file mode 100644 index 000000000..2d38a607d Binary files /dev/null and b/WebServer/Images/Icons/style-01/promotion.png differ diff --git a/WebServer/Images/Icons/style-01/pyramid.png b/WebServer/Images/Icons/style-01/pyramid.png new file mode 100644 index 000000000..4b940968b Binary files /dev/null and b/WebServer/Images/Icons/style-01/pyramid.png differ diff --git a/WebServer/Images/Icons/style-01/qtum.png b/WebServer/Images/Icons/style-01/qtum.png new file mode 100644 index 000000000..c8df5a140 Binary files /dev/null and b/WebServer/Images/Icons/style-01/qtum.png differ diff --git a/WebServer/Images/Icons/style-01/quality.png b/WebServer/Images/Icons/style-01/quality.png new file mode 100644 index 000000000..10ee8b6bd Binary files /dev/null and b/WebServer/Images/Icons/style-01/quality.png differ diff --git a/WebServer/Images/Icons/style-01/rate-scale.png b/WebServer/Images/Icons/style-01/rate-scale.png new file mode 100644 index 000000000..7471b89ff Binary files /dev/null and b/WebServer/Images/Icons/style-01/rate-scale.png differ diff --git a/WebServer/Images/Icons/style-01/record-definition.png b/WebServer/Images/Icons/style-01/record-definition.png new file mode 100644 index 000000000..364d300c0 Binary files /dev/null and b/WebServer/Images/Icons/style-01/record-definition.png differ diff --git a/WebServer/Images/Icons/style-01/record-property.png b/WebServer/Images/Icons/style-01/record-property.png new file mode 100644 index 000000000..3bc17e408 Binary files /dev/null and b/WebServer/Images/Icons/style-01/record-property.png differ diff --git a/WebServer/Images/Icons/style-01/responsive.png b/WebServer/Images/Icons/style-01/responsive.png new file mode 100644 index 000000000..3de364530 Binary files /dev/null and b/WebServer/Images/Icons/style-01/responsive.png differ diff --git a/WebServer/Images/Icons/style-01/schedule.png b/WebServer/Images/Icons/style-01/schedule.png new file mode 100644 index 000000000..cf928a0ea Binary files /dev/null and b/WebServer/Images/Icons/style-01/schedule.png differ diff --git a/WebServer/Images/Icons/style-01/scripts-library.png b/WebServer/Images/Icons/style-01/scripts-library.png new file mode 100644 index 000000000..8133ebb5b Binary files /dev/null and b/WebServer/Images/Icons/style-01/scripts-library.png differ diff --git a/WebServer/Images/Icons/style-01/search.png b/WebServer/Images/Icons/style-01/search.png new file mode 100644 index 000000000..595845f03 Binary files /dev/null and b/WebServer/Images/Icons/style-01/search.png differ diff --git a/WebServer/Images/Icons/style-01/security.png b/WebServer/Images/Icons/style-01/security.png new file mode 100644 index 000000000..cc32f2462 Binary files /dev/null and b/WebServer/Images/Icons/style-01/security.png differ diff --git a/WebServer/Images/Icons/style-01/session-backtesting.png b/WebServer/Images/Icons/style-01/session-backtesting.png new file mode 100644 index 000000000..25170c9e9 Binary files /dev/null and b/WebServer/Images/Icons/style-01/session-backtesting.png differ diff --git a/WebServer/Images/Icons/style-01/session-based-data.png b/WebServer/Images/Icons/style-01/session-based-data.png new file mode 100644 index 000000000..cd3e2bd5b Binary files /dev/null and b/WebServer/Images/Icons/style-01/session-based-data.png differ diff --git a/WebServer/Images/Icons/style-01/session-forward-testing.png b/WebServer/Images/Icons/style-01/session-forward-testing.png new file mode 100644 index 000000000..d32066568 Binary files /dev/null and b/WebServer/Images/Icons/style-01/session-forward-testing.png differ diff --git a/WebServer/Images/Icons/style-01/session-independent-data.png b/WebServer/Images/Icons/style-01/session-independent-data.png new file mode 100644 index 000000000..1b69e88d5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/session-independent-data.png differ diff --git a/WebServer/Images/Icons/style-01/session-live-trading.png b/WebServer/Images/Icons/style-01/session-live-trading.png new file mode 100644 index 000000000..02d91af01 Binary files /dev/null and b/WebServer/Images/Icons/style-01/session-live-trading.png differ diff --git a/WebServer/Images/Icons/style-01/session-paper-trading.png b/WebServer/Images/Icons/style-01/session-paper-trading.png new file mode 100644 index 000000000..5e8413e7e Binary files /dev/null and b/WebServer/Images/Icons/style-01/session-paper-trading.png differ diff --git a/WebServer/Images/Icons/style-01/session-reference.png b/WebServer/Images/Icons/style-01/session-reference.png new file mode 100644 index 000000000..d3c017532 Binary files /dev/null and b/WebServer/Images/Icons/style-01/session-reference.png differ diff --git a/WebServer/Images/Icons/style-01/settings.png b/WebServer/Images/Icons/style-01/settings.png new file mode 100644 index 000000000..878a9aa46 Binary files /dev/null and b/WebServer/Images/Icons/style-01/settings.png differ diff --git a/WebServer/Images/Icons/style-01/shapes-polygon-body.png b/WebServer/Images/Icons/style-01/shapes-polygon-body.png new file mode 100644 index 000000000..33a546c98 Binary files /dev/null and b/WebServer/Images/Icons/style-01/shapes-polygon-body.png differ diff --git a/WebServer/Images/Icons/style-01/shapes-polygon-border.png b/WebServer/Images/Icons/style-01/shapes-polygon-border.png new file mode 100644 index 000000000..b8b56d398 Binary files /dev/null and b/WebServer/Images/Icons/style-01/shapes-polygon-border.png differ diff --git a/WebServer/Images/Icons/style-01/shapes-polygon-vertex.png b/WebServer/Images/Icons/style-01/shapes-polygon-vertex.png new file mode 100644 index 000000000..2eaa6c232 Binary files /dev/null and b/WebServer/Images/Icons/style-01/shapes-polygon-vertex.png differ diff --git a/WebServer/Images/Icons/style-01/shapes-polygon.png b/WebServer/Images/Icons/style-01/shapes-polygon.png new file mode 100644 index 000000000..5b7ac0185 Binary files /dev/null and b/WebServer/Images/Icons/style-01/shapes-polygon.png differ diff --git a/WebServer/Images/Icons/style-01/shapes.png b/WebServer/Images/Icons/style-01/shapes.png new file mode 100644 index 000000000..67644126d Binary files /dev/null and b/WebServer/Images/Icons/style-01/shapes.png differ diff --git a/WebServer/Images/Icons/style-01/single-market-data.png b/WebServer/Images/Icons/style-01/single-market-data.png new file mode 100644 index 000000000..d88dbefb3 Binary files /dev/null and b/WebServer/Images/Icons/style-01/single-market-data.png differ diff --git a/WebServer/Images/Icons/style-01/sitemap.png b/WebServer/Images/Icons/style-01/sitemap.png new file mode 100644 index 000000000..0c864590f Binary files /dev/null and b/WebServer/Images/Icons/style-01/sitemap.png differ diff --git a/WebServer/Images/Icons/style-01/social-bot.png b/WebServer/Images/Icons/style-01/social-bot.png new file mode 100644 index 000000000..1df5bcc28 Binary files /dev/null and b/WebServer/Images/Icons/style-01/social-bot.png differ diff --git a/WebServer/Images/Icons/style-01/stage-close.png b/WebServer/Images/Icons/style-01/stage-close.png new file mode 100644 index 000000000..beb6dc1bd Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-close.png differ diff --git a/WebServer/Images/Icons/style-01/stage-open-position-size.png b/WebServer/Images/Icons/style-01/stage-open-position-size.png new file mode 100644 index 000000000..7eab6812e Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-open-position-size.png differ diff --git a/WebServer/Images/Icons/style-01/stage-open-postion-rate.png b/WebServer/Images/Icons/style-01/stage-open-postion-rate.png new file mode 100644 index 000000000..ea634cd71 Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-open-postion-rate.png differ diff --git a/WebServer/Images/Icons/style-01/stage-open-take-profit.png b/WebServer/Images/Icons/style-01/stage-open-take-profit.png new file mode 100644 index 000000000..c3db5908e Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-open-take-profit.png differ diff --git a/WebServer/Images/Icons/style-01/stage-open.png b/WebServer/Images/Icons/style-01/stage-open.png new file mode 100644 index 000000000..0a66b09e9 Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-open.png differ diff --git a/WebServer/Images/Icons/style-01/stage-trigger-take-position.png b/WebServer/Images/Icons/style-01/stage-trigger-take-position.png new file mode 100644 index 000000000..5e03218d2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-trigger-take-position.png differ diff --git a/WebServer/Images/Icons/style-01/stage-trigger-trigger-off.png b/WebServer/Images/Icons/style-01/stage-trigger-trigger-off.png new file mode 100644 index 000000000..cb1076837 Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-trigger-trigger-off.png differ diff --git a/WebServer/Images/Icons/style-01/stage-trigger-trigger-on.png b/WebServer/Images/Icons/style-01/stage-trigger-trigger-on.png new file mode 100644 index 000000000..e56d56f64 Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-trigger-trigger-on.png differ diff --git a/WebServer/Images/Icons/style-01/stage-trigger.png b/WebServer/Images/Icons/style-01/stage-trigger.png new file mode 100644 index 000000000..83a87e2d6 Binary files /dev/null and b/WebServer/Images/Icons/style-01/stage-trigger.png differ diff --git a/WebServer/Images/Icons/style-01/startup.png b/WebServer/Images/Icons/style-01/startup.png new file mode 100644 index 000000000..7ed8d6cb0 Binary files /dev/null and b/WebServer/Images/Icons/style-01/startup.png differ diff --git a/WebServer/Images/Icons/style-01/status-dependency.png b/WebServer/Images/Icons/style-01/status-dependency.png new file mode 100644 index 000000000..cb318dee5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/status-dependency.png differ diff --git a/WebServer/Images/Icons/style-01/status-report.png b/WebServer/Images/Icons/style-01/status-report.png new file mode 100644 index 000000000..f3361a6e9 Binary files /dev/null and b/WebServer/Images/Icons/style-01/status-report.png differ diff --git a/WebServer/Images/Icons/style-01/stellar.png b/WebServer/Images/Icons/style-01/stellar.png new file mode 100644 index 000000000..d853f8e51 Binary files /dev/null and b/WebServer/Images/Icons/style-01/stellar.png differ diff --git a/WebServer/Images/Icons/style-01/stop.png b/WebServer/Images/Icons/style-01/stop.png new file mode 100644 index 000000000..65fff4f18 Binary files /dev/null and b/WebServer/Images/Icons/style-01/stop.png differ diff --git a/WebServer/Images/Icons/style-01/style-condition.png b/WebServer/Images/Icons/style-01/style-condition.png new file mode 100644 index 000000000..eb9a065c1 Binary files /dev/null and b/WebServer/Images/Icons/style-01/style-condition.png differ diff --git a/WebServer/Images/Icons/style-01/style.png b/WebServer/Images/Icons/style-01/style.png new file mode 100644 index 000000000..4ae248158 Binary files /dev/null and b/WebServer/Images/Icons/style-01/style.png differ diff --git a/WebServer/Images/Icons/style-01/super-action.png b/WebServer/Images/Icons/style-01/super-action.png new file mode 100644 index 000000000..a3dc332fd Binary files /dev/null and b/WebServer/Images/Icons/style-01/super-action.png differ diff --git a/WebServer/Images/Icons/style-01/super-scripts.png b/WebServer/Images/Icons/style-01/super-scripts.png new file mode 100644 index 000000000..12e17e118 Binary files /dev/null and b/WebServer/Images/Icons/style-01/super-scripts.png differ diff --git a/WebServer/Images/Icons/style-01/support.png b/WebServer/Images/Icons/style-01/support.png new file mode 100644 index 000000000..fcafb34f3 Binary files /dev/null and b/WebServer/Images/Icons/style-01/support.png differ diff --git a/WebServer/Images/Icons/style-01/tap.png b/WebServer/Images/Icons/style-01/tap.png new file mode 100644 index 000000000..7f958daf5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/tap.png differ diff --git a/WebServer/Images/Icons/style-01/targeting.png b/WebServer/Images/Icons/style-01/targeting.png new file mode 100644 index 000000000..ef53bb1e6 Binary files /dev/null and b/WebServer/Images/Icons/style-01/targeting.png differ diff --git a/WebServer/Images/Icons/style-01/task-manager.png b/WebServer/Images/Icons/style-01/task-manager.png new file mode 100644 index 000000000..ee8d2bc25 Binary files /dev/null and b/WebServer/Images/Icons/style-01/task-manager.png differ diff --git a/WebServer/Images/Icons/style-01/task.png b/WebServer/Images/Icons/style-01/task.png new file mode 100644 index 000000000..e85e1ba2b Binary files /dev/null and b/WebServer/Images/Icons/style-01/task.png differ diff --git a/WebServer/Images/Icons/style-01/template-script.png b/WebServer/Images/Icons/style-01/template-script.png new file mode 100644 index 000000000..fbbc921f1 Binary files /dev/null and b/WebServer/Images/Icons/style-01/template-script.png differ diff --git a/WebServer/Images/Icons/style-01/template-structure.png b/WebServer/Images/Icons/style-01/template-structure.png new file mode 100644 index 000000000..212baedf4 Binary files /dev/null and b/WebServer/Images/Icons/style-01/template-structure.png differ diff --git a/WebServer/Images/Icons/style-01/template-target.png b/WebServer/Images/Icons/style-01/template-target.png new file mode 100644 index 000000000..233628a94 Binary files /dev/null and b/WebServer/Images/Icons/style-01/template-target.png differ diff --git a/WebServer/Images/Icons/style-01/testing-environment.png b/WebServer/Images/Icons/style-01/testing-environment.png new file mode 100644 index 000000000..d634fbc0e Binary files /dev/null and b/WebServer/Images/Icons/style-01/testing-environment.png differ diff --git a/WebServer/Images/Icons/style-01/testing.png b/WebServer/Images/Icons/style-01/testing.png new file mode 100644 index 000000000..2c3a28848 Binary files /dev/null and b/WebServer/Images/Icons/style-01/testing.png differ diff --git a/WebServer/Images/Icons/style-01/tether.png b/WebServer/Images/Icons/style-01/tether.png new file mode 100644 index 000000000..af6e43f43 Binary files /dev/null and b/WebServer/Images/Icons/style-01/tether.png differ diff --git a/WebServer/Images/Icons/style-01/text.png b/WebServer/Images/Icons/style-01/text.png new file mode 100644 index 000000000..959e64e90 Binary files /dev/null and b/WebServer/Images/Icons/style-01/text.png differ diff --git a/WebServer/Images/Icons/style-01/time-frame-scale.png b/WebServer/Images/Icons/style-01/time-frame-scale.png new file mode 100644 index 000000000..7aeece127 Binary files /dev/null and b/WebServer/Images/Icons/style-01/time-frame-scale.png differ diff --git a/WebServer/Images/Icons/style-01/time-line-chart.png b/WebServer/Images/Icons/style-01/time-line-chart.png new file mode 100644 index 000000000..3525af058 Binary files /dev/null and b/WebServer/Images/Icons/style-01/time-line-chart.png differ diff --git a/WebServer/Images/Icons/style-01/time-machine.png b/WebServer/Images/Icons/style-01/time-machine.png new file mode 100644 index 000000000..f10e3dda7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/time-machine.png differ diff --git a/WebServer/Images/Icons/style-01/time-period.png b/WebServer/Images/Icons/style-01/time-period.png new file mode 100644 index 000000000..15ea83404 Binary files /dev/null and b/WebServer/Images/Icons/style-01/time-period.png differ diff --git a/WebServer/Images/Icons/style-01/time-scale.png b/WebServer/Images/Icons/style-01/time-scale.png new file mode 100644 index 000000000..462140c6b Binary files /dev/null and b/WebServer/Images/Icons/style-01/time-scale.png differ diff --git a/WebServer/Images/Icons/style-01/timeline.png b/WebServer/Images/Icons/style-01/timeline.png new file mode 100644 index 000000000..8a7051d9f Binary files /dev/null and b/WebServer/Images/Icons/style-01/timeline.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-max.png b/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-max.png new file mode 100644 index 000000000..fa8168e6c Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-max.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-min-max.png b/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-min-max.png new file mode 100644 index 000000000..e7549e1e6 Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-min-max.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-min.png b/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-min.png new file mode 100644 index 000000000..22e67cda5 Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-auto-scale-auto-min.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-auto-scale-manual.png b/WebServer/Images/Icons/style-01/toggle-auto-scale-manual.png new file mode 100644 index 000000000..282f4dbac Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-auto-scale-manual.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-max.png b/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-max.png new file mode 100644 index 000000000..37b6f77b2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-max.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-min-max.png b/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-min-max.png new file mode 100644 index 000000000..a193213f7 Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-min-max.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-min.png b/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-min.png new file mode 100644 index 000000000..7c4a26043 Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-auto-time-scale-auto-min.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-auto-time-scale-manual.png b/WebServer/Images/Icons/style-01/toggle-auto-time-scale-manual.png new file mode 100644 index 000000000..a8da7ca60 Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-auto-time-scale-manual.png differ diff --git a/WebServer/Images/Icons/style-01/toggle-panel-off.png b/WebServer/Images/Icons/style-01/toggle-panel-off.png new file mode 100644 index 000000000..032a33409 Binary files /dev/null and b/WebServer/Images/Icons/style-01/toggle-panel-off.png differ diff --git a/WebServer/Images/Icons/style-01/tools.png b/WebServer/Images/Icons/style-01/tools.png new file mode 100644 index 000000000..a22d7f0a3 Binary files /dev/null and b/WebServer/Images/Icons/style-01/tools.png differ diff --git a/WebServer/Images/Icons/style-01/trend.png b/WebServer/Images/Icons/style-01/trend.png new file mode 100644 index 000000000..1a57bb1a1 Binary files /dev/null and b/WebServer/Images/Icons/style-01/trend.png differ diff --git a/WebServer/Images/Icons/style-01/tron.png b/WebServer/Images/Icons/style-01/tron.png new file mode 100644 index 000000000..65ebcbd98 Binary files /dev/null and b/WebServer/Images/Icons/style-01/tron.png differ diff --git a/WebServer/Images/Icons/style-01/upbit.png b/WebServer/Images/Icons/style-01/upbit.png new file mode 100644 index 000000000..6e3cb476d Binary files /dev/null and b/WebServer/Images/Icons/style-01/upbit.png differ diff --git a/WebServer/Images/Icons/style-01/upload.png b/WebServer/Images/Icons/style-01/upload.png new file mode 100644 index 000000000..50e4d79c2 Binary files /dev/null and b/WebServer/Images/Icons/style-01/upload.png differ diff --git a/WebServer/Images/Icons/style-01/us-dollar.png b/WebServer/Images/Icons/style-01/us-dollar.png new file mode 100644 index 000000000..ba31d4f09 Binary files /dev/null and b/WebServer/Images/Icons/style-01/us-dollar.png differ diff --git a/WebServer/Images/Icons/style-01/user-account.png b/WebServer/Images/Icons/style-01/user-account.png new file mode 100644 index 000000000..8c3b677da Binary files /dev/null and b/WebServer/Images/Icons/style-01/user-account.png differ diff --git a/WebServer/Images/Icons/style-01/user-assets.png b/WebServer/Images/Icons/style-01/user-assets.png new file mode 100644 index 000000000..bf9f73b4e Binary files /dev/null and b/WebServer/Images/Icons/style-01/user-assets.png differ diff --git a/WebServer/Images/Icons/style-01/user-keys.png b/WebServer/Images/Icons/style-01/user-keys.png new file mode 100644 index 000000000..906fe456f Binary files /dev/null and b/WebServer/Images/Icons/style-01/user-keys.png differ diff --git a/WebServer/Images/Icons/style-01/vector.png b/WebServer/Images/Icons/style-01/vector.png new file mode 100644 index 000000000..b9b1e7a02 Binary files /dev/null and b/WebServer/Images/Icons/style-01/vector.png differ diff --git a/WebServer/Images/Icons/style-01/video-player.png b/WebServer/Images/Icons/style-01/video-player.png new file mode 100644 index 000000000..b382fe80e Binary files /dev/null and b/WebServer/Images/Icons/style-01/video-player.png differ diff --git a/WebServer/Images/Icons/style-01/viewport.png b/WebServer/Images/Icons/style-01/viewport.png new file mode 100644 index 000000000..1365ecd7b Binary files /dev/null and b/WebServer/Images/Icons/style-01/viewport.png differ diff --git a/WebServer/Images/Icons/style-01/volume.png b/WebServer/Images/Icons/style-01/volume.png new file mode 100644 index 000000000..60d213b6d Binary files /dev/null and b/WebServer/Images/Icons/style-01/volume.png differ diff --git a/WebServer/Images/favicon.ico b/WebServer/Images/favicon.ico new file mode 100644 index 000000000..cd2c5d6af Binary files /dev/null and b/WebServer/Images/favicon.ico differ diff --git a/WebServer/Images/superalgos-header-background.png b/WebServer/Images/superalgos-header-background.png new file mode 100644 index 000000000..5c980aa38 Binary files /dev/null and b/WebServer/Images/superalgos-header-background.png differ diff --git a/WebServer/Images/superalgos-logo-for-color-background.png b/WebServer/Images/superalgos-logo-for-color-background.png new file mode 100644 index 000000000..40f8de2ab Binary files /dev/null and b/WebServer/Images/superalgos-logo-for-color-background.png differ diff --git a/WebServer/Images/superalgos-logo.png b/WebServer/Images/superalgos-logo.png new file mode 100644 index 000000000..995d19538 Binary files /dev/null and b/WebServer/Images/superalgos-logo.png differ diff --git a/WebServer/Images/superalgos-platform.jpg b/WebServer/Images/superalgos-platform.jpg new file mode 100644 index 000000000..7aecf4958 Binary files /dev/null and b/WebServer/Images/superalgos-platform.jpg differ diff --git a/WebServer/LegacyPlotter.js b/WebServer/LegacyPlotter.js new file mode 100644 index 000000000..cb4e49753 --- /dev/null +++ b/WebServer/LegacyPlotter.js @@ -0,0 +1,6 @@ +function getNewPlotter(pDataMineOrHost, pPlotter, pModule) { + let functionName = pDataMineOrHost + pPlotter + pModule; + functionName = functionName.replace(/-/g, ""); + functionName = 'new' + functionName + return window[functionName](); +} diff --git a/WebServer/PlotterPanel.js b/WebServer/PlotterPanel.js new file mode 100644 index 000000000..75e63863e --- /dev/null +++ b/WebServer/PlotterPanel.js @@ -0,0 +1,6 @@ +function getNewPlotterPanel(pDataMineOrHost, pPlotter, pModule, pPanel) { + let functionName = pDataMineOrHost + pPlotter + pModule + pPanel; + functionName = functionName.replace(/-/g, ""); + functionName = 'new' + functionName + return window[functionName](); +} diff --git a/WebServer/externalScripts/CCapture.all.min.js b/WebServer/externalScripts/CCapture.all.min.js new file mode 100644 index 000000000..bda376d9f --- /dev/null +++ b/WebServer/externalScripts/CCapture.all.min.js @@ -0,0 +1,2 @@ +"use strict";function download(t,e,i){function n(t){var e=t.split(/[:;,]/),i=e[1],n="base64"==e[2]?atob:decodeURIComponent,r=n(e.pop()),o=r.length,a=0,s=new Uint8Array(o);for(a;a>8,this.data[this.pos++]=t},t.prototype.writeDoubleBE=function(t){for(var e=new Uint8Array(new Float64Array([t]).buffer),i=e.length-1;i>=0;i--)this.writeByte(e[i])},t.prototype.writeFloatBE=function(t){for(var e=new Uint8Array(new Float32Array([t]).buffer),i=e.length-1;i>=0;i--)this.writeByte(e[i])},t.prototype.writeString=function(t){for(var e=0;e>8),this.writeU8(t);break;case 3:this.writeU8(32|t>>16),this.writeU8(t>>8),this.writeU8(t);break;case 4:this.writeU8(16|t>>24),this.writeU8(t>>16),this.writeU8(t>>8),this.writeU8(t);break;case 5:this.writeU8(8|t/4294967296&7),this.writeU8(t>>24),this.writeU8(t>>16),this.writeU8(t>>8),this.writeU8(t);break;default:throw new RuntimeException("Bad EBML VINT size "+e)}},t.prototype.measureEBMLVarInt=function(t){if(t<127)return 1;if(t<16383)return 2;if(t<2097151)return 3;if(t<268435455)return 4;if(t<34359738367)return 5;throw new RuntimeException("EBML VINT size not supported "+t)},t.prototype.writeEBMLVarInt=function(t){this.writeEBMLVarIntWidth(t,this.measureEBMLVarInt(t))},t.prototype.writeUnsignedIntBE=function(t,e){switch(void 0===e&&(e=this.measureUnsignedInt(t)),e){case 5:this.writeU8(Math.floor(t/4294967296));case 4:this.writeU8(t>>24);case 3:this.writeU8(t>>16);case 2:this.writeU8(t>>8);case 1:this.writeU8(t);break;default:throw new RuntimeException("Bad UINT size "+e)}},t.prototype.measureUnsignedInt=function(t){return t<256?1:t<65536?2:t<1<<24?3:t<4294967296?4:5},t.prototype.getAsDataArray=function(){if(this.posthis.length)throw"Seeking beyond the end of file is not allowed";this.pos=t},this.write=function(e){var i={offset:this.pos,data:e,length:r(e)},f=i.offset>=this.length;this.pos+=i.length,this.length=Math.max(this.length,this.pos),a=a.then(function(){if(h)return new Promise(function(e,r){n(i.data).then(function(n){var r=0,o=Buffer.from(n.buffer),a=function(n,o,s){r+=o,r>=s.length?e():t.write(h,s,r,s.length-r,i.offset+r,a)};t.write(h,o,0,o.length,i.offset,a)})});if(s)return new Promise(function(t,e){s.onwriteend=t,s.seek(i.offset),s.write(new Blob([i.data]))});if(!f)for(var e=0;e=r.offset+r.length)){if(i.offsetr.offset+r.length)throw new Error("Overwrite crosses blob boundaries");return i.offset==r.offset&&i.length==r.length?void(r.data=i.data):n(r.data).then(function(t){return r.data=t,n(i.data)}).then(function(t){i.data=t,r.data.set(i.data,i.offset-r.offset)})}}o.push(i)})},this.complete=function(t){return a=h||s?a.then(function(){return null}):a.then(function(){for(var e=[],i=0;i0&&e.trackNumber<127))throw"TrackNumber must be > 0 and < 127";return i.writeEBMLVarInt(e.trackNumber),i.writeU16BE(e.timecode),i.writeByte(128),{id:163,data:[i.getAsDataArray(),e.frame]}}function l(t){return{id:524531317,data:[{id:231,data:Math.round(t.timecode)}]}}function c(t,e,i){_.push({id:187,data:[{id:179,data:e},{id:183,data:[{id:247,data:t},{id:241,data:a(i)}]}]})}function p(){var e={id:475249515,data:_},i=new t(16+32*_.length);h(i,S.pos,e),S.write(i.getAsDataArray()),D.Cues.positionEBML.data=a(e.offset)}function m(){if(0!=T.length){for(var e=0,i=0;i=E&&m()}function y(){var e=new t(x.size),i=S.pos;h(e,x.dataOffset,x.data),S.seek(x.dataOffset),S.write(e.getAsDataArray()),S.seek(i)}function v(){var e=new t(8),i=S.pos;e.writeDoubleBE(U),S.seek(M.dataOffset),S.write(e.getAsDataArray()),S.seek(i)}var b,k,B,x,E=5e3,A=1,L=!1,T=[],U=0,F=0,I={quality:.95,fileWriter:null,fd:null,frameDuration:null,frameRate:null},D={Cues:{id:new Uint8Array([28,83,187,107]),positionEBML:null},SegmentInfo:{id:new Uint8Array([21,73,169,102]),positionEBML:null},Tracks:{id:new Uint8Array([22,84,174,107]),positionEBML:null}},M={id:17545,data:new s(0)},_=[],S=new e(n.fileWriter||n.fd);this.addFrame=function(t){if(L){if(t.width!=b||t.height!=k)throw"Frame size differs from previous frames"}else b=t.width,k=t.height,u(),L=!0;var e=r(t,{quality:n.quality});if(!e)throw"Couldn't decode WebP frame, does the browser support WebP?";g({frame:o(e),duration:n.frameDuration})},this.complete=function(){return m(),p(),y(),v(),S.complete("video/webm")},this.getWrittenSize=function(){return S.length},n=i(I,n||{}),w()}};"undefined"!=typeof module&&"undefined"!=typeof module.exports?module.exports=t(require("./ArrayBufferDataStream"),require("./BlobBuffer")):window.WebMWriter=t(ArrayBufferDataStream,BlobBuffer)}(),function(){function t(t){var e,i=new Uint8Array(t);for(e=0;e>18&63]+o[t>>12&63]+o[t>>6&63]+o[63&t]}var i,n,r,a=t.length%3,s="";for(i=0,r=t.length-a;in&&(e.push({blocks:o,length:i}),o=[],i=0),o.push(t),i+=t.headerLength+t.inputLength}),e.push({blocks:o,length:i}),e.forEach(function(e){var i=new Uint8Array(e.length),n=0;e.blocks.forEach(function(t){i.set(t.header,n),n+=t.headerLength,i.set(t.input,n),n+=t.inputLength}),t.push(i)}),t.push(new Uint8Array(2*r)),new Blob(t,{type:"octet/stream"})},t.prototype.clear=function(){this.written=0,this.out=n.clean(e)},window.Tar=t}(),function(t){function e(t,i){if({}.hasOwnProperty.call(e.cache,t))return e.cache[t];var n=e.resolve(t);if(!n)throw new Error("Failed to resolve module "+t);var r={id:t,require:e,filename:t,exports:{},loaded:!1,parent:i,children:[]};i&&i.children.push(r);var o=t.slice(0,t.lastIndexOf("/")+1);return e.cache[t]=r.exports,n.call(r.exports,r,r.exports,o,t),r.loaded=!0,e.cache[t]=r.exports}e.modules={},e.cache={},e.resolve=function(t){return{}.hasOwnProperty.call(e.modules,t)?e.modules[t]:void 0},e.define=function(t,i){e.modules[t]=i};var i=function(e){return e="/",{title:"browser",version:"v0.10.26",browser:!0,env:{},argv:[],nextTick:t.setImmediate||function(t){setTimeout(t,0)},cwd:function(){return e},chdir:function(t){e=t}}}();e.define("/gif.coffee",function(t,i,n,r){function o(t,e){return{}.hasOwnProperty.call(t,e)}function a(t,e){for(var i=0,n=e.length;ithis.frames.length;0<=this.frames.length?++e:--e)t.push(e);return t}.apply(this,arguments),n=0,r=i.length;ne;0<=e?++i:--i)t.push(i);return t}.apply(this,arguments),n=0,r=i.length;nt;this.freeWorkers.length<=t?++i:--i)e.push(i);return e}.apply(this,arguments).forEach(function(t){return function(e){var i;return console.log("spawning worker "+e),i=new Worker(t.options.workerScript),i.onmessage=function(t){return function(e){return t.activeWorkers.splice(t.activeWorkers.indexOf(i),1),t.freeWorkers.push(i),t.frameFinished(e.data)}}(t),t.freeWorkers.push(i)}}(this)),t},e.prototype.frameFinished=function(t){return console.log("frame "+t.index+" finished - "+this.activeWorkers.length+" active"),this.finishedFrames++,this.emit("progress",this.finishedFrames/this.frames.length),this.imageParts[t.index]=t,a(null,this.imageParts)?this.renderNextFrame():this.finishRendering()},e.prototype.finishRendering=function(){var t,e,i,n,r,o,a;r=0;for(var s=0,h=this.imageParts.length;s=this.frames.length?void 0:(t=this.frames[this.nextFrame++],i=this.freeWorkers.shift(),e=this.getTask(t),console.log("starting frame "+(e.index+1)+" of "+this.frames.length),this.activeWorkers.push(i),i.postMessage(e))},e.prototype.getContextData=function(t){return t.getImageData(0,0,this.options.width,this.options.height).data},e.prototype.getImageData=function(t){var e;return null!=this._canvas||(this._canvas=document.createElement("canvas"),this._canvas.width=this.options.width,this._canvas.height=this.options.height),e=this._canvas.getContext("2d"),e.setFill=this.options.background,e.fillRect(0,0,this.options.width,this.options.height),e.drawImage(t,0,0),this.getContextData(e)},e.prototype.getTask=function(t){var e,i;if(e=this.frames.indexOf(t),i={index:e,last:e===this.frames.length-1,delay:t.delay,transparent:t.transparent,width:this.options.width,height:this.options.height,quality:this.options.quality,repeat:this.options.repeat,canTransfer:"chrome"===h.name},null!=t.data)i.data=t.data;else if(null!=t.context)i.data=this.getContextData(t.context);else{if(null==t.image)throw new Error("Invalid frame");i.data=this.getImageData(t.image)}return i},e}(u),t.exports=l}),e.define("/browser.coffee",function(t,e,i,n){var r,o,a,s,h;s=navigator.userAgent.toLowerCase(),a=navigator.platform.toLowerCase(),h=s.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0],o="ie"===h[1]&&document.documentMode,r={name:"version"===h[1]?h[3]:h[1],version:o||parseFloat("opera"===h[1]&&h[4]?h[4]:h[2]),platform:{name:s.match(/ip(?:ad|od|hone)/)?"ios":(s.match(/(?:webos|android)/)||a.match(/mac|win|linux/)||["other"])[0]}},r[r.name]=!0,r[r.name+parseInt(r.version,10)]=!0,r.platform[r.platform.name]=!0,t.exports=r}),e.define("events",function(t,e,n,r){i.EventEmitter||(i.EventEmitter=function(){});var o=e.EventEmitter=i.EventEmitter,a="function"==typeof Array.isArray?Array.isArray:function(t){return"[object Array]"===Object.prototype.toString.call(t)},s=10;o.prototype.setMaxListeners=function(t){this._events||(this._events={}),this._events.maxListeners=t},o.prototype.emit=function(t){if("error"===t&&(!this._events||!this._events.error||a(this._events.error)&&!this._events.error.length))throw arguments[1]instanceof Error?arguments[1]:new Error("Uncaught, unspecified 'error' event.");if(!this._events)return!1;var e=this._events[t];if(!e)return!1;if("function"!=typeof e){if(a(e)){for(var i=Array.prototype.slice.call(arguments,1),n=e.slice(),r=0,o=n.length;r0&&this._events[t].length>i&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),console.trace())}this._events[t].push(e)}else this._events[t]=[this._events[t],e];else this._events[t]=e;return this},o.prototype.on=o.prototype.addListener,o.prototype.once=function(t,e){var i=this;return i.on(t,function n(){i.removeListener(t,n),e.apply(this,arguments)}),this},o.prototype.removeListener=function(t,e){if("function"!=typeof e)throw new Error("removeListener only takes instances of Function");if(!this._events||!this._events[t])return this;var i=this._events[t];if(a(i)){var n=i.indexOf(e);if(n<0)return this;i.splice(n,1),0==i.length&&delete this._events[t]}else this._events[t]===e&&delete this._events[t];return this},o.prototype.removeAllListeners=function(t){return t&&this._events&&this._events[t]&&(this._events[t]=null),this},o.prototype.listeners=function(t){return this._events||(this._events={}),this._events[t]||(this._events[t]=[]),a(this._events[t])||(this._events[t]=[this._events[t]]),this._events[t]}}),t.GIF=e("/gif.coffee")}.call(this,this),function(){function t(t){return t&&t.Object===Object?t:null}function e(t){return String("0000000"+t).slice(-7)}function i(){function t(){return Math.floor(65536*(1+Math.random())).toString(16).substring(1)}return t()+t()+"-"+t()+"-"+t()+"-"+t()+"-"+t()+t()+t()}function n(t){var e={};this.settings=t,this.on=function(t,i){e[t]=i},this.emit=function(t){var i=e[t];i&&i.apply(null,Array.prototype.slice.call(arguments,1))},this.filename=t.name||i(),this.extension="",this.mimeType=""}function r(t){n.call(this,t),this.extension=".tar",this.mimeType="application/x-tar",this.fileExtension="",this.baseFilename=this.filename,this.tape=null,this.count=0,this.part=1,this.frames=0}function o(t){r.call(this,t),this.type="image/png",this.fileExtension=".png"}function a(t){r.call(this,t),this.type="image/jpeg",this.fileExtension=".jpg",this.quality=t.quality/100||.8}function s(t){var e=document.createElement("canvas");"image/webp"!==e.toDataURL("image/webp").substr(5,10)&&console.log("WebP not supported - try another export format"),n.call(this,t),this.quality=t.quality/100||.8,this.extension=".webm",this.mimeType="video/webm",this.baseFilename=this.filename,this.framerate=t.framerate,this.frames=0,this.part=1,this.videoWriter=new WebMWriter({quality:this.quality,fileWriter:null,fd:null,frameRate:this.framerate})}function h(t){n.call(this,t),t.quality=t.quality/100||.8,this.encoder=new FFMpegServer.Video(t),this.encoder.on("process",function(){this.emit("process")}.bind(this)),this.encoder.on("finished",function(t,e){var i=this.callback;i&&(this.callback=void 0,i(t,e))}.bind(this)),this.encoder.on("progress",function(t){this.settings.onProgress&&this.settings.onProgress(t)}.bind(this)),this.encoder.on("error",function(t){alert(JSON.stringify(t,null,2))}.bind(this))}function f(t){n.call(this,t),this.framerate=this.settings.framerate,this.type="video/webm",this.extension=".webm",this.stream=null,this.mediaRecorder=null,this.chunks=[]}function u(t){n.call(this,t),t.quality=31-(30*t.quality/100||10),t.workers=t.workers||4,this.extension=".gif",this.mimeType="image/gif",this.canvas=document.createElement("canvas"),this.ctx=this.canvas.getContext("2d"),this.sizeSet=!1,this.encoder=new GIF({workers:t.workers,quality:t.quality,workerScript:t.workersPath+"gif.worker.js"}),this.encoder.on("progress",function(t){this.settings.onProgress&&this.settings.onProgress(t)}.bind(this)),this.encoder.on("finished",function(t){var e=this.callback;e&&(this.callback=void 0,e(t))}.bind(this))}function d(t){function e(){function t(){return this._hooked||(this._hooked=!0,this._hookedTime=this.currentTime||0,this.pause(),it.push(this)),this._hookedTime+M.startTime}b("Capturer start"),U=window.Date.now(),T=U+M.startTime,I=window.performance.now(),F=I+M.startTime,window.Date.prototype.getTime=function(){return T},window.Date.now=function(){return T},window.setTimeout=function(t,e){var i={callback:t,time:e,triggerTime:T+e};return _.push(i),b("Timeout set to "+i.time),i},window.clearTimeout=function(t){for(var e=0;e<_.length;e++)_[e]!=t||(_.splice(e,1),b("Timeout cleared"))},window.setInterval=function(t,e){var i={callback:t,time:e,triggerTime:T+e};return S.push(i),b("Interval set to "+i.time),i},window.clearInterval=function(t){return b("clear Interval"),null},window.requestAnimationFrame=function(t){W.push(t)},window.performance.now=function(){return F};try{Object.defineProperty(HTMLVideoElement.prototype,"currentTime",{get:t}),Object.defineProperty(HTMLAudioElement.prototype,"currentTime",{get:t})}catch(t){b(t)}}function i(){e(),D.start(),R=!0}function n(){R=!1,D.stop(),l()}function r(t,e){Z(t,0,e)}function d(){r(y)}function l(){b("Capturer stop"),window.setTimeout=Z,window.setInterval=J,window.clearInterval=Y,window.clearTimeout=$,window.requestAnimationFrame=Q,window.Date.prototype.getTime=et,window.Date.now=X,window.performance.now=tt}function c(){var t=C/M.framerate;(M.frameLimit&&C>=M.frameLimit||M.timeLimit&&t>=M.timeLimit)&&(n(),v());var e=new Date(null);e.setSeconds(t),M.motionBlurFrames>2?j.textContent="CCapture "+M.format+" | "+C+" frames ("+O+" inter) | "+e.toISOString().substr(11,8):j.textContent="CCapture "+M.format+" | "+C+" frames | "+e.toISOString().substr(11,8)}function p(t){N.width===t.width&&N.height===t.height||(N.width=t.width,N.height=t.height,z=new Uint16Array(N.height*N.width*4),V.fillStyle="#0",V.fillRect(0,0,N.width,N.height))}function m(t){V.drawImage(t,0,0),q=V.getImageData(0,0,N.width,N.height);for(var e=0;e2?(p(t),m(t),O>=.5*M.motionBlurFrames?w():d()):(D.add(t),C++,b("Full Frame! "+C)))}function y(){var t=1e3/M.framerate,e=(C+O/M.motionBlurFrames)*t;T=U+e,F=I+e,it.forEach(function(t){t._hookedTime=e/1e3}),c(),b("Frame: "+C+" "+O);for(var i=0;i<_.length;i++)T>=_[i].triggerTime&&(r(_[i].callback),_.splice(i,1));for(var i=0;i=S[i].triggerTime&&(r(S[i].callback),S[i].triggerTime+=S[i].time);W.forEach(function(t){r(t,T-k)}),W=[]}function v(t){t||(t=function(t){return download(t,D.filename+D.extension,D.mimeType),!1}),D.save(t)}function b(t){A&&console.log(t)}function B(t,e){P[t]=e}function x(t){var e=P[t];e&&e.apply(null,Array.prototype.slice.call(arguments,1))}function E(t){x("progress",t)}var A,L,T,U,F,I,d,D,M=t||{},_=(new Date,[]),S=[],C=0,O=0,W=[],R=!1,P={};M.framerate=M.framerate||60,M.motionBlurFrames=2*(M.motionBlurFrames||1),A=M.verbose||!1,L=M.display||!1,M.step=1e3/M.framerate,M.timeLimit=M.timeLimit||0,M.frameLimit=M.frameLimit||0,M.startTime=M.startTime||0;var j=document.createElement("div");j.style.position="absolute",j.style.left=j.style.top=0,j.style.backgroundColor="black",j.style.fontFamily="monospace",j.style.fontSize="11px",j.style.padding="5px",j.style.color="red",j.style.zIndex=1e5,M.display&&document.body.appendChild(j);var z,q,N=document.createElement("canvas"),V=N.getContext("2d");b("Step is set to "+M.step+"ms");var G={gif:u,webm:s,ffmpegserver:h,png:o,jpg:a,"webm-mediarecorder":f},H=G[M.format];if(!H)throw"Error: Incorrect or missing format: Valid formats are "+Object.keys(G).join(", ");if(D=new H(M),D.step=d,D.on("process",y),D.on("progress",E),"performance"in window==0&&(window.performance={}),Date.now=Date.now||function(){return(new Date).getTime()},"now"in window.performance==0){var K=Date.now();performance.timing&&performance.timing.navigationStart&&(K=performance.timing.navigationStart),window.performance.now=function(){return Date.now()-K}}var Z=window.setTimeout,J=window.setInterval,Y=window.clearInterval,$=window.clearTimeout,Q=window.requestAnimationFrame,X=window.Date.now,tt=window.performance.now,et=window.Date.prototype.getTime,it=[];return{start:i,capture:g,stop:n,save:v,on:B}}var l={function:!0,object:!0},c=(parseFloat,parseInt,l[typeof exports]&&exports&&!exports.nodeType?exports:void 0),p=l[typeof module]&&module&&!module.nodeType?module:void 0,m=p&&p.exports===c?c:void 0,w=t(c&&p&&"object"==typeof global&&global),g=t(l[typeof self]&&self),y=t(l[typeof window]&&window),v=t(l[typeof this]&&this),b=w||y!==(v&&v.window)&&y||g||v||Function("return this")();"gc"in window||(window.gc=function(){}),HTMLCanvasElement.prototype.toBlob||Object.defineProperty(HTMLCanvasElement.prototype,"toBlob",{value:function(t,e,i){for(var n=atob(this.toDataURL(e,i).split(",")[1]),r=n.length,o=new Uint8Array(r),a=0;a0&&this.frames/this.settings.framerate>=this.settings.autoSaveTime?this.save(function(t){this.filename=this.baseFilename+"-part-"+e(this.part),download(t,this.filename+this.extension,this.mimeType);var i=this.count;this.dispose(),this.count=i+1,this.part++,this.filename=this.baseFilename+"-part-"+e(this.part),this.frames=0,this.step()}.bind(this)):(this.count++,this.frames++,this.step())}.bind(this),i.readAsArrayBuffer(t)},r.prototype.save=function(t){t(this.tape.save())},r.prototype.dispose=function(){this.tape=new Tar,this.count=0},o.prototype=Object.create(r.prototype),o.prototype.add=function(t){t.toBlob(function(t){r.prototype.add.call(this,t)}.bind(this),this.type)},a.prototype=Object.create(r.prototype),a.prototype.add=function(t){t.toBlob(function(t){r.prototype.add.call(this,t)}.bind(this),this.type,this.quality)},s.prototype=Object.create(n.prototype),s.prototype.start=function(t){this.dispose()},s.prototype.add=function(t){this.videoWriter.addFrame(t),this.settings.autoSaveTime>0&&this.frames/this.settings.framerate>=this.settings.autoSaveTime?this.save(function(t){this.filename=this.baseFilename+"-part-"+e(this.part),download(t,this.filename+this.extension,this.mimeType),this.dispose(),this.part++,this.filename=this.baseFilename+"-part-"+e(this.part),this.step()}.bind(this)):(this.frames++,this.step())},s.prototype.save=function(t){this.videoWriter.complete().then(t)},s.prototype.dispose=function(t){this.frames=0,this.videoWriter=new WebMWriter({quality:this.quality,fileWriter:null,fd:null,frameRate:this.framerate})},h.prototype=Object.create(n.prototype),h.prototype.start=function(){this.encoder.start(this.settings)},h.prototype.add=function(t){this.encoder.add(t)},h.prototype.save=function(t){this.callback=t,this.encoder.end()},h.prototype.safeToProceed=function(){return this.encoder.safeToProceed()},f.prototype=Object.create(n.prototype),f.prototype.add=function(t){this.stream||(this.stream=t.captureStream(this.framerate),this.mediaRecorder=new MediaRecorder(this.stream),this.mediaRecorder.start(),this.mediaRecorder.ondataavailable=function(t){this.chunks.push(t.data)}.bind(this)),this.step()},f.prototype.save=function(t){this.mediaRecorder.onstop=function(e){var i=new Blob(this.chunks,{type:"video/webm"});this.chunks=[],t(i)}.bind(this),this.mediaRecorder.stop()},u.prototype=Object.create(n.prototype),u.prototype.add=function(t){this.sizeSet||(this.encoder.setOption("width",t.width),this.encoder.setOption("height",t.height),this.sizeSet=!0),this.canvas.width=t.width,this.canvas.height=t.height,this.ctx.drawImage(t,0,0),this.encoder.addFrame(this.ctx,{copy:!0,delay:this.settings.step}),this.step()},u.prototype.save=function(t){this.callback=t,this.encoder.render()},(y||g||{}).CCapture=d,"function"==typeof define&&"object"==typeof define.amd&&define.amd?define(function(){return d}):c&&p?(m&&((p.exports=d).CCapture=d),c.CCapture=d):b.CCapture=d}(); \ No newline at end of file diff --git a/WebServer/externalScripts/gif.worker.js b/WebServer/externalScripts/gif.worker.js new file mode 100644 index 000000000..269624e61 --- /dev/null +++ b/WebServer/externalScripts/gif.worker.js @@ -0,0 +1,3 @@ +// gif.worker.js 0.2.0 - https://github.com/jnordberg/gif.js +(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o=ByteArray.pageSize)this.newPage();this.pages[this.page][this.cursor++]=val};ByteArray.prototype.writeUTFBytes=function(string){for(var l=string.length,i=0;i=0)this.dispose=disposalCode};GIFEncoder.prototype.setRepeat=function(repeat){this.repeat=repeat};GIFEncoder.prototype.setTransparent=function(color){this.transparent=color};GIFEncoder.prototype.addFrame=function(imageData){this.image=imageData;this.colorTab=this.globalPalette&&this.globalPalette.slice?this.globalPalette:null;this.getImagePixels();this.analyzePixels();if(this.globalPalette===true)this.globalPalette=this.colorTab;if(this.firstFrame){this.writeLSD();this.writePalette();if(this.repeat>=0){this.writeNetscapeExt()}}this.writeGraphicCtrlExt();this.writeImageDesc();if(!this.firstFrame&&!this.globalPalette)this.writePalette();this.writePixels();this.firstFrame=false};GIFEncoder.prototype.finish=function(){this.out.writeByte(59)};GIFEncoder.prototype.setQuality=function(quality){if(quality<1)quality=1;this.sample=quality};GIFEncoder.prototype.setDither=function(dither){if(dither===true)dither="FloydSteinberg";this.dither=dither};GIFEncoder.prototype.setGlobalPalette=function(palette){this.globalPalette=palette};GIFEncoder.prototype.getGlobalPalette=function(){return this.globalPalette&&this.globalPalette.slice&&this.globalPalette.slice(0)||this.globalPalette};GIFEncoder.prototype.writeHeader=function(){this.out.writeUTFBytes("GIF89a")};GIFEncoder.prototype.analyzePixels=function(){if(!this.colorTab){this.neuQuant=new NeuQuant(this.pixels,this.sample);this.neuQuant.buildColormap();this.colorTab=this.neuQuant.getColormap()}if(this.dither){this.ditherPixels(this.dither.replace("-serpentine",""),this.dither.match(/-serpentine/)!==null)}else{this.indexPixels()}this.pixels=null;this.colorDepth=8;this.palSize=7;if(this.transparent!==null){this.transIndex=this.findClosest(this.transparent,true)}};GIFEncoder.prototype.indexPixels=function(imgq){var nPix=this.pixels.length/3;this.indexedPixels=new Uint8Array(nPix);var k=0;for(var j=0;j=0&&x1+x=0&&y1+y>16,(c&65280)>>8,c&255,used)};GIFEncoder.prototype.findClosestRGB=function(r,g,b,used){if(this.colorTab===null)return-1;if(this.neuQuant&&!used){return this.neuQuant.lookupRGB(r,g,b)}var c=b|g<<8|r<<16;var minpos=0;var dmin=256*256*256;var len=this.colorTab.length;for(var i=0,index=0;i=0){disp=dispose&7}disp<<=2;this.out.writeByte(0|disp|0|transp);this.writeShort(this.delay);this.out.writeByte(this.transIndex);this.out.writeByte(0)};GIFEncoder.prototype.writeImageDesc=function(){this.out.writeByte(44);this.writeShort(0);this.writeShort(0);this.writeShort(this.width);this.writeShort(this.height);if(this.firstFrame||this.globalPalette){this.out.writeByte(0)}else{this.out.writeByte(128|0|0|0|this.palSize)}};GIFEncoder.prototype.writeLSD=function(){this.writeShort(this.width);this.writeShort(this.height);this.out.writeByte(128|112|0|this.palSize);this.out.writeByte(0);this.out.writeByte(0)};GIFEncoder.prototype.writeNetscapeExt=function(){this.out.writeByte(33);this.out.writeByte(255);this.out.writeByte(11);this.out.writeUTFBytes("NETSCAPE2.0");this.out.writeByte(3);this.out.writeByte(1);this.writeShort(this.repeat);this.out.writeByte(0)};GIFEncoder.prototype.writePalette=function(){this.out.writeBytes(this.colorTab);var n=3*256-this.colorTab.length;for(var i=0;i>8&255)};GIFEncoder.prototype.writePixels=function(){var enc=new LZWEncoder(this.width,this.height,this.indexedPixels,this.colorDepth);enc.encode(this.out)};GIFEncoder.prototype.stream=function(){return this.out};module.exports=GIFEncoder},{"./LZWEncoder.js":2,"./TypedNeuQuant.js":3}],2:[function(require,module,exports){var EOF=-1;var BITS=12;var HSIZE=5003;var masks=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535];function LZWEncoder(width,height,pixels,colorDepth){var initCodeSize=Math.max(2,colorDepth);var accum=new Uint8Array(256);var htab=new Int32Array(HSIZE);var codetab=new Int32Array(HSIZE);var cur_accum,cur_bits=0;var a_count;var free_ent=0;var maxcode;var clear_flg=false;var g_init_bits,ClearCode,EOFCode;function char_out(c,outs){accum[a_count++]=c;if(a_count>=254)flush_char(outs)}function cl_block(outs){cl_hash(HSIZE);free_ent=ClearCode+2;clear_flg=true;output(ClearCode,outs)}function cl_hash(hsize){for(var i=0;i=0){disp=hsize_reg-i;if(i===0)disp=1;do{if((i-=disp)<0)i+=hsize_reg;if(htab[i]===fcode){ent=codetab[i];continue outer_loop}}while(htab[i]>=0)}output(ent,outs);ent=c;if(free_ent<1<0){outs.writeByte(a_count);outs.writeBytes(accum,0,a_count);a_count=0}}function MAXCODE(n_bits){return(1<0)cur_accum|=code<=8){char_out(cur_accum&255,outs);cur_accum>>=8;cur_bits-=8}if(free_ent>maxcode||clear_flg){if(clear_flg){maxcode=MAXCODE(n_bits=g_init_bits);clear_flg=false}else{++n_bits;if(n_bits==BITS)maxcode=1<0){char_out(cur_accum&255,outs);cur_accum>>=8;cur_bits-=8}flush_char(outs)}}this.encode=encode}module.exports=LZWEncoder},{}],3:[function(require,module,exports){var ncycles=100;var netsize=256;var maxnetpos=netsize-1;var netbiasshift=4;var intbiasshift=16;var intbias=1<>betashift;var betagamma=intbias<>3;var radiusbiasshift=6;var radiusbias=1<>3);var i,v;for(i=0;i>=netbiasshift;network[i][1]>>=netbiasshift;network[i][2]>>=netbiasshift;network[i][3]=i}}function altersingle(alpha,i,b,g,r){network[i][0]-=alpha*(network[i][0]-b)/initalpha;network[i][1]-=alpha*(network[i][1]-g)/initalpha;network[i][2]-=alpha*(network[i][2]-r)/initalpha}function alterneigh(radius,i,b,g,r){var lo=Math.abs(i-radius);var hi=Math.min(i+radius,netsize);var j=i+1;var k=i-1;var m=1;var p,a;while(jlo){a=radpower[m++];if(jlo){p=network[k--];p[0]-=a*(p[0]-b)/alpharadbias;p[1]-=a*(p[1]-g)/alpharadbias;p[2]-=a*(p[2]-r)/alpharadbias}}}function contest(b,g,r){var bestd=~(1<<31);var bestbiasd=bestd;var bestpos=-1;var bestbiaspos=bestpos;var i,n,dist,biasdist,betafreq;for(i=0;i>intbiasshift-netbiasshift);if(biasdist>betashift;freq[i]-=betafreq;bias[i]+=betafreq<>1;for(j=previouscol+1;j>1;for(j=previouscol+1;j<256;j++)netindex[j]=maxnetpos}function inxsearch(b,g,r){var a,p,dist;var bestd=1e3;var best=-1;var i=netindex[g];var j=i-1;while(i=0){if(i=bestd)i=netsize;else{i++;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist=0){p=network[j];dist=g-p[1];if(dist>=bestd)j=-1;else{j--;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist>radiusbiasshift;if(rad<=1)rad=0;for(i=0;i=lengthcount)pix-=lengthcount;i++;if(delta===0)delta=1;if(i%delta===0){alpha-=alpha/alphadec;radius-=radius/radiusdec;rad=radius>>radiusbiasshift;if(rad<=1)rad=0;for(j=0;j + + + + + Superalgos + + + + + + + + + + + + + + + + + + +
+
+
+
 
+ + + diff --git a/WebServer/require.js b/WebServer/require.js new file mode 100644 index 000000000..f9476f532 --- /dev/null +++ b/WebServer/require.js @@ -0,0 +1,2145 @@ +/** vim: et:ts=4:sw=4:sts=4 + * @license RequireJS 2.3.5 Copyright jQuery Foundation and other contributors. + * Released under MIT license, https://github.com/REQUIREJS/REQUIREJS/blob/master/LICENSE + */ +//Not using strict: uneven strict support in browsers, #392, and causes +//problems with REQUIREJS.exec()/transpiler plugins that may not be strict. +/*jslint regexp: true, nomen: true, sloppy: true */ +/*global window, navigator, document, importScripts, setTimeout, opera */ + +var REQUIREJS, REQUIRE, DEFINE; +(function (global, setTimeout) { + var req, s, head, baseElement, dataMain, src, + interactiveScript, currentlyAddingScript, mainScript, subPath, + version = '2.3.5', + commentRegExp = /\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/mg, + cjsRequireRegExp = /[^.]\s*REQUIRE\s*\(\s*["']([^'"\s]+)["']\s*\)/g, + jsSuffixRegExp = /\.js$/, + currDirRegExp = /^\.\//, + op = Object.prototype, + ostring = op.toString, + hasOwn = op.hasOwnProperty, + isBrowser = !!(typeof window !== 'undefined' && typeof navigator !== 'undefined' && window.document), + isWebWorker = !isBrowser && typeof importScripts !== 'undefined', + //PS3 indicates loaded and complete, but need to wait for complete + //specifically. Sequence is 'loading', 'loaded', execution, + // then 'complete'. The UA check is unfortunate, but not sure how + //to feature test w/o causing perf issues. + readyRegExp = isBrowser && navigator.platform === 'PLAYSTATION 3' ? + /^complete$/ : /^(complete|loaded)$/, + defContextName = '_', + //Oh the tragedy, detecting opera. See the usage of isOpera for reason. + isOpera = typeof opera !== 'undefined' && opera.toString() === '[object Opera]', + contexts = {}, + cfg = {}, + globalDefQueue = [], + useInteractive = false; + + //Could match something like ')//comment', do not lose the prefix to comment. + function commentReplace(match, singlePrefix) { + return singlePrefix || ''; + } + + function isFunction(it) { + return ostring.call(it) === '[object Function]'; + } + + function isArray(it) { + return ostring.call(it) === '[object Array]'; + } + + /** + * Helper function for iterating over an array. If the func returns + * a true value, it will break out of the loop. + */ + function each(ary, func) { + if (ary) { + var i; + for (i = 0; i < ary.length; i += 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + /** + * Helper function for iterating over an array backwards. If the func + * returns a true value, it will break out of the loop. + */ + function eachReverse(ary, func) { + if (ary) { + var i; + for (i = ary.length - 1; i > -1; i -= 1) { + if (ary[i] && func(ary[i], i, ary)) { + break; + } + } + } + } + + function hasProp(obj, prop) { + return hasOwn.call(obj, prop); + } + + function getOwn(obj, prop) { + return hasProp(obj, prop) && obj[prop]; + } + + /** + * Cycles over properties in an object and calls a function for each + * property value. If the function returns a truthy value, then the + * iteration is stopped. + */ + function eachProp(obj, func) { + var prop; + for (prop in obj) { + if (hasProp(obj, prop)) { + if (func(obj[prop], prop)) { + break; + } + } + } + } + + /** + * Simple function to mix in properties from source into target, + * but only if target does not already have a property of the same name. + */ + function mixin(target, source, force, deepStringMixin) { + if (source) { + eachProp(source, function (value, prop) { + if (force || !hasProp(target, prop)) { + if (deepStringMixin && typeof value === 'object' && value && + !isArray(value) && !isFunction(value) && + !(value instanceof RegExp)) { + + if (!target[prop]) { + target[prop] = {}; + } + mixin(target[prop], value, force, deepStringMixin); + } else { + target[prop] = value; + } + } + }); + } + return target; + } + + //Similar to Function.prototype.bind, but the 'this' object is specified + //first, since it is easier to read/figure out what 'this' will be. + function bind(obj, fn) { + return function () { + return fn.apply(obj, arguments); + }; + } + + function scripts() { + return document.getElementsByTagName('script'); + } + + function defaultOnError(err) { + throw err; + } + + //Allow getting a global that is expressed in + //dot notation, like 'a.b.c'. + function getGlobal(value) { + if (!value) { + return value; + } + var g = global; + each(value.split('.'), function (part) { + g = g[part]; + }); + return g; + } + + /** + * Constructs an error with a pointer to an URL with more information. + * @param {String} id the error ID that maps to an ID on a web page. + * @param {String} message human readable error. + * @param {Error} [err] the original error, if there is one. + * + * @returns {Error} + */ + function makeError(id, msg, err, requireModules) { + var e = new Error(msg + '\nhttp://REQUIREJS.org/docs/errors.html#' + id); + e.requireType = id; + e.requireModules = requireModules; + if (err) { + e.originalError = err; + } + return e; + } + + if (typeof DEFINE !== 'undefined') { + //If a DEFINE is already in play via another AMD loader, + //do not overwrite. + return; + } + + if (typeof REQUIREJS !== 'undefined') { + if (isFunction(REQUIREJS)) { + //Do not overwrite an existing REQUIREJS instance. + return; + } + cfg = REQUIREJS; + REQUIREJS = undefined; + } + + //Allow for a REQUIRE config object + if (typeof REQUIRE !== 'undefined' && !isFunction(REQUIRE)) { + //assume it is a config object. + cfg = REQUIRE; + REQUIRE = undefined; + } + + function newContext(contextName) { + var inCheckLoaded, Module, context, handlers, + checkLoadedTimeoutId, + config = { + //Defaults. Do not set a default for map + //config to speed up normalize(), which + //will run faster if there is no default. + waitSeconds: 60, + baseUrl: './', + paths: {}, + bundles: {}, + pkgs: {}, + shim: {}, + config: {} + }, + registry = {}, + //registry of just enabled modules, to speed + //cycle breaking code when lots of modules + //are registered, but not activated. + enabledRegistry = {}, + undefEvents = {}, + defQueue = [], + defined = {}, + urlFetched = {}, + bundlesMap = {}, + requireCounter = 1, + unnormalizedCounter = 1; + + /** + * Trims the . and .. from an array of path segments. + * It will keep a leading path segment if a .. will become + * the first path segment, to help with module name lookups, + * which act like paths, but can be remapped. But the end result, + * all paths that use this function should look normalized. + * NOTE: this method MODIFIES the input array. + * @param {Array} ary the array of path segments. + */ + function trimDots(ary) { + var i, part; + for (i = 0; i < ary.length; i++) { + part = ary[i]; + if (part === '.') { + ary.splice(i, 1); + i -= 1; + } else if (part === '..') { + // If at the start, or previous value is still .., + // keep them so that when converted to a path it may + // still work when converted to a path, even though + // as an ID it is less than ideal. In larger point + // releases, may be better to just kick out an error. + if (i === 0 || (i === 1 && ary[2] === '..') || ary[i - 1] === '..') { + continue; + } else if (i > 0) { + ary.splice(i - 1, 2); + i -= 2; + } + } + } + } + + /** + * Given a relative module name, like ./something, normalize it to + * a real name that can be mapped to a path. + * @param {String} name the relative name + * @param {String} baseName a real name that the name arg is relative + * to. + * @param {Boolean} applyMap apply the map config to the value. Should + * only be done if this normalization is for a dependency ID. + * @returns {String} normalized name + */ + function normalize(name, baseName, applyMap) { + var pkgMain, mapValue, nameParts, i, j, nameSegment, lastIndex, + foundMap, foundI, foundStarMap, starI, normalizedBaseParts, + baseParts = (baseName && baseName.split('/')), + map = config.map, + starMap = map && map['*']; + + //Adjust any relative paths. + if (name) { + name = name.split('/'); + lastIndex = name.length - 1; + + // If wanting node ID compatibility, strip .js from end + // of IDs. Have to do this here, and not in nameToUrl + // because node allows either .js or non .js to map + // to same file. + if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) { + name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, ''); + } + + // Starts with a '.' so need the baseName + if (name[0].charAt(0) === '.' && baseParts) { + //Convert baseName to array, and lop off the last part, + //so that . matches that 'directory' and not name of the baseName's + //module. For instance, baseName of 'one/two/three', maps to + //'one/two/three.js', but we want the directory, 'one/two' for + //this normalization. + normalizedBaseParts = baseParts.slice(0, baseParts.length - 1); + name = normalizedBaseParts.concat(name); + } + + trimDots(name); + name = name.join('/'); + } + + //Apply map config if available. + if (applyMap && map && (baseParts || starMap)) { + nameParts = name.split('/'); + + outerLoop: for (i = nameParts.length; i > 0; i -= 1) { + nameSegment = nameParts.slice(0, i).join('/'); + + if (baseParts) { + //Find the longest baseName segment match in the config. + //So, do joins on the biggest to smallest lengths of baseParts. + for (j = baseParts.length; j > 0; j -= 1) { + mapValue = getOwn(map, baseParts.slice(0, j).join('/')); + + //baseName segment has config, find if it has one for + //this name. + if (mapValue) { + mapValue = getOwn(mapValue, nameSegment); + if (mapValue) { + //Match, update name to the new value. + foundMap = mapValue; + foundI = i; + break outerLoop; + } + } + } + } + + //Check for a star map match, but just hold on to it, + //if there is a shorter segment match later in a matching + //config, then favor over this star map. + if (!foundStarMap && starMap && getOwn(starMap, nameSegment)) { + foundStarMap = getOwn(starMap, nameSegment); + starI = i; + } + } + + if (!foundMap && foundStarMap) { + foundMap = foundStarMap; + foundI = starI; + } + + if (foundMap) { + nameParts.splice(0, foundI, foundMap); + name = nameParts.join('/'); + } + } + + // If the name points to a package's name, use + // the package main instead. + pkgMain = getOwn(config.pkgs, name); + + return pkgMain ? pkgMain : name; + } + + function removeScript(name) { + if (isBrowser) { + each(scripts(), function (scriptNode) { + if (scriptNode.getAttribute('data-requiremodule') === name && + scriptNode.getAttribute('data-requirecontext') === context.contextName) { + scriptNode.parentNode.removeChild(scriptNode); + return true; + } + }); + } + } + + function hasPathFallback(id) { + var pathConfig = getOwn(config.paths, id); + if (pathConfig && isArray(pathConfig) && pathConfig.length > 1) { + //Pop off the first array value, since it failed, and + //retry + pathConfig.shift(); + context.REQUIRE.undef(id); + + //Custom REQUIRE that does not do map translation, since + //ID is "absolute", already mapped/resolved. + context.makeRequire(null, { + skipMap: true + })([id]); + + return true; + } + } + + //Turns a plugin!resource to [plugin, resource] + //with the plugin being undefined if the name + //did not have a plugin prefix. + function splitPrefix(name) { + var prefix, + index = name ? name.indexOf('!') : -1; + if (index > -1) { + prefix = name.substring(0, index); + name = name.substring(index + 1, name.length); + } + return [prefix, name]; + } + + /** + * Creates a module mapping that includes plugin prefix, module + * name, and path. If parentModuleMap is provided it will + * also normalize the name via REQUIRE.normalize() + * + * @param {String} name the module name + * @param {String} [parentModuleMap] parent module map + * for the module name, used to resolve relative names. + * @param {Boolean} isNormalized: is the ID already normalized. + * This is true if this call is done for a DEFINE() module ID. + * @param {Boolean} applyMap: apply the map config to the ID. + * Should only be true if this map is for a dependency. + * + * @returns {Object} + */ + function makeModuleMap(name, parentModuleMap, isNormalized, applyMap) { + var url, pluginModule, suffix, nameParts, + prefix = null, + parentName = parentModuleMap ? parentModuleMap.name : null, + originalName = name, + isDefine = true, + normalizedName = ''; + + //If no name, then it means it is a REQUIRE call, generate an + //internal name. + if (!name) { + isDefine = false; + name = '_@r' + (requireCounter += 1); + } + + nameParts = splitPrefix(name); + prefix = nameParts[0]; + name = nameParts[1]; + + if (prefix) { + prefix = normalize(prefix, parentName, applyMap); + pluginModule = getOwn(defined, prefix); + } + + //Account for relative paths if there is a base name. + if (name) { + if (prefix) { + if (isNormalized) { + normalizedName = name; + } else if (pluginModule && pluginModule.normalize) { + //Plugin is loaded, use its normalize method. + normalizedName = pluginModule.normalize(name, function (name) { + return normalize(name, parentName, applyMap); + }); + } else { + // If nested plugin references, then do not try to + // normalize, as it will not normalize correctly. This + // places a restriction on resourceIds, and the longer + // term solution is not to normalize until plugins are + // loaded and all normalizations to allow for async + // loading of a loader plugin. But for now, fixes the + // common uses. Details in #1131 + normalizedName = name.indexOf('!') === -1 ? + normalize(name, parentName, applyMap) : + name; + } + } else { + //A regular module. + normalizedName = normalize(name, parentName, applyMap); + + //Normalized name may be a plugin ID due to map config + //application in normalize. The map config values must + //already be normalized, so do not need to redo that part. + nameParts = splitPrefix(normalizedName); + prefix = nameParts[0]; + normalizedName = nameParts[1]; + isNormalized = true; + + url = context.nameToUrl(normalizedName); + } + } + + //If the id is a plugin id that cannot be determined if it needs + //normalization, stamp it with a unique ID so two matching relative + //ids that may conflict can be separate. + suffix = prefix && !pluginModule && !isNormalized ? + '_unnormalized' + (unnormalizedCounter += 1) : + ''; + + return { + prefix: prefix, + name: normalizedName, + parentMap: parentModuleMap, + unnormalized: !!suffix, + url: url, + originalName: originalName, + isDefine: isDefine, + id: (prefix ? + prefix + '!' + normalizedName : + normalizedName) + suffix + }; + } + + function getModule(depMap) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (!mod) { + mod = registry[id] = new context.Module(depMap); + } + + return mod; + } + + function on(depMap, name, fn) { + var id = depMap.id, + mod = getOwn(registry, id); + + if (hasProp(defined, id) && + (!mod || mod.defineEmitComplete)) { + if (name === 'defined') { + fn(defined[id]); + } + } else { + mod = getModule(depMap); + if (mod.error && name === 'error') { + fn(mod.error); + } else { + mod.on(name, fn); + } + } + } + + function onError(err, errback) { + var ids = err.requireModules, + notified = false; + + if (errback) { + errback(err); + } else { + each(ids, function (id) { + var mod = getOwn(registry, id); + if (mod) { + //Set error on module, so it skips timeout checks. + mod.error = err; + if (mod.events.error) { + notified = true; + mod.emit('error', err); + } + } + }); + + if (!notified) { + req.onError(err); + } + } + } + + /** + * Internal method to transfer globalQueue items to this context's + * defQueue. + */ + function takeGlobalQueue() { + //Push all the globalDefQueue items into the context's defQueue + if (globalDefQueue.length) { + each(globalDefQueue, function(queueItem) { + var id = queueItem[0]; + if (typeof id === 'string') { + context.defQueueMap[id] = true; + } + defQueue.push(queueItem); + }); + globalDefQueue = []; + } + } + + handlers = { + 'REQUIRE': function (mod) { + if (mod.REQUIRE) { + return mod.REQUIRE; + } else { + return (mod.REQUIRE = context.makeRequire(mod.map)); + } + }, + 'exports': function (mod) { + mod.usingExports = true; + if (mod.map.isDefine) { + if (mod.exports) { + return (defined[mod.map.id] = mod.exports); + } else { + return (mod.exports = defined[mod.map.id] = {}); + } + } + }, + 'module': function (mod) { + if (mod.module) { + return mod.module; + } else { + return (mod.module = { + id: mod.map.id, + uri: mod.map.url, + config: function () { + return getOwn(config.config, mod.map.id) || {}; + }, + exports: mod.exports || (mod.exports = {}) + }); + } + } + }; + + function cleanRegistry(id) { + //Clean up machinery used for waiting modules. + delete registry[id]; + delete enabledRegistry[id]; + } + + function breakCycle(mod, traced, processed) { + var id = mod.map.id; + + if (mod.error) { + mod.emit('error', mod.error); + } else { + traced[id] = true; + each(mod.depMaps, function (depMap, i) { + var depId = depMap.id, + dep = getOwn(registry, depId); + + //Only force things that have not completed + //being defined, so still in the registry, + //and only if it has not been matched up + //in the module already. + if (dep && !mod.depMatched[i] && !processed[depId]) { + if (getOwn(traced, depId)) { + mod.defineDep(i, defined[depId]); + mod.check(); //pass false? + } else { + breakCycle(dep, traced, processed); + } + } + }); + processed[id] = true; + } + } + + function checkLoaded() { + var err, usingPathFallback, + waitInterval = config.waitSeconds * 1000, + //It is possible to disable the wait interval by using waitSeconds of 0. + expired = waitInterval && (context.startTime + waitInterval) < new Date().getTime(), + noLoads = [], + reqCalls = [], + stillLoading = false, + needCycleCheck = true; + + //Do not bother if this call was a result of a cycle break. + if (inCheckLoaded) { + return; + } + + inCheckLoaded = true; + + //Figure out the state of all the modules. + eachProp(enabledRegistry, function (mod) { + var map = mod.map, + modId = map.id; + + //Skip things that are not enabled or in error state. + if (!mod.enabled) { + return; + } + + if (!map.isDefine) { + reqCalls.push(mod); + } + + if (!mod.error) { + //If the module should be executed, and it has not + //been inited and time is up, remember it. + if (!mod.inited && expired) { + if (hasPathFallback(modId)) { + usingPathFallback = true; + stillLoading = true; + } else { + noLoads.push(modId); + removeScript(modId); + } + } else if (!mod.inited && mod.fetched && map.isDefine) { + stillLoading = true; + if (!map.prefix) { + //No reason to keep looking for unfinished + //loading. If the only stillLoading is a + //plugin resource though, keep going, + //because it may be that a plugin resource + //is waiting on a non-plugin cycle. + return (needCycleCheck = false); + } + } + } + }); + + if (expired && noLoads.length) { + //If wait time expired, throw error of unloaded modules. + err = makeError('timeout', 'Load timeout for modules: ' + noLoads, null, noLoads); + err.contextName = context.contextName; + return onError(err); + } + + //Not expired, check for a cycle. + if (needCycleCheck) { + each(reqCalls, function (mod) { + breakCycle(mod, {}, {}); + }); + } + + //If still waiting on loads, and the waiting load is something + //other than a plugin resource, or there are still outstanding + //scripts, then just try back later. + if ((!expired || usingPathFallback) && stillLoading) { + //Something is still waiting to load. Wait for it, but only + //if a timeout is not already in effect. + if ((isBrowser || isWebWorker) && !checkLoadedTimeoutId) { + checkLoadedTimeoutId = setTimeout(function () { + checkLoadedTimeoutId = 0; + checkLoaded(); + }, 50); + } + } + + inCheckLoaded = false; + } + + Module = function (map) { + this.events = getOwn(undefEvents, map.id) || {}; + this.map = map; + this.shim = getOwn(config.shim, map.id); + this.depExports = []; + this.depMaps = []; + this.depMatched = []; + this.pluginMaps = {}; + this.depCount = 0; + + /* this.exports this.factory + this.depMaps = [], + this.enabled, this.fetched + */ + }; + + Module.prototype = { + init: function (depMaps, factory, errback, options) { + options = options || {}; + + //Do not do more inits if already done. Can happen if there + //are multiple DEFINE calls for the same module. That is not + //a normal, common case, but it is also not unexpected. + if (this.inited) { + return; + } + + this.factory = factory; + + if (errback) { + //Register for errors on this module. + this.on('error', errback); + } else if (this.events.error) { + //If no errback already, but there are error listeners + //on this module, set up an errback to pass to the deps. + errback = bind(this, function (err) { + this.emit('error', err); + }); + } + + //Do a copy of the dependency array, so that + //source inputs are not modified. For example + //"shim" deps are passed in here directly, and + //doing a direct modification of the depMaps array + //would affect that config. + this.depMaps = depMaps && depMaps.slice(0); + + this.errback = errback; + + //Indicate this module has be initialized + this.inited = true; + + this.ignore = options.ignore; + + //Could have option to init this module in enabled mode, + //or could have been previously marked as enabled. However, + //the dependencies are not known until init is called. So + //if enabled previously, now trigger dependencies as enabled. + if (options.enabled || this.enabled) { + //Enable this module and dependencies. + //Will call this.check() + this.enable(); + } else { + this.check(); + } + }, + + defineDep: function (i, depExports) { + //Because of cycles, defined callback for a given + //export can be called more than once. + if (!this.depMatched[i]) { + this.depMatched[i] = true; + this.depCount -= 1; + this.depExports[i] = depExports; + } + }, + + fetch: function () { + if (this.fetched) { + return; + } + this.fetched = true; + + context.startTime = (new Date()).getTime(); + + var map = this.map; + + //If the manager is for a plugin managed resource, + //ask the plugin to load it now. + if (this.shim) { + context.makeRequire(this.map, { + enableBuildCallback: true + })(this.shim.deps || [], bind(this, function () { + return map.prefix ? this.callPlugin() : this.load(); + })); + } else { + //Regular dependency. + return map.prefix ? this.callPlugin() : this.load(); + } + }, + + load: function () { + var url = this.map.url; + + //Regular dependency. + if (!urlFetched[url]) { + urlFetched[url] = true; + context.load(this.map.id, url); + } + }, + + /** + * Checks if the module is ready to DEFINE itself, and if so, + * DEFINE it. + */ + check: function () { + if (!this.enabled || this.enabling) { + return; + } + + var err, cjsModule, + id = this.map.id, + depExports = this.depExports, + exports = this.exports, + factory = this.factory; + + if (!this.inited) { + // Only fetch if not already in the defQueue. + if (!hasProp(context.defQueueMap, id)) { + this.fetch(); + } + } else if (this.error) { + this.emit('error', this.error); + } else if (!this.defining) { + //The factory could trigger another REQUIRE call + //that would result in checking this module to + //DEFINE itself again. If already in the process + //of doing that, skip this work. + this.defining = true; + + if (this.depCount < 1 && !this.defined) { + if (isFunction(factory)) { + //If there is an error listener, favor passing + //to that instead of throwing an error. However, + //only do it for DEFINE()'d modules. REQUIRE + //errbacks should not be called for failures in + //their callbacks (#699). However if a global + //onError is set, use that. + if ((this.events.error && this.map.isDefine) || + req.onError !== defaultOnError) { + try { + exports = context.execCb(id, factory, depExports, exports); + } catch (e) { + err = e; + } + } else { + exports = context.execCb(id, factory, depExports, exports); + } + + // Favor return value over exports. If node/cjs in play, + // then will not have a return value anyway. Favor + // module.exports assignment over exports object. + if (this.map.isDefine && exports === undefined) { + cjsModule = this.module; + if (cjsModule) { + exports = cjsModule.exports; + } else if (this.usingExports) { + //exports already set the defined value. + exports = this.exports; + } + } + + if (err) { + err.requireMap = this.map; + err.requireModules = this.map.isDefine ? [this.map.id] : null; + err.requireType = this.map.isDefine ? 'DEFINE' : 'REQUIRE'; + return onError((this.error = err)); + } + + } else { + //Just a literal value + exports = factory; + } + + this.exports = exports; + + if (this.map.isDefine && !this.ignore) { + defined[id] = exports; + + if (req.onResourceLoad) { + var resLoadMaps = []; + each(this.depMaps, function (depMap) { + resLoadMaps.push(depMap.normalizedMap || depMap); + }); + req.onResourceLoad(context, this.map, resLoadMaps); + } + } + + //Clean up + cleanRegistry(id); + + this.defined = true; + } + + //Finished the DEFINE stage. Allow calling check again + //to allow DEFINE notifications below in the case of a + //cycle. + this.defining = false; + + if (this.defined && !this.defineEmitted) { + this.defineEmitted = true; + this.emit('defined', this.exports); + this.defineEmitComplete = true; + } + + } + }, + + callPlugin: function () { + var map = this.map, + id = map.id, + //Map already normalized the prefix. + pluginMap = makeModuleMap(map.prefix); + + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(pluginMap); + + on(pluginMap, 'defined', bind(this, function (plugin) { + var load, normalizedMap, normalizedMod, + bundleId = getOwn(bundlesMap, this.map.id), + name = this.map.name, + parentName = this.map.parentMap ? this.map.parentMap.name : null, + localRequire = context.makeRequire(map.parentMap, { + enableBuildCallback: true + }); + + //If current map is not normalized, wait for that + //normalized name to load instead of continuing. + if (this.map.unnormalized) { + //Normalize the ID if the plugin allows it. + if (plugin.normalize) { + name = plugin.normalize(name, function (name) { + return normalize(name, parentName, true); + }) || ''; + } + + //prefix and name should already be normalized, no need + //for applying map config again either. + normalizedMap = makeModuleMap(map.prefix + '!' + name, + this.map.parentMap, + true); + on(normalizedMap, + 'defined', bind(this, function (value) { + this.map.normalizedMap = normalizedMap; + this.init([], function () { return value; }, null, { + enabled: true, + ignore: true + }); + })); + + normalizedMod = getOwn(registry, normalizedMap.id); + if (normalizedMod) { + //Mark this as a dependency for this plugin, so it + //can be traced for cycles. + this.depMaps.push(normalizedMap); + + if (this.events.error) { + normalizedMod.on('error', bind(this, function (err) { + this.emit('error', err); + })); + } + normalizedMod.enable(); + } + + return; + } + + //If a paths config, then just load that file instead to + //resolve the plugin, as it is built into that paths layer. + if (bundleId) { + this.map.url = context.nameToUrl(bundleId); + this.load(); + return; + } + + load = bind(this, function (value) { + this.init([], function () { return value; }, null, { + enabled: true + }); + }); + + load.error = bind(this, function (err) { + this.inited = true; + this.error = err; + err.requireModules = [id]; + + //Remove temp unnormalized modules for this module, + //since they will never be resolved otherwise now. + eachProp(registry, function (mod) { + if (mod.map.id.indexOf(id + '_unnormalized') === 0) { + cleanRegistry(mod.map.id); + } + }); + + onError(err); + }); + + //Allow plugins to load other code without having to know the + //context or how to 'complete' the load. + load.fromText = bind(this, function (text, textAlt) { + /*jslint evil: true */ + var moduleName = map.name, + moduleMap = makeModuleMap(moduleName), + hasInteractive = useInteractive; + + //As of 2.1.0, support just passing the text, to reinforce + //fromText only being called once per resource. Still + //support old style of passing moduleName but discard + //that moduleName in favor of the internal ref. + if (textAlt) { + text = textAlt; + } + + //Turn off interactive script matching for IE for any DEFINE + //calls in the text, then turn it back on at the end. + if (hasInteractive) { + useInteractive = false; + } + + //Prime the system by creating a module instance for + //it. + getModule(moduleMap); + + //Transfer any config to this other module. + if (hasProp(config.config, id)) { + config.config[moduleName] = config.config[id]; + } + + try { + req.exec(text); + } catch (e) { + return onError(makeError('fromtexteval', + 'fromText eval for ' + id + + ' failed: ' + e, + e, + [id])); + } + + if (hasInteractive) { + useInteractive = true; + } + + //Mark this as a dependency for the plugin + //resource + this.depMaps.push(moduleMap); + + //Support anonymous modules. + context.completeLoad(moduleName); + + //Bind the value of that module to the value for this + //resource ID. + localRequire([moduleName], load); + }); + + //Use parentName here since the plugin's name is not reliable, + //could be some weird string with no path that actually wants to + //reference the parentName's path. + plugin.load(map.name, localRequire, load, config); + })); + + context.enable(pluginMap, this); + this.pluginMaps[pluginMap.id] = pluginMap; + }, + + enable: function () { + enabledRegistry[this.map.id] = this; + this.enabled = true; + + //Set flag mentioning that the module is enabling, + //so that immediate calls to the defined callbacks + //for dependencies do not trigger inadvertent load + //with the depCount still being zero. + this.enabling = true; + + //Enable each dependency + each(this.depMaps, bind(this, function (depMap, i) { + var id, mod, handler; + + if (typeof depMap === 'string') { + //Dependency needs to be converted to a depMap + //and wired up to this module. + depMap = makeModuleMap(depMap, + (this.map.isDefine ? this.map : this.map.parentMap), + false, + !this.skipMap); + this.depMaps[i] = depMap; + + handler = getOwn(handlers, depMap.id); + + if (handler) { + this.depExports[i] = handler(this); + return; + } + + this.depCount += 1; + + on(depMap, 'defined', bind(this, function (depExports) { + if (this.undefed) { + return; + } + this.defineDep(i, depExports); + this.check(); + })); + + if (this.errback) { + on(depMap, 'error', bind(this, this.errback)); + } else if (this.events.error) { + // No direct errback on this module, but something + // else is listening for errors, so be sure to + // propagate the error correctly. + on(depMap, 'error', bind(this, function(err) { + this.emit('error', err); + })); + } + } + + id = depMap.id; + mod = registry[id]; + + //Skip special modules like 'REQUIRE', 'exports', 'module' + //Also, don't call enable if it is already enabled, + //important in circular dependency cases. + if (!hasProp(handlers, id) && mod && !mod.enabled) { + context.enable(depMap, this); + } + })); + + //Enable each plugin that is used in + //a dependency + eachProp(this.pluginMaps, bind(this, function (pluginMap) { + var mod = getOwn(registry, pluginMap.id); + if (mod && !mod.enabled) { + context.enable(pluginMap, this); + } + })); + + this.enabling = false; + + this.check(); + }, + + on: function (name, cb) { + var cbs = this.events[name]; + if (!cbs) { + cbs = this.events[name] = []; + } + cbs.push(cb); + }, + + emit: function (name, evt) { + each(this.events[name], function (cb) { + cb(evt); + }); + if (name === 'error') { + //Now that the error handler was triggered, remove + //the listeners, since this broken Module instance + //can stay around for a while in the registry. + delete this.events[name]; + } + } + }; + + function callGetModule(args) { + //Skip modules already defined. + if (!hasProp(defined, args[0])) { + getModule(makeModuleMap(args[0], null, true)).init(args[1], args[2]); + } + } + + function removeListener(node, func, name, ieName) { + //Favor detachEvent because of IE9 + //issue, see attachEvent/addEventListener comment elsewhere + //in this file. + if (node.detachEvent && !isOpera) { + //Probably IE. If not it will throw an error, which will be + //useful to know. + if (ieName) { + node.detachEvent(ieName, func); + } + } else { + node.removeEventListener(name, func, false); + } + } + + /** + * Given an event from a script node, get the REQUIREJS info from it, + * and then removes the event listeners on the node. + * @param {Event} evt + * @returns {Object} + */ + function getScriptData(evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + var node = evt.currentTarget || evt.srcElement; + + //Remove the listeners once here. + removeListener(node, context.onScriptLoad, 'load', 'onreadystatechange'); + removeListener(node, context.onScriptError, 'error'); + + return { + node: node, + id: node && node.getAttribute('data-requiremodule') + }; + } + + function intakeDefines() { + var args; + + //Any defined modules in the global queue, intake them now. + takeGlobalQueue(); + + //Make sure any remaining defQueue items get properly processed. + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + return onError(makeError('mismatch', 'Mismatched anonymous DEFINE() module: ' + + args[args.length - 1])); + } else { + //args are id, deps, factory. Should be normalized by the + //DEFINE() function. + callGetModule(args); + } + } + context.defQueueMap = {}; + } + + context = { + config: config, + contextName: contextName, + registry: registry, + defined: defined, + urlFetched: urlFetched, + defQueue: defQueue, + defQueueMap: {}, + Module: Module, + makeModuleMap: makeModuleMap, + nextTick: req.nextTick, + onError: onError, + + /** + * Set a configuration for the context. + * @param {Object} cfg config object to integrate. + */ + configure: function (cfg) { + //Make sure the baseUrl ends in a slash. + if (cfg.baseUrl) { + if (cfg.baseUrl.charAt(cfg.baseUrl.length - 1) !== '/') { + cfg.baseUrl += '/'; + } + } + + // Convert old style urlArgs string to a function. + if (typeof cfg.urlArgs === 'string') { + var urlArgs = cfg.urlArgs; + cfg.urlArgs = function(id, url) { + return (url.indexOf('?') === -1 ? '?' : '&') + urlArgs; + }; + } + + //Save off the paths since they REQUIRE special processing, + //they are additive. + var shim = config.shim, + objs = { + paths: true, + bundles: true, + config: true, + map: true + }; + + eachProp(cfg, function (value, prop) { + if (objs[prop]) { + if (!config[prop]) { + config[prop] = {}; + } + mixin(config[prop], value, true, true); + } else { + config[prop] = value; + } + }); + + //Reverse map the bundles + if (cfg.bundles) { + eachProp(cfg.bundles, function (value, prop) { + each(value, function (v) { + if (v !== prop) { + bundlesMap[v] = prop; + } + }); + }); + } + + //Merge shim + if (cfg.shim) { + eachProp(cfg.shim, function (value, id) { + //Normalize the structure + if (isArray(value)) { + value = { + deps: value + }; + } + if ((value.exports || value.init) && !value.exportsFn) { + value.exportsFn = context.makeShimExports(value); + } + shim[id] = value; + }); + config.shim = shim; + } + + //Adjust packages if necessary. + if (cfg.packages) { + each(cfg.packages, function (pkgObj) { + var location, name; + + pkgObj = typeof pkgObj === 'string' ? {name: pkgObj} : pkgObj; + + name = pkgObj.name; + location = pkgObj.location; + if (location) { + config.paths[name] = pkgObj.location; + } + + //Save pointer to main module ID for pkg name. + //Remove leading dot in main, so main paths are normalized, + //and remove any trailing .js, since different package + //envs have different conventions: some use a module name, + //some use a file name. + config.pkgs[name] = pkgObj.name + '/' + (pkgObj.main || 'main') + .replace(currDirRegExp, '') + .replace(jsSuffixRegExp, ''); + }); + } + + //If there are any "waiting to execute" modules in the registry, + //update the maps for them, since their info, like URLs to load, + //may have changed. + eachProp(registry, function (mod, id) { + //If module already has init called, since it is too + //late to modify them, and ignore unnormalized ones + //since they are transient. + if (!mod.inited && !mod.map.unnormalized) { + mod.map = makeModuleMap(id, null, true); + } + }); + + //If a deps array or a config callback is specified, then call + //REQUIRE with those args. This is useful when REQUIRE is defined as a + //config object before REQUIRE.js is loaded. + if (cfg.deps || cfg.callback) { + context.REQUIRE(cfg.deps || [], cfg.callback); + } + }, + + makeShimExports: function (value) { + function fn() { + var ret; + if (value.init) { + ret = value.init.apply(global, arguments); + } + return ret || (value.exports && getGlobal(value.exports)); + } + return fn; + }, + + makeRequire: function (relMap, options) { + options = options || {}; + + function localRequire(deps, callback, errback) { + var id, map, requireMod; + + if (options.enableBuildCallback && callback && isFunction(callback)) { + callback.__requireJsBuild = true; + } + + if (typeof deps === 'string') { + if (isFunction(callback)) { + //Invalid call + return onError(makeError('requireargs', 'Invalid REQUIRE call'), errback); + } + + //If REQUIRE|exports|module are requested, get the + //value for them from the special handlers. Caveat: + //this only works while module is being defined. + if (relMap && hasProp(handlers, deps)) { + return handlers[deps](registry[relMap.id]); + } + + //Synchronous access to one module. If REQUIRE.get is + //available (as in the Node adapter), prefer that. + if (req.get) { + return req.get(context, deps, relMap, localRequire); + } + + //Normalize module name, if it contains . or .. + map = makeModuleMap(deps, relMap, false, true); + id = map.id; + + if (!hasProp(defined, id)) { + return onError(makeError('notloaded', 'Module name "' + + id + + '" has not been loaded yet for context: ' + + contextName + + (relMap ? '' : '. Use REQUIRE([])'))); + } + return defined[id]; + } + + //Grab defines waiting in the global queue. + intakeDefines(); + + //Mark all the dependencies as needing to be loaded. + context.nextTick(function () { + //Some defines could have been added since the + //REQUIRE call, collect them. + intakeDefines(); + + requireMod = getModule(makeModuleMap(null, relMap)); + + //Store if map config should be applied to this REQUIRE + //call for dependencies. + requireMod.skipMap = options.skipMap; + + requireMod.init(deps, callback, errback, { + enabled: true + }); + + checkLoaded(); + }); + + return localRequire; + } + + mixin(localRequire, { + isBrowser: isBrowser, + + /** + * Converts a module name + .extension into an URL path. + * *Requires* the use of a module name. It does not support using + * plain URLs like nameToUrl. + */ + toUrl: function (moduleNamePlusExt) { + var ext, + index = moduleNamePlusExt.lastIndexOf('.'), + segment = moduleNamePlusExt.split('/')[0], + isRelative = segment === '.' || segment === '..'; + + //Have a file extension alias, and it is not the + //dots from a relative path. + if (index !== -1 && (!isRelative || index > 1)) { + ext = moduleNamePlusExt.substring(index, moduleNamePlusExt.length); + moduleNamePlusExt = moduleNamePlusExt.substring(0, index); + } + + return context.nameToUrl(normalize(moduleNamePlusExt, + relMap && relMap.id, true), ext, true); + }, + + defined: function (id) { + return hasProp(defined, makeModuleMap(id, relMap, false, true).id); + }, + + specified: function (id) { + id = makeModuleMap(id, relMap, false, true).id; + return hasProp(defined, id) || hasProp(registry, id); + } + }); + + //Only allow undef on top level REQUIRE calls + if (!relMap) { + localRequire.undef = function (id) { + //Bind any waiting DEFINE() calls to this context, + //fix for #408 + takeGlobalQueue(); + + var map = makeModuleMap(id, relMap, true), + mod = getOwn(registry, id); + + mod.undefed = true; + removeScript(id); + + delete defined[id]; + delete urlFetched[map.url]; + delete undefEvents[id]; + + //Clean queued defines too. Go backwards + //in array so that the splices do not + //mess up the iteration. + eachReverse(defQueue, function(args, i) { + if (args[0] === id) { + defQueue.splice(i, 1); + } + }); + delete context.defQueueMap[id]; + + if (mod) { + //Hold on to listeners in case the + //module will be attempted to be reloaded + //using a different config. + if (mod.events.defined) { + undefEvents[id] = mod.events; + } + + cleanRegistry(id); + } + }; + } + + return localRequire; + }, + + /** + * Called to enable a module if it is still in the registry + * awaiting enablement. A second arg, parent, the parent module, + * is passed in for context, when this method is overridden by + * the optimizer. Not shown here to keep code compact. + */ + enable: function (depMap) { + var mod = getOwn(registry, depMap.id); + if (mod) { + getModule(depMap).enable(); + } + }, + + /** + * Internal method used by environment adapters to complete a load event. + * A load event could be a script load or just a load pass from a synchronous + * load call. + * @param {String} moduleName the name of the module to potentially complete. + */ + completeLoad: function (moduleName) { + var found, args, mod, + shim = getOwn(config.shim, moduleName) || {}, + shExports = shim.exports; + + takeGlobalQueue(); + + while (defQueue.length) { + args = defQueue.shift(); + if (args[0] === null) { + args[0] = moduleName; + //If already found an anonymous module and bound it + //to this name, then this is some other anon module + //waiting for its completeLoad to fire. + if (found) { + break; + } + found = true; + } else if (args[0] === moduleName) { + //Found matching DEFINE call for this script! + found = true; + } + + callGetModule(args); + } + context.defQueueMap = {}; + + //Do this after the cycle of callGetModule in case the result + //of those calls/init calls changes the registry. + mod = getOwn(registry, moduleName); + + if (!found && !hasProp(defined, moduleName) && mod && !mod.inited) { + if (config.enforceDefine && (!shExports || !getGlobal(shExports))) { + if (hasPathFallback(moduleName)) { + return; + } else { + return onError(makeError('nodefine', + 'No DEFINE call for ' + moduleName, + null, + [moduleName])); + } + } else { + //A script that does not call DEFINE(), so just simulate + //the call for it. + callGetModule([moduleName, (shim.deps || []), shim.exportsFn]); + } + } + + checkLoaded(); + }, + + /** + * Converts a module name to a file path. Supports cases where + * moduleName may actually be just an URL. + * Note that it **does not** call normalize on the moduleName, + * it is assumed to have already been normalized. This is an + * internal API, not a public one. Use toUrl for the public API. + */ + nameToUrl: function (moduleName, ext, skipExt) { + var paths, syms, i, parentModule, url, + parentPath, bundleId, + pkgMain = getOwn(config.pkgs, moduleName); + + if (pkgMain) { + moduleName = pkgMain; + } + + bundleId = getOwn(bundlesMap, moduleName); + + if (bundleId) { + return context.nameToUrl(bundleId, ext, skipExt); + } + + //If a colon is in the URL, it indicates a protocol is used and it is just + //an URL to a file, or if it starts with a slash, contains a query arg (i.e. ?) + //or ends with .js, then assume the user meant to use an url and not a module id. + //The slash is important for protocol-less URLs as well as full paths. + if (req.jsExtRegExp.test(moduleName)) { + //Just a plain path, not module name lookup, so just return it. + //Add extension if it is included. This is a bit wonky, only non-.js things pass + //an extension, this method probably needs to be reworked. + url = moduleName + (ext || ''); + } else { + //A module that needs to be converted to a path. + paths = config.paths; + + syms = moduleName.split('/'); + //For each module name segment, see if there is a path + //registered for it. Start with most specific name + //and work up from it. + for (i = syms.length; i > 0; i -= 1) { + parentModule = syms.slice(0, i).join('/'); + + parentPath = getOwn(paths, parentModule); + if (parentPath) { + //If an array, it means there are a few choices, + //Choose the one that is desired + if (isArray(parentPath)) { + parentPath = parentPath[0]; + } + syms.splice(0, i, parentPath); + break; + } + } + + //Join the path parts together, then figure out if baseUrl is needed. + url = syms.join('/'); + url += (ext || (/^data\:|^blob\:|\?/.test(url) || skipExt ? '' : '.js')); + url = (url.charAt(0) === '/' || url.match(/^[\w\+\.\-]+:/) ? '' : config.baseUrl) + url; + } + + return config.urlArgs && !/^blob\:/.test(url) ? + url + config.urlArgs(moduleName, url) : url; + }, + + //Delegates to req.load. Broken out as a separate function to + //allow overriding in the optimizer. + load: function (id, url) { + req.load(context, id, url); + }, + + /** + * Executes a module callback function. Broken out as a separate function + * solely to allow the build system to sequence the files in the built + * layer in the right sequence. + * + * @private + */ + execCb: function (name, callback, args, exports) { + return callback.apply(exports, args); + }, + + /** + * callback for script loads, used to check status of loading. + * + * @param {Event} evt the event from the browser for the script + * that was loaded. + */ + onScriptLoad: function (evt) { + //Using currentTarget instead of target for Firefox 2.0's sake. Not + //all old browsers will be supported, but this one was easy enough + //to support and still makes sense. + if (evt.type === 'load' || + (readyRegExp.test((evt.currentTarget || evt.srcElement).readyState))) { + //Reset interactive script so a script node is not held onto for + //to long. + interactiveScript = null; + + //Pull out the name of the module and the context. + var data = getScriptData(evt); + context.completeLoad(data.id); + } + }, + + /** + * Callback for script errors. + */ + onScriptError: function (evt) { + var data = getScriptData(evt); + if (!hasPathFallback(data.id)) { + var parents = []; + eachProp(registry, function(value, key) { + if (key.indexOf('_@r') !== 0) { + each(value.depMaps, function(depMap) { + if (depMap.id === data.id) { + parents.push(key); + return true; + } + }); + } + }); + return onError(makeError('scripterror', 'Script error for "' + data.id + + (parents.length ? + '", needed by: ' + parents.join(', ') : + '"'), evt, [data.id])); + } + } + }; + + context.REQUIRE = context.makeRequire(); + return context; + } + + /** + * Main entry point. + * + * If the only argument to REQUIRE is a string, then the module that + * is represented by that string is fetched for the appropriate context. + * + * If the first argument is an array, then it will be treated as an array + * of dependency string names to fetch. An optional function callback can + * be specified to execute when all of those dependencies are available. + * + * Make a local req variable to help Caja compliance (it assumes things + * on a REQUIRE that are not standardized), and to give a short + * name for minification/local scope use. + */ + req = REQUIREJS = function (deps, callback, errback, optional) { + + //Find the right context, use default + var context, config, + contextName = defContextName; + + // Determine if have config object in the call. + if (!isArray(deps) && typeof deps !== 'string') { + // deps is a config object + config = deps; + if (isArray(callback)) { + // Adjust args if there are dependencies + deps = callback; + callback = errback; + errback = optional; + } else { + deps = []; + } + } + + if (config && config.context) { + contextName = config.context; + } + + context = getOwn(contexts, contextName); + if (!context) { + context = contexts[contextName] = req.s.newContext(contextName); + } + + if (config) { + context.configure(config); + } + + return context.REQUIRE(deps, callback, errback); + }; + + /** + * Support REQUIRE.config() to make it easier to cooperate with other + * AMD loaders on globally agreed names. + */ + req.config = function (config) { + return req(config); + }; + + /** + * Execute something after the current tick + * of the event loop. Override for other envs + * that have a better solution than setTimeout. + * @param {Function} fn function to execute later. + */ + req.nextTick = typeof setTimeout !== 'undefined' ? function (fn) { + setTimeout(fn, 4); + } : function (fn) { fn(); }; + + /** + * Export REQUIRE as a global, but only if it does not already exist. + */ + if (!REQUIRE) { + REQUIRE = req; + } + + req.version = version; + + //Used to filter out dependencies that are already paths. + req.jsExtRegExp = /^\/|:|\?|\.js$/; + req.isBrowser = isBrowser; + s = req.s = { + contexts: contexts, + newContext: newContext + }; + + //Create default context. + req({}); + + //Exports some context-sensitive methods on global REQUIRE. + each([ + 'toUrl', + 'undef', + 'defined', + 'specified' + ], function (prop) { + //Reference from contexts instead of early binding to default context, + //so that during builds, the latest instance of the default context + //with its config gets used. + req[prop] = function () { + var ctx = contexts[defContextName]; + return ctx.REQUIRE[prop].apply(ctx, arguments); + }; + }); + + if (isBrowser) { + head = s.head = document.getElementsByTagName('head')[0]; + //If BASE tag is in play, using appendChild is a problem for IE6. + //When that browser dies, this can be removed. Details in this jQuery bug: + //http://dev.jquery.com/ticket/2709 + baseElement = document.getElementsByTagName('base')[0]; + if (baseElement) { + head = s.head = baseElement.parentNode; + } + } + + /** + * Any errors that REQUIRE explicitly generates will be passed to this + * function. Intercept/override it if you want custom error handling. + * @param {Error} err the error object. + */ + req.onError = defaultOnError; + + /** + * Creates the node for the load command. Only used in browser envs. + */ + req.createNode = function (config, moduleName, url) { + var node = config.xhtml ? + document.createElementNS('http://www.w3.org/1999/xhtml', 'html:script') : + document.createElement('script'); + node.type = config.scriptType || 'text/javascript'; + node.charset = 'utf-8'; + node.async = true; + return node; + }; + + /** + * Does the request to load a module for the browser case. + * Make this a separate function to allow other environments + * to override it. + * + * @param {Object} context the REQUIRE context to find state. + * @param {String} moduleName the name of the module. + * @param {Object} url the URL to the module. + */ + req.load = function (context, moduleName, url) { + var config = (context && context.config) || {}, + node; + if (isBrowser) { + //In the browser so use a script tag + node = req.createNode(config, moduleName, url); + + node.setAttribute('data-requirecontext', context.contextName); + node.setAttribute('data-requiremodule', moduleName); + + //Set up load listener. Test attachEvent first because IE9 has + //a subtle issue in its addEventListener and script onload firings + //that do not match the behavior of all other browsers with + //addEventListener support, which fire the onload event for a + //script right after the script execution. See: + //https://connect.microsoft.com/IE/feedback/details/648057/script-onload-event-is-not-fired-immediately-after-script-execution + //UNFORTUNATELY Opera implements attachEvent but does not follow the script + //script execution mode. + if (node.attachEvent && + //Check if node.attachEvent is artificially added by custom script or + //natively supported by browser + //read https://github.com/REQUIREJS/REQUIREJS/issues/187 + //if we can NOT find [native code] then it must NOT natively supported. + //in IE8, node.attachEvent does not have toString() + //Note the test for "[native code" with no closing brace, see: + //https://github.com/REQUIREJS/REQUIREJS/issues/273 + !(node.attachEvent.toString && node.attachEvent.toString().indexOf('[native code') < 0) && + !isOpera) { + //Probably IE. IE (at least 6-8) do not fire + //script onload right after executing the script, so + //we cannot tie the anonymous DEFINE call to a name. + //However, IE reports the script as being in 'interactive' + //readyState at the time of the DEFINE call. + useInteractive = true; + + node.attachEvent('onreadystatechange', context.onScriptLoad); + //It would be great to add an error handler here to catch + //404s in IE9+. However, onreadystatechange will fire before + //the error handler, so that does not help. If addEventListener + //is used, then IE will fire error before load, but we cannot + //use that pathway given the connect.microsoft.com issue + //mentioned above about not doing the 'script execute, + //then fire the script load event listener before execute + //next script' that other browsers do. + //Best hope: IE10 fixes the issues, + //and then destroys all installs of IE 6-9. + //node.attachEvent('onerror', context.onScriptError); + } else { + node.addEventListener('load', context.onScriptLoad, false); + node.addEventListener('error', context.onScriptError, false); + } + node.src = url; + + //Calling onNodeCreated after all properties on the node have been + //set, but before it is placed in the DOM. + if (config.onNodeCreated) { + config.onNodeCreated(node, config, moduleName, url); + } + + //For some cache cases in IE 6-8, the script executes before the end + //of the appendChild execution, so to tie an anonymous DEFINE + //call to the module name (which is stored on the node), hold on + //to a reference to this node, but clear after the DOM insertion. + currentlyAddingScript = node; + if (baseElement) { + head.insertBefore(node, baseElement); + } else { + head.appendChild(node); + } + currentlyAddingScript = null; + + return node; + } else if (isWebWorker) { + try { + //In a web worker, use importScripts. This is not a very + //efficient use of importScripts, importScripts will block until + //its script is downloaded and evaluated. However, if web workers + //are in play, the expectation is that a build has been done so + //that only one script needs to be loaded anyway. This may need + //to be reevaluated if other use cases become common. + + // Post a task to the event loop to work around a bug in WebKit + // where the worker gets garbage-collected after calling + // importScripts(): https://webkit.org/b/153317 + setTimeout(function() {}, 0); + importScripts(url); + + //Account for anonymous modules + context.completeLoad(moduleName); + } catch (e) { + context.onError(makeError('importscripts', + 'importScripts failed for ' + + moduleName + ' at ' + url, + e, + [moduleName])); + } + } + }; + + function getInteractiveScript() { + if (interactiveScript && interactiveScript.readyState === 'interactive') { + return interactiveScript; + } + + eachReverse(scripts(), function (script) { + if (script.readyState === 'interactive') { + return (interactiveScript = script); + } + }); + return interactiveScript; + } + + //Look for a data-main script attribute, which could also adjust the baseUrl. + if (isBrowser && !cfg.skipDataMain) { + //Figure out baseUrl. Get it from the script tag with REQUIRE.js in it. + eachReverse(scripts(), function (script) { + //Set the 'head' where we can append children by + //using the script's parent. + if (!head) { + head = script.parentNode; + } + + //Look for a data-main attribute to set main script for the page + //to load. If it is there, the path to data main becomes the + //baseUrl, if it is not already set. + dataMain = script.getAttribute('data-main'); + if (dataMain) { + //Preserve dataMain in case it is a path (i.e. contains '?') + mainScript = dataMain; + + //Set final baseUrl if there is not already an explicit one, + //but only do so if the data-main value is not a loader plugin + //module ID. + if (!cfg.baseUrl && mainScript.indexOf('!') === -1) { + //Pull off the directory of data-main for use as the + //baseUrl. + src = mainScript.split('/'); + mainScript = src.pop(); + subPath = src.length ? src.join('/') + '/' : './'; + + cfg.baseUrl = subPath; + } + + //Strip off any trailing .js since mainScript is now + //like a module name. + mainScript = mainScript.replace(jsSuffixRegExp, ''); + + //If mainScript is still a path, fall back to dataMain + if (req.jsExtRegExp.test(mainScript)) { + mainScript = dataMain; + } + + //Put the data-main script in the files to load. + cfg.deps = cfg.deps ? cfg.deps.concat(mainScript) : [mainScript]; + + return true; + } + }); + } + + /** + * The function that handles definitions of modules. Differs from + * REQUIRE() in that a string for the module should be the first argument, + * and the function to execute after dependencies are loaded should + * return a value to DEFINE the module corresponding to the first argument's + * name. + */ + DEFINE = function (name, deps, callback) { + var node, context; + + //Allow for anonymous modules + if (typeof name !== 'string') { + //Adjust args appropriately + callback = deps; + deps = name; + name = null; + } + + //This module may not have dependencies + if (!isArray(deps)) { + callback = deps; + deps = null; + } + + //If no name, and callback is a function, then figure out if it a + //CommonJS thing with dependencies. + if (!deps && isFunction(callback)) { + deps = []; + //Remove comments from the callback string, + //look for REQUIRE calls, and pull them into the dependencies, + //but only if there are function args. + if (callback.length) { + callback + .toString() + .replace(commentRegExp, commentReplace) + .replace(cjsRequireRegExp, function (match, dep) { + deps.push(dep); + }); + + //May be a CommonJS thing even without REQUIRE calls, but still + //could use exports, and module. Avoid doing exports and module + //work though if it just needs REQUIRE. + //REQUIRES the function to expect the CommonJS variables in the + //order listed below. + deps = (callback.length === 1 ? ['REQUIRE'] : ['REQUIRE', 'exports', 'module']).concat(deps); + } + } + + //If in IE 6-8 and hit an anonymous DEFINE() call, do the interactive + //work. + if (useInteractive) { + node = currentlyAddingScript || getInteractiveScript(); + if (node) { + if (!name) { + name = node.getAttribute('data-requiremodule'); + } + context = contexts[node.getAttribute('data-requirecontext')]; + } + } + + //Always save off evaluating the def call until the script onload handler. + //This allows multiple modules to be in a file without prematurely + //tracing dependencies, and allows for anonymous module support, + //where the module name is not known until the script onload event + //occurs. If no context, use the global queue, and get it processed + //in the onscript load callback. + if (context) { + context.defQueue.push([name, deps, callback]); + context.defQueueMap[name] = true; + } else { + globalDefQueue.push([name, deps, callback]); + } + }; + + DEFINE.amd = { + jQuery: true + }; + + /** + * Executes the text. Normally just uses eval, but can be modified + * to use a better, environment-specific call. Only used for transpiling + * loader plugins, not for plain JS modules. + * @param {String} text the text to execute/evaluate. + */ + req.exec = function (text) { + /*jslint evil: true */ + return eval(text); + }; + + //Set up with config info. + req(cfg); +}(this, (typeof setTimeout === 'undefined' ? undefined : setTimeout))); diff --git a/package.json b/package.json index 37c6ecb63..95e6290cb 100644 --- a/package.json +++ b/package.json @@ -1,14 +1,17 @@ { - "name": "backend-server", - "version": "0.0.0", + "name": "backend-servers", + "version": "0.0.6", "description": "BackendServer", - "main": "app.js", + "main": "server.js", "author": { - "name": "Luis" + "name": "Luis-Fernando-Molina" }, "dependencies": { "child_process": "^1.0.2", "dotenv": "^8.2.0", - "ws": "^7.1.2" + "ws": "^7.1.2", + "ccxt": "^1.23.67", + "open": "^6.4.0", + "rimraf": "^3.0.2" } } diff --git a/server.js b/server.js index a9636899b..4a9cf0c44 100644 --- a/server.js +++ b/server.js @@ -1,7 +1,7 @@ process.on('uncaughtException', function (err) { if (err.message.indexOf("EADDRINUSE") > 0) { - console.log("Superalgos Backend Server cannot be started. Reason: the port " + port + " is already in use by another application.") + console.log("A Superalgos Backend Server cannot be started. Reason: the port " + port + " is already in use by another application.") return } console.log('[ERROR] Backend Server -> server -> uncaughtException -> err.message = ' + err.message) @@ -27,9 +27,26 @@ global.DEFAULT_FAIL_RESPONSE = { message: "Operation Failed" }; +global.DEFAULT_RETRY_RESPONSE = { + result: 'Retry', + message: 'Retry Later' +} + +global.CUSTOM_OK_RESPONSE = { + result: 'Ok, but check Message', + message: 'Custom Message' +} + +global.CUSTOM_FAIL_RESPONSE = { + result: 'Fail Because', + message: 'Custom Message' +} + + let EVENTS_SERVER = require('./eventsServer.js'); let WEB_SOCKETS_SERVER = require('./webSocketsServer.js'); let TASK_MANAGER_SERVER = require('./taskManagerServer.js'); +let WEB_SERVER = require('./webServer.js'); try { EVENTS_SERVER = EVENTS_SERVER.newEventsServer() @@ -43,6 +60,11 @@ try { TASK_MANAGER_SERVER = TASK_MANAGER_SERVER.newTaskManagerServer(WEB_SOCKETS_SERVER, EVENTS_SERVER) TASK_MANAGER_SERVER.initialize() TASK_MANAGER_SERVER.run() + + WEB_SERVER = WEB_SERVER.newWebServer(EVENTS_SERVER) + WEB_SERVER.initialize() + WEB_SERVER.run() + } catch (err) { console.log('[ERROR] BackendServers -> Task Manager -> server -> Error = ' + err.stack) } diff --git a/webServer.js b/webServer.js new file mode 100644 index 000000000..6953918df --- /dev/null +++ b/webServer.js @@ -0,0 +1,577 @@ +exports.newWebServer = function newWebServer(EVENTS_SERVER) { + + const MODULE = "Web Server" + + let thisObject = { + initialize: initialize, + finalize: finalize, + run: run + } + + require('dotenv').config() + const open = require('open') + + CONSOLE_LOG = process.env.CONSOLE_LOG === 'true' + CONSOLE_ERROR_LOG = process.env.CONSOLE_ERROR_LOG === 'true' + LOG_FILE_CONTENT = process.env.LOG_FILE_CONTENT === 'true' + + let port = process.env.WEB_SERVER_PORT + + let http = require('http') + let isHttpServerStarted = false + let cloneExecutorChildProcess + + return thisObject + + function finalize() { + + } + + function initialize() { + + } + + function run() { + startHtttpServer() + } + + function startHtttpServer() { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> startHtttpServer -> Entering function.') } + + try { + if (isHttpServerStarted === false) { + gWebServer = http.createServer(onBrowserRequest).listen(port) + isHttpServerStarted = true + open('http://localhost:' + port) + console.log('Web Server Started.') + } + } catch (err) { + console.log('[ERROR] webServer -> startHtttpServer -> Error = ' + err.stack) + } + } + + function onBrowserRequest(request, response) { + if (CONSOLE_LOG === true && request.url.indexOf('NO-LOG') === -1) { console.log('[INFO] webServer -> onBrowserRequest -> request.url = ' + request.url) } + + let requestParameters = request.url.split('/') + + if (requestParameters[1].indexOf('index.html') >= 0) { + /* + We use this to solve the problem when someone is arriving to the site with a sessionToken in the queryString. We extract here that + token, that will be sent later embedded into the HTML code, so that it can enter into the stardard circuit where any site can put + the sessionToken into their HTML code and from there the Browser app will log the user in. + */ + + let queryString = requestParameters[1].split('?') + + requestParameters[1] = '' + requestParameters[2] = queryString[1] + homePage() + + return + } + + requestParameters = request.url.split('?') // Remove version information + requestParameters = requestParameters[0].split('/') + + switch (requestParameters[1]) { + + case 'CCXT': + { + getBody(processRequest) + + function getBody(callback) { + let body = '' + + request.on('data', function (data) { + body += data + // Too much POST data + if (body.length > 1e6) { + request.connection.destroy() + } + }) + + request.on('end', function () { + callback(body) + }) + } + async function processRequest(body) { + try { + let params = JSON.parse(body) + + const ccxt = require('ccxt') + + switch (params.method) { + case 'fetchMarkets': { + + const exchangeClass = ccxt[params.exchangeId] + const exchangeConstructorParams = { + 'timeout': 30000, + 'enableRateLimit': true, + verbose: false + } + + let ccxtExchange = new exchangeClass(exchangeConstructorParams) + let ccxtMarkets = [] + + if (ccxtExchange.has.fetchMarkets === true) { + ccxtMarkets = await ccxtExchange.fetchMarkets() + } + respondWithContent(JSON.stringify(ccxtMarkets), response) + return + } + case 'listExchanges': { + let exchanges = [] + for (let i = 0; i < ccxt.exchanges.length; i++) { + let exchangeId = ccxt.exchanges[i] + + const exchangeClass = ccxt[exchangeId] + const exchangeConstructorParams = { + 'timeout': 30000, + 'enableRateLimit': true, + verbose: false + } + let ccxtExchange + try { ccxtExchange = new exchangeClass(exchangeConstructorParams) } + catch (err) { } + if (ccxtExchange === undefined) { continue } + + + if (ccxtExchange.has.fetchOHLCV === params.has.fetchOHLCV) { + if (ccxtExchange.has.fetchMarkets === params.has.fetchMarkets) { + if (ccxtExchange.timeframes['1m'] !== undefined) { + let exchange = { + name: ccxtExchange.name, + id: ccxtExchange.id + } + exchanges.push(exchange) + } + } + } + } + respondWithContent(JSON.stringify(exchanges), response) + return + } + } + + let content = { + err: global.DEFAULT_FAIL_RESPONSE // method not supported + } + } catch (err) { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> CCXT FetchMarkets -> Could not fetch markets.') } + let error = { + result: 'Fail Because', + message: err.message + } + respondWithContent(JSON.stringify(error), response) + } + } + break + } + + case 'ResetLogsAndData': + { + try { + let rimraf = require('rimraf') + rimraf.sync(process.env.STORAGE_PATH + '/Masters/Masters/AAJason.1.0') + rimraf.sync(process.env.LOG_PATH) + + respondWithContent(JSON.stringify(global.DEFAULT_OK_RESPONSE), response) + } catch (err) { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> ResetLogsAndData -> Could not delete Logs and Data.') } + let error = { + result: 'Fail Because', + message: err.message + } + respondWithContent(JSON.stringify(error), response) + } + break + } + + case 'LegacyPlotter.js': + { + respondWithFile(process.env.PATH_TO_WEB_SERVER + 'WebServer/LegacyPlotter.js', response) + } + break + + case 'PlotterPanel.js': + { + respondWithFile(process.env.PATH_TO_WEB_SERVER + 'WebServer/PlotterPanel.js', response) + } + break + + case 'Images': // This means the Images folder. + { + let path = process.env.PATH_TO_WEB_SERVER + 'WebServer/Images/' + requestParameters[2] + + if (requestParameters[3] !== undefined) { + path = path + '/' + requestParameters[3] + } + + if (requestParameters[4] !== undefined) { + path = path + '/' + requestParameters[4] + } + + if (requestParameters[5] !== undefined) { + path = path + '/' + requestParameters[5] + } + + path = unescape(path) + + respondWithImage(path, response) + } + break + + case 'favicon.ico': // This means the Scripts folder. + { + respondWithImage(process.env.PATH_TO_WEB_SERVER + 'WebServer/Images/' + 'favicon.ico', response) + } + break + + case 'CockpitSpace': // This means the CockpitSpace folder. + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/CockpitSpace/' + requestParameters[2], response) + } + break + + case 'TopSpace': // This means the TopSpace folder. + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/TopSpace/' + requestParameters[2], response) + } + break + + case 'DesignSpace': // This means the DesignSpace folder. + + { + if (requestParameters[3] === undefined) { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/DesignSpace/' + requestParameters[2], response) + return + } + if (requestParameters[4] === undefined) { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/DesignSpace/' + requestParameters[2] + '/' + requestParameters[3], response) + return + } + if (requestParameters[5] === undefined) { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/DesignSpace/' + requestParameters[2] + '/' + requestParameters[3] + '/' + requestParameters[4], response) + return + } + } + break + + case 'ControlsToolBox': // This means the DesignSpace folder. + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/ControlsToolBox/' + requestParameters[2], response) + } + break + + case 'Utilities': // This means the DesignSpace folder. + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/Utilities/' + requestParameters[2], response) + } + break + + case 'WebServer': // This means the WebServer folder. + { + respondWithFile(process.env.PATH_TO_WEB_SERVER + 'WebServer/' + requestParameters[2], response) + } + break + + case 'externalScripts': // This means the WebServer folder. + { + respondWithFile(process.env.PATH_TO_WEB_SERVER + 'WebServer/externalScripts/' + requestParameters[2], response) + } + break + + 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, response) + } + 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 + respondWithFile(filePath, response) + } + break + case 'Panels': + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/' + requestParameters[1] + '/' + requestParameters[2], response) + } + break + + case 'ChartLayers': + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/' + requestParameters[1] + '/' + requestParameters[2], response) + } + break + + case 'Spaces': + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/' + requestParameters[1] + '/' + requestParameters[2], response) + } + break + + case 'Scales': + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/' + requestParameters[1] + '/' + requestParameters[2], response) + } + break + + case 'Files': + { + respondWithFile(process.env.PATH_TO_FILES_COMPONENT + '/' + requestParameters[2], response) + } + break + + case 'FloatingSpace': + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/' + requestParameters[1] + '/' + requestParameters[2], response) + } + break + + case 'ChartingSpace': + { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/' + requestParameters[1] + '/' + requestParameters[2], response) + } + break + + case 'AppSchema.js': + { + let fs = require('fs') + + try { + let filePath = process.env.APP_SCHEMA_PATH + 'AppSchema.json' + fs.readFile(filePath, onFileRead) + } catch (e) { + console.log('[ERROR] Error reading the App Schema.', e) + } + + function onFileRead(err, appSchema) { + if (err) { + respondWithContent(undefined, response) + } else { + let responseContent = 'function getAppSchema(){ return ' + appSchema + '}' + respondWithContent(responseContent, response) + } + } + } + break + + case 'Workspace.js': + { + let fs = require('fs') + + try { + let filePath = process.env.WORKSPACE_PATH + 'Workspace.json' + fs.readFile(filePath, onFileRead) + } catch (e) { + console.log('[ERROR] Error reading the Workspace.', e) + } + + function onFileRead(err, workspace) { + if (err) { + respondWithContent(undefined, response) + } else { + let responseContent = 'function getWorkspace(){ return ' + workspace + '}' + respondWithContent(responseContent, response) + } + } + } + break + + case 'DataMines': + { + respondWithFile(process.env.DATA_MINES_PATH + '/' + requestParameters[2] + '.json', response) + } + break + + case 'TradingSystems': + { + respondWithFile(process.env.TRADING_SYSTEMS_PATH + '/' + requestParameters[2] + '.json', response) + } + break + + case 'SuperScripts': + { + respondWithFile(process.env.SUPER_SCRIPTS_PATH + '/' + requestParameters[2] + '.json', response) + } + break + + case 'Storage': + { + respondWithFile(process.env.STORAGE_PATH + '/' + request.url.substring(9), response) + } + break + + case 'GetDefinition': + { + respondWithFile(process.env.INTER_PROCESS_FILES_PATH + '/definition.json', response) + } + break + + case 'SaveDefinition': + { + let fs = require('fs') + let body = '' + + request.on('data', function (data) { + body += data + // Too much POST data + if (body.length > 1e6) { + request.connection.destroy() + } + }) + + request.on('end', function () { + try { + let filePath = process.env.INTER_PROCESS_FILES_PATH + '/definition.json' + fs.writeFile(filePath, body, onFileWrite) + } catch (e) { + console.log('[ERROR] Error writing user config.', e) + respondWithContent(undefined, response) + } + + function onFileWrite(err) { + if (err) { + respondWithContent(undefined, response) + } else { + let responseContent = 'User config updated.' + respondWithContent(responseContent, response) + } + } + }) + } + break + + default: + { + homePage() + } + } + + function homePage() { + if (requestParameters[1] === '') { + let fs = require('fs') + try { + let fileName = process.env.PATH_TO_WEB_SERVER + 'WebServer/index.html' + fs.readFile(fileName, onFileRead) + + function onFileRead(err, file) { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> onBrowserRequest -> onFileRead -> Entering function.') } + + try { + let fileContent = file.toString() + + fileContent = fileContent.replace('WEB_SERVER_PORT', process.env.WEB_SERVER_PORT) + respondWithContent(fileContent, response) + } catch (err) { + console.log('[ERROR] webServer -> onBrowserRequest -> File Not Found: ' + fileName + ' or Error = ' + err.stack) + } + } + } catch (err) { + console.log(err) + } + } else { + respondWithFile(process.env.PATH_TO_CANVAS_APP + '/' + requestParameters[1], response) + } + } + } + + function respondWithFile(fileName, response) { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithFile -> Entering function.') } + + let fs = require('fs') + if (fileName.indexOf('undefined') > 0) { + console.log('[WRN] webServer -> respondWithFile -> Received request for undefined file. ') + respondWithContent(undefined, response) + } else { + try { + fs.readFile(fileName, onFileRead) + + function onFileRead(err, file) { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithFile -> onFileRead -> Entering function.') } + if (!err) { + respondWithContent(file.toString(), response) + } else { + respondWithContent(undefined, response) + } + } + } catch (err) { + returnEmptyArray() + } + } + } + + function respondWithContent(content, response) { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithContent -> Entering function.') } + + try { + response.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate') // HTTP 1.1. + response.setHeader('Pragma', 'no-cache') // HTTP 1.0. + response.setHeader('Expires', '0') // Proxies. + response.setHeader('Access-Control-Allow-Origin', '*') // Allows to access data from other domains. + + if (content !== undefined) { + response.writeHead(200, { 'Content-Type': 'text/html' }) + response.write(content) + } else { + response.writeHead(404, { 'Content-Type': 'text/html' }) + response.write('The specified key does not exist.') + } + response.end('\n') + } catch (err) { + returnEmptyArray(response) + } + } + + function respondWithImage(fileName, response) { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithImage -> Entering function.') } + + let fs = require('fs') + try { + fs.readFile(fileName, onFileRead) + + function onFileRead(err, file) { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithImage -> onFileRead -> Entering function.') } + + try { + response.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate') // HTTP 1.1. + response.setHeader('Pragma', 'no-cache') // HTTP 1.0. + response.setHeader('Expires', '0') // Proxies. + response.setHeader('Access-Control-Allow-Origin', '*') // Allows to access data from other domains. + + response.writeHead(200, { 'Content-Type': 'image/png' }) + response.end(file, 'binary') + } catch (err) { + console.log('[ERROR] webServer -> respondWithImage -> onFileRead -> File Not Found: ' + fileName + ' or Error = ' + err.stack) + } + } + } catch (err) { + console.log('[ERROR] webServer -> respondWithImage -> err = ' + err.stack) + } + } + + function returnEmptyArray(response) { + try { + if (CONSOLE_LOG === true) { console.log('[INFO] webServer -> respondWithFile -> returnEmptyArray -> Entering function.') } + + response.setHeader('Cache-Control', 'no-cache, no-store, must-revalidate') // HTTP 1.1. + response.setHeader('Pragma', 'no-cache') // HTTP 1.0. + response.setHeader('Expires', '0') // Proxies. + + response.writeHead(200, { 'Content-Type': 'text/html' }) + response.write('[]') + response.end('\n') + } catch (err) { + console.log('[ERROR] webServer -> returnEmptyArray -> err.message ' + err.message) + } + } +} \ No newline at end of file