From 60d55f3daf9756e76e192b0c9590466ddaebee3e Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Thu, 30 May 2019 21:49:57 +0800 Subject: [PATCH 1/6] Initial Scratch --- .babelrc | 40 +- .eslintrc.js | 6 +- {src/utils => common}/__tests__/constants.js | 2 +- {src/services/api => common}/appId.js | 14 +- {src/services/api => common}/appIdResolver.js | 0 .../tradeEngine/utils => common}/broadcast.js | 2 +- src/constants/const.js => common/constants.js | 18 +- {src/utils => common}/error.js | 0 common/helpers.js | 121 +++++ .../integrations}/elevio.js | 9 +- .../integrations/googleDrive.js | 11 +- {src/utils => common/integrations}/gtm.js | 6 +- .../Interpreter.js => common/interpreter.js | 16 +- {src/utils => common/lang}/__tests__/i18n.js | 3 + {src/utils => common}/lang/i18n.js | 26 +- {src/utils => common}/lang/lang.js | 7 +- {src/utils => common}/observer.js | 5 + {src/utils => common}/storageManager.js | 0 .../utils/helpers.js => common/tools.js | 23 +- .../tradeEngine/Interface/CandleInterface.js | 0 .../Interface/IndicatorsInterface.js | 1 + .../tradeEngine/Interface/MiscInterface.js | 2 +- .../tradeEngine/Interface/TicksInterface.js | 0 .../tradeEngine/Interface/ToolsInterface.js | 0 .../tradeEngine/Interface/index.js | 14 +- .../tradeEngine/__tests__/BotApi.js | 6 +- .../tradeEngine/__tests__/Core.js | 0 .../tradeEngine/__tests__/StopStart.js | 6 +- .../tradeEngine/__tests__/UI.js | 0 .../__tests__/block-tests/After.js | 0 .../__tests__/block-tests/Before.js | 0 .../__tests__/block-tests/During.js | 0 .../__tests__/block-tests/Ticks.js | 0 .../__tests__/block-tests/indicators.js | 4 +- .../block-tests/sanitize-test/Blocks.js | 0 .../block-tests/sanitize-test/Trade.js | 0 .../block-tests/tools-test/Candles.js | 0 .../__tests__/block-tests/tools-test/Misc.js | 6 +- .../__tests__/block-tests/tools-test/Time.js | 0 .../tradeEngine/__tests__/jsi.js | 4 +- .../__tests__/shouldRestartOnError.js | 0 .../tradeEngine/__tests__/stages.js | 0 .../tradeEngine/__tests__/tools.js | 2 +- .../tradeEngine/trade/Balance.js | 5 +- .../tradeEngine/trade/OpenContract.js | 18 +- .../tradeEngine/trade/Proposal.js | 14 +- .../tradeEngine/trade/Purchase.js | 10 +- .../tradeEngine/trade/Sell.js | 10 +- .../tradeEngine/trade/Ticks.js | 18 +- .../tradeEngine/trade/Total.js | 16 +- .../tradeEngine/trade/index.js | 44 +- .../tradeEngine/trade/state/actions/index.js | 0 .../trade/state/actions/index.spec.js | 2 +- .../tradeEngine/trade/state/constants.js | 0 .../tradeEngine/trade/state/reducers/index.js | 52 ++ .../trade/state/reducers/index.spec.js | 2 +- .../tradeEngine/utils/cli.js | 10 +- .../tradeEngine/utils/sanitize.js | 4 +- .../tradeEngine => common}/utils/cliTools.js | 8 +- .../api => common/utils}/ticksService.js | 19 +- index.html | 9 +- package-lock.json | 484 ++++++++++++++---- package.json | 10 +- scratch/hooks/block.js | 78 +++ scratch/hooks/block_svg.js | 114 +++++ scratch/hooks/colours.js | 29 ++ scratch/hooks/data_category.js | 101 ++++ scratch/hooks/field_dropdown.js | 29 ++ scratch/hooks/field_image.js | 210 ++++++++ scratch/hooks/flyout_base.js | 49 ++ scratch/hooks/flyout_vertical.js | 106 ++++ scratch/hooks/gesture.js | 13 + scratch/hooks/icon.js | 34 ++ scratch/hooks/index.js | 13 + scratch/hooks/procedures.js | 137 +++++ scratch/hooks/toolbox.js | 113 ++++ scratch/hooks/variables.js | 35 ++ scratch/index.js | 133 +++-- scratch/relationChecker.js | 114 ----- scratch/sass/_blockly-toolbox.scss | 44 +- scratch/sass/_color.scss | 11 + scratch/shared.js | 448 ++++++++++++++++ scratch/utils.js | 15 +- src/.DS_Store | Bin 6148 -> 6148 bytes src/app.js | 8 +- src/app.jsx | 6 +- src/assets/sass/_bot.scss | 1 - src/components/bot.jsx | 15 +- src/components/workspace.jsx | 11 + src/services/api/__tests__/activeSymbols.js | 7 +- src/services/api/__tests__/index.js | 6 +- src/services/api/__tests__/ticksService.js | 11 +- src/services/api/chartTicksService.js | 4 +- src/services/api/footer-checks.js | 2 +- src/services/api/networkMonitor.js | 2 + src/services/api/shared.js | 14 +- src/services/api/symbolApi/activeSymbols.js | 8 +- src/services/api/symbolApi/index.js | 14 +- src/services/tradeEngine/.DS_Store | Bin 6148 -> 0 bytes .../tradeEngine/trade/state/reducers/index.js | 52 -- src/stores/connect.js | 2 +- src/utils/.DS_Store | Bin 6148 -> 0 bytes webpack.config.js | 26 +- 103 files changed, 2565 insertions(+), 539 deletions(-) rename {src/utils => common}/__tests__/constants.js (84%) rename {src/services/api => common}/appId.js (89%) rename {src/services/api => common}/appIdResolver.js (100%) rename {src/services/tradeEngine/utils => common}/broadcast.js (84%) rename src/constants/const.js => common/constants.js (92%) rename {src/utils => common}/error.js (100%) create mode 100644 common/helpers.js rename {src/utils/customerSupport => common/integrations}/elevio.js (92%) rename {src/utils => common}/integrations/googleDrive.js (97%) rename {src/utils => common/integrations}/gtm.js (90%) rename src/services/tradeEngine/utils/Interpreter.js => common/interpreter.js (96%) rename {src/utils => common/lang}/__tests__/i18n.js (99%) rename {src/utils => common}/lang/i18n.js (64%) rename {src/utils => common}/lang/lang.js (85%) rename {src/utils => common}/observer.js (99%) rename {src/utils => common}/storageManager.js (100%) rename src/services/tradeEngine/utils/helpers.js => common/tools.js (92%) rename {src/services => common}/tradeEngine/Interface/CandleInterface.js (100%) rename {src/services => common}/tradeEngine/Interface/IndicatorsInterface.js (99%) rename {src/services => common}/tradeEngine/Interface/MiscInterface.js (85%) rename {src/services => common}/tradeEngine/Interface/TicksInterface.js (100%) rename {src/services => common}/tradeEngine/Interface/ToolsInterface.js (100%) rename {src/services => common}/tradeEngine/Interface/index.js (92%) rename {src/services => common}/tradeEngine/__tests__/BotApi.js (91%) rename {src/services => common}/tradeEngine/__tests__/Core.js (100%) rename {src/services => common}/tradeEngine/__tests__/StopStart.js (85%) rename {src/services => common}/tradeEngine/__tests__/UI.js (100%) rename {src/services => common}/tradeEngine/__tests__/block-tests/After.js (100%) rename {src/services => common}/tradeEngine/__tests__/block-tests/Before.js (100%) rename {src/services => common}/tradeEngine/__tests__/block-tests/During.js (100%) rename {src/services => common}/tradeEngine/__tests__/block-tests/Ticks.js (100%) rename {src/services => common}/tradeEngine/__tests__/block-tests/indicators.js (98%) rename {src/services => common}/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js (100%) rename {src/services => common}/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js (100%) rename {src/services => common}/tradeEngine/__tests__/block-tests/tools-test/Candles.js (100%) rename {src/services => common}/tradeEngine/__tests__/block-tests/tools-test/Misc.js (87%) rename {src/services => common}/tradeEngine/__tests__/block-tests/tools-test/Time.js (100%) rename {src/services => common}/tradeEngine/__tests__/jsi.js (82%) rename {src/services => common}/tradeEngine/__tests__/shouldRestartOnError.js (100%) rename {src/services => common}/tradeEngine/__tests__/stages.js (100%) rename {src/services => common}/tradeEngine/__tests__/tools.js (96%) rename {src/services => common}/tradeEngine/trade/Balance.js (92%) rename {src/services => common}/tradeEngine/trade/OpenContract.js (94%) rename {src/services => common}/tradeEngine/trade/Proposal.js (96%) rename {src/services => common}/tradeEngine/trade/Purchase.js (89%) rename {src/services => common}/tradeEngine/trade/Sell.js (87%) rename {src/services => common}/tradeEngine/trade/Ticks.js (89%) rename {src/services => common}/tradeEngine/trade/Total.js (92%) rename {src/services => common}/tradeEngine/trade/index.js (75%) rename {src/services => common}/tradeEngine/trade/state/actions/index.js (100%) rename {src/services => common}/tradeEngine/trade/state/actions/index.spec.js (99%) rename {src/services => common}/tradeEngine/trade/state/constants.js (100%) create mode 100644 common/tradeEngine/trade/state/reducers/index.js rename {src/services => common}/tradeEngine/trade/state/reducers/index.spec.js (98%) rename {src/services => common}/tradeEngine/utils/cli.js (77%) rename {src/services => common}/tradeEngine/utils/sanitize.js (95%) rename {src/services/tradeEngine => common}/utils/cliTools.js (54%) rename {src/services/api => common/utils}/ticksService.js (96%) create mode 100644 scratch/hooks/block.js create mode 100644 scratch/hooks/block_svg.js create mode 100644 scratch/hooks/colours.js create mode 100644 scratch/hooks/data_category.js create mode 100644 scratch/hooks/field_dropdown.js create mode 100644 scratch/hooks/field_image.js create mode 100644 scratch/hooks/flyout_base.js create mode 100644 scratch/hooks/flyout_vertical.js create mode 100644 scratch/hooks/gesture.js create mode 100644 scratch/hooks/icon.js create mode 100644 scratch/hooks/index.js create mode 100644 scratch/hooks/procedures.js create mode 100644 scratch/hooks/toolbox.js create mode 100644 scratch/hooks/variables.js delete mode 100644 scratch/relationChecker.js create mode 100644 scratch/sass/_color.scss create mode 100644 scratch/shared.js create mode 100644 src/components/workspace.jsx delete mode 100644 src/services/tradeEngine/.DS_Store delete mode 100644 src/services/tradeEngine/trade/state/reducers/index.js delete mode 100644 src/utils/.DS_Store diff --git a/.babelrc b/.babelrc index 4f1c7815..182428a6 100644 --- a/.babelrc +++ b/.babelrc @@ -1,13 +1,29 @@ { - "presets": [ - ["@babel/preset-env", { - "modules": false - }], - "@babel/preset-react" - ], - "plugins": [ - ["@babel/plugin-proposal-decorators", { "legacy": true }], - ["@babel/plugin-syntax-dynamic-import"], - ["@babel/plugin-proposal-class-properties", { "loose" : true }], - ] -} + "presets": [ + "@babel/preset-react", + [ + "@babel/preset-env", + { + "targets": { + "browsers": [ + "last 2 versions", + "ios_saf >= 8", + "not IE <= 10", + "chrome >= 49", + "firefox >= 49", + "> 1%" + ] + }, + "loose": true, + "useBuiltIns": "usage", + "corejs": "2.6.5", + } + ] + ], + "plugins": [ + ["@babel/plugin-proposal-decorators", { "legacy": true }], + ["@babel/plugin-syntax-dynamic-import"], + ["@babel/plugin-proposal-object-rest-spread", { "useBuiltIns": "usage", "corejs": "2.6.5" }], + ["@babel/plugin-proposal-class-properties", { "useBuiltIns": "usage", "corejs": "2.6.5", "loose": true }] + ] +} \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 7e5186dc..74c6721a 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -6,12 +6,16 @@ module.exports = { amd : true, jquery : true, jest : true, + jasmine: true, }, globals: { Blockly: false, trackJs: false, jest: false, - dataLayer: false + dataLayer: false, + goog: false, + google: false, + gapi: false, }, rules: { camelcase : 0, diff --git a/src/utils/__tests__/constants.js b/common/__tests__/constants.js similarity index 84% rename from src/utils/__tests__/constants.js rename to common/__tests__/constants.js index 4d27cbb9..fd803068 100644 --- a/src/utils/__tests__/constants.js +++ b/common/__tests__/constants.js @@ -1,4 +1,4 @@ -import config, { updateConfigCurrencies } from '../const'; +import config, { updateConfigCurrencies } from '../constants'; describe('Configured currencies', () => { let configuration; diff --git a/src/services/api/appId.js b/common/appId.js similarity index 89% rename from src/services/api/appId.js rename to common/appId.js index 62fd341c..57daa7b8 100644 --- a/src/services/api/appId.js +++ b/common/appId.js @@ -1,4 +1,9 @@ -import { LiveApi } from 'binary-live-api'; +import { LiveApi } from 'binary-live-api'; +import AppIdMap from './appIdResolver'; +import { parseQueryString, isProduction, getExtension } from './helpers'; +import Elevio from './integrations/elevio'; +import GTM from './integrations/gtm'; +import { getLanguage } from './lang/lang'; import { addToken, removeToken, @@ -6,12 +11,7 @@ import { removeAllTokens, get as getStorage, set as setStorage, -} from '../common/utils/storageManager'; -import { parseQueryString, isProduction, getExtension } from '../common/utils/tools'; -import { getLanguage } from '../common/lang/lang'; -import AppIdMap from './appIdResolver'; -import Elevio from './elevio'; -import GTM from '../common/utils/gtm'; +} from './storageManager'; export const AppConstants = Object.freeze({ STORAGE_ACTIVE_TOKEN: 'activeToken', diff --git a/src/services/api/appIdResolver.js b/common/appIdResolver.js similarity index 100% rename from src/services/api/appIdResolver.js rename to common/appIdResolver.js diff --git a/src/services/tradeEngine/utils/broadcast.js b/common/broadcast.js similarity index 84% rename from src/services/tradeEngine/utils/broadcast.js rename to common/broadcast.js index 4c9a236a..ed61c5bb 100644 --- a/src/services/tradeEngine/utils/broadcast.js +++ b/common/broadcast.js @@ -1,4 +1,4 @@ -import { observer as globalObserver } from '../../common/utils/observer'; +import { observer as globalObserver } from './observer'; export const contract = c => globalObserver.emit('bot.contract', c); diff --git a/src/constants/const.js b/common/constants.js similarity index 92% rename from src/constants/const.js rename to common/constants.js index 844e3fa3..49aed47a 100644 --- a/src/constants/const.js +++ b/common/constants.js @@ -1,6 +1,5 @@ -import { translate } from '../../common/i18n'; -import { generateLiveApiInstance } from '../../common/appId'; -import { load as loadLang } from '../../common/lang'; +import { translate } from './lang/i18n'; +import { load as loadLang } from './lang/lang'; loadLang(); @@ -150,7 +149,7 @@ const config = { }, ], }, - barrierTypes: [['Offset +', '+'], ['Offset -', '-']], + barrierTypes: [['Offset\u00A0+', '+'], ['Offset\u00A0-', '-']], ohlcFields : [ [translate('Open'), 'open'], [translate('High'), 'high'], @@ -173,7 +172,7 @@ const config = { [translate('8 hours'), '28800'], [translate('1 day'), '86400'], ], - mainBlocks : ['trade', 'before_purchase', 'after_purchase', 'during_purchase'], + mainBlocks : ['trade_definition', 'before_purchase', 'after_purchase', 'during_purchase'], conditionsCategory: { callput : ['risefall', 'higherlower'], callputequal: ['risefallequals'], @@ -237,13 +236,8 @@ const config = { }; export async function updateConfigCurrencies() { - const api = generateLiveApiInstance(); - try { - const response = await api.getPayoutCurrencies(); - config.lists.CURRENCY = response.payout_currencies.map(c => [c, c]); - } catch (e) { - config.lists.CURRENCY = ['USD', 'EUR', 'GBP', 'AUD', ...CRYPTO_CURRENCIES].map(c => [c, c]); - } + // TODO: Retrieve currencies from API + config.lists.CURRENCY = ['USD', 'EUR', 'GBP', 'AUD', ...CRYPTO_CURRENCIES].map(c => [c, c]); } export default config; diff --git a/src/utils/error.js b/common/error.js similarity index 100% rename from src/utils/error.js rename to common/error.js diff --git a/common/helpers.js b/common/helpers.js new file mode 100644 index 00000000..8ccca388 --- /dev/null +++ b/common/helpers.js @@ -0,0 +1,121 @@ +import RenderHTML from 'react-render-html'; +import AppIdMap from './appIdResolver'; +import { getLanguage } from './lang/lang'; +import { translate as i18nTranslate } from './lang/i18n'; +import { observer as globalObserver } from './observer'; + +export const parseQueryString = () => { + if (typeof window === 'undefined') { + return {}; + } + const str = window.location.search; + const objURL = {}; + str.replace(new RegExp('([^?=&]+)(=([^&]*))?', 'g'), (a0, a1, a2, a3) => { + objURL[a1] = a3; + }); + return objURL; +}; + +export const getObjectValue = obj => obj[Object.keys(obj)[0]]; + +export const getUTCTime = date => { + const dateObject = new Date(date); + return `${`0${dateObject.getUTCHours()}`.slice(-2)}:${`0${dateObject.getUTCMinutes()}`.slice( + -2 + )}:${`0${dateObject.getUTCSeconds()}`.slice(-2)}`; +}; + +export const durationToSecond = duration => { + const parsedDuration = duration.match(/^([0-9]+)([stmhd])$/); + if (!parsedDuration) { + return 0; + } + const durationValue = parseFloat(parsedDuration[1]); + const durationType = parsedDuration[2]; + if (durationType === 's') { + return durationValue; + } + if (durationType === 't') { + return durationValue * 2; + } + if (durationType === 'm') { + return durationValue * 60; + } + if (durationType === 'h') { + return durationValue * 60 * 60; + } + if (durationType === 'd') { + return durationValue * 60 * 60 * 24; + } + return 0; +}; + +export const isProduction = () => document.location.hostname.replace(/^www./, '') in AppIdMap; + +export const createUrl = options => { + const getOption = property => Object.prototype.hasOwnProperty.call(options, property) && options[property]; + const language = getOption('addLanguage') ? `/${getLanguage()}` : ''; + const path = getOption('path') ? `/${getOption('path')}` : ''; + const htmlExtension = getOption('addHtmlExtension') ? '.html' : ''; + const subdomain = getOption('subdomain') ? `${getOption('subdomain')}.` : 'www.'; + if (isProduction()) { + let domainExtension = `.${getExtension()}`; + if (getOption('isNonBotPage')) { + switch (document.location.hostname.replace(/^www./, '')) { + case 'bot.binary.me': + case 'binary.bot': + domainExtension = '.me'; + break; + default: + domainExtension = '.com'; + break; + } + } + return `${document.location.protocol}//${subdomain}binary${domainExtension}${language}${path}${htmlExtension}`; + } + return `https://${subdomain}binary.com${language}${path}${htmlExtension}`; +}; + +export const translate = input => { + if (Array.isArray(input) && input.length > 0) { + const stringToBeTranslated = input[0].replace(/\[_([0-9])\]/g, '%$1'); + let translatedString = i18nTranslate(stringToBeTranslated); + + input.slice(1).forEach((replacement, index) => { + const regex = new RegExp(`%${index + 1}`, 'g'); + translatedString = translatedString.replace(regex, replacement); + }); + return RenderHTML(translatedString); + } + return i18nTranslate(input); +}; + +export const getExtension = () => { + const host = document.location.hostname; + const extension = host.split('.').slice(-1)[0]; + return host !== extension ? extension : ''; +}; + +export const showSpinnerInButton = $buttonElement => { + $buttonElement + .html(() => { + const barspinner = $('
'); + Array.from(new Array(5)).forEach((x, i) => { + const rect = $(`
`); + barspinner.append(rect); + }); + return barspinner; + }) + .prop('disabled', true); +}; + +export const removeSpinnerInButton = ($buttonElement, initialText) => { + $buttonElement.html(() => initialText).prop('disabled', false); +}; + +export const trackAndEmitError = (message, object = {}) => { + globalObserver.emit('ui.log.error', message); + if (window.trackJs) { + trackJs.track(`${message} - Error: ${JSON.stringify(object)}`); + } +}; diff --git a/src/utils/customerSupport/elevio.js b/common/integrations/elevio.js similarity index 92% rename from src/utils/customerSupport/elevio.js rename to common/integrations/elevio.js index 0035d2ff..c76baf6f 100644 --- a/src/utils/customerSupport/elevio.js +++ b/common/integrations/elevio.js @@ -1,8 +1,7 @@ -import { generateLiveApiInstance } from './appId'; -// import { getLanguage } from '../common/lang'; -import { getTokenList } from './utils/storageManager'; -import { translate } from '../common/i18n'; -import { getLanguage } from './lang'; +import { generateLiveApiInstance } from '../appId'; +import { translate } from '../lang/i18n'; +import { getLanguage } from '../lang/lang'; +import { getTokenList } from '../storageManager'; const Elevio = (() => { const init = () => { diff --git a/src/utils/integrations/googleDrive.js b/common/integrations/googleDrive.js similarity index 97% rename from src/utils/integrations/googleDrive.js rename to common/integrations/googleDrive.js index 1cdb4e61..36421a81 100644 --- a/src/utils/integrations/googleDrive.js +++ b/common/integrations/googleDrive.js @@ -1,9 +1,8 @@ -/* global google,gapi */ -import { getLanguage } from '../lang'; -import { observer as globalObserver } from '../utils/observer'; -import { translate, trackAndEmitError } from '../utils/tools'; -import { loadWorkspace, loadBlocks } from '../../botPage/view/blockly'; -import config from '../../botPage/common/const'; +import config from '../constants'; +import { translate, trackAndEmitError } from '../helpers'; +import { getLanguage } from '../lang/lang'; +import { observer as globalObserver } from '../observer'; +import { loadWorkspace, loadBlocks } from '../../scratch'; class GoogleDrive { constructor() { diff --git a/src/utils/gtm.js b/common/integrations/gtm.js similarity index 90% rename from src/utils/gtm.js rename to common/integrations/gtm.js index 418b8071..9654621f 100644 --- a/src/utils/gtm.js +++ b/common/integrations/gtm.js @@ -1,6 +1,6 @@ -import { getAppIdFallback } from '../../binaryApi/appId'; -import AppIdMap from '../../binaryApi/appIdResolver'; -import { getTokenList } from './storageManager'; +import { getAppIdFallback } from '../appId'; +import AppIdMap from '../appIdResolver'; +import { getTokenList } from '../storageManager'; const GTM = (() => { const isGtmApplicable = () => Object.values(AppIdMap).includes(`${getAppIdFallback()}`); diff --git a/src/services/tradeEngine/utils/Interpreter.js b/common/interpreter.js similarity index 96% rename from src/services/tradeEngine/utils/Interpreter.js rename to common/interpreter.js index 57854d44..81821d21 100644 --- a/src/services/tradeEngine/utils/Interpreter.js +++ b/common/interpreter.js @@ -1,7 +1,7 @@ -import JSInterpreter from 'js-interpreter'; -import { observer as globalObserver } from '../../common/utils/observer'; -import { createScope } from './CliTools'; -import Interface from './Interface'; +import JSInterpreter from 'js-interpreter'; +import { observer as globalObserver } from './observer'; +import { createScope } from './utils/cliTools'; +import Interface from './tradeEngine/Interface'; const unrecoverableErrors = [ 'InsufficientBalance', @@ -32,6 +32,7 @@ export default class Interpreter { constructor() { this.init(); } + init() { this.$scope = createScope(); this.bot = new Interface(this.$scope); @@ -40,6 +41,7 @@ export default class Interpreter { this.revert(watchName === 'before' ? this.beforeState : this.duringState) ); } + run(code) { const initFunc = (interpreter, scope) => { const BotIf = this.bot.getInterface('Bot'); @@ -135,23 +137,27 @@ export default class Interpreter { this.loop(); }); } + loop() { if (this.stopped || !this.interpreter.run()) { this.isErrorTriggered = false; this.onFinish(this.interpreter.pseudoToNative(this.interpreter.value)); } } + revert(state) { this.interpreter.restoreStateSnapshot(state); // eslint-disable-next-line no-underscore-dangle this.interpreter.paused_ = false; this.loop(); } + terminateSession() { this.$scope.api.disconnect(); globalObserver.emit('bot.stop'); this.stopped = true; } + stop() { if (this.bot.tradeEngine.isSold === false && !this.isErrorTriggered) { globalObserver.register('contract.status', contractStatus => { @@ -164,6 +170,7 @@ export default class Interpreter { this.terminateSession(); } } + createAsync(interpreter, func) { return interpreter.createAsyncFunction((...args) => { const callback = args.pop(); @@ -176,6 +183,7 @@ export default class Interpreter { .catch(e => this.$scope.observer.emit('Error', e)); }); } + hasStarted() { return !this.stopped; } diff --git a/src/utils/__tests__/i18n.js b/common/lang/__tests__/i18n.js similarity index 99% rename from src/utils/__tests__/i18n.js rename to common/lang/__tests__/i18n.js index 1e331eeb..df04fac9 100644 --- a/src/utils/__tests__/i18n.js +++ b/common/lang/__tests__/i18n.js @@ -6,12 +6,15 @@ class Xml { this.el = el; this.children = children; } + setAttribute(key, value) { this.el[key] = value; } + getAttribute(key) { return this.el[key]; } + getElementsByTagName(key) { return this.children[key]; } diff --git a/src/utils/lang/i18n.js b/common/lang/i18n.js similarity index 64% rename from src/utils/lang/i18n.js rename to common/lang/i18n.js index af02af8f..c011169a 100644 --- a/src/utils/lang/i18n.js +++ b/common/lang/i18n.js @@ -1,17 +1,17 @@ import sha1 from 'sha1'; -import zhTw from './translations/zh_TW/i10n.json'; -import de from './translations/de_DE/i10n.json'; -import id from './translations/id_ID/i10n.json'; -import zhCn from './translations/zh_CN/i10n.json'; -import it from './translations/it_IT/i10n.json'; -import vi from './translations/vi_VN/i10n.json'; -import pl from './translations/pl_PL/i10n.json'; -import ru from './translations/ru_RU/i10n.json'; -import pt from './translations/pt_PT/i10n.json'; -import es from './translations/es_ES/i10n.json'; -import fr from './translations/fr_FR/i10n.json'; -import en from './translations/en/i10n.json'; -import ach from './translations/ach_UG/i10n.json'; +import ach from '../../translations/ach_UG/i10n.json'; +import de from '../../translations/de_DE/i10n.json'; +import en from '../../translations/en/i10n.json'; +import es from '../../translations/es_ES/i10n.json'; +import fr from '../../translations/fr_FR/i10n.json'; +import id from '../../translations/id_ID/i10n.json'; +import it from '../../translations/it_IT/i10n.json'; +import pl from '../../translations/pl_PL/i10n.json'; +import pt from '../../translations/pt_PT/i10n.json'; +import ru from '../../translations/ru_RU/i10n.json'; +import vi from '../../translations/vi_VN/i10n.json'; +import zhCn from '../../translations/zh_CN/i10n.json'; +import zhTw from '../../translations/zh_TW/i10n.json'; export const supportedLanguages = { zh_tw: zhTw, diff --git a/src/utils/lang/lang.js b/common/lang/lang.js similarity index 85% rename from src/utils/lang/lang.js rename to common/lang/lang.js index 3072c093..cc5bc3c6 100644 --- a/src/utils/lang/lang.js +++ b/common/lang/lang.js @@ -1,6 +1,6 @@ -import { parseQueryString } from '../common/utils/tools'; -import { set as setStorage, get as getStorage } from '../utils/storageManager'; -import { supportedLanguages, translate, init } from './i18n'; +import { supportedLanguages, translate, init } from './i18n'; +import { parseQueryString } from '../helpers'; +import { set as setStorage, get as getStorage } from '../storageManager'; export const getLanguage = () => { const queryLang = parseQueryString().l; @@ -9,6 +9,7 @@ export const getLanguage = () => { return lang; }; +/* eslint-disable */ const addUiLang = () => { $('[data-i18n-text]').each(function each() { const el = $(this); diff --git a/src/utils/observer.js b/common/observer.js similarity index 99% rename from src/utils/observer.js rename to common/observer.js index 9fded664..f24ce51b 100644 --- a/src/utils/observer.js +++ b/common/observer.js @@ -4,6 +4,7 @@ export default class Observer { constructor() { this.eam = new Map(); // event action map } + register(event, _action, once, unregisterIfError, unregisterAllBefore) { if (unregisterAllBefore) { this.unregisterAll(event); @@ -39,15 +40,19 @@ export default class Observer { ? this.eam.set(event, actionList.push({ action, searchBy: _action })) : this.eam.set(event, new List().push({ action, searchBy: _action })); } + unregister(event, f) { this.eam = this.eam.set(event, this.eam.get(event).filter(r => r.searchBy !== f)); } + isRegistered(event) { return this.eam.has(event); } + unregisterAll(event) { this.eam = this.eam.delete(event); } + emit(event, data) { if (this.eam.has(event)) { this.eam.get(event).forEach(action => action.action(data)); diff --git a/src/utils/storageManager.js b/common/storageManager.js similarity index 100% rename from src/utils/storageManager.js rename to common/storageManager.js diff --git a/src/services/tradeEngine/utils/helpers.js b/common/tools.js similarity index 92% rename from src/services/tradeEngine/utils/helpers.js rename to common/tools.js index 72753e8b..ad8959f9 100644 --- a/src/services/tradeEngine/utils/helpers.js +++ b/common/tools.js @@ -1,11 +1,19 @@ -import { getUTCTime } from '../../common/utils/tools'; -import { translate } from '../../common/i18n'; -import { roundBalance } from '../../common/utils/tools'; -import { notify } from './broadcast'; -import config from '../constants/const'; +import { notify } from './broadcast'; +import config from './constants'; +import { getUTCTime } from './helpers'; +import { translate } from './lang/i18n'; export const noop = () => {}; +export const roundBalance = ({ currency, balance }) => { + const point = config.lists.CRYPTO_CURRENCIES.includes(currency) ? 8 : 2; + return Number(balance).toFixed(point); +}; + +const hasOwnProperty = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop); + +export const isVirtual = tokenInfo => hasOwnProperty(tokenInfo, 'loginInfo') && tokenInfo.loginInfo.is_virtual; + export const tradeOptionToProposal = tradeOption => tradeOption.contractTypes.map(type => { const proposal = { @@ -201,8 +209,3 @@ export const showDialog = options => $dialog.dialog(dialogOptions); $dialog.dialog('open'); }); - - export const roundBalance = ({ currency, balance }) => { - const point = config.lists.CRYPTO_CURRENCIES.includes(currency) ? 8 : 2; - return Number(balance).toFixed(point); - }; \ No newline at end of file diff --git a/src/services/tradeEngine/Interface/CandleInterface.js b/common/tradeEngine/Interface/CandleInterface.js similarity index 100% rename from src/services/tradeEngine/Interface/CandleInterface.js rename to common/tradeEngine/Interface/CandleInterface.js diff --git a/src/services/tradeEngine/Interface/IndicatorsInterface.js b/common/tradeEngine/Interface/IndicatorsInterface.js similarity index 99% rename from src/services/tradeEngine/Interface/IndicatorsInterface.js rename to common/tradeEngine/Interface/IndicatorsInterface.js index 40fb1d8c..363ca4f7 100644 --- a/src/services/tradeEngine/Interface/IndicatorsInterface.js +++ b/common/tradeEngine/Interface/IndicatorsInterface.js @@ -19,6 +19,7 @@ export default Interface => macda: (input, config, field) => this.decorate(macda, input, config).map(r => r[field]), }; } + decorate(f, input, config, ...args) { const pipSize = this.tradeEngine.getPipSize(); diff --git a/src/services/tradeEngine/Interface/MiscInterface.js b/common/tradeEngine/Interface/MiscInterface.js similarity index 85% rename from src/services/tradeEngine/Interface/MiscInterface.js rename to common/tradeEngine/Interface/MiscInterface.js index 7182a3da..c41da9b4 100644 --- a/src/services/tradeEngine/Interface/MiscInterface.js +++ b/common/tradeEngine/Interface/MiscInterface.js @@ -1,4 +1,4 @@ -import { observer as globalObserver } from '../../../common/utils/observer'; +import { observer as globalObserver } from '../../observer'; export default Interface => class extends Interface { diff --git a/src/services/tradeEngine/Interface/TicksInterface.js b/common/tradeEngine/Interface/TicksInterface.js similarity index 100% rename from src/services/tradeEngine/Interface/TicksInterface.js rename to common/tradeEngine/Interface/TicksInterface.js diff --git a/src/services/tradeEngine/Interface/ToolsInterface.js b/common/tradeEngine/Interface/ToolsInterface.js similarity index 100% rename from src/services/tradeEngine/Interface/ToolsInterface.js rename to common/tradeEngine/Interface/ToolsInterface.js diff --git a/src/services/tradeEngine/Interface/index.js b/common/tradeEngine/Interface/index.js similarity index 92% rename from src/services/tradeEngine/Interface/index.js rename to common/tradeEngine/Interface/index.js index 2ba66eae..20ae7200 100644 --- a/src/services/tradeEngine/Interface/index.js +++ b/common/tradeEngine/Interface/index.js @@ -1,7 +1,7 @@ -import TradeEngine from '../TradeEngine'; -import { noop, createDetails } from '../helpers'; -import TicksInterface from './TicksInterface'; -import ToolsInterface from './ToolsInterface'; +import TicksInterface from './TicksInterface'; +import ToolsInterface from './ToolsInterface'; +import TradeEngine from '../trade'; +import { noop, createDetails } from '../../tools'; /** * Bot - Bot Module @@ -16,6 +16,7 @@ export default class Interface extends ToolsInterface(TicksInterface(class {})) this.observer = $scope.observer; this.$scope = $scope; } + getInterface(name = 'Global') { if (name === 'Bot') { return { @@ -36,6 +37,7 @@ export default class Interface extends ToolsInterface(TicksInterface(class {})) }, }; } + getBotInterface() { const getDetail = i => createDetails(this.get('contract'))[i]; @@ -53,6 +55,7 @@ export default class Interface extends ToolsInterface(TicksInterface(class {})) readDetails : i => getDetail(i - 1), }; } + sleep(arg = 1) { return new Promise( r => @@ -63,6 +66,7 @@ export default class Interface extends ToolsInterface(TicksInterface(class {})) noop ); } + getProposal(contractType) { const proposals = this.get('proposals'); @@ -76,9 +80,11 @@ export default class Interface extends ToolsInterface(TicksInterface(class {})) return proposal; } + getSellPrice() { return this.tradeEngine.getSellPrice(); } + get(key) { return this.tradeEngine.getData().get(key); } diff --git a/src/services/tradeEngine/__tests__/BotApi.js b/common/tradeEngine/__tests__/BotApi.js similarity index 91% rename from src/services/tradeEngine/__tests__/BotApi.js rename to common/tradeEngine/__tests__/BotApi.js index dab0901c..a27f34f2 100644 --- a/src/services/tradeEngine/__tests__/BotApi.js +++ b/common/tradeEngine/__tests__/BotApi.js @@ -1,6 +1,6 @@ -import { expect } from 'chai'; -import Interface from '../Interface'; -import { createScope } from '../CliTools'; +import { expect } from 'chai'; +import Interface from '../Interface'; +import { createScope } from '../../utils/cliTools'; const $scope = createScope(); diff --git a/src/services/tradeEngine/__tests__/Core.js b/common/tradeEngine/__tests__/Core.js similarity index 100% rename from src/services/tradeEngine/__tests__/Core.js rename to common/tradeEngine/__tests__/Core.js diff --git a/src/services/tradeEngine/__tests__/StopStart.js b/common/tradeEngine/__tests__/StopStart.js similarity index 85% rename from src/services/tradeEngine/__tests__/StopStart.js rename to common/tradeEngine/__tests__/StopStart.js index 2cc25835..dba105d0 100644 --- a/src/services/tradeEngine/__tests__/StopStart.js +++ b/common/tradeEngine/__tests__/StopStart.js @@ -1,6 +1,6 @@ -import { expect } from 'chai'; -import { createInterpreter } from '../CliTools'; -import { parts } from './tools'; +import { expect } from 'chai'; +import { parts } from './tools'; +import { createInterpreter } from '../../utils/cliTools'; describe('Run Interpreter over bot', () => { let value; diff --git a/src/services/tradeEngine/__tests__/UI.js b/common/tradeEngine/__tests__/UI.js similarity index 100% rename from src/services/tradeEngine/__tests__/UI.js rename to common/tradeEngine/__tests__/UI.js diff --git a/src/services/tradeEngine/__tests__/block-tests/After.js b/common/tradeEngine/__tests__/block-tests/After.js similarity index 100% rename from src/services/tradeEngine/__tests__/block-tests/After.js rename to common/tradeEngine/__tests__/block-tests/After.js diff --git a/src/services/tradeEngine/__tests__/block-tests/Before.js b/common/tradeEngine/__tests__/block-tests/Before.js similarity index 100% rename from src/services/tradeEngine/__tests__/block-tests/Before.js rename to common/tradeEngine/__tests__/block-tests/Before.js diff --git a/src/services/tradeEngine/__tests__/block-tests/During.js b/common/tradeEngine/__tests__/block-tests/During.js similarity index 100% rename from src/services/tradeEngine/__tests__/block-tests/During.js rename to common/tradeEngine/__tests__/block-tests/During.js diff --git a/src/services/tradeEngine/__tests__/block-tests/Ticks.js b/common/tradeEngine/__tests__/block-tests/Ticks.js similarity index 100% rename from src/services/tradeEngine/__tests__/block-tests/Ticks.js rename to common/tradeEngine/__tests__/block-tests/Ticks.js diff --git a/src/services/tradeEngine/__tests__/block-tests/indicators.js b/common/tradeEngine/__tests__/block-tests/indicators.js similarity index 98% rename from src/services/tradeEngine/__tests__/block-tests/indicators.js rename to common/tradeEngine/__tests__/block-tests/indicators.js index e766decf..bc6bd5f1 100644 --- a/src/services/tradeEngine/__tests__/block-tests/indicators.js +++ b/common/tradeEngine/__tests__/block-tests/indicators.js @@ -42,8 +42,8 @@ const getIndicatorsFromApi = () => ); describe('Relative Strength Index', () => { - let result; - let expected; + let result, + expected; beforeAll(done => getIndicatorsFromApi().then(r => { diff --git a/src/services/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js b/common/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js similarity index 100% rename from src/services/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js rename to common/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js diff --git a/src/services/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js b/common/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js similarity index 100% rename from src/services/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js rename to common/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js diff --git a/src/services/tradeEngine/__tests__/block-tests/tools-test/Candles.js b/common/tradeEngine/__tests__/block-tests/tools-test/Candles.js similarity index 100% rename from src/services/tradeEngine/__tests__/block-tests/tools-test/Candles.js rename to common/tradeEngine/__tests__/block-tests/tools-test/Candles.js diff --git a/src/services/tradeEngine/__tests__/block-tests/tools-test/Misc.js b/common/tradeEngine/__tests__/block-tests/tools-test/Misc.js similarity index 87% rename from src/services/tradeEngine/__tests__/block-tests/tools-test/Misc.js rename to common/tradeEngine/__tests__/block-tests/tools-test/Misc.js index 5e74115f..03f0e30d 100644 --- a/src/services/tradeEngine/__tests__/block-tests/tools-test/Misc.js +++ b/common/tradeEngine/__tests__/block-tests/tools-test/Misc.js @@ -1,6 +1,6 @@ -import { expect } from 'chai'; -import { observer as globalObserver } from '../../../../../common/utils/observer'; -import { runAndGetResult } from '../../tools'; +import { expect } from 'chai'; +import { runAndGetResult } from '../../tools'; +import { observer as globalObserver } from '../../../../observer'; describe('Misc. tools', () => { let result; diff --git a/src/services/tradeEngine/__tests__/block-tests/tools-test/Time.js b/common/tradeEngine/__tests__/block-tests/tools-test/Time.js similarity index 100% rename from src/services/tradeEngine/__tests__/block-tests/tools-test/Time.js rename to common/tradeEngine/__tests__/block-tests/tools-test/Time.js diff --git a/src/services/tradeEngine/__tests__/jsi.js b/common/tradeEngine/__tests__/jsi.js similarity index 82% rename from src/services/tradeEngine/__tests__/jsi.js rename to common/tradeEngine/__tests__/jsi.js index 6e113caf..b14c31e3 100644 --- a/src/services/tradeEngine/__tests__/jsi.js +++ b/common/tradeEngine/__tests__/jsi.js @@ -1,5 +1,5 @@ -import { expect } from 'chai'; -import Interpreter from '../utils/Interpreter'; +import { expect } from 'chai'; +import Interpreter from '../../interpreter'; const interpreter = new Interpreter(); diff --git a/src/services/tradeEngine/__tests__/shouldRestartOnError.js b/common/tradeEngine/__tests__/shouldRestartOnError.js similarity index 100% rename from src/services/tradeEngine/__tests__/shouldRestartOnError.js rename to common/tradeEngine/__tests__/shouldRestartOnError.js diff --git a/src/services/tradeEngine/__tests__/stages.js b/common/tradeEngine/__tests__/stages.js similarity index 100% rename from src/services/tradeEngine/__tests__/stages.js rename to common/tradeEngine/__tests__/stages.js diff --git a/src/services/tradeEngine/__tests__/tools.js b/common/tradeEngine/__tests__/tools.js similarity index 96% rename from src/services/tradeEngine/__tests__/tools.js rename to common/tradeEngine/__tests__/tools.js index 1999d2bd..fc2aa61d 100644 --- a/src/services/tradeEngine/__tests__/tools.js +++ b/common/tradeEngine/__tests__/tools.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { createInterpreter } from '../CliTools'; +import { createInterpreter } from '../../utils/cliTools'; export const init = options => ` Bot.init('Xkq6oGFEHh6hJH8', { diff --git a/src/services/tradeEngine/trade/Balance.js b/common/tradeEngine/trade/Balance.js similarity index 92% rename from src/services/tradeEngine/trade/Balance.js rename to common/tradeEngine/trade/Balance.js index 28cffd67..b94e56e4 100644 --- a/src/services/tradeEngine/trade/Balance.js +++ b/common/tradeEngine/trade/Balance.js @@ -1,5 +1,5 @@ -import { roundBalance } from '../../common/tools'; -import { info } from '../utils/broadcast'; +import { info } from '../../broadcast'; +import { roundBalance } from '../../tools'; let balanceStr = ''; @@ -17,6 +17,7 @@ export default Engine => info({ accountID: this.accountInfo.loginid, balance: balanceStr }); }); } + // eslint-disable-next-line class-methods-use-this getBalance(type) { const { scope } = this.store.getState(); diff --git a/src/services/tradeEngine/trade/OpenContract.js b/common/tradeEngine/trade/OpenContract.js similarity index 94% rename from src/services/tradeEngine/trade/OpenContract.js rename to common/tradeEngine/trade/OpenContract.js index 8098c6d6..354cfb26 100644 --- a/src/services/tradeEngine/trade/OpenContract.js +++ b/common/tradeEngine/trade/OpenContract.js @@ -1,7 +1,11 @@ -import { roundBalance } from '../../common/tools'; -import { doUntilDone } from '../helpers'; -import { contractStatus, contractSettled, contract as broadcastContract } from '../utils/broadcast'; import { sell, openContractReceived } from './state/actions'; +import { + contractStatus, + contractSettled, + contract as + broadcastContract, +} from '../../broadcast'; +import { doUntilDone, roundBalance } from '../../tools'; const AFTER_FINISH_TIMEOUT = 5; @@ -54,11 +58,13 @@ export default Engine => } }); } + waitForAfter() { return new Promise(resolve => { this.afterPromise = resolve; }); } + subscribeToOpenContract(contractId = this.contractId) { if (this.contractId !== contractId) { this.retriedUnsuccessfullSellExpired = false; @@ -74,6 +80,7 @@ export default Engine => } = r); }); } + resetSubscriptionTimeout(timeout = this.getContractDuration() + AFTER_FINISH_TIMEOUT) { this.cancelSubscriptionTimeout(); this.subscriptionTimeout = setInterval(() => { @@ -81,14 +88,17 @@ export default Engine => this.resetSubscriptionTimeout(timeout); }, timeout * 1000); } + cancelSubscriptionTimeout() { clearTimeout(this.subscriptionTimeout); } + unsubscribeOpenContract() { if (this.openContractId) { doUntilDone(() => this.api.unsubscribeByID(this.openContractId)); } } + setContractFlags(contract) { const { is_expired: isExpired, @@ -105,9 +115,11 @@ export default Engine => this.hasEntryTick = Boolean(entryTick); } + expectedContractId(contractId) { return this.contractId && contractId === this.contractId; } + getSellPrice() { const { bid_price: bidPrice, buy_price: buyPrice, currency } = this.data.get('contract'); return Number(roundBalance({ currency, balance: Number(bidPrice) - Number(buyPrice) })); diff --git a/src/services/tradeEngine/trade/Proposal.js b/common/tradeEngine/trade/Proposal.js similarity index 96% rename from src/services/tradeEngine/trade/Proposal.js rename to common/tradeEngine/trade/Proposal.js index 1f7dfe1f..feb1d227 100644 --- a/src/services/tradeEngine/trade/Proposal.js +++ b/common/tradeEngine/trade/Proposal.js @@ -1,6 +1,6 @@ -import { translate } from '../../../common/i18n'; -import { tradeOptionToProposal, doUntilDone, getUUID } from '../helpers'; -import { proposalsReady, clearProposals } from './state/actions'; +import { proposalsReady, clearProposals } from './state/actions'; +import { translate } from '../../lang/i18n'; +import { tradeOptionToProposal, doUntilDone, getUUID } from '../../tools'; export default Engine => class Proposal extends Engine { @@ -12,6 +12,7 @@ export default Engine => this.proposalTemplates = tradeOptionToProposal(tradeOption); this.renewProposalsOnPurchase(); } + selectProposal(contractType) { let toBuy; @@ -38,13 +39,16 @@ export default Engine => askPrice: toBuy.ask_price, }; } + renewProposalsOnPurchase() { this.unsubscribeProposals().then(() => this.requestProposals()); } + clearProposals() { this.data = this.data.set('proposals', new Map()); this.store.dispatch(clearProposals()); } + requestProposals() { this.proposalTemplates.map(proposal => doUntilDone(() => @@ -81,6 +85,7 @@ export default Engine => ) ); } + observeProposals() { this.listen('proposal', r => { const { proposal, passthrough } = r; @@ -95,6 +100,7 @@ export default Engine => } }); } + unsubscribeProposals() { const proposalObj = this.data.get('proposals'); @@ -121,6 +127,7 @@ export default Engine => }) ); } + checkProposalReady() { const proposals = this.data.get('proposals'); @@ -128,6 +135,7 @@ export default Engine => this.startPromise.then(() => this.store.dispatch(proposalsReady())); } } + isNewTradeOption(tradeOption) { if (!this.tradeOption) { this.tradeOption = tradeOption; diff --git a/src/services/tradeEngine/trade/Purchase.js b/common/tradeEngine/trade/Purchase.js similarity index 89% rename from src/services/tradeEngine/trade/Purchase.js rename to common/tradeEngine/trade/Purchase.js index 77a585c8..1b4fbc50 100644 --- a/src/services/tradeEngine/trade/Purchase.js +++ b/common/tradeEngine/trade/Purchase.js @@ -1,8 +1,8 @@ -import { translate } from '../../../common/i18n'; -import { recoverFromError, doUntilDone } from '../helpers'; -import { contractStatus, info, notify } from '../utils/broadcast'; -import { purchaseSuccessful } from './state/actions'; -import { BEFORE_PURCHASE } from './state/constants'; +import { purchaseSuccessful } from './state/actions'; +import { BEFORE_PURCHASE } from './state/constants'; +import { contractStatus, info, notify } from '../../broadcast'; +import { translate } from '../../lang/i18n'; +import { recoverFromError, doUntilDone } from '../../tools'; let delayIndex = 0; diff --git a/src/services/tradeEngine/trade/Sell.js b/common/tradeEngine/trade/Sell.js similarity index 87% rename from src/services/tradeEngine/trade/Sell.js rename to common/tradeEngine/trade/Sell.js index b68f3c82..7b781a20 100644 --- a/src/services/tradeEngine/trade/Sell.js +++ b/common/tradeEngine/trade/Sell.js @@ -1,7 +1,7 @@ -import { translate } from '../../../common/i18n'; -import { recoverFromError, doUntilDone } from '../helpers'; -import { contractStatus, notify } from '../utils/broadcast'; -import { DURING_PURCHASE } from './state/constants'; +import { DURING_PURCHASE } from './state/constants'; +import { contractStatus, notify } from '../../broadcast'; +import { translate } from '../../lang/i18n'; +import { recoverFromError, doUntilDone } from '../../tools'; let delayIndex = 0; @@ -10,6 +10,7 @@ export default Engine => isSellAtMarketAvailable() { return this.contractId && !this.isSold && this.isSellAvailable && !this.isExpired; } + sellAtMarket() { // Prevent calling sell twice if (this.store.getState().scope !== DURING_PURCHASE) { @@ -46,6 +47,7 @@ export default Engine => delayIndex++ ).then(onSuccess); } + sellExpired() { if (this.isSellAvailable && this.isExpired) { doUntilDone(() => this.api.sellExpiredContracts()); diff --git a/src/services/tradeEngine/trade/Ticks.js b/common/tradeEngine/trade/Ticks.js similarity index 89% rename from src/services/tradeEngine/trade/Ticks.js rename to common/tradeEngine/trade/Ticks.js index 9ce8b42c..dd51a0de 100644 --- a/src/services/tradeEngine/trade/Ticks.js +++ b/common/tradeEngine/trade/Ticks.js @@ -1,8 +1,8 @@ -import { getLast } from 'binary-utils'; -import { translate } from '../../../common/i18n'; -import { getDirection, getLastDigit } from '../helpers'; -import { expectPositiveInteger } from '../utils/sanitize'; -import * as constants from './state/constants'; +import { getLast } from 'binary-utils'; +import * as constants from './state/constants'; +import { expectPositiveInteger } from '../utils/sanitize'; +import { translate } from '../../lang/i18n'; +import { getDirection, getLastDigit } from '../../tools'; let tickListenerKey; @@ -31,6 +31,7 @@ export default Engine => tickListenerKey = key; } } + getTicks() { return new Promise(resolve => this.$scope.ticksService @@ -38,6 +39,7 @@ export default Engine => .then(ticks => resolve(ticks.map(o => o.quote))) ); } + getLastTick(raw) { return new Promise(resolve => this.$scope.ticksService @@ -45,16 +47,19 @@ export default Engine => .then(ticks => resolve(raw ? getLast(ticks) : getLast(ticks).quote)) ); } + getLastDigit() { return new Promise(resolve => this.getLastTick().then(tick => resolve(getLastDigit(tick, this.getPipSize()))) ); } + getLastDigitList() { return new Promise(resolve => this.getTicks().then(ticks => resolve(ticks.map(tick => getLastDigit(tick, this.getPipSize())))) ); } + checkDirection(dir) { return new Promise(resolve => this.$scope.ticksService @@ -62,6 +67,7 @@ export default Engine => .then(ticks => resolve(getDirection(ticks) === dir)) ); } + getOhlc(args) { const { granularity = this.options.candleInterval || 60, field } = args || {}; @@ -71,6 +77,7 @@ export default Engine => .then(ohlc => resolve(field ? ohlc.map(o => o[field]) : ohlc)) ); } + getOhlcFromEnd(args) { const { index: i = 1 } = args || {}; @@ -78,6 +85,7 @@ export default Engine => return new Promise(resolve => this.getOhlc(args).then(ohlc => resolve(ohlc.slice(-index)[0]))); } + getPipSize() { return this.$scope.ticksService.pipSizes[this.symbol]; } diff --git a/src/services/tradeEngine/trade/Total.js b/common/tradeEngine/trade/Total.js similarity index 92% rename from src/services/tradeEngine/trade/Total.js rename to common/tradeEngine/trade/Total.js index 5231bdbc..20c43c1c 100644 --- a/src/services/tradeEngine/trade/Total.js +++ b/common/tradeEngine/trade/Total.js @@ -1,8 +1,8 @@ -import { translate } from '../../../common/i18n'; -import { roundBalance } from '../../common/tools'; -import { info, notify } from '../utils/broadcast'; -import createError from '../../common/error'; -import { observer as globalObserver } from '../../../common/utils/observer'; +import { info, notify } from '../../broadcast'; +import createError from '../../error'; +import { translate } from '../../lang/i18n'; +import { observer as globalObserver } from '../../observer'; +import { roundBalance } from '../../tools'; const skeleton = { totalProfit: 0, @@ -30,6 +30,7 @@ export default Engine => globalStat[accountID] = { ...skeleton }; }); } + updateTotals(contract) { const { sell_price: sellPrice, buy_price: buyPrice, currency } = contract; @@ -75,21 +76,25 @@ export default Engine => notify('warn', `${translate('Loss amount')}: ${profit}`); } } + updateAndReturnTotalRuns() { this.sessionRuns++; const accountStat = this.getAccountStat(); return ++accountStat.totalRuns; } + /* eslint-disable class-methods-use-this */ getTotalRuns() { const accountStat = this.getAccountStat(); return accountStat.totalRuns; } + getTotalProfit() { const accountStat = this.getAccountStat(); return Number(accountStat.totalProfit); } + /* eslint-enable */ checkLimits(tradeOption) { if (!tradeOption.limitations) { @@ -109,6 +114,7 @@ export default Engine => } } } + getAccountStat() { const { loginid: accountID } = this.accountInfo; diff --git a/src/services/tradeEngine/trade/index.js b/common/tradeEngine/trade/index.js similarity index 75% rename from src/services/tradeEngine/trade/index.js rename to common/tradeEngine/trade/index.js index cd8f0af1..8c2e6af5 100644 --- a/src/services/tradeEngine/trade/index.js +++ b/common/tradeEngine/trade/index.js @@ -1,22 +1,22 @@ -import { Map } from 'immutable'; -import { createStore, applyMiddleware } from 'redux'; -import thunk from 'redux-thunk'; -import { durationToSecond } from '../../../common/utils/tools'; -import { translate } from '../../..//common/i18n'; -import createError from '../../common/error'; -import { doUntilDone } from '../helpers'; +import { Map } from 'immutable'; +import { createStore, applyMiddleware } from 'redux'; +import thunk from 'redux-thunk'; +import Balance from './Balance'; +import OpenContract from './OpenContract'; +import Proposal from './Proposal'; +import Purchase from './Purchase'; +import Sell from './Sell'; +import rootReducer from './state/reducers'; +import * as constants from './state/constants'; +import { start } from './state/actions'; +import Ticks from './Ticks'; +import Total from './Total'; import { expectInitArg, expectTradeOptions } from '../utils/sanitize'; -import Proposal from './Proposal'; -import Total from './Total'; -import Balance from './Balance'; -import OpenContract from './OpenContract'; -import Sell from './Sell'; -import Purchase from './Purchase'; -import Ticks from './Ticks'; -import rootReducer from './state/reducers'; -import * as constants from './state/constants'; -import { start } from './state/actions'; -import { observer as globalObserver } from '../../../common/utils/observer'; +import createError from '../../error'; +import { doUntilDone } from '../../tools'; +import { translate } from '../../lang/i18n'; +import { durationToSecond } from '../../helpers'; +import { observer as globalObserver } from '../../observer'; const watchBefore = store => watchScope({ @@ -73,6 +73,7 @@ export default class TradeEngine extends Balance(Purchase(Sell(OpenContract(Prop this.data = new Map(); this.store = createStore(rootReducer, applyMiddleware(thunk)); } + init(...args) { const [token, options] = expectInitArg(args); @@ -86,6 +87,7 @@ export default class TradeEngine extends Balance(Purchase(Sell(OpenContract(Prop this.watchTicks(symbol); } + start(tradeOptions) { if (!this.options) { throw createError('NotInitialized', translate('Bot.init is not called')); @@ -103,6 +105,7 @@ export default class TradeEngine extends Balance(Purchase(Sell(OpenContract(Prop this.checkProposalReady(); } + loginAndGetBalance(token) { if (this.token === token) { return Promise.resolve(); @@ -121,11 +124,13 @@ export default class TradeEngine extends Balance(Purchase(Sell(OpenContract(Prop }) ); } + getContractDuration() { const { duration, duration_unit: durationUnit } = this.tradeOptions; return durationToSecond(`${duration}${durationUnit}`); } + observe() { this.observeOpenContract(); @@ -133,15 +138,18 @@ export default class TradeEngine extends Balance(Purchase(Sell(OpenContract(Prop this.observeProposals(); } + watch(watchName) { if (watchName === 'before') { return watchBefore(this.store); } return watchDuring(this.store); } + getData() { return this.data; } + listen(n, f) { this.api.events.on(n, f); } diff --git a/src/services/tradeEngine/trade/state/actions/index.js b/common/tradeEngine/trade/state/actions/index.js similarity index 100% rename from src/services/tradeEngine/trade/state/actions/index.js rename to common/tradeEngine/trade/state/actions/index.js diff --git a/src/services/tradeEngine/trade/state/actions/index.spec.js b/common/tradeEngine/trade/state/actions/index.spec.js similarity index 99% rename from src/services/tradeEngine/trade/state/actions/index.spec.js rename to common/tradeEngine/trade/state/actions/index.spec.js index 22b83595..be3e5dc1 100644 --- a/src/services/tradeEngine/trade/state/actions/index.spec.js +++ b/common/tradeEngine/trade/state/actions/index.spec.js @@ -1,5 +1,5 @@ import * as constants from '../constants'; -import * as actions from './'; +import * as actions from '.'; const getDispatchFromAction = ({ action, state }) => { const dispatch = jest.fn(); diff --git a/src/services/tradeEngine/trade/state/constants.js b/common/tradeEngine/trade/state/constants.js similarity index 100% rename from src/services/tradeEngine/trade/state/constants.js rename to common/tradeEngine/trade/state/constants.js diff --git a/common/tradeEngine/trade/state/reducers/index.js b/common/tradeEngine/trade/state/reducers/index.js new file mode 100644 index 00000000..5883522e --- /dev/null +++ b/common/tradeEngine/trade/state/reducers/index.js @@ -0,0 +1,52 @@ +import * as constants from '../constants'; + +const initialState = { + scope : constants.STOP, + proposalsReady: false, +}; + +const signal = (state = initialState, action) => { + switch (action.type) { + case constants.START: + return { + scope : constants.BEFORE_PURCHASE, + proposalsReady: state.proposalsReady, + }; + case constants.PROPOSALS_READY: + return { + ...state, + proposalsReady: true, + }; + case constants.CLEAR_PROPOSALS: + return { + ...state, + proposalsReady: false, + }; + case constants.PURCHASE_SUCCESSFUL: + return { + scope : constants.DURING_PURCHASE, + openContract : false, + proposalsReady: state.proposalsReady, + }; + case constants.OPEN_CONTRACT: + return { + scope : constants.DURING_PURCHASE, + openContract : true, + proposalsReady: state.proposalsReady, + }; + case constants.SELL: + return { + scope : constants.STOP, + proposalsReady: state.proposalsReady, + }; + case constants.NEW_TICK: + return { + ...state, + newTick: action.payload, + }; + default: + return state; + } +}; + +export default signal; diff --git a/src/services/tradeEngine/trade/state/reducers/index.spec.js b/common/tradeEngine/trade/state/reducers/index.spec.js similarity index 98% rename from src/services/tradeEngine/trade/state/reducers/index.spec.js rename to common/tradeEngine/trade/state/reducers/index.spec.js index 0ea5273b..af361e21 100644 --- a/src/services/tradeEngine/trade/state/reducers/index.spec.js +++ b/common/tradeEngine/trade/state/reducers/index.spec.js @@ -1,5 +1,5 @@ -import signal from './'; import * as constants from '../constants'; +import signal from '.'; let state; diff --git a/src/services/tradeEngine/utils/cli.js b/common/tradeEngine/utils/cli.js similarity index 77% rename from src/services/tradeEngine/utils/cli.js rename to common/tradeEngine/utils/cli.js index 8bb893a2..52315b54 100644 --- a/src/services/tradeEngine/utils/cli.js +++ b/common/tradeEngine/utils/cli.js @@ -1,8 +1,8 @@ -import fs from 'fs'; -import readline from 'readline'; -import program from 'commander'; -import { observer as globalObserver } from '../../common/utils/observer'; -import { createInterpreter } from './CliTools'; +import fs from 'fs'; +import readline from 'readline'; +import program from 'commander'; +import { observer as globalObserver } from '../../observer'; +import { createInterpreter } from '../../utils/cliTools'; const log = (...args) => console.log(`${new Date().toLocaleTimeString()}:`, ...args); // eslint-disable-line no-console diff --git a/src/services/tradeEngine/utils/sanitize.js b/common/tradeEngine/utils/sanitize.js similarity index 95% rename from src/services/tradeEngine/utils/sanitize.js rename to common/tradeEngine/utils/sanitize.js index e5e07b65..c7bd2813 100644 --- a/src/services/tradeEngine/utils/sanitize.js +++ b/common/tradeEngine/utils/sanitize.js @@ -1,5 +1,5 @@ -import { translate } from '../../common/i18n'; -import createError from '../common/error'; +import createError from '../../error'; +import { translate } from '../../lang/i18n'; const isPositiveNumber = num => Number.isFinite(num) && num > 0; diff --git a/src/services/tradeEngine/utils/cliTools.js b/common/utils/cliTools.js similarity index 54% rename from src/services/tradeEngine/utils/cliTools.js rename to common/utils/cliTools.js index 26d59679..b8e9d5e0 100644 --- a/src/services/tradeEngine/utils/cliTools.js +++ b/common/utils/cliTools.js @@ -1,7 +1,7 @@ -import Observer from '../../common/utils/observer'; -import Interpreter from '../utils/Interpreter'; -import TicksService from '../common/TicksService'; -import { generateLiveApiInstance } from '../../common/appId'; +import TicksService from './ticksService'; +import { generateLiveApiInstance } from '../appId'; +import Interpreter from '../interpreter'; +import Observer from '../observer'; export const createScope = () => { const observer = new Observer(); diff --git a/src/services/api/ticksService.js b/common/utils/ticksService.js similarity index 96% rename from src/services/api/ticksService.js rename to common/utils/ticksService.js index 507d3b26..227f64e5 100644 --- a/src/services/api/ticksService.js +++ b/common/utils/ticksService.js @@ -1,7 +1,7 @@ -import { Map } from 'immutable'; -import { historyToTicks, getLast } from 'binary-utils'; -import { observer as globalObserver } from '../../common/utils/observer'; -import { doUntilDone, getUUID } from '../bot/tools'; +import { Map } from 'immutable'; +import { historyToTicks, getLast } from 'binary-utils'; +import { doUntilDone, getUUID } from '../tools'; +import { observer as globalObserver } from '../observer'; const parseTick = tick => ({ epoch: +tick.epoch, @@ -48,6 +48,7 @@ export default class TicksService { this.subscriptions = new Map(); this.observe(); } + requestPipSizes() { if (this.pipSizes) { return Promise.resolve(this.pipSizes); @@ -63,6 +64,7 @@ export default class TicksService { }); }); } + request(options) { const { symbol, granularity } = options; @@ -78,6 +80,7 @@ export default class TicksService { return this.requestStream({ ...options, style }); } + monitor(options) { const { symbol, granularity, callback } = options; @@ -95,6 +98,7 @@ export default class TicksService { return key; } + stopMonitor(options) { const { symbol, granularity, key } = options; const type = getType(granularity); @@ -109,6 +113,7 @@ export default class TicksService { this.unsubscribeIfEmptyListeners(options); } + unsubscribeIfEmptyListeners(options) { const { symbol, granularity } = options; @@ -134,6 +139,7 @@ export default class TicksService { this.unsubscribeAllAndSubscribeListeners(symbol); } } + unsubscribeAllAndSubscribeListeners(symbol) { const ohlcSubscriptions = this.subscriptions.getIn(['ohlc', symbol]); const tickSubscription = this.subscriptions.getIn(['tick', symbol]); @@ -147,6 +153,7 @@ export default class TicksService { this.subscriptions = new Map(); } + updateTicksAndCallListeners(symbol, ticks) { if (this.ticks.get(symbol) === ticks) { return; @@ -159,6 +166,7 @@ export default class TicksService { listeners.forEach(callback => callback(this.ticks.get(symbol))); } } + updateCandlesAndCallListeners(address, candles) { if (this.ticks.getIn(address) === candles) { return; @@ -171,6 +179,7 @@ export default class TicksService { listeners.forEach(callback => callback(this.candles.getIn(address))); } } + observe() { this.api.events.on('tick', r => { const { tick, tick: { symbol, id } } = r; @@ -194,9 +203,11 @@ export default class TicksService { } }); } + requestStream(options) { return this.requestPipSizes().then(() => this.requestTicks(options)); } + requestTicks(options) { const { symbol, granularity, style } = options; diff --git a/index.html b/index.html index a81b4524..2c4ddc47 100644 --- a/index.html +++ b/index.html @@ -8,7 +8,10 @@ -
- +
+ + + - + + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 37c9f198..d828cbe8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1611,7 +1611,8 @@ "abab": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz", - "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==" + "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==", + "dev": true }, "abbrev": { "version": "1.1.1", @@ -1632,7 +1633,8 @@ "acorn": { "version": "5.7.3", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz", - "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==" + "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==", + "dev": true }, "acorn-dynamic-import": { "version": "4.0.0", @@ -1644,6 +1646,7 @@ "version": "4.3.2", "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz", "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==", + "dev": true, "requires": { "acorn": "^6.0.1", "acorn-walk": "^6.0.1" @@ -1652,7 +1655,8 @@ "acorn": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", - "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==" + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true } } }, @@ -1665,7 +1669,8 @@ "acorn-walk": { "version": "6.1.1", "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", - "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==" + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true }, "add-px-to-style": { "version": "1.0.0", @@ -1676,6 +1681,7 @@ "version": "6.10.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, "requires": { "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", @@ -1695,11 +1701,6 @@ "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", "dev": true }, - "almond": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/almond/-/almond-0.3.3.tgz", - "integrity": "sha1-oOfJWsdiTWQXtElLHmi/9pMWiiA=" - }, "amdefine": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", @@ -1903,7 +1904,8 @@ "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", - "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=" + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true }, "array-find": { "version": "1.0.0", @@ -2022,6 +2024,7 @@ "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, "requires": { "safer-buffer": "~2.1.0" } @@ -2067,7 +2070,8 @@ "assert-plus": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true }, "assertion-error": { "version": "1.1.0", @@ -2136,7 +2140,8 @@ "async-limiter": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==", + "dev": true }, "async-settle": { "version": "1.0.0", @@ -2150,7 +2155,8 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true }, "atob": { "version": "2.1.2", @@ -2175,12 +2181,14 @@ "aws-sign2": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true }, "aws4": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", - "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==" + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true }, "axobject-query": { "version": "2.0.2", @@ -2615,6 +2623,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, "requires": { "tweetnacl": "^0.14.3" } @@ -2647,14 +2656,6 @@ "rx-lite": "^4.0.8" } }, - "binary-style": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/binary-style/-/binary-style-0.2.4.tgz", - "integrity": "sha1-JNm2xfRSXO2/bPMFh2wCZB/UhZo=", - "requires": { - "select2": "4.0.5" - } - }, "binary-utils": { "version": "4.25.0", "resolved": "https://registry.npmjs.org/binary-utils/-/binary-utils-4.25.0.tgz", @@ -2674,10 +2675,79 @@ } }, "blockly": { - "version": "github:google/blockly#59e5ac6897d2d9800e0010b43681c9f7743e2ceb", - "from": "github:google/blockly#59e5ac6", + "version": "github:google/blockly#339a65374b9f393130e839aae00a5001bb3061bf", + "from": "github:google/blockly#339a653", + "dev": true, "requires": { - "jsdom": "^11.11.0" + "jsdom": "^13.2.0" + }, + "dependencies": { + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "jsdom": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-13.2.0.tgz", + "integrity": "sha512-cG1NtMWO9hWpqRNRR3dSvEQa8bFI6iLlqU2x4kwX51FQjp0qus8T9aBaAO6iGp3DeBrhdwuKxckknohkmfvsFw==", + "dev": true, + "requires": { + "abab": "^2.0.0", + "acorn": "^6.0.4", + "acorn-globals": "^4.3.0", + "array-equal": "^1.0.0", + "cssom": "^0.3.4", + "cssstyle": "^1.1.1", + "data-urls": "^1.1.0", + "domexception": "^1.0.1", + "escodegen": "^1.11.0", + "html-encoding-sniffer": "^1.0.2", + "nwsapi": "^2.0.9", + "parse5": "5.1.0", + "pn": "^1.1.0", + "request": "^2.88.0", + "request-promise-native": "^1.0.5", + "saxes": "^3.1.5", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.5.0", + "w3c-hr-time": "^1.0.1", + "w3c-xmlserializer": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^7.0.0", + "ws": "^6.1.2", + "xml-name-validator": "^3.0.0" + } + }, + "parse5": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.0.tgz", + "integrity": "sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ==", + "dev": true + }, + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + } } }, "bluebird": { @@ -2834,7 +2904,8 @@ "browser-process-hrtime": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz", - "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==" + "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==", + "dev": true }, "browser-resolve": { "version": "1.11.3", @@ -3140,7 +3211,8 @@ "caseless": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true }, "ccount": { "version": "1.0.4", @@ -3490,6 +3562,7 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -3742,7 +3815,8 @@ "core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true }, "cosmiconfig": { "version": "5.2.1", @@ -3842,6 +3916,16 @@ "sha.js": "^2.4.8" } }, + "cross-env": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.0.tgz", + "integrity": "sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.5", + "is-windows": "^1.0.0" + } + }, "cross-spawn": { "version": "6.0.5", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", @@ -4023,12 +4107,14 @@ "cssom": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz", - "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==" + "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==", + "dev": true }, "cssstyle": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz", "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==", + "dev": true, "requires": { "cssom": "0.3.x" } @@ -4067,6 +4153,7 @@ "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -4075,6 +4162,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz", "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==", + "dev": true, "requires": { "abab": "^2.0.0", "whatwg-mimetype": "^2.2.0", @@ -4085,6 +4173,7 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, "requires": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -4188,7 +4277,8 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true }, "default-compare": { "version": "1.0.0", @@ -4307,7 +4397,8 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true }, "delegates": { "version": "1.0.0", @@ -4607,6 +4698,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, "requires": { "webidl-conversions": "^4.0.2" } @@ -4706,6 +4798,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, "requires": { "jsbn": "~0.1.0", "safer-buffer": "^2.1.0" @@ -5044,6 +5137,7 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz", "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==", + "dev": true, "requires": { "esprima": "^3.1.3", "estraverse": "^4.2.0", @@ -5735,7 +5829,8 @@ "esprima": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", - "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=" + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true }, "esquery": { "version": "1.0.1", @@ -5758,12 +5853,14 @@ "estraverse": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=" + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true }, "esutils": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true }, "etag": { "version": "1.8.1", @@ -5985,6 +6082,51 @@ "jest-regex-util": "^24.3.0" } }, + "exports-loader": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/exports-loader/-/exports-loader-0.6.3.tgz", + "integrity": "sha1-V9x4kX9wm5byR/qR5ptVTIVQE8g=", + "dev": true, + "requires": { + "loader-utils": "0.2.x", + "source-map": "0.1.x" + }, + "dependencies": { + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, "express": { "version": "4.17.0", "resolved": "https://registry.npmjs.org/express/-/express-4.17.0.tgz", @@ -6092,7 +6234,8 @@ "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true }, "extend-shallow": { "version": "3.0.2", @@ -6194,7 +6337,8 @@ "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true }, "fancy-log": { "version": "1.3.3", @@ -6211,7 +6355,8 @@ "fast-deep-equal": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true }, "fast-glob": { "version": "2.2.7", @@ -6230,12 +6375,14 @@ "fast-json-stable-stringify": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true }, "faye-websocket": { "version": "0.10.0", @@ -6507,7 +6654,8 @@ "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true }, "fork-stream": { "version": "0.0.4", @@ -6519,6 +6667,7 @@ "version": "2.3.3", "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, "requires": { "asynckit": "^0.4.0", "combined-stream": "^1.0.6", @@ -6625,7 +6774,8 @@ "ansi-regex": { "version": "2.1.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "aproba": { "version": "1.2.0", @@ -6646,12 +6796,14 @@ "balanced-match": { "version": "1.0.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "brace-expansion": { "version": "1.1.11", "bundled": true, "dev": true, + "optional": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -6666,17 +6818,20 @@ "code-point-at": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "concat-map": { "version": "0.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "console-control-strings": { "version": "1.1.0", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "core-util-is": { "version": "1.0.2", @@ -6793,7 +6948,8 @@ "inherits": { "version": "2.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "ini": { "version": "1.3.5", @@ -6805,6 +6961,7 @@ "version": "1.0.0", "bundled": true, "dev": true, + "optional": true, "requires": { "number-is-nan": "^1.0.0" } @@ -6819,6 +6976,7 @@ "version": "3.0.4", "bundled": true, "dev": true, + "optional": true, "requires": { "brace-expansion": "^1.1.7" } @@ -6826,12 +6984,14 @@ "minimist": { "version": "0.0.8", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "minipass": { "version": "2.3.5", "bundled": true, "dev": true, + "optional": true, "requires": { "safe-buffer": "^5.1.2", "yallist": "^3.0.0" @@ -6850,6 +7010,7 @@ "version": "0.5.1", "bundled": true, "dev": true, + "optional": true, "requires": { "minimist": "0.0.8" } @@ -6930,7 +7091,8 @@ "number-is-nan": { "version": "1.0.1", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "object-assign": { "version": "4.1.1", @@ -6942,6 +7104,7 @@ "version": "1.4.0", "bundled": true, "dev": true, + "optional": true, "requires": { "wrappy": "1" } @@ -7027,7 +7190,8 @@ "safe-buffer": { "version": "5.1.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "safer-buffer": { "version": "2.1.2", @@ -7063,6 +7227,7 @@ "version": "1.0.2", "bundled": true, "dev": true, + "optional": true, "requires": { "code-point-at": "^1.0.0", "is-fullwidth-code-point": "^1.0.0", @@ -7082,6 +7247,7 @@ "version": "3.0.1", "bundled": true, "dev": true, + "optional": true, "requires": { "ansi-regex": "^2.0.0" } @@ -7125,12 +7291,14 @@ "wrappy": { "version": "1.0.2", "bundled": true, - "dev": true + "dev": true, + "optional": true }, "yallist": { "version": "3.0.3", "bundled": true, - "dev": true + "dev": true, + "optional": true } } }, @@ -7252,6 +7420,7 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, "requires": { "assert-plus": "^1.0.0" } @@ -8278,12 +8447,14 @@ "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true }, "har-validator": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, "requires": { "ajv": "^6.5.5", "har-schema": "^2.0.0" @@ -8446,6 +8617,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, "requires": { "whatwg-encoding": "^1.0.1" } @@ -8540,6 +8712,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "jsprim": "^1.2.2", @@ -8894,6 +9067,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -8969,6 +9143,51 @@ "integrity": "sha1-pVxS5McFx2XKIQ6SQqBrvMiqf2Y=", "dev": true }, + "imports-loader": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/imports-loader/-/imports-loader-0.6.5.tgz", + "integrity": "sha1-rnRlMDHVnjezwvslRKxhrq41MKY=", + "dev": true, + "requires": { + "loader-utils": "0.2.x", + "source-map": "0.1.x" + }, + "dependencies": { + "big.js": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz", + "integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==", + "dev": true + }, + "json5": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", + "dev": true + }, + "loader-utils": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz", + "integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0", + "object-assign": "^4.0.1" + } + }, + "source-map": { + "version": "0.1.43", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.43.tgz", + "integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=", + "dev": true, + "requires": { + "amdefine": ">=0.0.4" + } + } + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -9465,7 +9684,8 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true }, "is-unc-path": { "version": "1.0.0", @@ -9533,7 +9753,8 @@ "isstream": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true }, "istanbul-lib-coverage": { "version": "2.0.5", @@ -10257,11 +10478,6 @@ "integrity": "sha512-36+AdBzCL+y6qjw5Tx7HgzeGCzC81MDDgaUP8ld2zhx58HdqXGoBd+tHdrBMiyjGQs0Hxs/MLZTu/eHNJJuWPw==", "dev": true }, - "jquery-mousewheel": { - "version": "3.1.13", - "resolved": "https://registry.npmjs.org/jquery-mousewheel/-/jquery-mousewheel-3.1.13.tgz", - "integrity": "sha1-BvAzXxbjU6aV5yBr9QUDy1I6buU=" - }, "jquery-ui": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.12.1.tgz", @@ -10287,7 +10503,7 @@ "dev": true, "requires": { "acorn": "^4.0.11", - "clone": "github:aminmarashi/clone#d97b4f0ff3d3afebcaaf4a2ecc9c50fbce914900" + "clone": "github:aminmarashi/clone#d97b4f" }, "dependencies": { "acorn": { @@ -10335,12 +10551,14 @@ "jsbn": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=" + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true }, "jsdom": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz", "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==", + "dev": true, "requires": { "abab": "^2.0.0", "acorn": "^5.5.3", @@ -10385,12 +10603,14 @@ "json-schema": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" + "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", + "dev": true }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -10401,7 +10621,8 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true }, "json2csv": { "version": "3.11.5", @@ -10543,6 +10764,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", + "dev": true, "requires": { "assert-plus": "1.0.0", "extsprintf": "1.3.0", @@ -10681,7 +10903,8 @@ "left-pad": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz", - "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==" + "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==", + "dev": true }, "leven": { "version": "2.1.0", @@ -10693,6 +10916,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -11079,7 +11303,8 @@ "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", - "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=" + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true }, "lodash.tail": { "version": "4.1.1", @@ -11681,12 +11906,14 @@ "mime-db": { "version": "1.40.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==" + "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "dev": true }, "mime-types": { "version": "2.1.24", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "dev": true, "requires": { "mime-db": "1.40.0" } @@ -12282,12 +12509,14 @@ "nwsapi": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz", - "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==" + "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==", + "dev": true }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==" + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true }, "object-assign": { "version": "4.1.1", @@ -12511,6 +12740,7 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -12777,7 +13007,8 @@ "parse5": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", - "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==" + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "dev": true }, "parseurl": { "version": "1.3.3", @@ -13019,7 +13250,8 @@ "pn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", - "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==" + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true }, "portfinder": { "version": "1.0.20", @@ -13234,7 +13466,8 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true }, "prepend-http": { "version": "1.0.4", @@ -13633,7 +13866,8 @@ "psl": { "version": "1.1.31", "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", - "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==" + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true }, "public-encrypt": { "version": "4.0.3", @@ -13685,12 +13919,14 @@ "punycode": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true }, "qs": { "version": "6.5.2", "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", - "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==" + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true }, "query-string": { "version": "4.3.4", @@ -14213,6 +14449,7 @@ "version": "2.88.0", "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -14239,12 +14476,14 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -14256,6 +14495,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz", "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==", + "dev": true, "requires": { "lodash": "^4.17.11" } @@ -14264,6 +14504,7 @@ "version": "1.0.7", "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz", "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==", + "dev": true, "requires": { "request-promise-core": "1.1.2", "stealthy-require": "^1.1.1", @@ -14588,7 +14829,8 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true }, "sane": { "version": "4.1.0", @@ -14652,7 +14894,17 @@ "sax": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "saxes": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-3.1.9.tgz", + "integrity": "sha512-FZeKhJglhJHk7eWG5YM0z46VHmI3KJpMBAQm3xa9meDvd+wevB5GuBB0wc0exPInZiBBHqi00DbS8AcvCGCFMw==", + "dev": true, + "requires": { + "xmlchars": "^1.3.1" + } }, "scheduler": { "version": "0.13.6", @@ -14682,6 +14934,16 @@ } } }, + "scratch-blocks": { + "version": "0.1.0-prerelease.1558719162", + "resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.1558719162.tgz", + "integrity": "sha512-FV7AUQgfP7yRbcGZ2q8ZqFxu49+eh9uZ9p9El6TcZ8KfRYEfL7l9degqKIGLgN3svK99xRAvfs1qgin7oRGtzw==", + "dev": true, + "requires": { + "exports-loader": "0.6.3", + "imports-loader": "0.6.5" + } + }, "scroll": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/scroll/-/scroll-2.0.3.tgz", @@ -14718,15 +14980,6 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, - "select2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/select2/-/select2-4.0.5.tgz", - "integrity": "sha1-eqxQaSVhmFs007guxV4ib4lg1Ao=", - "requires": { - "almond": "~0.3.1", - "jquery-mousewheel": "~3.1.13" - } - }, "selfsigned": { "version": "1.10.4", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.4.tgz", @@ -15177,7 +15430,8 @@ "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true }, "source-map-resolve": { "version": "0.5.2", @@ -15397,6 +15651,7 @@ "version": "1.16.1", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "dev": true, "requires": { "asn1": "~0.2.3", "assert-plus": "^1.0.0", @@ -15475,7 +15730,8 @@ "stealthy-require": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz", - "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=" + "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=", + "dev": true }, "stream-browserify": { "version": "2.0.2", @@ -16170,7 +16426,8 @@ "symbol-tree": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", - "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=" + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true }, "table": { "version": "5.3.3", @@ -16500,6 +16757,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, "requires": { "psl": "^1.1.28", "punycode": "^2.1.1" @@ -16509,6 +16767,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -16592,6 +16851,7 @@ "version": "0.6.0", "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", + "dev": true, "requires": { "safe-buffer": "^5.0.1" } @@ -16599,12 +16859,14 @@ "tweetnacl": { "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true }, "type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, "requires": { "prelude-ls": "~1.1.2" } @@ -16981,6 +17243,7 @@ "version": "4.2.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -17072,7 +17335,8 @@ "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", - "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==" + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true }, "v8-compile-cache": { "version": "2.0.3", @@ -17121,6 +17385,7 @@ "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "dev": true, "requires": { "assert-plus": "^1.0.0", "core-util-is": "1.0.2", @@ -17351,10 +17616,22 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, "requires": { "browser-process-hrtime": "^0.1.2" } }, + "w3c-xmlserializer": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz", + "integrity": "sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg==", + "dev": true, + "requires": { + "domexception": "^1.0.1", + "webidl-conversions": "^4.0.2", + "xml-name-validator": "^3.0.0" + } + }, "walker": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", @@ -17387,7 +17664,8 @@ "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", - "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==" + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true }, "webpack": { "version": "4.32.2", @@ -17887,6 +18165,7 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, "requires": { "iconv-lite": "0.4.24" } @@ -17894,12 +18173,14 @@ "whatwg-mimetype": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==" + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true }, "whatwg-url": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz", "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==", + "dev": true, "requires": { "lodash.sortby": "^4.7.0", "tr46": "^1.0.1", @@ -17949,7 +18230,8 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true }, "worker-farm": { "version": "1.7.0", @@ -18021,6 +18303,7 @@ "version": "5.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", + "dev": true, "requires": { "async-limiter": "~1.0.0" } @@ -18034,7 +18317,14 @@ "xml-name-validator": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==" + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlchars": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-1.3.1.tgz", + "integrity": "sha512-tGkGJkN8XqCod7OT+EvGYK5Z4SfDQGD30zAa58OcnAa0RRWgzUEK72tkXhsX1FZd+rgnhRxFtmO+ihkp8LHSkw==", + "dev": true }, "xtend": { "version": "4.0.1", diff --git a/package.json b/package.json index 72828452..71b0c9c4 100644 --- a/package.json +++ b/package.json @@ -14,10 +14,11 @@ ] }, "scripts": { + "lint-fix": "eslint ./src ./common ./scratch --fix", "build": "rimraf dist && cross-env NODE_ENV=production webpack --mode=production --optimize-minimize --progress", "watch": "webpack --mode=development --progress --watch", - "start": "rimraf dist && webpack-dev-server --mode=development --open --hot --inline", - "test": "jest -w 10 --coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage", + "start": "eslint ./src ./common ./scratch && rimraf dist && webpack-dev-server --mode=development --open --hot --inline", + "test": "eslint ./src ./common ./scratch && jest -w 10 --coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage", "gh-pages": "gh-pages --dist '.' --src '{index.html,manifest.json,dist/**,CNAME}'", "gh-pages:folder": "yarn gh-pages --src '{index.html,manifest.json,dist/**}' --dest $1", "release": "d() { test -z $1 && echo 'Please specify branch.' && exit 1; (git show-branch $1) || exit 1; git stash; git checkout $1; npm i; rm -rf branch/$1; mkdir -p branch/$1 ; gulp build-min; cp -r www/ branch/$1; gulp release-branch --branch $1;}; d", @@ -43,8 +44,10 @@ "babel-loader": "^8.0.6", "binary-live-api": "^29.0.0", "binary-utils": "^4.23.0", + "blockly": "github:google/blockly#339a653", "chai": "^4.1.2", "coveralls": "^3.0.3", + "cross-env": "^5.2.0", "css-hot-loader": "^1.4.4", "css-loader": "^2.1.1", "deep-diff": "^1.0.2", @@ -94,6 +97,7 @@ "redux": "^4.0.1", "redux-thunk": "^2.2.0", "sass-loader": "^7.1.0", + "scratch-blocks": "0.1.0-prerelease.1558719162", "sha1": "^1.1.1", "stylelint": "^10.0.1", "stylelint-no-unsupported-browser-features": "^3.0.2", @@ -106,8 +110,6 @@ }, "dependencies": { "@binary-com/smartcharts": "^0.3.9", - "binary-style": "^0.2.4", - "blockly": "github:google/blockly#59e5ac6", "commander": "^2.20.0", "concat-stream": "^2.0.0", "core-js": "^2.6.5", diff --git a/scratch/hooks/block.js b/scratch/hooks/block.js new file mode 100644 index 00000000..b95986ca --- /dev/null +++ b/scratch/hooks/block.js @@ -0,0 +1,78 @@ +/* eslint-disable func-names */ + +Blockly.Block.prototype.getSiblings = function() { + const siblings = [this]; + ['getPreviousBlock', 'getNextBlock'].forEach(functionName => { + let block = this[functionName](); + while (block !== null) { + const parent = this.getParent(); + if (parent && parent.id === block.id) { + break; + } + + siblings.push(block); + block = block[functionName](); + } + }); + return siblings; +}; + +Blockly.Block.prototype.getChildByType = function(type) { + return this.getDescendants().find(child => child.type === type); +}; + +Blockly.Block.prototype.getChildFieldValue = function(childType, childField) { + const childBlock = this.getChildByType(childType); + if (childBlock) { + const value = childBlock.getFieldValue(childField); + return value; + } + return null; +}; + +Blockly.Block.prototype.childValueToCode = function(childType, childField) { + const childBlock = this.getChildByType(childType); + return childBlock && Blockly.JavaScript.valueToCode(childBlock, childField, Blockly.JavaScript.ORDER_ATOMIC); +}; + +Blockly.Block.prototype.getBlocksInStatement = function(statementInputName) { + const blocksInStatement = []; + const firstBlock = this.getInputTargetBlock(statementInputName); + + if (firstBlock) { + return firstBlock.getSiblings(); + } + return blocksInStatement; +}; + +Blockly.Block.prototype.getLastConnectionInStatement = function(statementInputName) { + const firstBlockInStack = this.getInputTargetBlock(statementInputName); + if (firstBlockInStack) { + return firstBlockInStack.lastConnectionInStack(); + } + const statementInput = this.getInput(statementInputName); + return statementInput.connection; +}; + +Blockly.Block.prototype.isDescendantOf = function(type) { + let parentBlock = this.getParent(); + while (parentBlock !== null) { + if (parentBlock.type === type) { + return true; + } + parentBlock = parentBlock.getParent(); + } + return false; +}; + +Blockly.Block.prototype.getTopParent = function() { + let parent = this.getParent(); + while (parent !== null) { + const nextParent = parent.getParent(); + if (!nextParent) { + return parent; + } + parent = nextParent; + } + return null; +}; diff --git a/scratch/hooks/block_svg.js b/scratch/hooks/block_svg.js new file mode 100644 index 00000000..9cb17d0b --- /dev/null +++ b/scratch/hooks/block_svg.js @@ -0,0 +1,114 @@ +/* eslint-disable func-names, no-underscore-dangle */ +import { translate } from '../../common/lang/i18n'; + +/** + * Set whether the block is disabled or not. + * @param {boolean} disabled True if disabled. + * deriv-bot: Call updateDisabled() when setDisabled is called. + */ +Blockly.BlockSvg.prototype.setDisabled = function(disabled) { + if (this.disabled !== disabled) { + Blockly.BlockSvg.superClass_.setDisabled.call(this, disabled); + if (this.rendered) { + this.updateDisabled(); + } + } +}; + +/** + * Enable or disable a block. + */ +Blockly.BlockSvg.prototype.updateDisabled = function() { + if (this.disabled || this.getInheritedDisabled()) { + const added = Blockly.utils.addClass(/** @type {!Element} */ (this.svgGroup_), 'blocklyDisabled'); + if (added) { + this.svgPath_.setAttribute('fill', `url(#${this.workspace.options.disabledPatternId})`); + } + } else { + const removed = Blockly.utils.removeClass(/** @type {!Element} */ (this.svgGroup_), 'blocklyDisabled'); + if (removed) { + this.updateColour(); + } + } + const children = this.getChildren(false); + children.forEach(child => { + child.updateDisabled(); + }); +}; + +/** + * Show the context menu for this block. + * @param {!Event} e Mouse event. + * @private + * deriv-bot: Restore contextMenu options from Blockly unavailable in Scratch + */ +Blockly.BlockSvg.prototype.showContextMenu_ = function(e) { + if (this.workspace.options.readOnly || !this.contextMenu) { + return; + } + // Save the current block in a variable for use in closures. + const block = this; + const menuOptions = []; + + if (this.isDeletable() && this.isMovable() && !block.isInFlyout) { + menuOptions.push(Blockly.ContextMenu.blockDuplicateOption(block, e)); + + if (this.isEditable() && this.workspace.options.comments) { + menuOptions.push(Blockly.ContextMenu.blockCommentOption(block)); + } + + menuOptions.push(Blockly.ContextMenu.blockDeleteOption(block)); + } else if (this.parentBlock_ && this.isShadow_) { + this.parentBlock_.showContextMenu_(e); + return; + } + + // Option to collapse/expand block. + if (this.workspace.options.collapse) { + if (this.collapsed_) { + const expandOption = { enabled: true }; + expandOption.text = translate('Expand Block'); + expandOption.callback = function() { + block.setCollapsed(false); + }; + menuOptions.push(expandOption); + } else { + const collapseOption = { enabled: true }; + collapseOption.text = translate('Collapse Block'); + collapseOption.callback = function() { + block.setCollapsed(true); + }; + menuOptions.push(collapseOption); + } + } + + // Option to disable/enable block. + if (this.workspace.options.disable) { + const disableOption = { + text : this.disabled ? translate('Enable Block') : translate('Disable Block'), + enabled: !this.getInheritedDisabled(), + callback() { + const group = Blockly.Events.getGroup(); + + if (!group) { + Blockly.Events.setGroup(true); + } + + block.setDisabled(!block.disabled); + + if (!group) { + Blockly.Events.setGroup(false); + } + }, + }; + menuOptions.push(disableOption); + + // Allow the block to add or modify menuOptions. + if (this.customContextMenu) { + this.customContextMenu(menuOptions); + } + + Blockly.ContextMenu.show(e, menuOptions, this.RTL); + Blockly.ContextMenu.currentBlock = this; + } +}; diff --git a/scratch/hooks/colours.js b/scratch/hooks/colours.js new file mode 100644 index 00000000..5481babc --- /dev/null +++ b/scratch/hooks/colours.js @@ -0,0 +1,29 @@ +Blockly.Colours.Binary = { + colour : '#dedede', + colourSecondary: '#e2e2e2', + colourTertiary : '#bababa', +}; + +Blockly.Colours.BinaryLessGray = { + colour : '#f3f3f3', + colourSecondary: '#e2e2e2', + colourTertiary : '#bababa', +}; + +Blockly.Colours.BinaryPurple = { + colour : '#dedede', + colourSecondary: '#e2e2e2', + colourTertiary : '#bababa', +}; + +Blockly.Colours.BinaryLessPurple = { + colour : '#dedede', + colourSecondary: '#e2e2e2', + colourTertiary : '#bababa', +}; + +Blockly.Colours.BinaryProcedures = { + colour : '#1876d2', + colourSecondary: '#0d47a1', + colourTertiary : '#0d47a1', +}; diff --git a/scratch/hooks/data_category.js b/scratch/hooks/data_category.js new file mode 100644 index 00000000..c05d6742 --- /dev/null +++ b/scratch/hooks/data_category.js @@ -0,0 +1,101 @@ +/* eslint-disable func-names, no-underscore-dangle */ +import { translate } from '../../common/lang/i18n'; + +/** + * Construct the blocks required by the flyout for the variable category. + * @param {!Blockly.Workspace} workspace The workspace containing variables. + * @return {!Array.} Array of XML block elements. + */ +Blockly.DataCategory = function(workspace) { + const variableModelList = workspace.getVariablesOfType(''); + const xmlList = []; + + // `Create Variable`-button + Blockly.DataCategory.addCreateButton(xmlList, workspace); + + if (variableModelList.length > 0) { + const generateVariableFieldXmlString = variableModel => { + // The variable name may be user input, so it may contain characters that + // need to be escaped to create valid XML. + const escapedText = `${goog.string.htmlEscape(variableModel.name)}`; + return escapedText; + }; + + // TEMP: Label for testing only + const operationsLabel = document.createElement('label'); + operationsLabel.setAttribute('text', translate('variables_set')); + xmlList.push(operationsLabel); + + const firstVariable = variableModelList[0]; + + // Create 'Set `var` to'-block + if (Blockly.Blocks.variables_set) { + const gap = Blockly.Blocks.math_change ? 8 : 24; + const setBlockText = `${generateVariableFieldXmlString( + firstVariable + )}`; + const setBlock = Blockly.Xml.textToDom(setBlockText).firstChild; + xmlList.push(setBlock); + } + + // TEMP: Label for testing only + const changeLabel = document.createElement('label'); + changeLabel.setAttribute('text', translate('math_change')); + xmlList.push(changeLabel); + + // Create 'Change `var` by `1`'-block + if (Blockly.Blocks.math_change) { + const gap = Blockly.Blocks.variables_get ? 20 : 8; + const changeBlockText = `${generateVariableFieldXmlString( + firstVariable + )}1`; + const changeBlock = Blockly.Xml.textToDom(changeBlockText).firstChild; + xmlList.push(changeBlock); + } + + // TEMP: Label for testing only + const variablesLabel = document.createElement('label'); + variablesLabel.setAttribute('text', translate('variable_get')); + xmlList.push(variablesLabel); + + // Create `variable_get` block for each variable + if (Blockly.Blocks.variables_get) { + variableModelList.sort(Blockly.VariableModel.compareByName); + + variableModelList.forEach(variable => { + const getBlockText = `${generateVariableFieldXmlString( + variable + )}`; + const getBlock = Blockly.Xml.textToDom(getBlockText).firstChild; + xmlList.push(getBlock); + }); + } + } + + return xmlList; +}; + +/** + * Construct a create variable button and push it to the xmlList. + * @param {!Array.} xmlList Array of XML block elements. + * @param {Blockly.Workspace} workspace Workspace to register callback to. + * deriv-bot: We only use a single type of variable, so `type` arg was removed. + */ +Blockly.DataCategory.addCreateButton = function(xmlList, workspace) { + const buttonXml = goog.dom.createDom('button'); + // Set default msg, callbackKey, and callback values for type 'VARIABLE' + const msg = Blockly.Msg.NEW_VARIABLE; + const callbackKey = 'CREATE_VARIABLE'; + const callback = function(button) { + const buttonWorkspace = button.getTargetWorkspace(); + Blockly.Variables.createVariable(buttonWorkspace, null, ''); + buttonWorkspace.toolbox_.showCategory_('Variables'); + }; + + buttonXml.setAttribute('text', msg); + buttonXml.setAttribute('callbackKey', callbackKey); + workspace.registerButtonCallback(callbackKey, callback); + xmlList.push(buttonXml); +}; diff --git a/scratch/hooks/field_dropdown.js b/scratch/hooks/field_dropdown.js new file mode 100644 index 00000000..6868170e --- /dev/null +++ b/scratch/hooks/field_dropdown.js @@ -0,0 +1,29 @@ +/* eslint-disable func-names, no-underscore-dangle */ +Blockly.FieldDropdown.prototype.updateOptions = function(options, optDefault = null, triggerEvent = true) { + const previousValue = this.getValue(); + + Blockly.Events.disable(); + + this.menuGenerator_ = options; + + if (optDefault && this.menuGenerator_.findIndex(item => item[1] === optDefault) !== -1) { + this.setValue(''); + this.setValue(optDefault); + } else if (this.menuGenerator_.length > 0) { + this.setValue(''); + this.setValue(this.menuGenerator_[0][1]); + } + + Blockly.Events.enable(); + + if (triggerEvent) { + const event = new Blockly.Events.BlockChange( + this.sourceBlock_, + 'field', + this.name, + previousValue, + this.getValue() + ); + Blockly.Events.fire(event); + } +}; diff --git a/scratch/hooks/field_image.js b/scratch/hooks/field_image.js new file mode 100644 index 00000000..b292529d --- /dev/null +++ b/scratch/hooks/field_image.js @@ -0,0 +1,210 @@ +/* eslint-disable func-names, no-underscore-dangle */ +/** + * Class for an image on a block. + * deriv-bot: Blockly implementation vs. Scratch for click handlers + * @param {string} src The URL of the image. + * @param {number} width Width of the image. + * @param {number} height Height of the image. + * @param {string=} optAlt Optional alt text for when block is collapsed. + * @param {Function=} optOnClick Optional function to be called when the image + * is clicked. If optOnClick is defined, optAlt must also be defined. + * @param {boolean=} optFlipRtl Whether to flip the icon in RTL. + * @extends {Blockly.Field} + * @constructor + */ +Blockly.FieldImage = function(src, width, height, optAlt, optOnClick, optFlipRtl) { + this.sourceBlock_ = null; + + // Ensure height and width are numbers. Strings are bad at math. + this.height_ = Number(height); + this.width_ = Number(width); + this.size_ = new goog.math.Size(this.width_, this.height_); + this.flipRtl_ = optFlipRtl; + this.tooltip_ = ''; + this.setValue(src); + this.setText(optAlt); + + if (typeof optOnClick === 'function') { + this.clickHandler_ = optOnClick; + } +}; +goog.inherits(Blockly.FieldImage, Blockly.Field); + +/** + * Construct a FieldImage from a JSON arg object, + * dereferencing any string table references. + * @param {!Object} options A JSON object with options (src, width, height, + * alt, and flipRtl). + * @return {!Blockly.FieldImage} The new field instance. + * @package + * @nocollapse + */ +Blockly.FieldImage.fromJson = function(options) { + const src = Blockly.utils.replaceMessageReferences(options.src); + const width = Number(Blockly.utils.replaceMessageReferences(options.width)); + const height = Number(Blockly.utils.replaceMessageReferences(options.height)); + const alt = Blockly.utils.replaceMessageReferences(options.alt); + const flipRtl = !!options.flipRtl; + return new Blockly.FieldImage(src, width, height, alt, null, flipRtl); +}; + +/** + * Editable fields are saved by the XML renderer, non-editable fields are not. + */ +Blockly.FieldImage.prototype.EDITABLE = false; + +/** + * Install this image on a block. + */ +Blockly.FieldImage.prototype.init = function() { + if (this.fieldGroup_) { + // Image has already been initialized once. + return; + } + // Build the DOM. + /** @type {SVGElement} */ + this.fieldGroup_ = Blockly.utils.createSvgElement('g', {}, null); + if (!this.visible_) { + this.fieldGroup_.style.display = 'none'; + } + /** @type {SVGElement} */ + this.imageElement_ = Blockly.utils.createSvgElement( + 'image', + { + height: `${this.height_}px`, + width : `${this.width_}px`, + }, + this.fieldGroup_ + ); + this.setValue(this.src_); + this.setText(this.text_); + this.sourceBlock_.getSvgRoot().appendChild(this.fieldGroup_); + + if (this.tooltip_) { + this.imageElement_.tooltip = this.tooltip_; + } else { + // Configure the field to be transparent with respect to tooltips. + this.setTooltip(this.sourceBlock_); + } + Blockly.Tooltip.bindMouseEvents(this.imageElement_); + + this.maybeAddClickHandler_(); +}; + +/** + * Dispose of all DOM objects belonging to this text. + */ +Blockly.FieldImage.prototype.dispose = function() { + goog.dom.removeNode(this.fieldGroup_); + this.fieldGroup_ = null; + this.imageElement_ = null; +}; + +/** + * Bind events for a mouse down on the image, but only if a click handler has + * been defined. + * @private + */ +Blockly.FieldImage.prototype.maybeAddClickHandler_ = function() { + if (this.clickHandler_) { + this.mouseDownWrapper_ = Blockly.bindEventWithChecks_(this.fieldGroup_, 'mousedown', this, this.clickHandler_); + // pxtblockly & deriv-bot: if a click handler is attached to the image, change the cursor to a pointer + if (this.imageElement_) this.imageElement_.style.cursor = 'pointer'; + } +}; + +/** + * Change the tooltip text for this field. + * @param {string|!Element} newTip Text for tooltip or a parent element to + * link to for its tooltip. + */ +Blockly.FieldImage.prototype.setTooltip = function(newTip) { + this.tooltip_ = newTip; + if (this.imageElement_) { + this.imageElement_.tooltip = newTip; + } +}; + +/** + * Get the source URL of this image. + * @return {string} Current text. + * @override + */ +Blockly.FieldImage.prototype.getValue = function() { + return this.src_; +}; + +/** + * Set the source URL of this image. + * @param {?string} src New source. + * @override + */ +Blockly.FieldImage.prototype.setValue = function(src) { + if (src === null) { + // No change if null. + return; + } + this.src_ = src; + if (this.imageElement_) { + this.imageElement_.setAttributeNS('http://www.w3.org/1999/xlink', 'xlink:href', src || ''); + } +}; + +/** + * Get whether to flip this image in RTL + * @return {boolean} True if we should flip in RTL. + */ +Blockly.FieldImage.prototype.getFlipRtl = function() { + return this.flipRtl_; +}; + +/** + * Set the alt text of this image. + * @param {?string} alt New alt text. + * @override + */ +Blockly.FieldImage.prototype.setText = function(alt) { + if (alt === null) { + // No change if null. + return; + } + this.text_ = alt; + if (this.imageElement_) { + this.imageElement_.setAttribute('alt', alt || ''); + } +}; + +/** + * Images are fixed width, no need to render. + * @private + */ +Blockly.FieldImage.prototype.render_ = function() { + // NOP +}; + +/** + * Images are fixed width, no need to render even if forced. + */ +Blockly.FieldImage.prototype.forceRerender = function() { + // NOP +}; + +/** + * Images are fixed width, no need to update. + * @private + */ +Blockly.FieldImage.prototype.updateWidth = function() { + // NOP +}; + +/** + * If field click is called, and click handler defined, + * call the handler. + */ +Blockly.FieldImage.prototype.showEditor_ = function() { + if (this.clickHandler_) { + this.clickHandler_(this); + } +}; + +Blockly.Field.register('field_image', Blockly.FieldImage); diff --git a/scratch/hooks/flyout_base.js b/scratch/hooks/flyout_base.js new file mode 100644 index 00000000..2ab51744 --- /dev/null +++ b/scratch/hooks/flyout_base.js @@ -0,0 +1,49 @@ +/* eslint-disable func-names, no-underscore-dangle */ +/** + * Margin around the edges of the blocks in the flyout. + * @type {number} + * @const + */ +Blockly.Flyout.prototype.MARGIN = 24; + +/** + * Update the view based on coordinates calculated in position(). + * @param {number} width The computed width of the flyout's SVG group + * @param {number} height The computed height of the flyout's SVG group. + * @param {number} x The computed x origin of the flyout's SVG group. + * @param {number} y The computed y origin of the flyout's SVG group. + * @protected + * deriv-bot: Imported from Blockly, used in flyout_vertical.js + */ +Blockly.Flyout.prototype.positionAt_ = function(width, height, x, y) { + this.svgGroup_.setAttribute('width', width); + this.svgGroup_.setAttribute('height', height); + if (this.svgGroup_.tagName === 'svg') { + const transform = `translate(${x}px,${y}px)`; + Blockly.utils.setCssTransform(this.svgGroup_, transform); + } else { + // IE and Edge don't support CSS transforms on SVG elements so + // it's important to set the transform on the SVG element itself + const transform = `translate(${x},${y})`; + this.svgGroup_.setAttribute('transform', transform); + } + + // Update the scrollbar (if one exists). + if (this.scrollbar_) { + // Set the scrollbars origin to be the top left of the flyout. + this.scrollbar_.setOrigin(x, y); + this.scrollbar_.resize(); + // Set the position again so that if the metrics were the same (and the + // resize failed) our position is still updated. + this.scrollbar_.setPosition_(this.scrollbar_.position_.x, this.scrollbar_.position_.y); + } +}; + +/** + * Get the width of the flyout. + * @return {number} The width of the flyout. + * deriv-bot: Return actual width rather than this.DEFAULT_WIDTH. + */ +Blockly.Flyout.prototype.getWidth = function() { + return this.width_; +}; diff --git a/scratch/hooks/flyout_vertical.js b/scratch/hooks/flyout_vertical.js new file mode 100644 index 00000000..7ed93ad0 --- /dev/null +++ b/scratch/hooks/flyout_vertical.js @@ -0,0 +1,106 @@ +/* eslint-disable func-names, no-underscore-dangle */ +// deriv-bot: Blockly value, Scratch resets this to, req for correct spacing in flyout. +Blockly.BlockSvg.TAB_WIDTH = 8; + +/** + * Move the flyout to the edge of the workspace. + */ +Blockly.VerticalFlyout.prototype.position = function() { + if (!this.isVisible()) { + return; + } + const targetWorkspaceMetrics = this.targetWorkspace_.getMetrics(); + if (!targetWorkspaceMetrics) { + // Hidden components will return null. + return; + } + // Record the height for Blockly.Flyout.getMetrics_ + // deriv-bot: -20 so it's unattached to bottom. + this.height_ = targetWorkspaceMetrics.viewHeight - 30; + + const edgeWidth = this.width_ - this.CORNER_RADIUS; + // deriv-bot: use this.height_ instead of targetWorkspaceMetrics.veiwHeight + const edgeHeight = this.height_ - 2 * this.CORNER_RADIUS; + this.setBackgroundPath_(edgeWidth, edgeHeight); + + // Y is always 0 since this is a vertical flyout. + // deriv-bot: We want some spacing between top and toolbox. + const y = 10; + let x; + + // If this flyout is the toolbox flyout. + if (this.targetWorkspace_.toolboxPosition === this.toolboxPosition_) { + // If there is a category toolbox. + if (targetWorkspaceMetrics.toolboxWidth) { + if (this.toolboxPosition_ === Blockly.TOOLBOX_AT_LEFT) { + x = this.parentToolbox_.HtmlDiv.clientWidth + Blockly.BlockSvg.TAB_WIDTH; // deriv-bot: Allow for dynamic toolbox width. + } else { + x = targetWorkspaceMetrics.viewWidth - this.width_; + } + } else if (this.toolboxPosition_ === Blockly.TOOLBOX_AT_LEFT) { + x = 0; + } else { + x = targetWorkspaceMetrics.viewWidth; + } + } else if (this.toolboxPosition_ === Blockly.TOOLBOX_AT_LEFT) { + x = 0; + } else { + // Because the anchor point of the flyout is on the left, but we want + // to align the right edge of the flyout with the right edge of the + // blocklyDiv, we calculate the full width of the div minus the width + // of the flyout. + x = targetWorkspaceMetrics.viewWidth + targetWorkspaceMetrics.absoluteLeft - this.width_; + } + this.positionAt_(this.width_, this.height_, x, y); +}; + +/** + * Compute width of flyout. Position mat under each block. + * For RTL: Lay out the blocks and buttons to be right-aligned. + * deriv-bot: Imported from Blockly to allow for dynamic width flyout. + * @private + */ +Blockly.VerticalFlyout.prototype.reflowInternal_ = function() { + this.workspace_.scale = this.targetWorkspace_.scale; + let flyoutWidth = 0; + const blocks = this.workspace_.getTopBlocks(false); + + blocks.forEach(block => { + let { width } = block.getHeightWidth(); + if (block.outputConnection) { + width -= Blockly.BlockSvg.TAB_WIDTH; + } + flyoutWidth = Math.max(flyoutWidth, width); + }); + + this.buttons_.forEach(button => { + flyoutWidth = Math.max(flyoutWidth, button.width); + }); + + flyoutWidth += this.MARGIN * 1.5 + Blockly.BlockSvg.TAB_WIDTH; + flyoutWidth *= this.workspace_.scale; + flyoutWidth += Blockly.Scrollbar.scrollbarThickness; + + if (this.width_ !== flyoutWidth) { + blocks.forEach(block => { + if (this.RTL) { + // With the flyoutWidth known, right-align the blocks. + const oldX = block.getRelativeToSurfaceXY().x; + const newX = flyoutWidth / this.workspace_.scale - this.MARGIN - Blockly.BlockSvg.TAB_WIDTH; + block.moveBy(newX - oldX, 0); + } + }); + + if (this.RTL) { + // With the flyoutWidth known, right-align the buttons. + this.buttons_.forEach(button => { + const { y } = button.getPosition(); + const x = flyoutWidth / this.workspace_.scale - button.width - this.MARGIN - Blockly.BlockSvg.TAB_WIDTH; + button.moveTo(x, y); + }); + } + // Record the width for .getMetrics_ and .position. + this.width_ = flyoutWidth; + this.position(); + } +}; diff --git a/scratch/hooks/gesture.js b/scratch/hooks/gesture.js new file mode 100644 index 00000000..21f52bcb --- /dev/null +++ b/scratch/hooks/gesture.js @@ -0,0 +1,13 @@ +/* eslint-disable func-names, no-underscore-dangle */ + +/** + * Whether this gesture is a click on a field. This should only be called when + * ending a gesture (mouse up, touch end). + * deriv-bot: Don't allow block interaction while in flyout. + * @return {boolean} Whether this gesture was a click on a field. + * @private + */ +Blockly.Gesture.prototype.isFieldClick_ = function() { + const fieldEditable = this.startField_ ? this.startField_.isCurrentlyEditable() : false; + return fieldEditable && !this.hasExceededDragRadius_ && (!this.flyout_ || !this.flyout_.autoClose); +}; diff --git a/scratch/hooks/icon.js b/scratch/hooks/icon.js new file mode 100644 index 00000000..e4f09229 --- /dev/null +++ b/scratch/hooks/icon.js @@ -0,0 +1,34 @@ +/* eslint-disable func-names, no-underscore-dangle */ +/** + * Render the icon. + * @param {number} cursorX Horizontal offset at which to position the icon. + * @return {number} Horizontal offset for next item to draw. + */ +Blockly.Icon.prototype.renderIcon = function(cursorX) { + if (this.collapseHidden && this.block_.isCollapsed()) { + this.iconGroup_.setAttribute('display', 'none'); + return cursorX; + } + + this.iconGroup_.setAttribute('display', 'block'); + + let newCursorX = cursorX; + + const TOP_MARGIN = 9; + const width = this.SIZE; + + if (this.block_.RTL) { + newCursorX -= width; + } + + this.iconGroup_.setAttribute('transform', `translate(${newCursorX},${TOP_MARGIN})`); + this.computeIconLocation(); + + if (this.block_.RTL) { + newCursorX -= Blockly.BlockSvg.SEP_SPACE_X; + } else { + newCursorX += width + Blockly.BlockSvg.SEP_SPACE_X; + } + + return newCursorX; +}; diff --git a/scratch/hooks/index.js b/scratch/hooks/index.js new file mode 100644 index 00000000..88a3727b --- /dev/null +++ b/scratch/hooks/index.js @@ -0,0 +1,13 @@ +import './block'; +import './block_svg'; +import './colours'; +import './data_category'; +import './field_dropdown'; +import './field_image'; +import './flyout_base'; +import './flyout_vertical'; +import './gesture'; +import './icon'; +import './procedures'; +import './toolbox'; +import './variables'; diff --git a/scratch/hooks/procedures.js b/scratch/hooks/procedures.js new file mode 100644 index 00000000..9538684a --- /dev/null +++ b/scratch/hooks/procedures.js @@ -0,0 +1,137 @@ +/* eslint-disable func-names, no-underscore-dangle */ +import { translate } from '../../common/lang/i18n'; + +/** + * Construct the blocks required by the flyout for the procedure category. + * @param {!Blockly.Workspace} workspace The workspace containing procedures. + * @return {!Array.} Array of XML block elements. + */ +Blockly.Procedures.flyoutCategory = function(workspace) { + const xmlList = []; + + if (Blockly.Blocks.procedures_defnoreturn) { + const label = document.createElement('label'); + label.setAttribute('text', translate('procedures_defnoreturn')); + xmlList.push(label); + + // + // do something + // + const block = document.createElement('block'); + block.setAttribute('type', 'procedures_defnoreturn'); + block.setAttribute('gap', 16); + + // TEMP + const nameField = document.createElement('field'); + nameField.setAttribute('name', 'NAME'); + nameField.appendChild(document.createTextNode(translate('do something'))); + + block.appendChild(nameField); + xmlList.push(block); + } + + if (Blockly.Blocks.procedures_defreturn) { + const label = document.createElement('label'); + label.setAttribute('text', translate('procedures_defreturn')); // TEMP + label.setAttribute('web-class', 'test'); + xmlList.push(label); + + // + // do something + // + const block = document.createElement('block'); + block.setAttribute('type', 'procedures_defreturn'); + block.setAttribute('gap', 16); + + const nameField = document.createElement('field'); + nameField.setAttribute('name', 'NAME'); + nameField.appendChild(document.createTextNode(translate('do something'))); + + block.appendChild(nameField); + xmlList.push(block); + } + + if (Blockly.Blocks.procedures_ifreturn) { + const label = document.createElement('label'); + label.setAttribute('text', translate('procedures_ifreturn')); // TEMP + xmlList.push(label); + + // + const block = document.createElement('block'); + block.setAttribute('type', 'procedures_ifreturn'); + block.setAttribute('gap', 16); + xmlList.push(block); + } + + if (xmlList.length) { + // Add slightly larger gap between system blocks and user calls. + xmlList[xmlList.length - 1].setAttribute('gap', 24); + } + + function populateProcedures(procedureList, templateName) { + for (let i = 0; i < procedureList.length; i++) { + const name = procedureList[i][0]; + const args = procedureList[i][1]; + + // + // + // + // + // + const block = document.createElement('block'); + block.setAttribute('type', templateName); + block.setAttribute('gap', 16); + + const mutation = document.createElement('mutation'); + mutation.setAttribute('name', name); + block.appendChild(mutation); + + args.forEach(argumentName => { + const arg = document.createElement('arg'); + arg.setAttribute('name', argumentName); + mutation.appendChild(arg); + }); + + xmlList.push(block); + } + } + + const tuple = Blockly.Procedures.allProcedures(workspace); + populateProcedures(tuple[0], 'procedures_callnoreturn'); + populateProcedures(tuple[1], 'procedures_callreturn'); + return xmlList; +}; + +/** + * Find the definition block for the named procedure. + * @param {string} name Name of procedure. + * @param {!Blockly.Workspace} workspace The workspace to search. + * @return {Blockly.Block} The procedure definition block, or null not found. + */ +Blockly.Procedures.getDefinition = function(name, workspace) { + // Assume that a procedure definition is a top block. + const blocks = workspace.getTopBlocks(false); + for (let i = 0; i < blocks.length; i++) { + if (blocks[i].getProcedureDef) { + const tuple = blocks[i].getProcedureDef(); + if (tuple && Blockly.Names.equals(tuple[0], name)) { + return blocks[i]; + } + } + } + return null; +}; + +// Scratch has a broken version where they return `false` if Blockly.Names.equals(procName[0], name). +// https://github.com/LLK/scratch-blocks/pull/1930 +Blockly.Procedures.isNameUsed = function(name, workspace, optExclude) { + const blocks = workspace.getAllBlocks(false); + // Iterate through every block and check the name. + return blocks.some(block => { + if (block !== optExclude && block.getProcedureDef) { + const procName = block.getProcedureDef(); + return Blockly.Names.equals(procName[0], name); + } + return false; + }); +}; diff --git a/scratch/hooks/toolbox.js b/scratch/hooks/toolbox.js new file mode 100644 index 00000000..ed9307bb --- /dev/null +++ b/scratch/hooks/toolbox.js @@ -0,0 +1,113 @@ +/* eslint-disable func-names, no-underscore-dangle */ +/** + * Fill the toolbox with categories and blocks. + * @param {!Node} newTree DOM tree of blocks. + * @private + */ +Blockly.Toolbox.prototype.populate_ = function(newTree) { + this.categoryMenu_.populate(newTree); +}; + +/** + * Show blocks for specific category in flyout + * This is different from Scratch as they show everything in one single flyout. + * @private + */ +Blockly.Toolbox.prototype.showCategory_ = function(category_id) { + let allContents = []; + + const category = this.categoryMenu_.categories_.find(menuCategory => menuCategory.id_ === category_id); + if (!category) { + return; + } + + allContents = allContents.concat(category.getContents()); + + // TEMP: For testing only, generate labels for each block for QA + let newAllContents = []; + if (Array.isArray(allContents) && allContents.length > 1) { + allContents.forEach(node => { + if (node.nodeName === 'block') { + const type = node.getAttribute('type'); + const labelString = ``; + + const labelXml = Blockly.Xml.textToDom(labelString); + newAllContents.push(...[labelXml.firstChild, node]); + } + }); + } else { + newAllContents = allContents; + } + + this.flyout_.autoClose = true; + this.flyout_.show(newAllContents); +}; + +/** + * Opens the selected category + * deriv-bot: unlike in Scratch, we want to have category-specific flyouts + removed opt_shouldScroll + * @param {Blockly.Toolbox.Category} item The category to select. + */ +Blockly.Toolbox.prototype.setSelectedItem = function(item) { + if (this.selectedItem_) { + // They selected a different category but one was already open. Close it. + this.selectedItem_.setSelected(false); + } + this.selectedItem_ = item; + if (this.selectedItem_ != null) { + this.selectedItem_.setSelected(true); + // Scroll flyout to the top of the selected category + const categoryId = item.id_; + this.showCategory_(categoryId); + } else { + this.flyout_.hide(); + } +}; + +/** + * Update the flyout's contents without closing it. Should be used in response + * to a change in one of the dynamic categories, such as variables or + * procedures. + * deriv-bot: We don't want to showAll_() cause it'll populate the entire + * flyout with all available blocks. This method is called by refreshToolboxSelection_() + * which does the actual refreshing. + */ +Blockly.Toolbox.prototype.refreshSelection = function() { + // this.showAll_(); +}; + +/** + * Move the toolbox to the edge. + */ +Blockly.Toolbox.prototype.position = function() { + const treeDiv = this.HtmlDiv; + if (!treeDiv) { + // Not initialized yet. + return; + } + const svg = this.workspace_.getParentSvg(); + const svgSize = Blockly.svgSize(svg); + if (this.horizontalLayout_) { + treeDiv.style.left = '0'; + treeDiv.style.height = 'auto'; + treeDiv.style.width = `${svgSize.width}px`; + this.height = treeDiv.offsetHeight; + if (this.toolboxPosition === Blockly.TOOLBOX_AT_TOP) { + // Top + treeDiv.style.top = '0'; + } else { + // Bottom + treeDiv.style.bottom = '0'; + } + } else { + if (this.toolboxPosition === Blockly.TOOLBOX_AT_RIGHT) { + // Right + treeDiv.style.right = '0'; + } else { + // Left + treeDiv.style.left = '0'; + } + treeDiv.style.height = '100%'; + } + this.flyout_.position(); +}; diff --git a/scratch/hooks/variables.js b/scratch/hooks/variables.js new file mode 100644 index 00000000..51e9b176 --- /dev/null +++ b/scratch/hooks/variables.js @@ -0,0 +1,35 @@ +/* eslint-disable func-names */ +/** + * Find all user-created variables that are in use in the workspace. + * For use by generators. + * To get a list of all variables on a workspace, including unused variables, + * call Workspace.getAllVariables. + * deriv-bot: Required for JS generator to work. + * @param {!Blockly.Workspace} ws The workspace to search for variables. + * @return {!Array.} Array of variable models. + */ +Blockly.Variables.allUsedVarModels = function(ws) { + const blocks = ws.getAllBlocks(false); + const variableHash = Object.create(null); + + // Iterate through every block and add each variable to the hash. + blocks.forEach(block => { + const blockVariables = block.getVarModels(); + if (blockVariables) { + blockVariables.forEach(blockVariable => { + const id = blockVariable.getId(); + if (id) { + variableHash[id] = blockVariable; + } + }); + } + }); + + // Flatten the hash into a list. + const variableList = []; + Object.keys(variableHash).forEach(id => { + variableList.push(variableHash[id]); + }); + + return variableList; +}; diff --git a/scratch/index.js b/scratch/index.js index e78d213b..5ba21806 100644 --- a/scratch/index.js +++ b/scratch/index.js @@ -1,10 +1,7 @@ -import './customBlockly'; -import blocks from './blocks'; import { isMainBlock, save, disable, - deleteBlocksLoadedBy, addLoadersFirst, cleanUpOnLoad, addDomAsBlock, @@ -14,14 +11,63 @@ import { removeUnavailableMarkets, strategyHasValidTradeTypeCategory, cleanBeforeExport, -} from './utils'; -import Interpreter from '../src/engine/utils/Interpreter'; -import createError from '../../common/error'; -import { translate, xml as translateXml } from '../../../common/i18n'; -import { getLanguage } from '../../../common/lang'; -import { observer as globalObserver } from '../../../common/utils/observer'; -import { showDialog } from '../../bot/tools'; -import GTM from '../scratch/utils'; +} from './utils'; +import createError from '../common/error'; +import GTM from '../common/integrations/gtm'; +import Interpreter from '../common/interpreter'; +import { translate, xml as translateXml } from '../common/lang/i18n'; +import { getLanguage } from '../common/lang/lang'; +import { observer as globalObserver } from '../common/observer'; +import { showDialog } from '../common/tools'; + +export const scratchWorkspaceInit = async (scratch_area_name, scratch_div_name) => { + try { + const toolbox_xml = await fetch('dist/toolbox.xml').then(response => response.text()); + const main_xml = await fetch('dist/main.xml').then(response => response.text()); + const workspace = Blockly.inject(scratch_div_name, { + media : 'dist/media/', + toolbox : toolbox_xml, + trashcan: true, + zoom : { + wheel: true, + }, + }); + + // TODO: Add GTM workspace listener for `Block Event` + // workspace.addChangeListener(() => {}); + + Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(main_xml), workspace); + + const onWorkspaceResize = () => { + let el_scratch_area = document.getElementById(scratch_area_name); + + const scratch_area = el_scratch_area; + const scratch_div = document.getElementById(scratch_div_name); + + let x = 0; + let y = 0; + + do { + x += el_scratch_area.offsetLeft; + y += el_scratch_area.offsetTop; + el_scratch_area = el_scratch_area.offsetParent; + } while (el_scratch_area); + + // Position scratch_div over scratch_area. + scratch_div.style.left = `${x}px`; + scratch_div.style.top = `${y}px`; + scratch_div.style.width = `${scratch_area.offsetWidth}px`; + scratch_div.style.height = `${scratch_area.offsetHeight}px`; + + Blockly.svgResize(workspace); + }; + + window.addEventListener('resize', onWorkspaceResize); + onWorkspaceResize(); + } catch (error) { + // TODO: Handle error. + } +}; const setBeforeUnload = off => { if (off) { @@ -45,14 +91,7 @@ const disableStrayBlocks = () => { } }); }; -const disposeBlocksWithLoaders = () => { - Blockly.mainWorkspace.addChangeListener(ev => { - setBeforeUnload(); - if (ev.type === 'delete' && ev.oldXml.getAttribute('type') === 'loader' && ev.group !== 'undo') { - deleteBlocksLoadedBy(ev.blockId, ev.group); - } - }); -}; + const marketsWereRemoved = xml => { if (!Array.from(xml.children).every(block => !removeUnavailableMarkets(block))) { if (window.trackJs) { @@ -77,6 +116,7 @@ const marketsWereRemoved = xml => { } return false; }; + export const loadWorkspace = xml => { if (!strategyHasValidTradeTypeCategory(xml)) return; if (marketsWereRemoved(xml)) return; @@ -129,10 +169,12 @@ export const loadBlocks = (xml, dropEvent = {}) => { } ); }; + const xmlToStr = xml => { const serializer = new XMLSerializer(); return serializer.serializeToString(xml); }; + const addBlocklyTranslation = () => { $.ajaxPrefilter(options => { options.async = true; // eslint-disable-line no-param-reassign @@ -149,6 +191,7 @@ const addBlocklyTranslation = () => { $.getScript(`translations/${lang}.js`, resolve); }); }; + const onresize = () => { let element = document.getElementById('blocklyArea'); const blocklyArea = element; @@ -166,15 +209,17 @@ const onresize = () => { blocklyDiv.style.width = `${blocklyArea.offsetWidth}px`; blocklyDiv.style.height = `${blocklyArea.offsetHeight}px`; }; + const render = workspace => () => { onresize(); Blockly.svgResize(workspace); }; + const overrideBlocklyDefaultShape = () => { const addDownloadToMenu = block => { if (block instanceof Object) { // eslint-disable-next-line no-param-reassign, max-len - block.customContextMenu = function customContextMenu(options) { + block.customContextMenu = function(options) { options.push({ text : translate('Download'), enabled : true, @@ -183,7 +228,7 @@ const overrideBlocklyDefaultShape = () => { '' ); xml.appendChild(Blockly.Xml.blockToDom(this)); - save('binary-bot-block', true, xml); + save('deriv-bot-block', true, xml); }, }); }; @@ -196,6 +241,7 @@ const overrideBlocklyDefaultShape = () => { } }); }; + const repaintDefaultColours = () => { Blockly.Msg.LOGIC_HUE = '#DEDEDE'; Blockly.Msg.LOOPS_HUE = '#DEDEDE'; @@ -207,14 +253,14 @@ const repaintDefaultColours = () => { Blockly.Msg.VARIABLES_DYNAMIC_HUE = '#DEDEDE'; Blockly.Msg.PROCEDURES_HUE = '#DEDEDE'; - Blockly.Blocks.logic.HUE = '#DEDEDE'; - Blockly.Blocks.loops.HUE = '#DEDEDE'; - Blockly.Blocks.math.HUE = '#DEDEDE'; - Blockly.Blocks.texts.HUE = '#DEDEDE'; - Blockly.Blocks.lists.HUE = '#DEDEDE'; - Blockly.Blocks.colour.HUE = '#DEDEDE'; - Blockly.Blocks.variables.HUE = '#DEDEDE'; - Blockly.Blocks.procedures.HUE = '#DEDEDE'; + // Blockly.Blocks.logic.HUE = '#DEDEDE'; + // Blockly.Blocks.loops.HUE = '#DEDEDE'; + // Blockly.Blocks.math.HUE = '#DEDEDE'; + // Blockly.Blocks.texts.HUE = '#DEDEDE'; + // Blockly.Blocks.lists.HUE = '#DEDEDE'; + // Blockly.Blocks.colour.HUE = '#DEDEDE'; + // Blockly.Blocks.variables.HUE = '#DEDEDE'; + // Blockly.Blocks.procedures.HUE = '#DEDEDE'; }; export default class _Blockly { @@ -222,16 +268,18 @@ export default class _Blockly { this.blocksXmlStr = ''; this.generatedJs = ''; // eslint-disable-next-line no-underscore-dangle - Blockly.WorkspaceSvg.prototype.preloadAudio_ = () => {}; // https://github.com/google/blockly/issues/299 + // Blockly.WorkspaceSvg.prototype.preloadAudio_ = () => {}; // https://github.com/google/blockly/issues/299 this.initPromise = new Promise(resolve => { $.get('xml/toolbox.xml', toolboxXml => { - blocks(); const workspace = Blockly.inject('blocklyDiv', { toolbox: xmlToStr(translateXml(toolboxXml.getElementsByTagName('xml')[0])), zoom : { - wheel: false, + wheel : true, + startScale: 1.1, }, - trashcan: false, + trashcan : true, + scrollbars: true, + media : 'image/scratch/', }); workspace.addChangeListener(event => { if (event.type === Blockly.Events.BLOCK_CREATE) { @@ -268,7 +316,6 @@ export default class _Blockly { this.blocksXmlStr = Blockly.Xml.domToPrettyText(main); Blockly.Xml.domToWorkspace(main.getElementsByTagName('xml')[0], workspace); this.zoomOnPlusMinus(); - disposeBlocksWithLoaders(); setTimeout(() => { setBeforeUnload(true); Blockly.mainWorkspace.cleanUp(); @@ -280,6 +327,7 @@ export default class _Blockly { }); }); } + /* eslint-disable class-methods-use-this */ zoomOnPlusMinus(zoomIn) { const metrics = Blockly.mainWorkspace.getMetrics(); @@ -289,12 +337,14 @@ export default class _Blockly { Blockly.mainWorkspace.zoom(metrics.viewWidth / 2, metrics.viewHeight / 2, -1); } } + resetWorkspace() { Blockly.Events.setGroup('reset'); Blockly.mainWorkspace.clear(); Blockly.Xml.domToWorkspace(Blockly.Xml.textToDom(this.blocksXmlStr), Blockly.mainWorkspace); Blockly.Events.setGroup(false); } + /* eslint-disable class-methods-use-this */ cleanUp() { Blockly.Events.setGroup(true); @@ -313,6 +363,7 @@ export default class _Blockly { // Fire an event to allow scrollbars to resize. Blockly.mainWorkspace.resizeContents(); } + /* eslint-disable class-methods-use-this */ load(blockStr = '', dropEvent = {}) { let xml; @@ -333,6 +384,7 @@ export default class _Blockly { throw createError('FileLoad', translate('Unable to load the block file')); } } + /* eslint-disable class-methods-use-this */ save(arg) { const { filename, collection } = arg; @@ -344,21 +396,20 @@ export default class _Blockly { save(filename, collection, xml); } + run(limitations = {}) { disableStrayBlocks(); + let code; try { code = ` var BinaryBotPrivateInit, BinaryBotPrivateStart, BinaryBotPrivateBeforePurchase, BinaryBotPrivateDuringPurchase, BinaryBotPrivateAfterPurchase; - var BinaryBotPrivateLastTickTime var BinaryBotPrivateTickAnalysisList = []; - function BinaryBotPrivateRun(f, arg) { if (f) return f(arg); return false; } - function BinaryBotPrivateTickAnalysis() { var currentTickTime = Bot.getLastTick(true).epoch if (currentTickTime === BinaryBotPrivateLastTickTime) { @@ -369,13 +420,9 @@ function BinaryBotPrivateTickAnalysis() { BinaryBotPrivateRun(BinaryBotPrivateTickAnalysisList[BinaryBotPrivateI]); } } - var BinaryBotPrivateLimitations = ${JSON.stringify(limitations)}; - ${Blockly.JavaScript.workspaceToCode(Blockly.mainWorkspace)} - BinaryBotPrivateRun(BinaryBotPrivateInit); - while(true) { BinaryBotPrivateTickAnalysis(); BinaryBotPrivateRun(BinaryBotPrivateStart) @@ -407,6 +454,7 @@ while(true) { this.stop(); } } + stop(stopBeforeStart) { if (!stopBeforeStart) { const $runButtons = $('#runButton, #summaryRunButton'); @@ -421,16 +469,19 @@ while(true) { this.interpreter = null; } } + /* eslint-disable class-methods-use-this */ undo() { Blockly.Events.setGroup('undo'); Blockly.mainWorkspace.undo(); Blockly.Events.setGroup(false); } + /* eslint-disable class-methods-use-this */ redo() { Blockly.mainWorkspace.undo(true); } + /* eslint-disable class-methods-use-this */ hasStarted() { return this.interpreter && this.interpreter.hasStarted(); diff --git a/scratch/relationChecker.js b/scratch/relationChecker.js deleted file mode 100644 index c4b03989..00000000 --- a/scratch/relationChecker.js +++ /dev/null @@ -1,114 +0,0 @@ -/* eslint-disable no-underscore-dangle */ -import { observer as globalObserver } from '../../../common/utils/observer'; -import { durationToSecond } from '../../../common/utils/tools'; -import config from '../../common/const'; -import { symbolApi } from '../shared'; -import { translate } from '../../../common/i18n'; -import { findTopParentBlock, disable, enable, expandDuration } from './utils'; - -const isInRange = (amount, min, max) => !Number.isNaN(+amount) && +amount >= min && +amount <= max; - -const getNumField = (block, fieldName) => { - let field = block.getInputTargetBlock(fieldName); - if (field !== null && field.type === 'math_number') { - field = field.getFieldValue('NUM').trim(); - return field; - } - return ''; -}; - -const insideHolder = blockObj => { - const parent = findTopParentBlock(blockObj); - if (blockObj.isInFlyout) { - return true; - } - if (parent !== null && ['block_holder', 'loader'].indexOf(parent.type) >= 0) { - return true; - } - return false; -}; - -const getListField = (block, fieldName) => block.getFieldValue(fieldName); - -const conditionFields = (blockObj, ev) => { - if ( - (ev.type === 'change' && ev.element === 'field') || - (ev.type === 'move' && typeof ev.newInputName === 'string') - ) { - const symbol = blockObj.getFieldValue('SYMBOL_LIST'); - const tradeType = blockObj.getFieldValue('TRADETYPE_LIST'); - - if (!symbol || !tradeType) { - return; - } - - let duration = getNumField(blockObj, 'DURATION'); - const durationType = getListField(blockObj, 'DURATIONTYPE_LIST'); - - if (duration) { - duration = +duration; - const { minDuration } = symbolApi.getLimitation(symbol, tradeType); - const durationInSeconds = durationToSecond(duration + durationType); - if (!durationInSeconds) { - globalObserver.emit('ui.log.warn', translate('Duration must be a positive integer')); - } else if (durationInSeconds < durationToSecond(minDuration)) { - globalObserver.emit( - 'ui.log.warn', - `${translate('Minimum duration is')} ${expandDuration(minDuration)}` - ); - } else if (durationType === 't' && !(Number.isInteger(duration) && isInRange(duration, 5, 10))) { - globalObserver.emit('ui.log.warn', translate('Number of ticks must be between 5 and 10')); - } else if (!Number.isInteger(duration) || duration < 1) { - globalObserver.emit('ui.log.warn', translate('Expiry time cannot be equal to start time')); - } - } - - let prediction = +getNumField(blockObj, 'PREDICTION'); - - if (prediction) { - prediction = +prediction; - if (!Number.isInteger(prediction) || !isInRange(prediction, 0, 9)) { - globalObserver.emit('ui.log.warn', translate('Prediction must be one digit')); - } - } - } -}; - -const enableIfInside = (blockObj, condition, disableMsg) => { - const topParent = findTopParentBlock(blockObj); - - if (insideHolder(blockObj) || (topParent && condition(topParent))) { - enable(blockObj); - return true; - } - disable(blockObj, disableMsg); - return false; -}; - -const insideMain = (blockObj, ev, name, topName, topDesc) => - enableIfInside( - blockObj, - topParent => topParent.type === topName, - `${name} ${translate('must be added inside:')} ${topDesc}` - ); - -export const insideTrade = (...args) => insideMain(...args, 'trade', 'trade') && conditionFields(...args); - -export const insideBeforePurchase = (...args) => insideMain(...args, 'before_purchase', 'Before Purchase'); - -export const insideDuringPurchase = (...args) => insideMain(...args, 'during_purchase', 'During Purchase'); - -export const insideAfterPurchase = (...args) => insideMain(...args, 'after_purchase', 'After Purchase'); - -const getScopeNames = scopes => scopes.map(n => config.scopeNames[n]); - -export const insideScope = (blockObj, ev, name, scopes) => - enableIfInside( - blockObj, - topParent => scopes.includes(topParent.type), - `${name} ${translate('must be added inside')}: (${getScopeNames(scopes)})` - ); - -export const mainScope = (blockObj, ev, name) => { - insideScope(blockObj, ev, name, ['trade', 'during_purchase', 'before_purchase', 'after_purchase', 'tick_analysis']); -}; diff --git a/scratch/sass/_blockly-toolbox.scss b/scratch/sass/_blockly-toolbox.scss index d4694e1f..395e9e72 100644 --- a/scratch/sass/_blockly-toolbox.scss +++ b/scratch/sass/_blockly-toolbox.scss @@ -14,12 +14,12 @@ } .blocklyTreeIcon.blocklyTreeIconOpen { - background-image: url('../image/down-arrow.svg') !important; + // background-image: url('dist/media/image/down-arrow.svg') !important; background-position: -0.19em -0.38em !important; } .blocklyTreeIcon.blocklyTreeIconClosedLtr { - background-image: url('../image/down-arrow.svg') !important; + // background-image: url('dist/media/image/down-arrow.svg') !important; background-position: -0.19em -0.38em !important; } @@ -44,10 +44,11 @@ } .blocklyFlyoutBackground { - fill: $white !important; + fill: #fcfcfc !important; fill-opacity: 1 !important; stroke: $brand-dark-gray; - stroke-width: 0.06em; + stroke-width: 0.15em; + stroke-linecap: round; } .blocklyToolboxDiv { @@ -70,22 +71,45 @@ opacity: 1 !important; } -.blocklyScrollbarVertical, -.blocklyScrollbarHorizontal { - display: none; +.blocklySelected > .blocklyPath { + stroke: #fc3; + stroke-width: 2px; } .blocklyTreeRow { + // box-shadow: inset 0 -0.06em 0 0 #dedede; margin-bottom: 0px !important; height: 1.9em !important; padding-top: 0.25em; - box-shadow: inset 0 -0.06em 0 0 #dedede; /* stylelint-disable-line */ } .blocklySvg { position: absolute; } -.blocklyMainBackground { - stroke: none; +.scratchCategoryMenu { + width: 100%; + color: #575e75; + font-size: 1em; + user-select: none; +} + +.scratchCategoryMenuItem { + padding: 0.5em 1em; + cursor: pointer; + text-align: left; +} + +.scratchCategoryItemBubble { + display: none; } + +#scratch_area { + position: absolute; + height: 100%; + width: 100%; +} + +#scratch_div { + position: absolute; +} \ No newline at end of file diff --git a/scratch/sass/_color.scss b/scratch/sass/_color.scss new file mode 100644 index 00000000..0a313f34 --- /dev/null +++ b/scratch/sass/_color.scss @@ -0,0 +1,11 @@ +$brand-gray: #f2f2f2; +$brand-dark-gray: #dedede; +$brand-blue: #2a3052; +$brand-dark-blue: #15212d; +$brand-orange: #e98024; +$brand-btn: #2e8836; +$brand-btn-active: #14602b; +$brand-primary-dark: #15212d; +$white: #ffffff; +$black: #000000; +$toolbox-btn-active: #dddddd; diff --git a/scratch/shared.js b/scratch/shared.js new file mode 100644 index 00000000..012d452d --- /dev/null +++ b/scratch/shared.js @@ -0,0 +1,448 @@ +import filesaver from 'file-saver'; +import { oppositesToDropdown } from './utils'; +import { generateLiveApiInstance } from '../common/appId'; +import config from '../common/constants'; +import { translate } from '../common/lang/i18n'; +import { observer as globalObserver } from '../common/observer'; +import { + get as getStorage, + set as setStorage, + getTokenList, + removeAllTokens, +} from '../common/storageManager'; +import { symbolApi } from '../src/services/api/shared'; + +let purchaseChoices = [[translate('Click to select'), '']]; + +export const saveAs = ({ data, filename, type }) => { + const blob = new Blob([data], { type }); + filesaver.saveAs(blob, filename); +}; + +export const getPurchaseChoices = () => purchaseChoices; + +const filterPurchaseChoices = (contractType, oppositesName) => { + const { [oppositesName]: tradeTypes } = config.opposites; + + let tmpPurchaseChoices = tradeTypes.filter(k => + contractType === 'both' ? true : contractType === Object.keys(k)[0] + ); + + if (!tmpPurchaseChoices.length) { + tmpPurchaseChoices = tradeTypes; + } + return oppositesToDropdown(tmpPurchaseChoices); +}; + +export const updatePurchaseChoices = (contractType, oppositesName) => { + purchaseChoices = filterPurchaseChoices(contractType, oppositesName); + const purchases = Blockly.mainWorkspace + .getAllBlocks() + .filter(r => ['purchase', 'payout', 'ask_price'].indexOf(r.type) >= 0); + Blockly.Events.recordUndo = false; + purchases.forEach(purchase => { + const value = purchase.getField('PURCHASE_LIST').getValue(); + Blockly.WidgetDiv.hideIfOwner(purchase.getField('PURCHASE_LIST')); + if (value === purchaseChoices[0][1]) { + purchase.getField('PURCHASE_LIST').setText(purchaseChoices[0][0]); + } else if (purchaseChoices.length === 2 && value === purchaseChoices[1][1]) { + purchase.getField('PURCHASE_LIST').setText(purchaseChoices[1][0]); + } else { + purchase.getField('PURCHASE_LIST').setValue(purchaseChoices[0][1]); + purchase.getField('PURCHASE_LIST').setText(purchaseChoices[0][0]); + } + }); + Blockly.Events.recordUndo = true; +}; + +export const expectValue = (block, field) => { + const value = Blockly.JavaScript.valueToCode(block, field, Blockly.JavaScript.ORDER_ATOMIC); + if (!value) { + throw Error(translate(`${field} cannot be empty`)); + } + return value; +}; + +export const fieldGeneratorMapping = {}; + +const getActiveSymbols = symbols => + Object.keys(symbols).reduce( + (acc, symbol) => + symbolApi.getAllowedCategories(symbol).length ? { ...acc, [symbol]: symbols[symbol] } : { ...acc }, + {} + ); + +const getActiveSubMarket = submarkets => + Object.keys(submarkets).reduce( + (acc, submarket) => + Object.keys(getActiveSymbols(submarkets[submarket].symbols)).length + ? { ...acc, [submarket]: submarkets[submarket] } + : { ...acc }, + {} + ); + +const getActiveMarket = markets => + Object.keys(markets).reduce( + (acc, market) => + Object.keys(getActiveSubMarket(markets[market].submarkets)).length + ? { ...acc, [market]: markets[market] } + : { ...acc }, + {} + ); + +fieldGeneratorMapping.MARKET_LIST = () => { + const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets()); + return Object.keys(markets).map(e => [markets[e].name, e]); +}; + +fieldGeneratorMapping.SUBMARKET_LIST = block => () => { + const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets()); + const marketName = block.getFieldValue('MARKET_LIST'); + if (!marketName || marketName === 'Invalid') { + return [['', 'Invalid']]; + } + const submarkets = getActiveSubMarket(markets[marketName].submarkets); + return ( + Object.keys(submarkets) + .map(e => [submarkets[e].name, e]) + // Filter out markets we don't have contracts for + .filter(submarket => !['energy'].includes(submarket[1])) + ); +}; + +fieldGeneratorMapping.SYMBOL_LIST = block => () => { + const markets = getActiveMarket(symbolApi.activeSymbols.getMarkets()); + const submarketName = block.getFieldValue('SUBMARKET_LIST'); + if (!submarketName || submarketName === 'Invalid') { + return [['', '']]; + } + const marketName = block.getFieldValue('MARKET_LIST'); + const submarkets = getActiveSubMarket(markets[marketName].submarkets); + const symbols = getActiveSymbols(submarkets[submarketName].symbols); + return ( + Object.keys(symbols) + .map(e => [symbols[e].display, symbols[e].symbol]) + // Filter out symbols we don't have contracts for (these symbols have only forward-starting) + .filter(symbol => !['frxGBPNOK', 'frxUSDNOK', 'frxUSDNEK', 'frxUSDSEK'].includes(symbol[1])) + ); +}; + +fieldGeneratorMapping.TRADETYPECAT_LIST = block => () => { + const symbol = block.getFieldValue('SYMBOL_LIST'); + if (!symbol) { + return [['', '']]; + } + const allowedCategories = symbolApi.getAllowedCategories(symbol.toLowerCase()); + return Object.keys(config.conditionsCategoryName) + .filter(e => allowedCategories.indexOf(e) >= 0) + .map(e => [config.conditionsCategoryName[e], e]); +}; + +fieldGeneratorMapping.TRADETYPE_LIST = block => () => { + const tradeTypeCat = block.getFieldValue('TRADETYPECAT_LIST'); + if (!tradeTypeCat) { + return [['', '']]; + } + return ( + config.conditionsCategory[tradeTypeCat] + .map(e => [config.opposites[e.toUpperCase()].map(c => c[Object.keys(c)[0]]).join('/'), e]) + // Filter out trade types we don't offer + .filter( + tradeType => !(block.getFieldValue('SUBMARKET_LIST') === 'smart_fx' && tradeType[1] === 'higherlower') + ) + ); +}; + +export const dependentFieldMapping = { + MARKET_LIST : 'SUBMARKET_LIST', + SUBMARKET_LIST : 'SYMBOL_LIST', + SYMBOL_LIST : 'TRADETYPECAT_LIST', + TRADETYPECAT_LIST: 'TRADETYPE_LIST', +}; + +const contractsForStore = JSON.parse(getStorage('contractsForStore') || '[]'); + +const getContractCategory = input => + Object.keys(config.conditionsCategory).find(c => c === input || config.conditionsCategory[c].includes(input)); + +const matchesBarrierCategory = (contract, contractCategory) => { + const conditions = []; + Object.keys(config.barrierCategories).some(barrierCategory => { + if (config.barrierCategories[barrierCategory].includes(contractCategory)) { + conditions.push(contract.barrier_category === barrierCategory); + } + return conditions.length; + }); + // If `barrierCategory` for `contractCategory` not found fallback to all contracts + return !conditions.includes(false); +}; + +const filterContractsByCategory = (contracts, contractCategory, contractType) => { + if (!contracts) return []; + return contracts.filter(contract => { + // We don't offer forward-starting contracts in deriv-bot, remove these + if (contract.start_type === 'forward') { + return false; + } + return contract.contract_category === contractCategory && matchesBarrierCategory(contract, contractType); + }); +}; + +export const getDurationsForContracts = (contractsAvailable, selectedContractType) => { + const defaultDurations = [ + [translate('Ticks'), 't'], + [translate('Seconds'), 's'], + [translate('Minutes'), 'm'], + [translate('Hours'), 'h'], + [translate('Days'), 'd'], + ]; + const noDurationsAvailable = [{ label: translate('Not available'), unit: 'na', minimum: 0 }]; + if (!contractsAvailable) return noDurationsAvailable; + + const getMinimumAmount = input => input.replace(/\D/g, ''); + const getDurationIndex = input => defaultDurations.findIndex(d => d[1] === input.replace(/\d+/g, '')); + + const offeredDurations = []; + + const contractsForContractCategory = filterContractsByCategory( + contractsAvailable, + getContractCategory(selectedContractType), + selectedContractType + ); + contractsForContractCategory.forEach(c => { + if (!c.min_contract_duration || !c.max_contract_duration) return; + + const startIndex = getDurationIndex(c.min_contract_duration); + const endIndex = getDurationIndex(c.max_contract_duration === '1d' ? '24h' : c.max_contract_duration); + + defaultDurations.slice(startIndex, endIndex + 1).forEach((duration, index) => { + if (!offeredDurations.find(offeredDuration => offeredDuration.unit === duration[1])) { + offeredDurations.push({ + label : duration[0], + unit : duration[1], + minimum: index === 0 ? getMinimumAmount(c.min_contract_duration) : 1, + }); + } + }); + }); + // If only intraday contracts available remove day-durations + if (contractsForContractCategory.every(c => c.expiry_type === 'intraday')) { + const dayDurationIndex = offeredDurations.findIndex(d => d[1] === 'd'); + if (dayDurationIndex !== -1) { + offeredDurations.splice(dayDurationIndex, 1); + } + } + if (!offeredDurations.length) { + return noDurationsAvailable; + } + return ( + offeredDurations + // Maintain order based on duration unit + .sort((a, b) => getDurationIndex(a.unit) - getDurationIndex(b.unit)) + ); +}; + +export const haveContractsForSymbol = underlyingSymbol => { + const contractsForSymbol = contractsForStore.find(c => c.symbol === underlyingSymbol); + if (!contractsForSymbol) { + return false; + } + const tokenList = getTokenList(); + const isDifferentAccount = () => tokenList.length && contractsForSymbol.accountName !== tokenList[0].accountName; + if (isDifferentAccount()) { + return false; + } + // Data expired, return cached data, retrieve updated data in background (if not already doing so) + const isExpiredData = () => Math.floor((Date.now() - contractsForSymbol.timestamp) / 1000) > 600; + if (isExpiredData()) { + const event = `contractsLoaded.${underlyingSymbol}`; + if (!globalObserver.isRegistered(event)) { + globalObserver.register(event); + getContractsAvailableForSymbolFromApi(underlyingSymbol); + } + } + return contractsForSymbol; +}; + +export const getContractsAvailableForSymbol = async underlyingSymbol => { + const contractsForSymbol = haveContractsForSymbol(underlyingSymbol); + if (!contractsForSymbol) { + const contractsAvailableForSymbol = await getContractsAvailableForSymbolFromApi(underlyingSymbol); + return Promise.resolve(contractsAvailableForSymbol.available); + } + return Promise.resolve(contractsForSymbol.available); +}; + +export const getContractsAvailableForSymbolFromApi = async underlyingSymbol => { + const api = generateLiveApiInstance(); + let tokenList = getTokenList(); + if (tokenList.length) { + try { + await api.authorize(tokenList[0].token); + } catch (e) { + removeAllTokens(); + tokenList = []; + } + } + const contractsForSymbol = {}; + try { + const response = await api.getContractsForSymbol(underlyingSymbol); + if (response.contracts_for) { + Object.assign(contractsForSymbol, { + symbol : underlyingSymbol, + available: response.contracts_for.available, + timestamp: Date.now(), + }); + if (tokenList.length) { + Object.assign(contractsForSymbol, { + accountName: tokenList[0].accountName, + }); + } + // Avoid duplicate symbols in contractsForStore + contractsForStore + .filter(c => c.symbol === underlyingSymbol) + .forEach(() => + contractsForStore.splice(contractsForStore.findIndex(c => c.symbol === underlyingSymbol), 1) + ); + contractsForStore.push(contractsForSymbol); + setStorage('contractsForStore', JSON.stringify(contractsForStore)); + globalObserver.unregisterAll(`contractsLoaded.${underlyingSymbol}`); + } + } catch (e) { + if (window.trackJs) { + trackJs.addMetadata('getContractsAvailableForSymbolFromApi Error', e.message); + } + } + if (typeof api.disconnect === 'function') { + api.disconnect(); + } + return contractsForSymbol; +}; + +export const getBarriersForContracts = (contracts, selectedContractType, selectedDuration, selectedBarrierTypes) => { + const barriers = { values: [] }; + const category = getContractCategory(selectedContractType); + const contractsForContractCategory = filterContractsByCategory(contracts, category, selectedContractType); + + const offsetRegex = new RegExp('^[-|+]([0-9]+.[0-9]+)$'); + const isOffset = input => input && offsetRegex.test(input.toString()); + + if (contractsForContractCategory) { + const barrierProps = ['high_barrier', 'low_barrier']; + + selectedBarrierTypes.forEach((barrierType, index) => { + const selectedOffset = ['+', '-'].includes(barrierType); + + // Find barriers based on selected duration & by selected barrier type + // i.e. Hours & days can have different barrier values, offset + absolute sometimes have different values + let contract; + contract = contractsForContractCategory.find(c => { + const durations = getDurationsForContracts([c], selectedContractType); + if (durations.map(duration => duration.unit).includes(selectedDuration)) { + const barrierIsOffset = () => isOffset(c.barrier || c[barrierProps[index]]); + return (selectedOffset && barrierIsOffset()) || (!selectedOffset && !barrierIsOffset()); + } + return false; + }); + if (!contract) { + contract = contractsForContractCategory.find( + c => barrierType === 'absolute' && !isOffset(c.barrier || c.high_barrier) + ); + } + // Fallback to contract with smallest barriers + if (!contract) { + contract = contractsForContractCategory + .sort((a, b) => { + const c = a.barrier || a.high_barrier; + const d = b.barrier || b.high_barrier; + return parseFloat(c) - parseFloat(d); + }) + .shift(); + } + const barrierlessCategories = ['reset', 'runs']; + if (contract && !barrierlessCategories.includes(contract.contract_category)) { + const propName = contract.barriers === 1 ? 'barrier' : barrierProps[index]; + if (contract[propName]) { + const barrierMatch = contract[propName].toString().match(offsetRegex); + barriers.values[index] = barrierMatch ? barrierMatch[1] : contract[propName]; + } + + if (['intraday', 'tick'].includes(contract.expiry_type) && isOffset(contract[propName])) { + barriers.allowBothTypes = true; // Allow both offset + absolute barriers + } else if (barrierType === 'absolute' && !isOffset(contract[propName])) { + barriers.allowAbsoluteType = true; + } + + if (contract.barriers === 1) { + selectedBarrierTypes.splice(index + 1, 1); + } + } + }); + if ( + barriers.values.length === 2 && + selectedBarrierTypes.every(val => val === selectedBarrierTypes[0]) && + barriers.values.every(val => val === barriers.values[0]) + ) { + // Set distinct values if equal barrier types have equal values + barriers.values[1] = (barriers.values[0] * 0.95).toFixed(1); + } + } + return barriers; +}; + +export const getPredictionForContracts = (contracts, selectedContractType) => { + const category = getContractCategory(selectedContractType); + const contractsForContractCategory = filterContractsByCategory(contracts, category, selectedContractType); + + const contractMapping = {}; + if (category === 'digits') { + contractMapping.matchesdiffers = ['DIGITMATCH', 'DIGITDIFF']; + contractMapping.overunder = ['DIGITOVER', 'DIGITUNDER']; + } else if (category === 'highlowticks') { + contractMapping.highlowticks = ['TICKHIGH', 'TICKLOW']; + } + + const predictionRange = []; + if (contractMapping[selectedContractType]) { + const contract = contractsForContractCategory.find(c => + contractMapping[selectedContractType].includes(c.contract_type) + ); + if (contract && contract.last_digit_range) { + predictionRange.push(...contract.last_digit_range); + } else { + predictionRange.push(0); + } + } + return predictionRange; +}; + +export const pollForContracts = symbol => + new Promise(resolve => { + const contractsForSymbol = haveContractsForSymbol(symbol); + if (!contractsForSymbol) { + // Register an event and use as a lock to avoid spamming API + const event = `contractsLoaded.${symbol}`; + if (!globalObserver.isRegistered(event)) { + globalObserver.register(event, () => {}); + getContractsAvailableForSymbol(symbol).then(contracts => { + globalObserver.unregisterAll(event); // Release the lock + resolve(contracts); + }); + } else { + // Request in progress, start polling localStorage until contracts are available. + const pollingFn = setInterval(() => { + const contracts = haveContractsForSymbol(symbol); + if (contracts) { + clearInterval(pollingFn); + resolve(contracts.available); + } + }, 100); + setTimeout(() => { + clearInterval(pollingFn); + resolve([]); + }, 10000); + } + } else { + resolve(contractsForSymbol.available); + } + }); diff --git a/scratch/utils.js b/scratch/utils.js index cacb8aa7..f9a6fc2e 100644 --- a/scratch/utils.js +++ b/scratch/utils.js @@ -1,8 +1,7 @@ -import { fieldGeneratorMapping } from './blocks/shared'; -import { saveAs } from '../shared'; -import config from '../../common/const'; -import { translate } from '../../../common/i18n'; -import { observer as globalObserver } from '../../../common/utils/observer'; +import { fieldGeneratorMapping, saveAs } from './shared'; +import config from '../common/constants'; +import { translate } from '../common/lang/i18n'; +import { observer as globalObserver } from '../common/observer'; export const isMainBlock = blockType => config.mainBlocks.indexOf(blockType) >= 0; @@ -215,7 +214,7 @@ export const insideMainBlocks = block => { return parent.type && isMainBlock(parent.type); }; -export const save = (filename = 'binary-bot', collection = false, xmlDom) => { +export const save = (filename = 'deriv-bot', collection = false, xmlDom) => { xmlDom.setAttribute('collection', collection ? 'true' : 'false'); const data = Blockly.Xml.domToPrettyText(xmlDom); saveAs({ data, type: 'text/xml;charset=utf-8', filename: `${filename}.xml` }); @@ -254,6 +253,7 @@ class DeleteStray extends Blockly.Events.Abstract { super(block); this.run(true); } + run(redo) { const { recordUndo } = Blockly.Events; Blockly.Events.recordUndo = false; @@ -280,6 +280,7 @@ class Hide extends Blockly.Events.Abstract { this.sourceHeaderId = header.id; this.run(true); } + run() { const { recordUndo } = Blockly.Events; Blockly.Events.recordUndo = false; @@ -308,11 +309,13 @@ export const deleteBlocksLoadedBy = (id, eventGroup = true) => { }); Blockly.Events.setGroup(false); }; + export const fixArgumentAttribute = xml => { Array.from(xml.getElementsByTagName('arg')).forEach(o => { if (o.hasAttribute('varid')) o.setAttribute('varId', o.getAttribute('varid')); }); }; + export const addDomAsBlock = blockXml => { if (blockXml.tagName === 'variables') { return Blockly.Xml.domToVariables(blockXml, Blockly.mainWorkspace); diff --git a/src/.DS_Store b/src/.DS_Store index 004d93c1173e04a0c4121f4288b331277a98f736..feb337f5b9b8cc95b35666582c358cd56c2b7703 100644 GIT binary patch delta 71 zcmZoMXfc=|#>B)qu~2NHo+2aH#(>?7j9il)SR^*9uv9Z{mf_%Lnb;7!nVo~51E_4X ZAjfy+$^0UY91K9f$iTp|IYML&GXQtu5B~rF delta 495 zcmZoMXfc=|#>B!ku~2NHo+6{*#(>?7i#IScF$zw0V3OFZ!c@&z&&p8BP{NSOki$^y znUkNKl#`#tz`!8Dz`!UDq&5D70g%POfTS|1ytn|W@>EhmPG)h5fx&e~CT12^Hg*mU zE)FhUuGrv={PN(E#FEltr^KRY5HBFHBqIsR4$05Y0kP{r5+R96VVSAr@d6^w`FSOY znR%&2VBMK1sX#R`;hA|U`Q=XerFkjEV1t4o5*!?y9Gvk2lGW9QhDJIHMkXe;IttZ> z1_q`&3MQtewY8ia;;M$Wo(Z{?Rn;}Mb+f?UU|?i~&O za|<9!mYSf-=H|P&K*NCJhZWNdGtYyL=qgeOs3^$LK(c}n80shvC<`vi%gN762Z}OI jEIhoKor9kP7@eCJGJj{D%rD}|0rUwINYCa7ku}T!ufcw@ diff --git a/src/app.js b/src/app.js index 15e96f16..c35241fc 100644 --- a/src/app.js +++ b/src/app.js @@ -1,9 +1,11 @@ -import React from 'react'; -import ReactDOM from 'react-dom'; -import App from './app.jsx'; +import React from 'react'; +import ReactDOM from 'react-dom'; +import App from './app.jsx'; +import { scratchWorkspaceInit } from '../scratch'; ReactDOM.render( , document.getElementById('root'), + () => scratchWorkspaceInit('scratch_area', 'scratch_div') ); diff --git a/src/app.jsx b/src/app.jsx index 58bde61a..53f58db0 100644 --- a/src/app.jsx +++ b/src/app.jsx @@ -1,8 +1,8 @@ import { Provider } from 'mobx-react'; -import React from 'react'; -import Bot from './components/bot.jsx'; -import RootStore from './stores'; +import React from 'react'; +import Bot from './components/bot.jsx'; +import RootStore from './stores'; class App extends React.Component { rootStore = new RootStore(); diff --git a/src/assets/sass/_bot.scss b/src/assets/sass/_bot.scss index 4e0577bf..ae8d07e2 100644 --- a/src/assets/sass/_bot.scss +++ b/src/assets/sass/_bot.scss @@ -1,4 +1,3 @@ - .main { background: rgba(206, 17, 17, 0.5); } \ No newline at end of file diff --git a/src/components/bot.jsx b/src/components/bot.jsx index f6d0d032..8f495134 100644 --- a/src/components/bot.jsx +++ b/src/components/bot.jsx @@ -1,11 +1,12 @@ -import React from 'react'; -import { connect } from '../stores/connect'; -import '../assets/sass/_bot.scss'; +import React from 'react'; +import Workspace from './workspace.jsx'; +import { connect } from '../stores/connect'; +import '../assets/sass/_bot.scss'; -const Bot = ({ - title, -}) => ( -
{title}
+const Bot = () => ( + + + ); export default connect(({ bot }) => ({ diff --git a/src/components/workspace.jsx b/src/components/workspace.jsx new file mode 100644 index 00000000..f35ea778 --- /dev/null +++ b/src/components/workspace.jsx @@ -0,0 +1,11 @@ +import React from 'react'; +import '../../scratch/sass/_blockly-toolbox.scss'; + +const Workspace = () => ( + +
+
+ +); + +export default Workspace; diff --git a/src/services/api/__tests__/activeSymbols.js b/src/services/api/__tests__/activeSymbols.js index 7d92a5b3..ff3bed65 100644 --- a/src/services/api/__tests__/activeSymbols.js +++ b/src/services/api/__tests__/activeSymbols.js @@ -1,8 +1,9 @@ /* eslint-disable import/no-extraneous-dependencies */ -import { expect } from 'chai'; -import deep from 'deep-diff'; -import ActiveSymbols from '../activeSymbols'; +import { expect } from 'chai'; +import deep from 'deep-diff'; +import ActiveSymbols from '../symbolApi/activeSymbols'; import { generateLiveApiInstance } from '../../../../common/appId'; + /* There is a market called forex, which has a submarket called major_pairs, which has a symbol called frxEURUSD diff --git a/src/services/api/__tests__/index.js b/src/services/api/__tests__/index.js index df01c7e0..bfe7b173 100644 --- a/src/services/api/__tests__/index.js +++ b/src/services/api/__tests__/index.js @@ -1,6 +1,6 @@ /* eslint-disable no-unused-expressions */ -import { expect } from 'chai'; -import _Symbol from '../index'; +import { expect } from 'chai'; +import _Symbol from '../symbolApi'; import { generateLiveApiInstance } from '../../../../common/appId'; describe('symbol', () => { @@ -8,7 +8,7 @@ describe('symbol', () => { describe('Checking functions', () => { let symbol; // eslint-disable-next-line prefer-arrow-callback - beforeAll(function beforeAll(done) { + beforeAll(function(done) { symbol = new _Symbol(api); symbol.initPromise.then(() => { done(); diff --git a/src/services/api/__tests__/ticksService.js b/src/services/api/__tests__/ticksService.js index 16ad5ebb..3d17be9c 100644 --- a/src/services/api/__tests__/ticksService.js +++ b/src/services/api/__tests__/ticksService.js @@ -1,6 +1,6 @@ /* eslint-disable no-unused-expressions */ -import TicksService from '../ticksService'; -import { logoutAllTokens, addTokenIfValid, generateLiveApiInstance } from '../../../common/appId'; +import { logoutAllTokens, addTokenIfValid, generateLiveApiInstance } from '../../../../common/appId'; +import TicksService from '../../../../common/utils/ticksService'; jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000; @@ -23,7 +23,6 @@ describe('Ticks Service', () => { describe('Monitor ticks', () => { const ticks = []; beforeAll(done => { - let key; const callback = ticksList => { ticks.push(ticksList); if (ticks.length === 3) { @@ -31,15 +30,15 @@ describe('Ticks Service', () => { done(); } }; - key = ticksService.monitor({ symbol: 'R_100', callback }); + const key = ticksService.monitor({ symbol: 'R_100', callback }); }); it('Ticks stream received', () => { expect(isTicksList(ticks[0])).toBeTruthy(); }); }); describe('Get ticks', () => { - let ticks; - let candles; + let ticks, + candles; beforeAll(done => { ticksService .request({ symbol: 'R_25' }) diff --git a/src/services/api/chartTicksService.js b/src/services/api/chartTicksService.js index c4bbdafa..55d7a2d6 100644 --- a/src/services/api/chartTicksService.js +++ b/src/services/api/chartTicksService.js @@ -1,5 +1,5 @@ -import { doUntilDone } from '../botPage/bot/tools'; -import TicksService from '../botPage/common/TicksService'; +import { doUntilDone } from '../../../common/tools'; +import TicksService from '../../../common/utils/ticksService'; export default class ChartTicksService extends TicksService { observe() { diff --git a/src/services/api/footer-checks.js b/src/services/api/footer-checks.js index d3489397..0df4703c 100644 --- a/src/services/api/footer-checks.js +++ b/src/services/api/footer-checks.js @@ -1,5 +1,5 @@ /* eslint-disable import/prefer-default-export */ -import { generateLiveApiInstance } from './appId'; +import { generateLiveApiInstance } from '../../../common/appId'; export default async function isEuCountry() { const api = generateLiveApiInstance(); diff --git a/src/services/api/networkMonitor.js b/src/services/api/networkMonitor.js index d951232a..72d5142f 100644 --- a/src/services/api/networkMonitor.js +++ b/src/services/api/networkMonitor.js @@ -4,6 +4,7 @@ export default class NetworkMonitor { this.parentElement = parentElement; this.addEvents(); } + addEvents() { if ('onLine' in navigator) { window.addEventListener('online', () => this.setStatus()); @@ -14,6 +15,7 @@ export default class NetworkMonitor { } this.setStatus(); } + setStatus() { if (navigator.onLine) { this.parentElement.html(''); diff --git a/src/services/api/shared.js b/src/services/api/shared.js index fa842490..6e4e51e7 100644 --- a/src/services/api/shared.js +++ b/src/services/api/shared.js @@ -1,8 +1,7 @@ -import filesaver from 'file-saver'; -import Observer from '../common/utils/observer'; -import { generateLiveApiInstance } from '../../common/appId'; -import _Symbol from '../common/symbolApi'; -import TicksService from '../common/TicksService'; +import _Symbol from './symbolApi'; +import { generateLiveApiInstance } from '../../../common/appId'; +import Observer from '../../../common/observer'; +import TicksService from '../../../common/utils/ticksService'; let tmpApi = generateLiveApiInstance(); @@ -47,9 +46,4 @@ export const updateRow = (prevRowIndex, trade, state) => ({ ], }); -export const saveAs = ({ data, filename, type }) => { - const blob = new Blob([data], { type }); - filesaver.saveAs(blob, filename); -}; - export const restrictInputCharacter = ({ whitelistRegEx, input }) => input.match(new RegExp(whitelistRegEx)); diff --git a/src/services/api/symbolApi/activeSymbols.js b/src/services/api/symbolApi/activeSymbols.js index 4558d995..15abeefe 100644 --- a/src/services/api/symbolApi/activeSymbols.js +++ b/src/services/api/symbolApi/activeSymbols.js @@ -11,9 +11,9 @@ const groupBy = (arr, field) => return grouped; }, {}); -let apiActiveSymbols; -let groupedMarkets; -let groupedSubmarkets; +let apiActiveSymbols, + groupedMarkets, + groupedSubmarkets; const parsedMarkets = {}; const parsedSubmarkets = {}; @@ -66,10 +66,12 @@ export default class ActiveSymbols { parseSubmarkets(); parseSymbols(); } + /* eslint-disable class-methods-use-this */ getMarkets() { return parsedMarkets; } + getSymbols() { return parsedSymbols; } diff --git a/src/services/api/symbolApi/index.js b/src/services/api/symbolApi/index.js index 67923f14..d59889f7 100644 --- a/src/services/api/symbolApi/index.js +++ b/src/services/api/symbolApi/index.js @@ -1,7 +1,7 @@ -import ActiveSymbols from './activeSymbols'; -import config from '../../common/const'; -import { getObjectValue } from '../../../common/utils/tools'; -import { getTokenList, removeAllTokens } from '../../../common/utils/storageManager'; +import ActiveSymbols from './activeSymbols'; +import config from '../../../../common/constants'; +import { getObjectValue } from '../../../../common/helpers'; +import { getTokenList, removeAllTokens } from '../../../../common/storageManager'; const noop = () => {}; @@ -68,6 +68,7 @@ export default class _Symbol { } }); } + /* eslint-disable class-methods-use-this */ getLimitation(symbol, condition) { const category = getCategoryForCondition(condition); @@ -75,20 +76,25 @@ export default class _Symbol { minDuration: parsedAssetIndex[symbol.toLowerCase()][category], }; } + isConditionAllowedInSymbol(symbol, condition) { const { conditions } = getAllowedConditionsOrCategoriesForSymbol(symbol); return conditions.includes(condition); } + getConditionName(condition) { const [con1, con2] = config.opposites[condition.toUpperCase()]; return `${getObjectValue(con1)}/${getObjectValue(con2)}`; } + getCategoryNameForCondition(condition) { return config.conditionsCategoryName[getCategoryForCondition(condition)]; } + getAllowedCategories(symbol) { return getAllowedConditionsOrCategoriesForSymbol(symbol).categories; } + getAllowedCategoryNames(symbol) { const { categories } = getAllowedConditionsOrCategoriesForSymbol(symbol); return categories.map(el => config.conditionsCategoryName[el]); diff --git a/src/services/tradeEngine/.DS_Store b/src/services/tradeEngine/.DS_Store deleted file mode 100644 index 5fa7daea7644be0378fa5e1ec527442517b01731..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKyH3L}6upL4DzJ1!49FkQrGF4YK&r$L6fLXL^U+V$~wA|;CXI^SaBnqtjsfJ zbV)PnP$wQ0*fJmvhy%aP0baXnykfC(hgiFd_1kRslkvpLJ$NioX z{rl)?XBl(wP3Gh*S6OL14*FVjVf0PuluoEm!+4Zq(bjW0E3fbP?J(0^xmeTl#60QPK-+J;5x#Q||Z99THO?+1;>7&uHVnpX!pa|8fZ zFl++X{7Jz%+F{@@wTKynvZ+9us@xGn*>sF+#|s>$7Hv8yclc1QvT`RBWvb)(+R#Y_ z7Nr*l!~x%dReM|K{eN%y`QJ~HJ8?i9_*V|7O4N=*{3N%x7JeM>wHmF9#=*SQqDevL iwqtX_Tk$5E3CwA}00s_Iix@%3hk&s`I&t7f9e4+HevWeh diff --git a/src/services/tradeEngine/trade/state/reducers/index.js b/src/services/tradeEngine/trade/state/reducers/index.js deleted file mode 100644 index 7d38160b..00000000 --- a/src/services/tradeEngine/trade/state/reducers/index.js +++ /dev/null @@ -1,52 +0,0 @@ -import * as constants from '../constants'; - -const initialState = { - scope : constants.STOP, - proposalsReady: false, -}; - -const signal = (state = initialState, action) => { - switch (action.type) { - case constants.START: - return { - scope : constants.BEFORE_PURCHASE, - proposalsReady: state.proposalsReady, - }; - case constants.PROPOSALS_READY: - return { - ...state, - proposalsReady: true, - }; - case constants.CLEAR_PROPOSALS: - return { - ...state, - proposalsReady: false, - }; - case constants.PURCHASE_SUCCESSFUL: - return { - scope : constants.DURING_PURCHASE, - openContract : false, - proposalsReady: state.proposalsReady, - }; - case constants.OPEN_CONTRACT: - return { - scope : constants.DURING_PURCHASE, - openContract : true, - proposalsReady: state.proposalsReady, - }; - case constants.SELL: - return { - scope : constants.STOP, - proposalsReady: state.proposalsReady, - }; - case constants.NEW_TICK: - return { - ...state, - newTick: action.payload, - }; - default: - return state; - } -}; - -export default signal; diff --git a/src/stores/connect.js b/src/stores/connect.js index 64b1f003..5288772c 100644 --- a/src/stores/connect.js +++ b/src/stores/connect.js @@ -1,4 +1,4 @@ -import { inject } from 'mobx-react'; +import { inject } from 'mobx-react'; import React, { Component } from 'react'; function connectMainStore(mapperFunction) { diff --git a/src/utils/.DS_Store b/src/utils/.DS_Store deleted file mode 100644 index 1e0c8626d62934745d08c88552b52995ec3908d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKu};G<5IvU;sbJ{H=wIl_W~#uBy0H{WQCle?6@fjU(%)bNi67z%cz0)oL}^eb zRG~ZR{G9WheR+<2F%h}x>vBRgCZYt&I2fVXBRtO9kwLWZpp!XDdZCi$G|yHYZ!;Vt z1H5-5-ZAXlBlfP|zsc;O$hVqu^0wbAFVb|86$^|eyPMnVUHX36=ea!4bGvS?%-sWqPsWG%xAP91w}~-e3>X8)$^dFM zOLD4ctubH>7y~r}d_H(6V~AKO%F%&Ft^mLx%p&N^KO4}q0T?1yim*VOh5|Lz#Vdx> zaM*qH3lS?t4JRinW1hIOi#HS}tHbWaom^0~))+7b+6 Date: Thu, 30 May 2019 21:59:21 +0800 Subject: [PATCH 2/6] Enable Travis --- travis.yml => .travis.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename travis.yml => .travis.yml (100%) diff --git a/travis.yml b/.travis.yml similarity index 100% rename from travis.yml rename to .travis.yml From 0b2a0f8e16f8d989df9b6dbfef171222b7a68b95 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 31 May 2019 11:28:58 +0800 Subject: [PATCH 3/6] Restructure --- .DS_Store | Bin 10244 -> 0 bytes examples/.DS_Store | Bin 6148 -> 0 bytes examples/cli-examples/.DS_Store | Bin 6148 -> 0 bytes src/.DS_Store | Bin 6148 -> 0 bytes src/app.js | 2 +- src/assets/images/.DS_Store | Bin 6148 -> 0 bytes .../sass/scratch}/_blockly-toolbox.scss | 0 .../assets/sass/scratch}/_color.scss | 0 .../assets/sass/scratch}/_toolbox.scss | 0 src/components/workspace.jsx | 2 +- common/constants.js => src/constants/const.js | 4 +-- {scratch => src/scratch}/hooks/block.js | 0 {scratch => src/scratch}/hooks/block_svg.js | 2 +- {scratch => src/scratch}/hooks/colours.js | 0 .../scratch}/hooks/data_category.js | 2 +- .../scratch}/hooks/field_dropdown.js | 0 {scratch => src/scratch}/hooks/field_image.js | 0 {scratch => src/scratch}/hooks/flyout_base.js | 0 .../scratch}/hooks/flyout_vertical.js | 0 {scratch => src/scratch}/hooks/gesture.js | 0 {scratch => src/scratch}/hooks/icon.js | 0 {scratch => src/scratch}/hooks/index.js | 0 {scratch => src/scratch}/hooks/procedures.js | 2 +- {scratch => src/scratch}/hooks/toolbox.js | 0 {scratch => src/scratch}/hooks/variables.js | 0 {scratch => src/scratch}/index.js | 14 +++++----- {scratch => src/scratch}/shared.js | 12 ++++---- .../scratch}/sounds/announcement.ogg | Bin {scratch => src/scratch}/sounds/coins.ogg | Bin .../scratch}/sounds/i-am-being-serious.ogg | Bin {scratch => src/scratch}/sounds/job-done.ogg | Bin .../scratch}/sounds/out-of-bounds.ogg | Bin {scratch => src/scratch}/utils.js | 6 ++-- {scratch => src/scratch}/xml/main.xml | 0 {scratch => src/scratch}/xml/toolbox.xml | 0 src/services/api/__tests__/activeSymbols.js | 2 +- src/services/api/__tests__/index.js | 2 +- src/services/api/__tests__/ticksService.js | 6 ++-- {common => src/services/api}/appId.js | 10 +++---- {common => src/services/api}/appIdResolver.js | 0 src/services/api/chartTicksService.js | 4 +-- src/services/api/footer-checks.js | 2 +- src/services/api/shared.js | 6 ++-- src/services/api/symbolApi/index.js | 6 ++-- .../services/api}/ticksService.js | 4 +-- .../tradeEngine/Interface/CandleInterface.js | 0 .../Interface/IndicatorsInterface.js | 0 .../tradeEngine/Interface/MiscInterface.js | 2 +- .../tradeEngine/Interface/TicksInterface.js | 0 .../tradeEngine/Interface/ToolsInterface.js | 0 .../services}/tradeEngine/Interface/index.js | 2 +- .../services}/tradeEngine/__tests__/BotApi.js | 2 +- .../services}/tradeEngine/__tests__/Core.js | 0 .../tradeEngine/__tests__/StopStart.js | 2 +- .../services}/tradeEngine/__tests__/UI.js | 0 .../__tests__/block-tests/After.js | 0 .../__tests__/block-tests/Before.js | 0 .../__tests__/block-tests/During.js | 0 .../__tests__/block-tests/Ticks.js | 0 .../__tests__/block-tests/indicators.js | 0 .../block-tests/sanitize-test/Blocks.js | 0 .../block-tests/sanitize-test/Trade.js | 0 .../block-tests/tools-test/Candles.js | 0 .../__tests__/block-tests/tools-test/Misc.js | 2 +- .../__tests__/block-tests/tools-test/Time.js | 0 .../services}/tradeEngine/__tests__/jsi.js | 2 +- .../__tests__/shouldRestartOnError.js | 0 .../services}/tradeEngine/__tests__/stages.js | 0 .../services}/tradeEngine/__tests__/tools.js | 2 +- .../services}/tradeEngine/trade/Balance.js | 4 +-- .../tradeEngine/trade/OpenContract.js | 4 +-- .../services}/tradeEngine/trade/Proposal.js | 4 +-- .../services}/tradeEngine/trade/Purchase.js | 6 ++-- .../services}/tradeEngine/trade/Sell.js | 6 ++-- .../services}/tradeEngine/trade/Ticks.js | 4 +-- .../services}/tradeEngine/trade/Total.js | 10 +++---- .../services}/tradeEngine/trade/index.js | 10 +++---- .../tradeEngine/trade/state/actions/index.js | 0 .../trade/state/actions/index.spec.js | 0 .../tradeEngine/trade/state/constants.js | 0 .../tradeEngine/trade/state/reducers/index.js | 0 .../trade/state/reducers/index.spec.js | 0 .../services/tradeEngine/utils}/broadcast.js | 2 +- .../services}/tradeEngine/utils/cli.js | 4 +-- .../services/tradeEngine}/utils/cliTools.js | 8 +++--- .../services/tradeEngine/utils/helpers.js | 6 ++-- .../tradeEngine/utils}/interpreter.js | 6 ++-- .../services}/tradeEngine/utils/sanitize.js | 4 +-- {common => src/utils}/__tests__/constants.js | 2 +- {common/lang => src/utils}/__tests__/i18n.js | 4 +-- .../utils/customerSupport}/elevio.js | 2 +- {common => src/utils}/error.js | 0 {common/integrations => src/utils}/gtm.js | 6 ++-- .../utils}/integrations/googleDrive.js | 4 +-- {common => src/utils}/lang/i18n.js | 26 +++++++++--------- {common => src/utils}/lang/lang.js | 2 +- {common => src/utils}/observer.js | 0 {common => src/utils}/storageManager.js | 0 common/helpers.js => src/utils/tools.js | 2 +- webpack.config.js | 4 +-- 100 files changed, 116 insertions(+), 116 deletions(-) delete mode 100644 .DS_Store delete mode 100644 examples/.DS_Store delete mode 100644 examples/cli-examples/.DS_Store delete mode 100644 src/.DS_Store delete mode 100644 src/assets/images/.DS_Store rename {scratch/sass => src/assets/sass/scratch}/_blockly-toolbox.scss (100%) rename {scratch/sass => src/assets/sass/scratch}/_color.scss (100%) rename {scratch/sass => src/assets/sass/scratch}/_toolbox.scss (100%) rename common/constants.js => src/constants/const.js (98%) rename {scratch => src/scratch}/hooks/block.js (100%) rename {scratch => src/scratch}/hooks/block_svg.js (98%) rename {scratch => src/scratch}/hooks/colours.js (100%) rename {scratch => src/scratch}/hooks/data_category.js (98%) rename {scratch => src/scratch}/hooks/field_dropdown.js (100%) rename {scratch => src/scratch}/hooks/field_image.js (100%) rename {scratch => src/scratch}/hooks/flyout_base.js (100%) rename {scratch => src/scratch}/hooks/flyout_vertical.js (100%) rename {scratch => src/scratch}/hooks/gesture.js (100%) rename {scratch => src/scratch}/hooks/icon.js (100%) rename {scratch => src/scratch}/hooks/index.js (100%) rename {scratch => src/scratch}/hooks/procedures.js (98%) rename {scratch => src/scratch}/hooks/toolbox.js (100%) rename {scratch => src/scratch}/hooks/variables.js (100%) rename {scratch => src/scratch}/index.js (96%) rename {scratch => src/scratch}/shared.js (97%) rename {scratch => src/scratch}/sounds/announcement.ogg (100%) rename {scratch => src/scratch}/sounds/coins.ogg (100%) rename {scratch => src/scratch}/sounds/i-am-being-serious.ogg (100%) rename {scratch => src/scratch}/sounds/job-done.ogg (100%) rename {scratch => src/scratch}/sounds/out-of-bounds.ogg (100%) rename {scratch => src/scratch}/utils.js (98%) rename {scratch => src/scratch}/xml/main.xml (100%) rename {scratch => src/scratch}/xml/toolbox.xml (100%) rename {common => src/services/api}/appId.js (92%) rename {common => src/services/api}/appIdResolver.js (100%) rename {common/utils => src/services/api}/ticksService.js (98%) rename {common => src/services}/tradeEngine/Interface/CandleInterface.js (100%) rename {common => src/services}/tradeEngine/Interface/IndicatorsInterface.js (100%) rename {common => src/services}/tradeEngine/Interface/MiscInterface.js (86%) rename {common => src/services}/tradeEngine/Interface/TicksInterface.js (100%) rename {common => src/services}/tradeEngine/Interface/ToolsInterface.js (100%) rename {common => src/services}/tradeEngine/Interface/index.js (98%) rename {common => src/services}/tradeEngine/__tests__/BotApi.js (96%) rename {common => src/services}/tradeEngine/__tests__/Core.js (100%) rename {common => src/services}/tradeEngine/__tests__/StopStart.js (94%) rename {common => src/services}/tradeEngine/__tests__/UI.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/After.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/Before.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/During.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/Ticks.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/indicators.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/tools-test/Candles.js (100%) rename {common => src/services}/tradeEngine/__tests__/block-tests/tools-test/Misc.js (94%) rename {common => src/services}/tradeEngine/__tests__/block-tests/tools-test/Time.js (100%) rename {common => src/services}/tradeEngine/__tests__/jsi.js (89%) rename {common => src/services}/tradeEngine/__tests__/shouldRestartOnError.js (100%) rename {common => src/services}/tradeEngine/__tests__/stages.js (100%) rename {common => src/services}/tradeEngine/__tests__/tools.js (96%) rename {common => src/services}/tradeEngine/trade/Balance.js (92%) rename {common => src/services}/tradeEngine/trade/OpenContract.js (96%) rename {common => src/services}/tradeEngine/trade/Proposal.js (99%) rename {common => src/services}/tradeEngine/trade/Purchase.js (92%) rename {common => src/services}/tradeEngine/trade/Sell.js (89%) rename {common => src/services}/tradeEngine/trade/Ticks.js (95%) rename {common => src/services}/tradeEngine/trade/Total.js (91%) rename {common => src/services}/tradeEngine/trade/index.js (92%) rename {common => src/services}/tradeEngine/trade/state/actions/index.js (100%) rename {common => src/services}/tradeEngine/trade/state/actions/index.spec.js (100%) rename {common => src/services}/tradeEngine/trade/state/constants.js (100%) rename {common => src/services}/tradeEngine/trade/state/reducers/index.js (100%) rename {common => src/services}/tradeEngine/trade/state/reducers/index.spec.js (100%) rename {common => src/services/tradeEngine/utils}/broadcast.js (85%) rename {common => src/services}/tradeEngine/utils/cli.js (89%) rename {common => src/services/tradeEngine}/utils/cliTools.js (52%) rename common/tools.js => src/services/tradeEngine/utils/helpers.js (97%) rename {common => src/services/tradeEngine/utils}/interpreter.js (97%) rename {common => src/services}/tradeEngine/utils/sanitize.js (94%) rename {common => src/utils}/__tests__/constants.js (82%) rename {common/lang => src/utils}/__tests__/i18n.js (94%) rename {common/integrations => src/utils/customerSupport}/elevio.js (97%) rename {common => src/utils}/error.js (100%) rename {common/integrations => src/utils}/gtm.js (89%) rename {common => src/utils}/integrations/googleDrive.js (99%) rename {common => src/utils}/lang/i18n.js (63%) rename {common => src/utils}/lang/lang.js (99%) rename {common => src/utils}/observer.js (100%) rename {common => src/utils}/storageManager.js (100%) rename common/helpers.js => src/utils/tools.js (98%) diff --git a/.DS_Store b/.DS_Store deleted file mode 100644 index 6611d78b22bd21ac9065db56311022efbb7f24a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10244 zcmeHM&1(}u6n|@5yQ$R%Kd6F-J*c!&OHxx6M2KxF6ja2B9<aITyvIC~p*nae zFs@Hn1#vO1cAL+_C!KB7DssKN%T^q_R*%I#8XLO0dp7o(W}n%&xo;+2@*3%Srao7j z$W$+~uQQo?DJ#q8JkMD!XR_z*LSr_%ebRI58QU#Xxw4%vK;+T|+s%8832)BL*SMXu zXfVx)8JUglY&OTn$49KOLq`@ytmfgvu@NhA@X*3S#2nlkKQ?`(Jb$Zsd*RLl<_%0s zo?$c~zL)cdCv(Pv zEo>HDaAB2l0oSpmp$4y%`d?ipr{{B3p-|MwxRiA#Cy?o+P>J2*&Lv5>G{uz0n-+Njx9d0|Y5_aIE zE8x6b+Q&z+yQ-&V4(r1f`?^1H4R&&>JM@n%iGKJA5wOJ0Qq>Y0zb1`z|Np=K1JxtY2xtWU7y?FjDxI2u`K5P>U{CC=-9oy8#E8kY1m`Nq z_;Wlse~!lodyXGMVzM#D8KIn%yd^klK!5$ufZzLMqwoKJ{Dn>5{}CpkZwtS2|Njno CsOE71 diff --git a/examples/.DS_Store b/examples/.DS_Store deleted file mode 100644 index a367de1031c25f9a96eafa28a1f7b78f7dcf347f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKO>fgM7=FDK=9VFPKpJqt7Y;~8N~ZQWDP#d@w@E>80JJ4bv_?wes7Wc%b;|D; z65=QD7k1fUe}EfTegSu0e*mpYE4WmE{7UxYkLR`hK9TJh0Ejz`Y=AZZP)q_FEzEvl zqFUjPb6tKG=7J7SXdZwdTjegJS!CW&iiHDjC-C|hkic2 z`{n-L`NQS>=#ThCe|jyJSkl6Ezw!rp%JXC7h`2ZL9M15Y&VA9D_%^;?EaOhc=brCB z{^05O7L1+opYi<;eM_h`rl`5cj2)(w_SXAF?*B)N-~Y2tre+i{3j9|JkcQ`bE{3G<*16!sUCS^XViG2J owL5DTB$30xMPE8#BwN2mk;8 diff --git a/examples/cli-examples/.DS_Store b/examples/cli-examples/.DS_Store deleted file mode 100644 index ab0ccbcc54859cbc07fa9ac962383e66457f003a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK-D=c86h5(iy-C=x-$Ri>LF0tXF_=Cy! z(xwf>;eS*>&fR&6FmD30c6j~u-HvYX@&iw9wq6k9TRLx>CsIu4^JX)@}0m+pwX3e!9(RDZgUr<-XWi&0k$ z^SD&`rgIfP3adW)ajyCym*XJUaeLnUc)YN@+~x}_wDR)Lc#V3seZbuzkTSp}>Dr&s~GK5)21-(am#EgdM-6#yuY zk;)LuqoU++gTBF9Bi_K6rUEsUnJWghbu!nmjTc>SZhQJ%pL@k47RWe{8I&f00RPoivR!s diff --git a/src/.DS_Store b/src/.DS_Store deleted file mode 100644 index feb337f5b9b8cc95b35666582c358cd56c2b7703..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKF;2rk5Znt9GNDOHc_k8+YZ?<7q15>Rii4oAu|-0S8zi1U3qRoze1k8*?Cr|f z*pX;J2<=L{bH1DPdB-Q8kBHptb`=v%i70|Ij`k1+jK|q~HqxF6(1m-HbWIoV4Xt}@ z>-dWb@VlE(MkN(gAvW)Co|oA&FP9j{;&AuC!}nmJjKQ4zGG1h5Q3ZyCL0(a&sopz! zeT&bI<}W9pZ{e=K&8@C_^Y3CMZcx_^*5$fe6CGpD$5u@p?m#V_@pcUlPj}C;)bNG# z`Rv;`1JB%&&zh!yDPRixhyvKN*`j?xi>81nUFD>$OB8ECNhha=52rIbJ)yWTJMQlTom?Vl(G)NR zx(e*b<&^jT)9vT~ZjxP@0;a&fQoxPVMLI)Cy0`X<, diff --git a/src/assets/images/.DS_Store b/src/assets/images/.DS_Store deleted file mode 100644 index 7db0cd5d840e36430f573e2c46e7c8f5f2bbaa23..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKyKVw85Zp~rbW)ltQ@W((53JKsq|Of@phUR>(O;8%7k>t`4 z|Ka06{lWhHzZvJ`&6*vG`t67pPZzC$ z9H{^mxK`jbmaWzQCHzkRe@)_w3Q&Q6rGU=*ufD^RvbIhhXSKG#S8&TY!p$&u3I;F7 kKrhEwSULXiq{u5a$9_#51D%ez(}DaMFkNU=;MoeC0a?@>3jhEB diff --git a/scratch/sass/_blockly-toolbox.scss b/src/assets/sass/scratch/_blockly-toolbox.scss similarity index 100% rename from scratch/sass/_blockly-toolbox.scss rename to src/assets/sass/scratch/_blockly-toolbox.scss diff --git a/scratch/sass/_color.scss b/src/assets/sass/scratch/_color.scss similarity index 100% rename from scratch/sass/_color.scss rename to src/assets/sass/scratch/_color.scss diff --git a/scratch/sass/_toolbox.scss b/src/assets/sass/scratch/_toolbox.scss similarity index 100% rename from scratch/sass/_toolbox.scss rename to src/assets/sass/scratch/_toolbox.scss diff --git a/src/components/workspace.jsx b/src/components/workspace.jsx index f35ea778..f9798e11 100644 --- a/src/components/workspace.jsx +++ b/src/components/workspace.jsx @@ -1,5 +1,5 @@ import React from 'react'; -import '../../scratch/sass/_blockly-toolbox.scss'; +import '../assets/sass/scratch/_blockly-toolbox.scss'; const Workspace = () => ( diff --git a/common/constants.js b/src/constants/const.js similarity index 98% rename from common/constants.js rename to src/constants/const.js index 49aed47a..3078f8e0 100644 --- a/common/constants.js +++ b/src/constants/const.js @@ -1,5 +1,5 @@ -import { translate } from './lang/i18n'; -import { load as loadLang } from './lang/lang'; +import { translate } from '../utils/lang/i18n'; +import { load as loadLang } from '../utils/lang/lang'; loadLang(); diff --git a/scratch/hooks/block.js b/src/scratch/hooks/block.js similarity index 100% rename from scratch/hooks/block.js rename to src/scratch/hooks/block.js diff --git a/scratch/hooks/block_svg.js b/src/scratch/hooks/block_svg.js similarity index 98% rename from scratch/hooks/block_svg.js rename to src/scratch/hooks/block_svg.js index 9cb17d0b..771aa8a6 100644 --- a/scratch/hooks/block_svg.js +++ b/src/scratch/hooks/block_svg.js @@ -1,5 +1,5 @@ /* eslint-disable func-names, no-underscore-dangle */ -import { translate } from '../../common/lang/i18n'; +import { translate } from '../../utils/lang/i18n'; /** * Set whether the block is disabled or not. diff --git a/scratch/hooks/colours.js b/src/scratch/hooks/colours.js similarity index 100% rename from scratch/hooks/colours.js rename to src/scratch/hooks/colours.js diff --git a/scratch/hooks/data_category.js b/src/scratch/hooks/data_category.js similarity index 98% rename from scratch/hooks/data_category.js rename to src/scratch/hooks/data_category.js index c05d6742..f8b03767 100644 --- a/scratch/hooks/data_category.js +++ b/src/scratch/hooks/data_category.js @@ -1,5 +1,5 @@ /* eslint-disable func-names, no-underscore-dangle */ -import { translate } from '../../common/lang/i18n'; +import { translate } from '../../utils/lang/i18n'; /** * Construct the blocks required by the flyout for the variable category. diff --git a/scratch/hooks/field_dropdown.js b/src/scratch/hooks/field_dropdown.js similarity index 100% rename from scratch/hooks/field_dropdown.js rename to src/scratch/hooks/field_dropdown.js diff --git a/scratch/hooks/field_image.js b/src/scratch/hooks/field_image.js similarity index 100% rename from scratch/hooks/field_image.js rename to src/scratch/hooks/field_image.js diff --git a/scratch/hooks/flyout_base.js b/src/scratch/hooks/flyout_base.js similarity index 100% rename from scratch/hooks/flyout_base.js rename to src/scratch/hooks/flyout_base.js diff --git a/scratch/hooks/flyout_vertical.js b/src/scratch/hooks/flyout_vertical.js similarity index 100% rename from scratch/hooks/flyout_vertical.js rename to src/scratch/hooks/flyout_vertical.js diff --git a/scratch/hooks/gesture.js b/src/scratch/hooks/gesture.js similarity index 100% rename from scratch/hooks/gesture.js rename to src/scratch/hooks/gesture.js diff --git a/scratch/hooks/icon.js b/src/scratch/hooks/icon.js similarity index 100% rename from scratch/hooks/icon.js rename to src/scratch/hooks/icon.js diff --git a/scratch/hooks/index.js b/src/scratch/hooks/index.js similarity index 100% rename from scratch/hooks/index.js rename to src/scratch/hooks/index.js diff --git a/scratch/hooks/procedures.js b/src/scratch/hooks/procedures.js similarity index 98% rename from scratch/hooks/procedures.js rename to src/scratch/hooks/procedures.js index 9538684a..6b807a84 100644 --- a/scratch/hooks/procedures.js +++ b/src/scratch/hooks/procedures.js @@ -1,5 +1,5 @@ /* eslint-disable func-names, no-underscore-dangle */ -import { translate } from '../../common/lang/i18n'; +import { translate } from '../../utils/lang/i18n'; /** * Construct the blocks required by the flyout for the procedure category. diff --git a/scratch/hooks/toolbox.js b/src/scratch/hooks/toolbox.js similarity index 100% rename from scratch/hooks/toolbox.js rename to src/scratch/hooks/toolbox.js diff --git a/scratch/hooks/variables.js b/src/scratch/hooks/variables.js similarity index 100% rename from scratch/hooks/variables.js rename to src/scratch/hooks/variables.js diff --git a/scratch/index.js b/src/scratch/index.js similarity index 96% rename from scratch/index.js rename to src/scratch/index.js index 5ba21806..6f1cb3b3 100644 --- a/scratch/index.js +++ b/src/scratch/index.js @@ -12,13 +12,13 @@ import { strategyHasValidTradeTypeCategory, cleanBeforeExport, } from './utils'; -import createError from '../common/error'; -import GTM from '../common/integrations/gtm'; -import Interpreter from '../common/interpreter'; -import { translate, xml as translateXml } from '../common/lang/i18n'; -import { getLanguage } from '../common/lang/lang'; -import { observer as globalObserver } from '../common/observer'; -import { showDialog } from '../common/tools'; +import GTM from '../utils/gtm'; +import createError from '../utils/error'; +import Interpreter from '../services/tradeEngine/utils/interpreter'; +import { translate, xml as translateXml } from '../utils/lang/i18n'; +import { getLanguage } from '../utils/lang/lang'; +import { observer as globalObserver } from '../utils/observer'; +import { showDialog } from '../services/tradeEngine/utils/helpers'; export const scratchWorkspaceInit = async (scratch_area_name, scratch_div_name) => { try { diff --git a/scratch/shared.js b/src/scratch/shared.js similarity index 97% rename from scratch/shared.js rename to src/scratch/shared.js index 012d452d..404cf4a6 100644 --- a/scratch/shared.js +++ b/src/scratch/shared.js @@ -1,16 +1,16 @@ import filesaver from 'file-saver'; import { oppositesToDropdown } from './utils'; -import { generateLiveApiInstance } from '../common/appId'; -import config from '../common/constants'; -import { translate } from '../common/lang/i18n'; -import { observer as globalObserver } from '../common/observer'; +import { generateLiveApiInstance } from '../services/api/appId'; +import config from '../constants/const'; +import { translate } from '../utils/lang/i18n'; +import { observer as globalObserver } from '../utils/observer'; import { get as getStorage, set as setStorage, getTokenList, removeAllTokens, -} from '../common/storageManager'; -import { symbolApi } from '../src/services/api/shared'; +} from '../utils/storageManager'; +import { symbolApi } from '../services/api/shared'; let purchaseChoices = [[translate('Click to select'), '']]; diff --git a/scratch/sounds/announcement.ogg b/src/scratch/sounds/announcement.ogg similarity index 100% rename from scratch/sounds/announcement.ogg rename to src/scratch/sounds/announcement.ogg diff --git a/scratch/sounds/coins.ogg b/src/scratch/sounds/coins.ogg similarity index 100% rename from scratch/sounds/coins.ogg rename to src/scratch/sounds/coins.ogg diff --git a/scratch/sounds/i-am-being-serious.ogg b/src/scratch/sounds/i-am-being-serious.ogg similarity index 100% rename from scratch/sounds/i-am-being-serious.ogg rename to src/scratch/sounds/i-am-being-serious.ogg diff --git a/scratch/sounds/job-done.ogg b/src/scratch/sounds/job-done.ogg similarity index 100% rename from scratch/sounds/job-done.ogg rename to src/scratch/sounds/job-done.ogg diff --git a/scratch/sounds/out-of-bounds.ogg b/src/scratch/sounds/out-of-bounds.ogg similarity index 100% rename from scratch/sounds/out-of-bounds.ogg rename to src/scratch/sounds/out-of-bounds.ogg diff --git a/scratch/utils.js b/src/scratch/utils.js similarity index 98% rename from scratch/utils.js rename to src/scratch/utils.js index f9a6fc2e..fadec909 100644 --- a/scratch/utils.js +++ b/src/scratch/utils.js @@ -1,7 +1,7 @@ import { fieldGeneratorMapping, saveAs } from './shared'; -import config from '../common/constants'; -import { translate } from '../common/lang/i18n'; -import { observer as globalObserver } from '../common/observer'; +import config from '../constants/const'; +import { translate } from '../utils/lang/i18n'; +import { observer as globalObserver } from '../utils/observer'; export const isMainBlock = blockType => config.mainBlocks.indexOf(blockType) >= 0; diff --git a/scratch/xml/main.xml b/src/scratch/xml/main.xml similarity index 100% rename from scratch/xml/main.xml rename to src/scratch/xml/main.xml diff --git a/scratch/xml/toolbox.xml b/src/scratch/xml/toolbox.xml similarity index 100% rename from scratch/xml/toolbox.xml rename to src/scratch/xml/toolbox.xml diff --git a/src/services/api/__tests__/activeSymbols.js b/src/services/api/__tests__/activeSymbols.js index ff3bed65..464ed031 100644 --- a/src/services/api/__tests__/activeSymbols.js +++ b/src/services/api/__tests__/activeSymbols.js @@ -1,8 +1,8 @@ /* eslint-disable import/no-extraneous-dependencies */ import { expect } from 'chai'; import deep from 'deep-diff'; +import { generateLiveApiInstance } from '../appId'; import ActiveSymbols from '../symbolApi/activeSymbols'; -import { generateLiveApiInstance } from '../../../../common/appId'; /* There is a market called forex, which has a submarket diff --git a/src/services/api/__tests__/index.js b/src/services/api/__tests__/index.js index bfe7b173..abdd7453 100644 --- a/src/services/api/__tests__/index.js +++ b/src/services/api/__tests__/index.js @@ -1,7 +1,7 @@ /* eslint-disable no-unused-expressions */ import { expect } from 'chai'; import _Symbol from '../symbolApi'; -import { generateLiveApiInstance } from '../../../../common/appId'; +import { generateLiveApiInstance } from '../appId'; describe('symbol', () => { const api = generateLiveApiInstance(); diff --git a/src/services/api/__tests__/ticksService.js b/src/services/api/__tests__/ticksService.js index 3d17be9c..b4a54e5e 100644 --- a/src/services/api/__tests__/ticksService.js +++ b/src/services/api/__tests__/ticksService.js @@ -1,7 +1,7 @@ /* eslint-disable no-unused-expressions */ -import { logoutAllTokens, addTokenIfValid, generateLiveApiInstance } from '../../../../common/appId'; -import TicksService from '../../../../common/utils/ticksService'; - +import { logoutAllTokens, addTokenIfValid, generateLiveApiInstance } from '../appId'; +import TicksService from '../ticksService'; + jasmine.DEFAULT_TIMEOUT_INTERVAL = 20000; const ticksService = new TicksService(generateLiveApiInstance()); diff --git a/common/appId.js b/src/services/api/appId.js similarity index 92% rename from common/appId.js rename to src/services/api/appId.js index 57daa7b8..b4e0baad 100644 --- a/common/appId.js +++ b/src/services/api/appId.js @@ -1,9 +1,7 @@ import { LiveApi } from 'binary-live-api'; import AppIdMap from './appIdResolver'; -import { parseQueryString, isProduction, getExtension } from './helpers'; -import Elevio from './integrations/elevio'; -import GTM from './integrations/gtm'; -import { getLanguage } from './lang/lang'; +import { parseQueryString, isProduction, getExtension } from '../../utils/tools'; +import { getLanguage } from '../../utils/lang/lang'; import { addToken, removeToken, @@ -11,7 +9,9 @@ import { removeAllTokens, get as getStorage, set as setStorage, -} from './storageManager'; +} from '../../utils/storageManager'; +import Elevio from '../../utils/customerSupport/elevio'; +import GTM from '../../utils/gtm'; export const AppConstants = Object.freeze({ STORAGE_ACTIVE_TOKEN: 'activeToken', diff --git a/common/appIdResolver.js b/src/services/api/appIdResolver.js similarity index 100% rename from common/appIdResolver.js rename to src/services/api/appIdResolver.js diff --git a/src/services/api/chartTicksService.js b/src/services/api/chartTicksService.js index 55d7a2d6..bbc740da 100644 --- a/src/services/api/chartTicksService.js +++ b/src/services/api/chartTicksService.js @@ -1,5 +1,5 @@ -import { doUntilDone } from '../../../common/tools'; -import TicksService from '../../../common/utils/ticksService'; +import TicksService from './ticksService'; +import { doUntilDone } from '../../utils/tools'; export default class ChartTicksService extends TicksService { observe() { diff --git a/src/services/api/footer-checks.js b/src/services/api/footer-checks.js index 0df4703c..d3489397 100644 --- a/src/services/api/footer-checks.js +++ b/src/services/api/footer-checks.js @@ -1,5 +1,5 @@ /* eslint-disable import/prefer-default-export */ -import { generateLiveApiInstance } from '../../../common/appId'; +import { generateLiveApiInstance } from './appId'; export default async function isEuCountry() { const api = generateLiveApiInstance(); diff --git a/src/services/api/shared.js b/src/services/api/shared.js index 6e4e51e7..55198bbc 100644 --- a/src/services/api/shared.js +++ b/src/services/api/shared.js @@ -1,7 +1,7 @@ import _Symbol from './symbolApi'; -import { generateLiveApiInstance } from '../../../common/appId'; -import Observer from '../../../common/observer'; -import TicksService from '../../../common/utils/ticksService'; +import { generateLiveApiInstance } from './appId'; +import TicksService from './ticksService'; +import Observer from '../../utils/observer'; let tmpApi = generateLiveApiInstance(); diff --git a/src/services/api/symbolApi/index.js b/src/services/api/symbolApi/index.js index d59889f7..7d3d20be 100644 --- a/src/services/api/symbolApi/index.js +++ b/src/services/api/symbolApi/index.js @@ -1,7 +1,7 @@ import ActiveSymbols from './activeSymbols'; -import config from '../../../../common/constants'; -import { getObjectValue } from '../../../../common/helpers'; -import { getTokenList, removeAllTokens } from '../../../../common/storageManager'; +import config from '../../../constants/const'; +import { getObjectValue } from '../../../utils/tools'; +import { getTokenList, removeAllTokens } from '../../../utils/storageManager'; const noop = () => {}; diff --git a/common/utils/ticksService.js b/src/services/api/ticksService.js similarity index 98% rename from common/utils/ticksService.js rename to src/services/api/ticksService.js index 227f64e5..b9bcfcc9 100644 --- a/common/utils/ticksService.js +++ b/src/services/api/ticksService.js @@ -1,7 +1,7 @@ import { Map } from 'immutable'; import { historyToTicks, getLast } from 'binary-utils'; -import { doUntilDone, getUUID } from '../tools'; -import { observer as globalObserver } from '../observer'; +import { doUntilDone, getUUID } from '../tradeEngine/utils/helpers'; +import { observer as globalObserver } from '../../utils/observer'; const parseTick = tick => ({ epoch: +tick.epoch, diff --git a/common/tradeEngine/Interface/CandleInterface.js b/src/services/tradeEngine/Interface/CandleInterface.js similarity index 100% rename from common/tradeEngine/Interface/CandleInterface.js rename to src/services/tradeEngine/Interface/CandleInterface.js diff --git a/common/tradeEngine/Interface/IndicatorsInterface.js b/src/services/tradeEngine/Interface/IndicatorsInterface.js similarity index 100% rename from common/tradeEngine/Interface/IndicatorsInterface.js rename to src/services/tradeEngine/Interface/IndicatorsInterface.js diff --git a/common/tradeEngine/Interface/MiscInterface.js b/src/services/tradeEngine/Interface/MiscInterface.js similarity index 86% rename from common/tradeEngine/Interface/MiscInterface.js rename to src/services/tradeEngine/Interface/MiscInterface.js index c41da9b4..c37e60ad 100644 --- a/common/tradeEngine/Interface/MiscInterface.js +++ b/src/services/tradeEngine/Interface/MiscInterface.js @@ -1,4 +1,4 @@ -import { observer as globalObserver } from '../../observer'; +import { observer as globalObserver } from '../../../utils/observer'; export default Interface => class extends Interface { diff --git a/common/tradeEngine/Interface/TicksInterface.js b/src/services/tradeEngine/Interface/TicksInterface.js similarity index 100% rename from common/tradeEngine/Interface/TicksInterface.js rename to src/services/tradeEngine/Interface/TicksInterface.js diff --git a/common/tradeEngine/Interface/ToolsInterface.js b/src/services/tradeEngine/Interface/ToolsInterface.js similarity index 100% rename from common/tradeEngine/Interface/ToolsInterface.js rename to src/services/tradeEngine/Interface/ToolsInterface.js diff --git a/common/tradeEngine/Interface/index.js b/src/services/tradeEngine/Interface/index.js similarity index 98% rename from common/tradeEngine/Interface/index.js rename to src/services/tradeEngine/Interface/index.js index 20ae7200..e5f8efdc 100644 --- a/common/tradeEngine/Interface/index.js +++ b/src/services/tradeEngine/Interface/index.js @@ -1,7 +1,7 @@ import TicksInterface from './TicksInterface'; import ToolsInterface from './ToolsInterface'; import TradeEngine from '../trade'; -import { noop, createDetails } from '../../tools'; +import { noop, createDetails } from '../utils/helpers'; /** * Bot - Bot Module diff --git a/common/tradeEngine/__tests__/BotApi.js b/src/services/tradeEngine/__tests__/BotApi.js similarity index 96% rename from common/tradeEngine/__tests__/BotApi.js rename to src/services/tradeEngine/__tests__/BotApi.js index a27f34f2..6ef30190 100644 --- a/common/tradeEngine/__tests__/BotApi.js +++ b/src/services/tradeEngine/__tests__/BotApi.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import Interface from '../Interface'; -import { createScope } from '../../utils/cliTools'; +import { createScope } from '../utils/cliTools'; const $scope = createScope(); diff --git a/common/tradeEngine/__tests__/Core.js b/src/services/tradeEngine/__tests__/Core.js similarity index 100% rename from common/tradeEngine/__tests__/Core.js rename to src/services/tradeEngine/__tests__/Core.js diff --git a/common/tradeEngine/__tests__/StopStart.js b/src/services/tradeEngine/__tests__/StopStart.js similarity index 94% rename from common/tradeEngine/__tests__/StopStart.js rename to src/services/tradeEngine/__tests__/StopStart.js index dba105d0..43e0686b 100644 --- a/common/tradeEngine/__tests__/StopStart.js +++ b/src/services/tradeEngine/__tests__/StopStart.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { parts } from './tools'; -import { createInterpreter } from '../../utils/cliTools'; +import { createInterpreter } from '../utils/cliTools'; describe('Run Interpreter over bot', () => { let value; diff --git a/common/tradeEngine/__tests__/UI.js b/src/services/tradeEngine/__tests__/UI.js similarity index 100% rename from common/tradeEngine/__tests__/UI.js rename to src/services/tradeEngine/__tests__/UI.js diff --git a/common/tradeEngine/__tests__/block-tests/After.js b/src/services/tradeEngine/__tests__/block-tests/After.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/After.js rename to src/services/tradeEngine/__tests__/block-tests/After.js diff --git a/common/tradeEngine/__tests__/block-tests/Before.js b/src/services/tradeEngine/__tests__/block-tests/Before.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/Before.js rename to src/services/tradeEngine/__tests__/block-tests/Before.js diff --git a/common/tradeEngine/__tests__/block-tests/During.js b/src/services/tradeEngine/__tests__/block-tests/During.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/During.js rename to src/services/tradeEngine/__tests__/block-tests/During.js diff --git a/common/tradeEngine/__tests__/block-tests/Ticks.js b/src/services/tradeEngine/__tests__/block-tests/Ticks.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/Ticks.js rename to src/services/tradeEngine/__tests__/block-tests/Ticks.js diff --git a/common/tradeEngine/__tests__/block-tests/indicators.js b/src/services/tradeEngine/__tests__/block-tests/indicators.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/indicators.js rename to src/services/tradeEngine/__tests__/block-tests/indicators.js diff --git a/common/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js b/src/services/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js rename to src/services/tradeEngine/__tests__/block-tests/sanitize-test/Blocks.js diff --git a/common/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js b/src/services/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js rename to src/services/tradeEngine/__tests__/block-tests/sanitize-test/Trade.js diff --git a/common/tradeEngine/__tests__/block-tests/tools-test/Candles.js b/src/services/tradeEngine/__tests__/block-tests/tools-test/Candles.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/tools-test/Candles.js rename to src/services/tradeEngine/__tests__/block-tests/tools-test/Candles.js diff --git a/common/tradeEngine/__tests__/block-tests/tools-test/Misc.js b/src/services/tradeEngine/__tests__/block-tests/tools-test/Misc.js similarity index 94% rename from common/tradeEngine/__tests__/block-tests/tools-test/Misc.js rename to src/services/tradeEngine/__tests__/block-tests/tools-test/Misc.js index 03f0e30d..8d7c6661 100644 --- a/common/tradeEngine/__tests__/block-tests/tools-test/Misc.js +++ b/src/services/tradeEngine/__tests__/block-tests/tools-test/Misc.js @@ -1,6 +1,6 @@ import { expect } from 'chai'; import { runAndGetResult } from '../../tools'; -import { observer as globalObserver } from '../../../../observer'; +import { observer as globalObserver } from '../../../../../utils/observer'; describe('Misc. tools', () => { let result; diff --git a/common/tradeEngine/__tests__/block-tests/tools-test/Time.js b/src/services/tradeEngine/__tests__/block-tests/tools-test/Time.js similarity index 100% rename from common/tradeEngine/__tests__/block-tests/tools-test/Time.js rename to src/services/tradeEngine/__tests__/block-tests/tools-test/Time.js diff --git a/common/tradeEngine/__tests__/jsi.js b/src/services/tradeEngine/__tests__/jsi.js similarity index 89% rename from common/tradeEngine/__tests__/jsi.js rename to src/services/tradeEngine/__tests__/jsi.js index b14c31e3..73e47820 100644 --- a/common/tradeEngine/__tests__/jsi.js +++ b/src/services/tradeEngine/__tests__/jsi.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import Interpreter from '../../interpreter'; +import Interpreter from '../utils/interpreter'; const interpreter = new Interpreter(); diff --git a/common/tradeEngine/__tests__/shouldRestartOnError.js b/src/services/tradeEngine/__tests__/shouldRestartOnError.js similarity index 100% rename from common/tradeEngine/__tests__/shouldRestartOnError.js rename to src/services/tradeEngine/__tests__/shouldRestartOnError.js diff --git a/common/tradeEngine/__tests__/stages.js b/src/services/tradeEngine/__tests__/stages.js similarity index 100% rename from common/tradeEngine/__tests__/stages.js rename to src/services/tradeEngine/__tests__/stages.js diff --git a/common/tradeEngine/__tests__/tools.js b/src/services/tradeEngine/__tests__/tools.js similarity index 96% rename from common/tradeEngine/__tests__/tools.js rename to src/services/tradeEngine/__tests__/tools.js index fc2aa61d..75df5f35 100644 --- a/common/tradeEngine/__tests__/tools.js +++ b/src/services/tradeEngine/__tests__/tools.js @@ -1,5 +1,5 @@ import { expect } from 'chai'; -import { createInterpreter } from '../../utils/cliTools'; +import { createInterpreter } from '../utils/cliTools'; export const init = options => ` Bot.init('Xkq6oGFEHh6hJH8', { diff --git a/common/tradeEngine/trade/Balance.js b/src/services/tradeEngine/trade/Balance.js similarity index 92% rename from common/tradeEngine/trade/Balance.js rename to src/services/tradeEngine/trade/Balance.js index b94e56e4..a458a946 100644 --- a/common/tradeEngine/trade/Balance.js +++ b/src/services/tradeEngine/trade/Balance.js @@ -1,5 +1,5 @@ -import { info } from '../../broadcast'; -import { roundBalance } from '../../tools'; +import { info } from '../utils/broadcast'; +import { roundBalance } from '../utils/helpers'; let balanceStr = ''; diff --git a/common/tradeEngine/trade/OpenContract.js b/src/services/tradeEngine/trade/OpenContract.js similarity index 96% rename from common/tradeEngine/trade/OpenContract.js rename to src/services/tradeEngine/trade/OpenContract.js index 354cfb26..f89333ef 100644 --- a/common/tradeEngine/trade/OpenContract.js +++ b/src/services/tradeEngine/trade/OpenContract.js @@ -4,8 +4,8 @@ import { contractSettled, contract as broadcastContract, -} from '../../broadcast'; -import { doUntilDone, roundBalance } from '../../tools'; +} from '../utils/broadcast'; +import { doUntilDone, roundBalance } from '../utils/helpers'; const AFTER_FINISH_TIMEOUT = 5; diff --git a/common/tradeEngine/trade/Proposal.js b/src/services/tradeEngine/trade/Proposal.js similarity index 99% rename from common/tradeEngine/trade/Proposal.js rename to src/services/tradeEngine/trade/Proposal.js index feb1d227..b8e22157 100644 --- a/common/tradeEngine/trade/Proposal.js +++ b/src/services/tradeEngine/trade/Proposal.js @@ -1,6 +1,6 @@ import { proposalsReady, clearProposals } from './state/actions'; -import { translate } from '../../lang/i18n'; -import { tradeOptionToProposal, doUntilDone, getUUID } from '../../tools'; +import { translate } from '../../../utils/lang/i18n'; +import { tradeOptionToProposal, doUntilDone, getUUID } from '../utils/helpers'; export default Engine => class Proposal extends Engine { diff --git a/common/tradeEngine/trade/Purchase.js b/src/services/tradeEngine/trade/Purchase.js similarity index 92% rename from common/tradeEngine/trade/Purchase.js rename to src/services/tradeEngine/trade/Purchase.js index 1b4fbc50..e91cb272 100644 --- a/common/tradeEngine/trade/Purchase.js +++ b/src/services/tradeEngine/trade/Purchase.js @@ -1,8 +1,8 @@ import { purchaseSuccessful } from './state/actions'; import { BEFORE_PURCHASE } from './state/constants'; -import { contractStatus, info, notify } from '../../broadcast'; -import { translate } from '../../lang/i18n'; -import { recoverFromError, doUntilDone } from '../../tools'; +import { contractStatus, info, notify } from '../utils/broadcast'; +import { translate } from '../../../utils/lang/i18n'; +import { recoverFromError, doUntilDone } from '../utils/helpers'; let delayIndex = 0; diff --git a/common/tradeEngine/trade/Sell.js b/src/services/tradeEngine/trade/Sell.js similarity index 89% rename from common/tradeEngine/trade/Sell.js rename to src/services/tradeEngine/trade/Sell.js index 7b781a20..8b8326a5 100644 --- a/common/tradeEngine/trade/Sell.js +++ b/src/services/tradeEngine/trade/Sell.js @@ -1,7 +1,7 @@ import { DURING_PURCHASE } from './state/constants'; -import { contractStatus, notify } from '../../broadcast'; -import { translate } from '../../lang/i18n'; -import { recoverFromError, doUntilDone } from '../../tools'; +import { contractStatus, notify } from '../utils/broadcast'; +import { translate } from '../../../utils/lang/i18n'; +import { recoverFromError, doUntilDone } from '../utils/helpers'; let delayIndex = 0; diff --git a/common/tradeEngine/trade/Ticks.js b/src/services/tradeEngine/trade/Ticks.js similarity index 95% rename from common/tradeEngine/trade/Ticks.js rename to src/services/tradeEngine/trade/Ticks.js index dd51a0de..402dde57 100644 --- a/common/tradeEngine/trade/Ticks.js +++ b/src/services/tradeEngine/trade/Ticks.js @@ -1,8 +1,8 @@ import { getLast } from 'binary-utils'; import * as constants from './state/constants'; import { expectPositiveInteger } from '../utils/sanitize'; -import { translate } from '../../lang/i18n'; -import { getDirection, getLastDigit } from '../../tools'; +import { translate } from '../../../utils/lang/i18n'; +import { getDirection, getLastDigit } from '../utils/helpers'; let tickListenerKey; diff --git a/common/tradeEngine/trade/Total.js b/src/services/tradeEngine/trade/Total.js similarity index 91% rename from common/tradeEngine/trade/Total.js rename to src/services/tradeEngine/trade/Total.js index 20c43c1c..882d5b53 100644 --- a/common/tradeEngine/trade/Total.js +++ b/src/services/tradeEngine/trade/Total.js @@ -1,8 +1,8 @@ -import { info, notify } from '../../broadcast'; -import createError from '../../error'; -import { translate } from '../../lang/i18n'; -import { observer as globalObserver } from '../../observer'; -import { roundBalance } from '../../tools'; +import { info, notify } from '../utils/broadcast'; +import createError from '../../../utils/error'; +import { translate } from '../../../utils/lang/i18n'; +import { observer as globalObserver } from '../../../utils/observer'; +import { roundBalance } from '../utils/helpers'; const skeleton = { totalProfit: 0, diff --git a/common/tradeEngine/trade/index.js b/src/services/tradeEngine/trade/index.js similarity index 92% rename from common/tradeEngine/trade/index.js rename to src/services/tradeEngine/trade/index.js index 8c2e6af5..3add107a 100644 --- a/common/tradeEngine/trade/index.js +++ b/src/services/tradeEngine/trade/index.js @@ -12,11 +12,11 @@ import { start } from './state/actions'; import Ticks from './Ticks'; import Total from './Total'; import { expectInitArg, expectTradeOptions } from '../utils/sanitize'; -import createError from '../../error'; -import { doUntilDone } from '../../tools'; -import { translate } from '../../lang/i18n'; -import { durationToSecond } from '../../helpers'; -import { observer as globalObserver } from '../../observer'; +import createError from '../../../utils/error'; +import { doUntilDone } from '../utils/helpers'; +import { translate } from '../../../utils/lang/i18n'; +import { durationToSecond } from '../../../utils/tools'; +import { observer as globalObserver } from '../../../utils/observer'; const watchBefore = store => watchScope({ diff --git a/common/tradeEngine/trade/state/actions/index.js b/src/services/tradeEngine/trade/state/actions/index.js similarity index 100% rename from common/tradeEngine/trade/state/actions/index.js rename to src/services/tradeEngine/trade/state/actions/index.js diff --git a/common/tradeEngine/trade/state/actions/index.spec.js b/src/services/tradeEngine/trade/state/actions/index.spec.js similarity index 100% rename from common/tradeEngine/trade/state/actions/index.spec.js rename to src/services/tradeEngine/trade/state/actions/index.spec.js diff --git a/common/tradeEngine/trade/state/constants.js b/src/services/tradeEngine/trade/state/constants.js similarity index 100% rename from common/tradeEngine/trade/state/constants.js rename to src/services/tradeEngine/trade/state/constants.js diff --git a/common/tradeEngine/trade/state/reducers/index.js b/src/services/tradeEngine/trade/state/reducers/index.js similarity index 100% rename from common/tradeEngine/trade/state/reducers/index.js rename to src/services/tradeEngine/trade/state/reducers/index.js diff --git a/common/tradeEngine/trade/state/reducers/index.spec.js b/src/services/tradeEngine/trade/state/reducers/index.spec.js similarity index 100% rename from common/tradeEngine/trade/state/reducers/index.spec.js rename to src/services/tradeEngine/trade/state/reducers/index.spec.js diff --git a/common/broadcast.js b/src/services/tradeEngine/utils/broadcast.js similarity index 85% rename from common/broadcast.js rename to src/services/tradeEngine/utils/broadcast.js index ed61c5bb..bd5444f7 100644 --- a/common/broadcast.js +++ b/src/services/tradeEngine/utils/broadcast.js @@ -1,4 +1,4 @@ -import { observer as globalObserver } from './observer'; +import { observer as globalObserver } from '../../../utils/observer'; export const contract = c => globalObserver.emit('bot.contract', c); diff --git a/common/tradeEngine/utils/cli.js b/src/services/tradeEngine/utils/cli.js similarity index 89% rename from common/tradeEngine/utils/cli.js rename to src/services/tradeEngine/utils/cli.js index 52315b54..5962c7f3 100644 --- a/common/tradeEngine/utils/cli.js +++ b/src/services/tradeEngine/utils/cli.js @@ -1,8 +1,8 @@ import fs from 'fs'; import readline from 'readline'; import program from 'commander'; -import { observer as globalObserver } from '../../observer'; -import { createInterpreter } from '../../utils/cliTools'; +import { createInterpreter } from './cliTools'; +import { observer as globalObserver } from '../../../utils/observer'; const log = (...args) => console.log(`${new Date().toLocaleTimeString()}:`, ...args); // eslint-disable-line no-console diff --git a/common/utils/cliTools.js b/src/services/tradeEngine/utils/cliTools.js similarity index 52% rename from common/utils/cliTools.js rename to src/services/tradeEngine/utils/cliTools.js index b8e9d5e0..61943d1f 100644 --- a/common/utils/cliTools.js +++ b/src/services/tradeEngine/utils/cliTools.js @@ -1,7 +1,7 @@ -import TicksService from './ticksService'; -import { generateLiveApiInstance } from '../appId'; -import Interpreter from '../interpreter'; -import Observer from '../observer'; +import Interpreter from './interpreter'; +import TicksService from '../../api/ticksService'; +import { generateLiveApiInstance } from '../../api/appId'; +import Observer from '../../../utils/observer'; export const createScope = () => { const observer = new Observer(); diff --git a/common/tools.js b/src/services/tradeEngine/utils/helpers.js similarity index 97% rename from common/tools.js rename to src/services/tradeEngine/utils/helpers.js index ad8959f9..e3bf9bd5 100644 --- a/common/tools.js +++ b/src/services/tradeEngine/utils/helpers.js @@ -1,7 +1,7 @@ import { notify } from './broadcast'; -import config from './constants'; -import { getUTCTime } from './helpers'; -import { translate } from './lang/i18n'; +import config from '../../../constants/const'; +import { getUTCTime } from '../../../utils/tools'; +import { translate } from '../../../utils/lang/i18n'; export const noop = () => {}; diff --git a/common/interpreter.js b/src/services/tradeEngine/utils/interpreter.js similarity index 97% rename from common/interpreter.js rename to src/services/tradeEngine/utils/interpreter.js index 81821d21..1d8c683a 100644 --- a/common/interpreter.js +++ b/src/services/tradeEngine/utils/interpreter.js @@ -1,7 +1,7 @@ import JSInterpreter from 'js-interpreter'; -import { observer as globalObserver } from './observer'; -import { createScope } from './utils/cliTools'; -import Interface from './tradeEngine/Interface'; +import { createScope } from './cliTools'; +import { observer as globalObserver } from '../../../utils/observer'; +import Interface from '../Interface'; const unrecoverableErrors = [ 'InsufficientBalance', diff --git a/common/tradeEngine/utils/sanitize.js b/src/services/tradeEngine/utils/sanitize.js similarity index 94% rename from common/tradeEngine/utils/sanitize.js rename to src/services/tradeEngine/utils/sanitize.js index c7bd2813..706c4bd6 100644 --- a/common/tradeEngine/utils/sanitize.js +++ b/src/services/tradeEngine/utils/sanitize.js @@ -1,5 +1,5 @@ -import createError from '../../error'; -import { translate } from '../../lang/i18n'; +import createError from '../../../utils/error'; +import { translate } from '../../../utils/lang/i18n'; const isPositiveNumber = num => Number.isFinite(num) && num > 0; diff --git a/common/__tests__/constants.js b/src/utils/__tests__/constants.js similarity index 82% rename from common/__tests__/constants.js rename to src/utils/__tests__/constants.js index fd803068..ad1e68b6 100644 --- a/common/__tests__/constants.js +++ b/src/utils/__tests__/constants.js @@ -1,4 +1,4 @@ -import config, { updateConfigCurrencies } from '../constants'; +import config, { updateConfigCurrencies } from '../../constants/const'; describe('Configured currencies', () => { let configuration; diff --git a/common/lang/__tests__/i18n.js b/src/utils/__tests__/i18n.js similarity index 94% rename from common/lang/__tests__/i18n.js rename to src/utils/__tests__/i18n.js index df04fac9..54d4b959 100644 --- a/common/lang/__tests__/i18n.js +++ b/src/utils/__tests__/i18n.js @@ -1,5 +1,5 @@ -import { expect } from 'chai'; -import { translate, init, xml as translateXml } from '../i18n'; +import { expect } from 'chai'; +import { translate, init, xml as translateXml } from '../lang/i18n'; class Xml { constructor(el, children = {}) { diff --git a/common/integrations/elevio.js b/src/utils/customerSupport/elevio.js similarity index 97% rename from common/integrations/elevio.js rename to src/utils/customerSupport/elevio.js index c76baf6f..7accf26b 100644 --- a/common/integrations/elevio.js +++ b/src/utils/customerSupport/elevio.js @@ -1,4 +1,4 @@ -import { generateLiveApiInstance } from '../appId'; +import { generateLiveApiInstance } from '../../services/api/appId'; import { translate } from '../lang/i18n'; import { getLanguage } from '../lang/lang'; import { getTokenList } from '../storageManager'; diff --git a/common/error.js b/src/utils/error.js similarity index 100% rename from common/error.js rename to src/utils/error.js diff --git a/common/integrations/gtm.js b/src/utils/gtm.js similarity index 89% rename from common/integrations/gtm.js rename to src/utils/gtm.js index 9654621f..7c7c5257 100644 --- a/common/integrations/gtm.js +++ b/src/utils/gtm.js @@ -1,6 +1,6 @@ -import { getAppIdFallback } from '../appId'; -import AppIdMap from '../appIdResolver'; -import { getTokenList } from '../storageManager'; +import { getTokenList } from './storageManager'; +import { getAppIdFallback } from '../services/api/appId'; +import AppIdMap from '../services/api/appIdResolver'; const GTM = (() => { const isGtmApplicable = () => Object.values(AppIdMap).includes(`${getAppIdFallback()}`); diff --git a/common/integrations/googleDrive.js b/src/utils/integrations/googleDrive.js similarity index 99% rename from common/integrations/googleDrive.js rename to src/utils/integrations/googleDrive.js index 36421a81..be39d0bd 100644 --- a/common/integrations/googleDrive.js +++ b/src/utils/integrations/googleDrive.js @@ -1,7 +1,7 @@ -import config from '../constants'; -import { translate, trackAndEmitError } from '../helpers'; import { getLanguage } from '../lang/lang'; import { observer as globalObserver } from '../observer'; +import { translate, trackAndEmitError } from '../tools'; +import config from '../../constants/const'; import { loadWorkspace, loadBlocks } from '../../scratch'; class GoogleDrive { diff --git a/common/lang/i18n.js b/src/utils/lang/i18n.js similarity index 63% rename from common/lang/i18n.js rename to src/utils/lang/i18n.js index c011169a..5d539de7 100644 --- a/common/lang/i18n.js +++ b/src/utils/lang/i18n.js @@ -1,17 +1,17 @@ import sha1 from 'sha1'; -import ach from '../../translations/ach_UG/i10n.json'; -import de from '../../translations/de_DE/i10n.json'; -import en from '../../translations/en/i10n.json'; -import es from '../../translations/es_ES/i10n.json'; -import fr from '../../translations/fr_FR/i10n.json'; -import id from '../../translations/id_ID/i10n.json'; -import it from '../../translations/it_IT/i10n.json'; -import pl from '../../translations/pl_PL/i10n.json'; -import pt from '../../translations/pt_PT/i10n.json'; -import ru from '../../translations/ru_RU/i10n.json'; -import vi from '../../translations/vi_VN/i10n.json'; -import zhCn from '../../translations/zh_CN/i10n.json'; -import zhTw from '../../translations/zh_TW/i10n.json'; +import ach from '../../../translations/ach_UG/i10n.json'; +import de from '../../../translations/de_DE/i10n.json'; +import en from '../../../translations/en/i10n.json'; +import es from '../../../translations/es_ES/i10n.json'; +import fr from '../../../translations/fr_FR/i10n.json'; +import id from '../../../translations/id_ID/i10n.json'; +import it from '../../../translations/it_IT/i10n.json'; +import pl from '../../../translations/pl_PL/i10n.json'; +import pt from '../../../translations/pt_PT/i10n.json'; +import ru from '../../../translations/ru_RU/i10n.json'; +import vi from '../../../translations/vi_VN/i10n.json'; +import zhCn from '../../../translations/zh_CN/i10n.json'; +import zhTw from '../../../translations/zh_TW/i10n.json'; export const supportedLanguages = { zh_tw: zhTw, diff --git a/common/lang/lang.js b/src/utils/lang/lang.js similarity index 99% rename from common/lang/lang.js rename to src/utils/lang/lang.js index cc5bc3c6..8ab65673 100644 --- a/common/lang/lang.js +++ b/src/utils/lang/lang.js @@ -1,5 +1,5 @@ import { supportedLanguages, translate, init } from './i18n'; -import { parseQueryString } from '../helpers'; +import { parseQueryString } from '../tools'; import { set as setStorage, get as getStorage } from '../storageManager'; export const getLanguage = () => { diff --git a/common/observer.js b/src/utils/observer.js similarity index 100% rename from common/observer.js rename to src/utils/observer.js diff --git a/common/storageManager.js b/src/utils/storageManager.js similarity index 100% rename from common/storageManager.js rename to src/utils/storageManager.js diff --git a/common/helpers.js b/src/utils/tools.js similarity index 98% rename from common/helpers.js rename to src/utils/tools.js index 8ccca388..6436b637 100644 --- a/common/helpers.js +++ b/src/utils/tools.js @@ -1,8 +1,8 @@ import RenderHTML from 'react-render-html'; -import AppIdMap from './appIdResolver'; import { getLanguage } from './lang/lang'; import { translate as i18nTranslate } from './lang/i18n'; import { observer as globalObserver } from './observer'; +import AppIdMap from '../services/api/appIdResolver'; export const parseQueryString = () => { if (typeof window === 'undefined') { diff --git a/webpack.config.js b/webpack.config.js index 9bf40e7a..ef8a3364 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,7 +6,7 @@ const StyleLintPlugin = require('stylelint-webpack-plugin'); module.exports = { entry : [ '@babel/polyfill', - path.join(__dirname, './scratch/hooks'), + path.join(__dirname, './src/scratch/hooks'), path.join(__dirname, './src/app.js'), ], output: { @@ -55,7 +55,7 @@ module.exports = { new MiniCssExtractPlugin({ filename: 'bot.css' }), new StyleLintPlugin( { fix: true }), new CopyWebpackPlugin([ - { from: 'scratch/xml' }, + { from: './src/scratch/xml' }, { from: './node_modules/scratch-blocks/media', to: 'media' }, { from: './node_modules/scratch-blocks/blockly_compressed_vertical.js', to: 'scratch-compressed.js' }, { from: './node_modules/scratch-blocks/msg/messages.js', to: 'scratch-messages.js' }, From 884d0b14159afc90a99755db9ed3beb15d8ed2d0 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 31 May 2019 12:01:08 +0800 Subject: [PATCH 4/6] Fix eslint --- src/services/api/appId.js | 6 +++--- src/services/tradeEngine/trade/Proposal.js | 2 +- src/services/tradeEngine/trade/Purchase.js | 2 +- src/services/tradeEngine/trade/Sell.js | 2 +- src/services/tradeEngine/trade/Ticks.js | 2 +- src/services/tradeEngine/trade/Total.js | 2 +- src/services/tradeEngine/trade/index.js | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/services/api/appId.js b/src/services/api/appId.js index b4e0baad..3437962e 100644 --- a/src/services/api/appId.js +++ b/src/services/api/appId.js @@ -1,6 +1,7 @@ import { LiveApi } from 'binary-live-api'; import AppIdMap from './appIdResolver'; -import { parseQueryString, isProduction, getExtension } from '../../utils/tools'; +import Elevio from '../../utils/customerSupport/elevio'; +import GTM from '../../utils/gtm'; import { getLanguage } from '../../utils/lang/lang'; import { addToken, @@ -10,8 +11,7 @@ import { get as getStorage, set as setStorage, } from '../../utils/storageManager'; -import Elevio from '../../utils/customerSupport/elevio'; -import GTM from '../../utils/gtm'; +import { parseQueryString, isProduction, getExtension } from '../../utils/tools'; export const AppConstants = Object.freeze({ STORAGE_ACTIVE_TOKEN: 'activeToken', diff --git a/src/services/tradeEngine/trade/Proposal.js b/src/services/tradeEngine/trade/Proposal.js index b8e22157..f1ce3c61 100644 --- a/src/services/tradeEngine/trade/Proposal.js +++ b/src/services/tradeEngine/trade/Proposal.js @@ -1,6 +1,6 @@ import { proposalsReady, clearProposals } from './state/actions'; -import { translate } from '../../../utils/lang/i18n'; import { tradeOptionToProposal, doUntilDone, getUUID } from '../utils/helpers'; +import { translate } from '../../../utils/lang/i18n'; export default Engine => class Proposal extends Engine { diff --git a/src/services/tradeEngine/trade/Purchase.js b/src/services/tradeEngine/trade/Purchase.js index e91cb272..4e3519b3 100644 --- a/src/services/tradeEngine/trade/Purchase.js +++ b/src/services/tradeEngine/trade/Purchase.js @@ -1,8 +1,8 @@ import { purchaseSuccessful } from './state/actions'; import { BEFORE_PURCHASE } from './state/constants'; import { contractStatus, info, notify } from '../utils/broadcast'; -import { translate } from '../../../utils/lang/i18n'; import { recoverFromError, doUntilDone } from '../utils/helpers'; +import { translate } from '../../../utils/lang/i18n'; let delayIndex = 0; diff --git a/src/services/tradeEngine/trade/Sell.js b/src/services/tradeEngine/trade/Sell.js index 8b8326a5..84f2e832 100644 --- a/src/services/tradeEngine/trade/Sell.js +++ b/src/services/tradeEngine/trade/Sell.js @@ -1,7 +1,7 @@ import { DURING_PURCHASE } from './state/constants'; import { contractStatus, notify } from '../utils/broadcast'; -import { translate } from '../../../utils/lang/i18n'; import { recoverFromError, doUntilDone } from '../utils/helpers'; +import { translate } from '../../../utils/lang/i18n'; let delayIndex = 0; diff --git a/src/services/tradeEngine/trade/Ticks.js b/src/services/tradeEngine/trade/Ticks.js index 402dde57..c3b85c47 100644 --- a/src/services/tradeEngine/trade/Ticks.js +++ b/src/services/tradeEngine/trade/Ticks.js @@ -1,8 +1,8 @@ import { getLast } from 'binary-utils'; import * as constants from './state/constants'; +import { getDirection, getLastDigit } from '../utils/helpers'; import { expectPositiveInteger } from '../utils/sanitize'; import { translate } from '../../../utils/lang/i18n'; -import { getDirection, getLastDigit } from '../utils/helpers'; let tickListenerKey; diff --git a/src/services/tradeEngine/trade/Total.js b/src/services/tradeEngine/trade/Total.js index 882d5b53..06c19742 100644 --- a/src/services/tradeEngine/trade/Total.js +++ b/src/services/tradeEngine/trade/Total.js @@ -1,8 +1,8 @@ import { info, notify } from '../utils/broadcast'; +import { roundBalance } from '../utils/helpers'; import createError from '../../../utils/error'; import { translate } from '../../../utils/lang/i18n'; import { observer as globalObserver } from '../../../utils/observer'; -import { roundBalance } from '../utils/helpers'; const skeleton = { totalProfit: 0, diff --git a/src/services/tradeEngine/trade/index.js b/src/services/tradeEngine/trade/index.js index 3add107a..72391abf 100644 --- a/src/services/tradeEngine/trade/index.js +++ b/src/services/tradeEngine/trade/index.js @@ -11,9 +11,9 @@ import * as constants from './state/constants'; import { start } from './state/actions'; import Ticks from './Ticks'; import Total from './Total'; +import { doUntilDone } from '../utils/helpers'; import { expectInitArg, expectTradeOptions } from '../utils/sanitize'; import createError from '../../../utils/error'; -import { doUntilDone } from '../utils/helpers'; import { translate } from '../../../utils/lang/i18n'; import { durationToSecond } from '../../../utils/tools'; import { observer as globalObserver } from '../../../utils/observer'; From e0d6c42555cb2bc40072be890336502ee67ba99f Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 31 May 2019 12:48:11 +0800 Subject: [PATCH 5/6] Re-order imports --- src/scratch/index.js | 4 ++-- src/scratch/shared.js | 4 ++-- src/services/tradeEngine/Interface/IndicatorsInterface.js | 8 ++++---- src/services/tradeEngine/Interface/ToolsInterface.js | 4 ++-- src/services/tradeEngine/trade/index.js | 4 ++-- src/utils/customerSupport/elevio.js | 2 +- src/utils/lang/lang.js | 4 ++-- src/utils/tools.js | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/scratch/index.js b/src/scratch/index.js index 6f1cb3b3..cba70e85 100644 --- a/src/scratch/index.js +++ b/src/scratch/index.js @@ -12,13 +12,13 @@ import { strategyHasValidTradeTypeCategory, cleanBeforeExport, } from './utils'; +import { showDialog } from '../services/tradeEngine/utils/helpers'; +import Interpreter from '../services/tradeEngine/utils/interpreter'; import GTM from '../utils/gtm'; import createError from '../utils/error'; -import Interpreter from '../services/tradeEngine/utils/interpreter'; import { translate, xml as translateXml } from '../utils/lang/i18n'; import { getLanguage } from '../utils/lang/lang'; import { observer as globalObserver } from '../utils/observer'; -import { showDialog } from '../services/tradeEngine/utils/helpers'; export const scratchWorkspaceInit = async (scratch_area_name, scratch_div_name) => { try { diff --git a/src/scratch/shared.js b/src/scratch/shared.js index 404cf4a6..1e61723c 100644 --- a/src/scratch/shared.js +++ b/src/scratch/shared.js @@ -1,7 +1,8 @@ import filesaver from 'file-saver'; import { oppositesToDropdown } from './utils'; -import { generateLiveApiInstance } from '../services/api/appId'; import config from '../constants/const'; +import { generateLiveApiInstance } from '../services/api/appId'; +import { symbolApi } from '../services/api/shared'; import { translate } from '../utils/lang/i18n'; import { observer as globalObserver } from '../utils/observer'; import { @@ -10,7 +11,6 @@ import { getTokenList, removeAllTokens, } from '../utils/storageManager'; -import { symbolApi } from '../services/api/shared'; let purchaseChoices = [[translate('Click to select'), '']]; diff --git a/src/services/tradeEngine/Interface/IndicatorsInterface.js b/src/services/tradeEngine/Interface/IndicatorsInterface.js index 363ca4f7..e59a6e4b 100644 --- a/src/services/tradeEngine/Interface/IndicatorsInterface.js +++ b/src/services/tradeEngine/Interface/IndicatorsInterface.js @@ -1,8 +1,8 @@ -import sma, { simpleMovingAverageArray as smaa } from '@binary-com/binary-indicators/lib/simpleMovingAverage'; +import sma, { simpleMovingAverageArray as smaa } from '@binary-com/binary-indicators/lib/simpleMovingAverage'; import ema, { exponentialMovingAverageArray as emaa } from '@binary-com/binary-indicators/lib/exponentialMovingAverage'; -import bb, { bollingerBandsArray as bba } from '@binary-com/binary-indicators/lib/bollingerBands'; -import rsi, { relativeStrengthIndexArray as rsia } from '@binary-com/binary-indicators/lib/relativeStrengthIndex'; -import macda from '@binary-com/binary-indicators/lib/macd'; +import bb, { bollingerBandsArray as bba } from '@binary-com/binary-indicators/lib/bollingerBands'; +import rsi, { relativeStrengthIndexArray as rsia } from '@binary-com/binary-indicators/lib/relativeStrengthIndex'; +import macda from '@binary-com/binary-indicators/lib/macd'; export default Interface => class extends Interface { diff --git a/src/services/tradeEngine/Interface/ToolsInterface.js b/src/services/tradeEngine/Interface/ToolsInterface.js index 90fb23f4..9c8be2d7 100644 --- a/src/services/tradeEngine/Interface/ToolsInterface.js +++ b/src/services/tradeEngine/Interface/ToolsInterface.js @@ -1,6 +1,6 @@ -import CandleInterface from './CandleInterface'; -import MiscInterface from './MiscInterface'; +import CandleInterface from './CandleInterface'; import IndicatorsInterface from './IndicatorsInterface'; +import MiscInterface from './MiscInterface'; // prettier-ignore export default Interface => class extends IndicatorsInterface( diff --git a/src/services/tradeEngine/trade/index.js b/src/services/tradeEngine/trade/index.js index 72391abf..141a8683 100644 --- a/src/services/tradeEngine/trade/index.js +++ b/src/services/tradeEngine/trade/index.js @@ -6,9 +6,9 @@ import OpenContract from './OpenContract'; import Proposal from './Proposal'; import Purchase from './Purchase'; import Sell from './Sell'; -import rootReducer from './state/reducers'; -import * as constants from './state/constants'; import { start } from './state/actions'; +import * as constants from './state/constants'; +import rootReducer from './state/reducers'; import Ticks from './Ticks'; import Total from './Total'; import { doUntilDone } from '../utils/helpers'; diff --git a/src/utils/customerSupport/elevio.js b/src/utils/customerSupport/elevio.js index 7accf26b..00c6d2e8 100644 --- a/src/utils/customerSupport/elevio.js +++ b/src/utils/customerSupport/elevio.js @@ -1,7 +1,7 @@ -import { generateLiveApiInstance } from '../../services/api/appId'; import { translate } from '../lang/i18n'; import { getLanguage } from '../lang/lang'; import { getTokenList } from '../storageManager'; +import { generateLiveApiInstance } from '../../services/api/appId'; const Elevio = (() => { const init = () => { diff --git a/src/utils/lang/lang.js b/src/utils/lang/lang.js index 8ab65673..5df75acb 100644 --- a/src/utils/lang/lang.js +++ b/src/utils/lang/lang.js @@ -1,6 +1,6 @@ import { supportedLanguages, translate, init } from './i18n'; -import { parseQueryString } from '../tools'; -import { set as setStorage, get as getStorage } from '../storageManager'; +import { parseQueryString } from '../tools'; +import { set as setStorage, get as getStorage } from '../storageManager'; export const getLanguage = () => { const queryLang = parseQueryString().l; diff --git a/src/utils/tools.js b/src/utils/tools.js index 6436b637..f23eee19 100644 --- a/src/utils/tools.js +++ b/src/utils/tools.js @@ -1,7 +1,7 @@ import RenderHTML from 'react-render-html'; -import { getLanguage } from './lang/lang'; -import { translate as i18nTranslate } from './lang/i18n'; import { observer as globalObserver } from './observer'; +import { translate as i18nTranslate } from './lang/i18n'; +import { getLanguage } from './lang/lang'; import AppIdMap from '../services/api/appIdResolver'; export const parseQueryString = () => { From 89cb5215b1904ca727a43e27fed5df838e7704a9 Mon Sep 17 00:00:00 2001 From: Aaron Imming Date: Fri, 31 May 2019 13:18:32 +0800 Subject: [PATCH 6/6] Update scripts --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 71b0c9c4..0ee63d65 100644 --- a/package.json +++ b/package.json @@ -14,11 +14,10 @@ ] }, "scripts": { - "lint-fix": "eslint ./src ./common ./scratch --fix", "build": "rimraf dist && cross-env NODE_ENV=production webpack --mode=production --optimize-minimize --progress", "watch": "webpack --mode=development --progress --watch", - "start": "eslint ./src ./common ./scratch && rimraf dist && webpack-dev-server --mode=development --open --hot --inline", - "test": "eslint ./src ./common ./scratch && jest -w 10 --coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage", + "start": "eslint ./src && rimraf dist && webpack-dev-server --mode=development --open --hot --inline", + "test": "eslint ./src && jest -w 10 --coverage && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage", "gh-pages": "gh-pages --dist '.' --src '{index.html,manifest.json,dist/**,CNAME}'", "gh-pages:folder": "yarn gh-pages --src '{index.html,manifest.json,dist/**}' --dest $1", "release": "d() { test -z $1 && echo 'Please specify branch.' && exit 1; (git show-branch $1) || exit 1; git stash; git checkout $1; npm i; rm -rf branch/$1; mkdir -p branch/$1 ; gulp build-min; cp -r www/ branch/$1; gulp release-branch --branch $1;}; d",