smartxtrader 3.8.1-xm.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1270) hide show
  1. package/.babelrc +20 -0
  2. package/.dockerignore +5 -0
  3. package/.eslintignore +6 -0
  4. package/.eslintrc.js +81 -0
  5. package/.gitattributes +6 -0
  6. package/.stylelintrc.js +33 -0
  7. package/Dockerfile +14 -0
  8. package/Gruntfile.js +38 -0
  9. package/LICENSE +201 -0
  10. package/README.md +191 -0
  11. package/api/_lib/http_utils.js +150 -0
  12. package/api/_lib/legal_consent_store.js +108 -0
  13. package/api/_lib/telegram_session_store.js +182 -0
  14. package/api/_lib/telegram_subscription.js +507 -0
  15. package/api/deriv/auth.js +501 -0
  16. package/api/legal/accept.js +99 -0
  17. package/api/legal/delete.js +77 -0
  18. package/api/legal/status.js +71 -0
  19. package/api/logout.js +58 -0
  20. package/api/session-status.js +74 -0
  21. package/api/telegram/auth.js +117 -0
  22. package/api/telegram/control.js +10 -0
  23. package/api/telegram/logout.js +69 -0
  24. package/api/telegram/notify-login.js +79 -0
  25. package/api/telegram/status.js +153 -0
  26. package/api/telegram/webhook.js +1361 -0
  27. package/binary.com.conf +22 -0
  28. package/build/aliases.yaml +66 -0
  29. package/build/babel.js +19 -0
  30. package/build/checkDependencies.js +10 -0
  31. package/build/clean.js +5 -0
  32. package/build/concurrent.js +8 -0
  33. package/build/config/constants.js +54 -0
  34. package/build/config/helpers.js +37 -0
  35. package/build/config/init.js +48 -0
  36. package/build/connect.js +103 -0
  37. package/build/copy.js +30 -0
  38. package/build/cssmin.js +20 -0
  39. package/build/eslint.js +15 -0
  40. package/build/gh-pages.js +27 -0
  41. package/build/hashres.js +17 -0
  42. package/build/mochaTest.js +20 -0
  43. package/build/postcss.js +20 -0
  44. package/build/sass.js +17 -0
  45. package/build/shell.js +194 -0
  46. package/build/stylelint.js +13 -0
  47. package/build/watch.js +21 -0
  48. package/build/webpack/config_app.js +23 -0
  49. package/build/webpack/config_common.js +77 -0
  50. package/build/webpack/helpers.js +19 -0
  51. package/build/webpack/paths.js +11 -0
  52. package/build/webpack/plugins.js +84 -0
  53. package/build/webpack.js +23 -0
  54. package/crowdin.yaml +6 -0
  55. package/cyberpunk-ui/index.html +14 -0
  56. package/cyberpunk-ui/package-lock.json +6321 -0
  57. package/cyberpunk-ui/package.json +37 -0
  58. package/cyberpunk-ui/public/icons/icon-192.svg +21 -0
  59. package/cyberpunk-ui/public/icons/icon-512.svg +21 -0
  60. package/cyberpunk-ui/public/manifest.webmanifest +22 -0
  61. package/cyberpunk-ui/src/App.jsx +49 -0
  62. package/cyberpunk-ui/src/api/client.js +53 -0
  63. package/cyberpunk-ui/src/api/session.ts +42 -0
  64. package/cyberpunk-ui/src/components/chart/DigitDistributionTable.jsx +522 -0
  65. package/cyberpunk-ui/src/components/chart/TradingChart.jsx +45 -0
  66. package/cyberpunk-ui/src/components/common/InstrumentBadge.jsx +28 -0
  67. package/cyberpunk-ui/src/components/common/KeyboardShortcuts.jsx +47 -0
  68. package/cyberpunk-ui/src/components/common/NotificationsCenter.jsx +24 -0
  69. package/cyberpunk-ui/src/components/common/SubscriptionGate.jsx +388 -0
  70. package/cyberpunk-ui/src/components/layout/SplitLayout.jsx +65 -0
  71. package/cyberpunk-ui/src/components/layout/TradingBackground.jsx +210 -0
  72. package/cyberpunk-ui/src/components/legal/LegalGate.jsx +250 -0
  73. package/cyberpunk-ui/src/components/navigation/BottomNav.jsx +45 -0
  74. package/cyberpunk-ui/src/components/navigation/TopBar.jsx +98 -0
  75. package/cyberpunk-ui/src/components/panels/ChartPanel.jsx +92 -0
  76. package/cyberpunk-ui/src/components/panels/PositionsHistory.jsx +94 -0
  77. package/cyberpunk-ui/src/components/panels/TradePanel.jsx +450 -0
  78. package/cyberpunk-ui/src/components/panels/TransformerRangeModal.jsx +184 -0
  79. package/cyberpunk-ui/src/components/panels/Watchlist.jsx +81 -0
  80. package/cyberpunk-ui/src/components/settings/ChartSettingsPortal.jsx +66 -0
  81. package/cyberpunk-ui/src/components/settings/SettingsSheet.jsx +76 -0
  82. package/cyberpunk-ui/src/config/legal.js +104 -0
  83. package/cyberpunk-ui/src/config/smartanalizer.js +128 -0
  84. package/cyberpunk-ui/src/hooks/useAppLayout.js +34 -0
  85. package/cyberpunk-ui/src/main.jsx +21 -0
  86. package/cyberpunk-ui/src/pages/AuthPage.tsx +265 -0
  87. package/cyberpunk-ui/src/pages/Dashboard.jsx +55 -0
  88. package/cyberpunk-ui/src/pages/Markets.jsx +15 -0
  89. package/cyberpunk-ui/src/pages/RegisterPage.tsx +202 -0
  90. package/cyberpunk-ui/src/pages/SettingsPage.jsx +180 -0
  91. package/cyberpunk-ui/src/pages/Trades.jsx +12 -0
  92. package/cyberpunk-ui/src/routes/AppRouter.jsx +21 -0
  93. package/cyberpunk-ui/src/store/sessionSlice.js +94 -0
  94. package/cyberpunk-ui/src/store/settingsSlice.js +68 -0
  95. package/cyberpunk-ui/src/store/store.js +18 -0
  96. package/cyberpunk-ui/src/store/symbolsSlice.js +93 -0
  97. package/cyberpunk-ui/src/store/uiSlice.js +80 -0
  98. package/cyberpunk-ui/src/styles/global.css +1404 -0
  99. package/cyberpunk-ui/src/theme/ThemeProvider.jsx +47 -0
  100. package/cyberpunk-ui/src/utils/authToken.ts +99 -0
  101. package/cyberpunk-ui/src/utils/instrumentIcons.js +24 -0
  102. package/cyberpunk-ui/src/utils/persist.js +24 -0
  103. package/cyberpunk-ui/src/vite-env.d.ts +9 -0
  104. package/cyberpunk-ui/tsconfig.json +21 -0
  105. package/cyberpunk-ui/tsconfig.node.json +9 -0
  106. package/cyberpunk-ui/vite.config.js +34 -0
  107. package/docker-compose.portainer.yml +13 -0
  108. package/docker-compose.yml +13 -0
  109. package/docs/canvasjs-candlesticks.md +138 -0
  110. package/docs/portainer-deployment.md +22 -0
  111. package/docs/telegram-bridge.md +207 -0
  112. package/docs/telegram_bot_integration.md +172 -0
  113. package/docs/value-distribution-scheme.ru.md +35 -0
  114. package/favicon.ico +0 -0
  115. package/mobile/App.js +138 -0
  116. package/mobile/chartHtml.js +147 -0
  117. package/mobile/components/AnimatedBackground.js +145 -0
  118. package/mobile/components/ChartWebView.js +113 -0
  119. package/mobile/components/Controls.js +245 -0
  120. package/mobile/metro.config.js +17 -0
  121. package/mobile/theme.js +57 -0
  122. package/package.json +181 -0
  123. package/packages/canvasjs-runtime/LICENSE +201 -0
  124. package/packages/canvasjs-runtime/README.md +7 -0
  125. package/packages/canvasjs-runtime/index.js +18 -0
  126. package/packages/canvasjs-runtime/package.json +18 -0
  127. package/packages/webtrader-charts/.gitattributes +3 -0
  128. package/packages/webtrader-charts/LICENSE +201 -0
  129. package/packages/webtrader-charts/README.md +154 -0
  130. package/packages/webtrader-charts/package.json +17 -0
  131. package/packages/webtrader-charts/rollup.config.iife.mjs +6 -0
  132. package/packages/webtrader-charts/rollup.config.mjs +144 -0
  133. package/packages/webtrader-charts/src/chartDraw.js +171 -0
  134. package/packages/webtrader-charts/src/chartOptions.html +173 -0
  135. package/packages/webtrader-charts/src/chartOptions.js +412 -0
  136. package/packages/webtrader-charts/src/chartOptions.scss +368 -0
  137. package/packages/webtrader-charts/src/chartTemplateManager.html +74 -0
  138. package/packages/webtrader-charts/src/chartTemplateManager.js +305 -0
  139. package/packages/webtrader-charts/src/chartWindow.html +12 -0
  140. package/packages/webtrader-charts/src/chartWindow.js +224 -0
  141. package/packages/webtrader-charts/src/charts.js +689 -0
  142. package/packages/webtrader-charts/src/charts.scss +128 -0
  143. package/packages/webtrader-charts/src/common/chartingRequestMap.js +381 -0
  144. package/packages/webtrader-charts/src/common/currentprice.js +155 -0
  145. package/packages/webtrader-charts/src/common/globals.js +15 -0
  146. package/packages/webtrader-charts/src/common/highchartsMousewheel.js +50 -0
  147. package/packages/webtrader-charts/src/common/indicators.js +340 -0
  148. package/packages/webtrader-charts/src/common/liveapi.js +194 -0
  149. package/packages/webtrader-charts/src/common/notification.js +37 -0
  150. package/packages/webtrader-charts/src/common/ohlc_handler.js +160 -0
  151. package/packages/webtrader-charts/src/common/rivetsExtra.js +163 -0
  152. package/packages/webtrader-charts/src/common/stream_handler.js +164 -0
  153. package/packages/webtrader-charts/src/common/utils.js +121 -0
  154. package/packages/webtrader-charts/src/crosshair.js +24 -0
  155. package/packages/webtrader-charts/src/draw/horizontal_line.js +124 -0
  156. package/packages/webtrader-charts/src/draw/properties_selector.html +4 -0
  157. package/packages/webtrader-charts/src/draw/properties_selector.js +87 -0
  158. package/packages/webtrader-charts/src/draw/vertical_line.js +123 -0
  159. package/packages/webtrader-charts/src/i18n/ach.json +102 -0
  160. package/packages/webtrader-charts/src/i18n/ar.json +96 -0
  161. package/packages/webtrader-charts/src/i18n/build.js +35 -0
  162. package/packages/webtrader-charts/src/i18n/de.json +102 -0
  163. package/packages/webtrader-charts/src/i18n/dictionary.json +1 -0
  164. package/packages/webtrader-charts/src/i18n/en.json +102 -0
  165. package/packages/webtrader-charts/src/i18n/es.json +102 -0
  166. package/packages/webtrader-charts/src/i18n/fr.json +102 -0
  167. package/packages/webtrader-charts/src/i18n/id.json +102 -0
  168. package/packages/webtrader-charts/src/i18n/it.json +102 -0
  169. package/packages/webtrader-charts/src/i18n/ja.json +102 -0
  170. package/packages/webtrader-charts/src/i18n/pl.json +102 -0
  171. package/packages/webtrader-charts/src/i18n/pt.json +102 -0
  172. package/packages/webtrader-charts/src/i18n/ru.json +102 -0
  173. package/packages/webtrader-charts/src/i18n/th.json +102 -0
  174. package/packages/webtrader-charts/src/i18n/vi.json +102 -0
  175. package/packages/webtrader-charts/src/i18n/zh_cn.json +102 -0
  176. package/packages/webtrader-charts/src/i18n/zh_tw.json +102 -0
  177. package/packages/webtrader-charts/src/images/Dash.svg +1 -0
  178. package/packages/webtrader-charts/src/images/DashDot.svg +1 -0
  179. package/packages/webtrader-charts/src/images/Dot.svg +1 -0
  180. package/packages/webtrader-charts/src/images/LongDash.svg +1 -0
  181. package/packages/webtrader-charts/src/images/LongDashDot.svg +1 -0
  182. package/packages/webtrader-charts/src/images/LongDashDotDot.svg +1 -0
  183. package/packages/webtrader-charts/src/images/ShortDash.svg +1 -0
  184. package/packages/webtrader-charts/src/images/ShortDashDot.svg +1 -0
  185. package/packages/webtrader-charts/src/images/ShortDashDotDot.svg +1 -0
  186. package/packages/webtrader-charts/src/images/ShortDot.svg +1 -0
  187. package/packages/webtrader-charts/src/images/Solid.svg +1 -0
  188. package/packages/webtrader-charts/src/images/back-arrow-w.svg +1 -0
  189. package/packages/webtrader-charts/src/images/back-arrow.svg +1 -0
  190. package/packages/webtrader-charts/src/images/blogger.svg +1 -0
  191. package/packages/webtrader-charts/src/images/blue_up_arrow.svg +1 -0
  192. package/packages/webtrader-charts/src/images/circle-close.svg +1 -0
  193. package/packages/webtrader-charts/src/images/close-blue.svg +1 -0
  194. package/packages/webtrader-charts/src/images/close-white.svg +1 -0
  195. package/packages/webtrader-charts/src/images/close.svg +1 -0
  196. package/packages/webtrader-charts/src/images/favorite-active.svg +1 -0
  197. package/packages/webtrader-charts/src/images/favorite-normal.svg +1 -0
  198. package/packages/webtrader-charts/src/images/fb.svg +1 -0
  199. package/packages/webtrader-charts/src/images/g-plus.svg +1 -0
  200. package/packages/webtrader-charts/src/images/horizontal_line.svg +1 -0
  201. package/packages/webtrader-charts/src/images/ic-edit.svg +1 -0
  202. package/packages/webtrader-charts/src/images/ic-search.svg +1 -0
  203. package/packages/webtrader-charts/src/images/ic-tip.svg +1 -0
  204. package/packages/webtrader-charts/src/images/images.js +33 -0
  205. package/packages/webtrader-charts/src/images/indicators/Abandoned_baby.svg +1 -0
  206. package/packages/webtrader-charts/src/images/indicators/Advance_block.svg +1 -0
  207. package/packages/webtrader-charts/src/images/indicators/Bet_hold.svg +1 -0
  208. package/packages/webtrader-charts/src/images/indicators/Bullish Piercing.svg +1 -0
  209. package/packages/webtrader-charts/src/images/indicators/Dark_cloud_cover.svg +1 -0
  210. package/packages/webtrader-charts/src/images/indicators/Doji.svg +1 -0
  211. package/packages/webtrader-charts/src/images/indicators/Doji_star.svg +1 -0
  212. package/packages/webtrader-charts/src/images/indicators/Download.svg +1 -0
  213. package/packages/webtrader-charts/src/images/indicators/Dragonfly_doji.svg +1 -0
  214. package/packages/webtrader-charts/src/images/indicators/Engulfing_pattern.svg +1 -0
  215. package/packages/webtrader-charts/src/images/indicators/Inverted-hammer.svg +1 -0
  216. package/packages/webtrader-charts/src/images/indicators/breakaway_pattern.svg +1 -0
  217. package/packages/webtrader-charts/src/images/indicators/closing_marubozu.svg +1 -0
  218. package/packages/webtrader-charts/src/images/indicators/counterattack.svg +1 -0
  219. package/packages/webtrader-charts/src/images/indicators/down_fractal.svg +1 -0
  220. package/packages/webtrader-charts/src/images/indicators/evening_doji_star.svg +1 -0
  221. package/packages/webtrader-charts/src/images/indicators/evening_star.svg +1 -0
  222. package/packages/webtrader-charts/src/images/indicators/gap_three_methods.svg +1 -0
  223. package/packages/webtrader-charts/src/images/indicators/gravestone_doji.svg +1 -0
  224. package/packages/webtrader-charts/src/images/indicators/hammer.svg +1 -0
  225. package/packages/webtrader-charts/src/images/indicators/hanging_man.svg +1 -0
  226. package/packages/webtrader-charts/src/images/indicators/harami_cross.svg +1 -0
  227. package/packages/webtrader-charts/src/images/indicators/harami_pattern.svg +1 -0
  228. package/packages/webtrader-charts/src/images/indicators/high_wave.svg +1 -0
  229. package/packages/webtrader-charts/src/images/indicators/hikkake.svg +1 -0
  230. package/packages/webtrader-charts/src/images/indicators/homing_pigeon.svg +1 -0
  231. package/packages/webtrader-charts/src/images/indicators/identical_three_crows.svg +1 -0
  232. package/packages/webtrader-charts/src/images/indicators/in-neck.svg +1 -0
  233. package/packages/webtrader-charts/src/images/indicators/indicatorImages.js +126 -0
  234. package/packages/webtrader-charts/src/images/indicators/kicking.svg +1 -0
  235. package/packages/webtrader-charts/src/images/indicators/ladder-bottom.svg +1 -0
  236. package/packages/webtrader-charts/src/images/indicators/long-legged-doji.svg +1 -0
  237. package/packages/webtrader-charts/src/images/indicators/long-line-candles.svg +1 -0
  238. package/packages/webtrader-charts/src/images/indicators/marubozu.svg +1 -0
  239. package/packages/webtrader-charts/src/images/indicators/mat-hold.svg +1 -0
  240. package/packages/webtrader-charts/src/images/indicators/matching-low.svg +1 -0
  241. package/packages/webtrader-charts/src/images/indicators/morning-doji-start.svg +1 -0
  242. package/packages/webtrader-charts/src/images/indicators/morning-star.svg +1 -0
  243. package/packages/webtrader-charts/src/images/indicators/on-neck.svg +1 -0
  244. package/packages/webtrader-charts/src/images/indicators/rickshaw man.svg +1 -0
  245. package/packages/webtrader-charts/src/images/indicators/rising falling three methods.svg +1 -0
  246. package/packages/webtrader-charts/src/images/indicators/salled pattern.svg +1 -0
  247. package/packages/webtrader-charts/src/images/indicators/separating lines.svg +1 -0
  248. package/packages/webtrader-charts/src/images/indicators/shooting star.svg +1 -0
  249. package/packages/webtrader-charts/src/images/indicators/short line candle.svg +1 -0
  250. package/packages/webtrader-charts/src/images/indicators/side by side white line.svg +1 -0
  251. package/packages/webtrader-charts/src/images/indicators/spinning top.svg +1 -0
  252. package/packages/webtrader-charts/src/images/indicators/stick sandwich.svg +1 -0
  253. package/packages/webtrader-charts/src/images/indicators/takuri line.svg +1 -0
  254. package/packages/webtrader-charts/src/images/indicators/tasuki gap.svg +1 -0
  255. package/packages/webtrader-charts/src/images/indicators/three_black_crows.svg +1 -0
  256. package/packages/webtrader-charts/src/images/indicators/three_inside_up_down.svg +1 -0
  257. package/packages/webtrader-charts/src/images/indicators/three_line_strike.svg +1 -0
  258. package/packages/webtrader-charts/src/images/indicators/three_outside_up_down.svg +1 -0
  259. package/packages/webtrader-charts/src/images/indicators/three_river.svg +1 -0
  260. package/packages/webtrader-charts/src/images/indicators/three_stars_in_the_south.svg +1 -0
  261. package/packages/webtrader-charts/src/images/indicators/three_white_soldiers.svg +1 -0
  262. package/packages/webtrader-charts/src/images/indicators/thrusting_pattern.svg +1 -0
  263. package/packages/webtrader-charts/src/images/indicators/tristar.svg +1 -0
  264. package/packages/webtrader-charts/src/images/indicators/two_crows.svg +1 -0
  265. package/packages/webtrader-charts/src/images/indicators/typprice.svg +1 -0
  266. package/packages/webtrader-charts/src/images/indicators/up_fractal.svg +1 -0
  267. package/packages/webtrader-charts/src/images/indicators/upside_gap_two_crows.svg +1 -0
  268. package/packages/webtrader-charts/src/images/maximize.svg +1 -0
  269. package/packages/webtrader-charts/src/images/minimize.svg +1 -0
  270. package/packages/webtrader-charts/src/images/orange_down_arrow.svg +1 -0
  271. package/packages/webtrader-charts/src/images/twitter.svg +1 -0
  272. package/packages/webtrader-charts/src/images/vertical_line.svg +1 -0
  273. package/packages/webtrader-charts/src/images/vk.svg +1 -0
  274. package/packages/webtrader-charts/src/index.js +61 -0
  275. package/packages/webtrader-charts/src/index.scss +5 -0
  276. package/packages/webtrader-charts/src/indicatorBuilder.html +141 -0
  277. package/packages/webtrader-charts/src/indicatorBuilder.js +157 -0
  278. package/packages/webtrader-charts/src/indicatorBuilder.scss +386 -0
  279. package/packages/webtrader-charts/src/indicatorManagement.html +123 -0
  280. package/packages/webtrader-charts/src/indicatorManagement.js +217 -0
  281. package/packages/webtrader-charts/src/indicatorManagement.scss +264 -0
  282. package/packages/webtrader-charts/src/indicators/ATR.js +130 -0
  283. package/packages/webtrader-charts/src/indicators/BOP.js +86 -0
  284. package/packages/webtrader-charts/src/indicators/IndicatorBase.js +119 -0
  285. package/packages/webtrader-charts/src/indicators/NATR.js +63 -0
  286. package/packages/webtrader-charts/src/indicators/ROCP.js +64 -0
  287. package/packages/webtrader-charts/src/indicators/ROCR.js +64 -0
  288. package/packages/webtrader-charts/src/indicators/STDDEV.js +107 -0
  289. package/packages/webtrader-charts/src/indicators/WILLR.js +64 -0
  290. package/packages/webtrader-charts/src/indicators/adx.js +115 -0
  291. package/packages/webtrader-charts/src/indicators/adxr.js +53 -0
  292. package/packages/webtrader-charts/src/indicators/alligator.js +140 -0
  293. package/packages/webtrader-charts/src/indicators/alma.js +80 -0
  294. package/packages/webtrader-charts/src/indicators/ao.js +119 -0
  295. package/packages/webtrader-charts/src/indicators/apo.js +57 -0
  296. package/packages/webtrader-charts/src/indicators/aroon.js +173 -0
  297. package/packages/webtrader-charts/src/indicators/aroonosc.js +75 -0
  298. package/packages/webtrader-charts/src/indicators/bbands.js +204 -0
  299. package/packages/webtrader-charts/src/indicators/cc.js +51 -0
  300. package/packages/webtrader-charts/src/indicators/cci.js +97 -0
  301. package/packages/webtrader-charts/src/indicators/cdl-mangled-props.js +1135 -0
  302. package/packages/webtrader-charts/src/indicators/cdl.js +1694 -0
  303. package/packages/webtrader-charts/src/indicators/chop.js +79 -0
  304. package/packages/webtrader-charts/src/indicators/cks.js +190 -0
  305. package/packages/webtrader-charts/src/indicators/cmo.js +104 -0
  306. package/packages/webtrader-charts/src/indicators/dc.js +175 -0
  307. package/packages/webtrader-charts/src/indicators/dema.js +70 -0
  308. package/packages/webtrader-charts/src/indicators/dx.js +162 -0
  309. package/packages/webtrader-charts/src/indicators/ema.js +66 -0
  310. package/packages/webtrader-charts/src/indicators/fractal.js +162 -0
  311. package/packages/webtrader-charts/src/indicators/hma.js +74 -0
  312. package/packages/webtrader-charts/src/indicators/ichimoku.js +246 -0
  313. package/packages/webtrader-charts/src/indicators/index.js +73 -0
  314. package/packages/webtrader-charts/src/indicators/kama.js +83 -0
  315. package/packages/webtrader-charts/src/indicators/lsma.js +71 -0
  316. package/packages/webtrader-charts/src/indicators/lwma.js +75 -0
  317. package/packages/webtrader-charts/src/indicators/macd.js +188 -0
  318. package/packages/webtrader-charts/src/indicators/mama.js +178 -0
  319. package/packages/webtrader-charts/src/indicators/mass.js +93 -0
  320. package/packages/webtrader-charts/src/indicators/max.js +61 -0
  321. package/packages/webtrader-charts/src/indicators/min.js +61 -0
  322. package/packages/webtrader-charts/src/indicators/mom.js +63 -0
  323. package/packages/webtrader-charts/src/indicators/ppo.js +200 -0
  324. package/packages/webtrader-charts/src/indicators/roc.js +63 -0
  325. package/packages/webtrader-charts/src/indicators/rsi.js +75 -0
  326. package/packages/webtrader-charts/src/indicators/sar.js +216 -0
  327. package/packages/webtrader-charts/src/indicators/sma.js +71 -0
  328. package/packages/webtrader-charts/src/indicators/smma.js +81 -0
  329. package/packages/webtrader-charts/src/indicators/stoch.js +169 -0
  330. package/packages/webtrader-charts/src/indicators/stochf.js +140 -0
  331. package/packages/webtrader-charts/src/indicators/stochrsi.js +70 -0
  332. package/packages/webtrader-charts/src/indicators/stochs.js +141 -0
  333. package/packages/webtrader-charts/src/indicators/sum.js +60 -0
  334. package/packages/webtrader-charts/src/indicators/t3.js +119 -0
  335. package/packages/webtrader-charts/src/indicators/tema.js +81 -0
  336. package/packages/webtrader-charts/src/indicators/trange.js +75 -0
  337. package/packages/webtrader-charts/src/indicators/trima.js +73 -0
  338. package/packages/webtrader-charts/src/indicators/typprice.js +50 -0
  339. package/packages/webtrader-charts/src/indicators/ultosc.js +103 -0
  340. package/packages/webtrader-charts/src/indicators/var.js +96 -0
  341. package/packages/webtrader-charts/src/indicators/wclprice.js +51 -0
  342. package/packages/webtrader-charts/src/indicators/wma.js +79 -0
  343. package/packages/webtrader-charts/src/indicators-config.js +2138 -0
  344. package/packages/webtrader-charts/src/lib/jquery.ddslick.js +361 -0
  345. package/packages/webtrader-charts/src/lib/leanModal.js +81 -0
  346. package/packages/webtrader-charts/src/lib/leanModal.scss +52 -0
  347. package/packages/webtrader-charts/src/lib/spectrum.js +2323 -0
  348. package/packages/webtrader-charts/src/lib/spectrum.scss +507 -0
  349. package/packages/webtrader-charts/src/lib/toastr.js +380 -0
  350. package/packages/webtrader-charts/src/lib/toastr.scss +161 -0
  351. package/packages/webtrader-charts/src/mobileview.scss +29 -0
  352. package/packages/webtrader-charts/src/overlayManagement.html +30 -0
  353. package/packages/webtrader-charts/src/overlayManagement.js +297 -0
  354. package/packages/webtrader-charts/src/overlayManagement.scss +77 -0
  355. package/packages/webtrader-charts/src/tableView.html +28 -0
  356. package/packages/webtrader-charts/src/tableView.js +166 -0
  357. package/packages/webtrader-charts/src/tableView.scss +15 -0
  358. package/scripts/README.md +68 -0
  359. package/scripts/__tests__/static_strings.js +32 -0
  360. package/scripts/__tests__/svg_test.js +47 -0
  361. package/scripts/common.js +93 -0
  362. package/scripts/config/pages.js +124 -0
  363. package/scripts/config/sitemap_urls.js +56 -0
  364. package/scripts/extract_js_texts.js +180 -0
  365. package/scripts/gettext.js +155 -0
  366. package/scripts/js_texts/extracted_strings_app.js +520 -0
  367. package/scripts/js_texts/static_strings_app.js +62 -0
  368. package/scripts/js_translation.js +99 -0
  369. package/scripts/render.js +406 -0
  370. package/scripts/sitemap.js +68 -0
  371. package/scripts/ssr-scriptjs-shim.js +5 -0
  372. package/scripts/update_translations.sh +76 -0
  373. package/src/download/fonts/binary_symbols.woff +0 -0
  374. package/src/download/fonts/guide/casino_hand-webfont.eot +0 -0
  375. package/src/download/fonts/guide/casino_hand-webfont.svg +243 -0
  376. package/src/download/fonts/guide/casino_hand-webfont.ttf +0 -0
  377. package/src/download/fonts/guide/casino_hand-webfont.woff +0 -0
  378. package/src/images/common/authenticated.svg +1 -0
  379. package/src/images/common/close_icon.svg +1 -0
  380. package/src/images/common/email_sent.svg +1 -0
  381. package/src/images/common/globe-with_logo.svg +1 -0
  382. package/src/images/common/ic-anchor.svg +1 -0
  383. package/src/images/common/livechat.svg +1 -0
  384. package/src/images/common/logos/ic-brand-binarybot (2).svg +18 -0
  385. package/src/images/common/logos/ic-brand-binarybot.svg +21 -0
  386. package/src/images/common/logos/ic-brand-dbot.svg +1 -0
  387. package/src/images/common/logos/ic-brand-dmt5.svg +1 -0
  388. package/src/images/common/logos/ic-brand-dtrade2.svg +1 -0
  389. package/src/images/common/logos/ic-brand-dtrader.svg +36 -0
  390. package/src/images/common/logos/ic-brand-dxtrade.svg +1 -0
  391. package/src/images/common/logos/icon_smarttrader.svg +1 -0
  392. package/src/images/common/logos/xxhdpi.png +0 -0
  393. package/src/images/common/og_image.gif +0 -0
  394. package/src/images/common/plus.svg +1 -0
  395. package/src/images/common/scrollup_icon.svg +1 -0
  396. package/src/images/languages/ic-flag-de.svg +1 -0
  397. package/src/images/languages/ic-flag-en.svg +1 -0
  398. package/src/images/languages/ic-flag-es.svg +1 -0
  399. package/src/images/languages/ic-flag-fr.svg +1 -0
  400. package/src/images/languages/ic-flag-id.svg +1 -0
  401. package/src/images/languages/ic-flag-it.svg +1 -0
  402. package/src/images/languages/ic-flag-pl.svg +1 -0
  403. package/src/images/languages/ic-flag-pt.svg +1 -0
  404. package/src/images/languages/ic-flag-ru.svg +1 -0
  405. package/src/images/languages/ic-flag-th.svg +1 -0
  406. package/src/images/languages/ic-flag-uk.svg +1 -0
  407. package/src/images/languages/ic-flag-vi.svg +1 -0
  408. package/src/images/languages/ic-flag-zh_cn.svg +1 -0
  409. package/src/images/languages/ic-flag-zh_tw.svg +1 -0
  410. package/src/images/pages/contact/chat-icon.svg +1 -0
  411. package/src/images/pages/contact/search-icon.svg +1 -0
  412. package/src/images/pages/footer/ic-fullscreen.svg +1 -0
  413. package/src/images/pages/footer/ic-help-centre.svg +66 -0
  414. package/src/images/pages/footer/ic-livechat.svg +4 -0
  415. package/src/images/pages/footer/ic-whatsapp.svg +6 -0
  416. package/src/images/pages/header/copytrader.png +0 -0
  417. package/src/images/pages/header/copytrader.svg +8 -0
  418. package/src/images/pages/header/deriv-com-logo.svg +1 -0
  419. package/src/images/pages/header/deriv-com-logo1.svg +1 -0
  420. package/src/images/pages/header/deriv-logo.svg +8 -0
  421. package/src/images/pages/header/header.svg +63 -0
  422. package/src/images/pages/header/ic-add-account.svg +1 -0
  423. package/src/images/pages/header/ic-alert-danger.svg +1 -0
  424. package/src/images/pages/header/ic-alert-info.svg +1 -0
  425. package/src/images/pages/header/ic-alert-success.svg +1 -0
  426. package/src/images/pages/header/ic-alert-warning.svg +1 -0
  427. package/src/images/pages/header/ic-appstore-home.svg +1 -0
  428. package/src/images/pages/header/ic-bell.svg +1 -0
  429. package/src/images/pages/header/ic-box.svg +1 -0
  430. package/src/images/pages/header/ic-brand-binarybot.svg +21 -0
  431. package/src/images/pages/header/ic-brand-dbot.svg +31 -0
  432. package/src/images/pages/header/ic-brand-dtrader.svg +25 -0
  433. package/src/images/pages/header/ic-cashier.svg +1 -0
  434. package/src/images/pages/header/ic-chevron-down.svg +1 -0
  435. package/src/images/pages/header/ic-chevron-left.svg +1 -0
  436. package/src/images/pages/header/ic-chevron-right.svg +1 -0
  437. package/src/images/pages/header/ic-close.svg +1 -0
  438. package/src/images/pages/header/ic-currency-aud.svg +1 -0
  439. package/src/images/pages/header/ic-currency-bch.svg +1 -0
  440. package/src/images/pages/header/ic-currency-btc.svg +1 -0
  441. package/src/images/pages/header/ic-currency-dai.svg +1 -0
  442. package/src/images/pages/header/ic-currency-eth.svg +1 -0
  443. package/src/images/pages/header/ic-currency-eur.svg +1 -0
  444. package/src/images/pages/header/ic-currency-eusdt.svg +1 -0
  445. package/src/images/pages/header/ic-currency-gbp.svg +1 -0
  446. package/src/images/pages/header/ic-currency-ltc.svg +1 -0
  447. package/src/images/pages/header/ic-currency-tusdt.svg +1 -0
  448. package/src/images/pages/header/ic-currency-unknown.svg +1 -0
  449. package/src/images/pages/header/ic-currency-usd.svg +1 -0
  450. package/src/images/pages/header/ic-currency-usdc.svg +1 -0
  451. package/src/images/pages/header/ic-currency-ust.svg +1 -0
  452. package/src/images/pages/header/ic-currency-virtual.svg +1 -0
  453. package/src/images/pages/header/ic-hamburger.svg +1 -0
  454. package/src/images/pages/header/ic-help-centre.svg +66 -0
  455. package/src/images/pages/header/ic-livechat.svg +1 -0
  456. package/src/images/pages/header/ic-logout.svg +1 -0
  457. package/src/images/pages/header/ic-portfolio.svg +1 -0
  458. package/src/images/pages/header/ic-profit-table.svg +1 -0
  459. package/src/images/pages/header/ic-reports.svg +1 -0
  460. package/src/images/pages/header/ic-statement.svg +1 -0
  461. package/src/images/pages/header/ic-trade.svg +23 -0
  462. package/src/images/pages/header/ic-user-outline.svg +1 -0
  463. package/src/images/pages/header/ic-whatsapp.svg +1 -0
  464. package/src/images/pages/header/logo_smart_trader.svg +1811 -0
  465. package/src/images/pages/header/mobile-menu/mobile-menu-appstore.svg +5 -0
  466. package/src/images/pages/header/mobile-menu/mobile-menu-arrow-down.svg +3 -0
  467. package/src/images/pages/header/mobile-menu/mobile-menu-arrow-left.svg +3 -0
  468. package/src/images/pages/header/mobile-menu/mobile-menu-arrow-right.svg +3 -0
  469. package/src/images/pages/header/mobile-menu/mobile-menu-gmail.svg +4 -0
  470. package/src/images/pages/header/mobile-menu/mobile-menu-kodxyz.svg +5 -0
  471. package/src/images/pages/header/mobile-menu/mobile-menu-livechat.svg +6 -0
  472. package/src/images/pages/header/mobile-menu/mobile-menu-logo.svg +5 -0
  473. package/src/images/pages/header/mobile-menu/mobile-menu-logout.svg +5 -0
  474. package/src/images/pages/header/mobile-menu/mobile-menu-platform-dbot.svg +6 -0
  475. package/src/images/pages/header/mobile-menu/mobile-menu-platform-dtrader.svg +4 -0
  476. package/src/images/pages/header/mobile-menu/mobile-menu-platform-smarttrader.svg +4 -0
  477. package/src/images/pages/header/mobile-menu/mobile-menu-portfolio.svg +4 -0
  478. package/src/images/pages/header/mobile-menu/mobile-menu-profit.svg +4 -0
  479. package/src/images/pages/header/mobile-menu/mobile-menu-reports.svg +4 -0
  480. package/src/images/pages/header/mobile-menu/mobile-menu-statement.svg +6 -0
  481. package/src/images/pages/header/mobile-menu/mobile-menu-trade.svg +5 -0
  482. package/src/images/pages/header/wallets/ic-wallets-combined-aud.svg +1 -0
  483. package/src/images/pages/header/wallets/ic-wallets-combined-btc.svg +1 -0
  484. package/src/images/pages/header/wallets/ic-wallets-combined-eth.svg +1 -0
  485. package/src/images/pages/header/wallets/ic-wallets-combined-eur.svg +1 -0
  486. package/src/images/pages/header/wallets/ic-wallets-combined-eusdt.svg +1 -0
  487. package/src/images/pages/header/wallets/ic-wallets-combined-gbp.svg +1 -0
  488. package/src/images/pages/header/wallets/ic-wallets-combined-ltc.svg +1 -0
  489. package/src/images/pages/header/wallets/ic-wallets-combined-tusdt.svg +1 -0
  490. package/src/images/pages/header/wallets/ic-wallets-combined-usd.svg +1 -0
  491. package/src/images/pages/header/wallets/ic-wallets-combined-usdc.svg +1 -0
  492. package/src/images/pages/header/wallets/ic-wallets-combined-virtual.svg +1 -0
  493. package/src/images/pages/header/wallets/ic-wallets-currency-aud.svg +1 -0
  494. package/src/images/pages/header/wallets/ic-wallets-currency-btc.svg +1 -0
  495. package/src/images/pages/header/wallets/ic-wallets-currency-eth.svg +1 -0
  496. package/src/images/pages/header/wallets/ic-wallets-currency-eur.svg +1 -0
  497. package/src/images/pages/header/wallets/ic-wallets-currency-eusdt.svg +1 -0
  498. package/src/images/pages/header/wallets/ic-wallets-currency-gbp.svg +1 -0
  499. package/src/images/pages/header/wallets/ic-wallets-currency-ltc.svg +1 -0
  500. package/src/images/pages/header/wallets/ic-wallets-currency-tusdt.svg +1 -0
  501. package/src/images/pages/header/wallets/ic-wallets-currency-usd.svg +1 -0
  502. package/src/images/pages/header/wallets/ic-wallets-currency-usdc.svg +1 -0
  503. package/src/images/pages/header/wallets/ic-wallets-currency-virtual.svg +1 -0
  504. package/src/images/pages/header/wallets/ic-wallets-deriv-apps.svg +8 -0
  505. package/src/images/pages/header/wallets/wallet-apps-logo.svg +1 -0
  506. package/src/images/pages/header/wallets/wallet-deriv-logo.svg +8 -0
  507. package/src/images/pages/home/arrow_left.svg +1 -0
  508. package/src/images/pages/home/arrow_right.svg +1 -0
  509. package/src/images/pages/set_currency/aud.svg +1 -0
  510. package/src/images/pages/set_currency/bch.svg +1 -0
  511. package/src/images/pages/set_currency/btc.svg +1 -0
  512. package/src/images/pages/set_currency/busd.svg +1 -0
  513. package/src/images/pages/set_currency/dai.svg +1 -0
  514. package/src/images/pages/set_currency/etc.svg +1 -0
  515. package/src/images/pages/set_currency/eth.svg +1 -0
  516. package/src/images/pages/set_currency/eur.svg +1 -0
  517. package/src/images/pages/set_currency/eurs.svg +1 -0
  518. package/src/images/pages/set_currency/eusdt.svg +1 -0
  519. package/src/images/pages/set_currency/gbp.svg +1 -0
  520. package/src/images/pages/set_currency/idk.svg +1 -0
  521. package/src/images/pages/set_currency/ltc.svg +1 -0
  522. package/src/images/pages/set_currency/pax.svg +1 -0
  523. package/src/images/pages/set_currency/tick-normal.svg +1 -0
  524. package/src/images/pages/set_currency/tick-selected.svg +1 -0
  525. package/src/images/pages/set_currency/tusd.svg +1 -0
  526. package/src/images/pages/set_currency/usb.svg +1 -0
  527. package/src/images/pages/set_currency/usd.svg +1 -0
  528. package/src/images/pages/set_currency/usdc.svg +1 -0
  529. package/src/images/pages/set_currency/usdk.svg +1 -0
  530. package/src/images/pages/set_currency/ust.svg +1 -0
  531. package/src/images/pages/trade/call_spread.svg +1 -0
  532. package/src/images/pages/trade/chart_payout_range.svg +1 -0
  533. package/src/images/pages/trade/ic_arrow_dropdown_light.svg +1 -0
  534. package/src/images/pages/trade/put_spread.svg +1 -0
  535. package/src/images/pages/trade-explanation/de/close-low.svg +1 -0
  536. package/src/images/pages/trade-explanation/de/differs.svg +1 -0
  537. package/src/images/pages/trade-explanation/de/down.svg +1 -0
  538. package/src/images/pages/trade-explanation/de/ends-between.svg +1 -0
  539. package/src/images/pages/trade-explanation/de/ends-outside.svg +1 -0
  540. package/src/images/pages/trade-explanation/de/even.svg +1 -0
  541. package/src/images/pages/trade-explanation/de/falls.svg +1 -0
  542. package/src/images/pages/trade-explanation/de/goes-outside.svg +1 -0
  543. package/src/images/pages/trade-explanation/de/high-close.svg +1 -0
  544. package/src/images/pages/trade-explanation/de/high-low.svg +1 -0
  545. package/src/images/pages/trade-explanation/de/high-tick.svg +1 -0
  546. package/src/images/pages/trade-explanation/de/higher.svg +1 -0
  547. package/src/images/pages/trade-explanation/de/low-tick.svg +1 -0
  548. package/src/images/pages/trade-explanation/de/lower.svg +1 -0
  549. package/src/images/pages/trade-explanation/de/matches.svg +1 -0
  550. package/src/images/pages/trade-explanation/de/no-touch.svg +1 -0
  551. package/src/images/pages/trade-explanation/de/odd.svg +1 -0
  552. package/src/images/pages/trade-explanation/de/only-downs.svg +1 -0
  553. package/src/images/pages/trade-explanation/de/only-ups.svg +1 -0
  554. package/src/images/pages/trade-explanation/de/over.svg +1 -0
  555. package/src/images/pages/trade-explanation/de/reset-call.svg +1 -0
  556. package/src/images/pages/trade-explanation/de/reset-put.svg +1 -0
  557. package/src/images/pages/trade-explanation/de/rises.svg +1 -0
  558. package/src/images/pages/trade-explanation/de/stays-between.svg +1 -0
  559. package/src/images/pages/trade-explanation/de/touch.svg +1 -0
  560. package/src/images/pages/trade-explanation/de/under.svg +1 -0
  561. package/src/images/pages/trade-explanation/de/up.svg +1 -0
  562. package/src/images/pages/trade-explanation/en/call-spread.svg +1 -0
  563. package/src/images/pages/trade-explanation/en/close-low.svg +1 -0
  564. package/src/images/pages/trade-explanation/en/differs.svg +1 -0
  565. package/src/images/pages/trade-explanation/en/down.svg +1 -0
  566. package/src/images/pages/trade-explanation/en/ends-between.svg +1 -0
  567. package/src/images/pages/trade-explanation/en/ends-outside.svg +1 -0
  568. package/src/images/pages/trade-explanation/en/even.svg +1 -0
  569. package/src/images/pages/trade-explanation/en/falls.svg +1 -0
  570. package/src/images/pages/trade-explanation/en/goes-outside.svg +1 -0
  571. package/src/images/pages/trade-explanation/en/high-close.svg +1 -0
  572. package/src/images/pages/trade-explanation/en/high-low.svg +1 -0
  573. package/src/images/pages/trade-explanation/en/high-tick.svg +1 -0
  574. package/src/images/pages/trade-explanation/en/higher.svg +1 -0
  575. package/src/images/pages/trade-explanation/en/low-tick.svg +1 -0
  576. package/src/images/pages/trade-explanation/en/lower.svg +1 -0
  577. package/src/images/pages/trade-explanation/en/matches.svg +1 -0
  578. package/src/images/pages/trade-explanation/en/no-touch.svg +1 -0
  579. package/src/images/pages/trade-explanation/en/odd.svg +1 -0
  580. package/src/images/pages/trade-explanation/en/only-downs.svg +1 -0
  581. package/src/images/pages/trade-explanation/en/only-ups.svg +1 -0
  582. package/src/images/pages/trade-explanation/en/over.svg +1 -0
  583. package/src/images/pages/trade-explanation/en/put-spread.svg +1 -0
  584. package/src/images/pages/trade-explanation/en/reset-call.svg +1 -0
  585. package/src/images/pages/trade-explanation/en/reset-put.svg +1 -0
  586. package/src/images/pages/trade-explanation/en/rises.svg +1 -0
  587. package/src/images/pages/trade-explanation/en/stays-between.svg +1 -0
  588. package/src/images/pages/trade-explanation/en/touch.svg +1 -0
  589. package/src/images/pages/trade-explanation/en/under.svg +1 -0
  590. package/src/images/pages/trade-explanation/en/up.svg +1 -0
  591. package/src/images/pages/trade-explanation/es/close-low.svg +1 -0
  592. package/src/images/pages/trade-explanation/es/differs.svg +1 -0
  593. package/src/images/pages/trade-explanation/es/down.svg +1 -0
  594. package/src/images/pages/trade-explanation/es/ends-between.svg +1 -0
  595. package/src/images/pages/trade-explanation/es/ends-outside.svg +1 -0
  596. package/src/images/pages/trade-explanation/es/even.svg +1 -0
  597. package/src/images/pages/trade-explanation/es/falls.svg +1 -0
  598. package/src/images/pages/trade-explanation/es/goes-outside.svg +1 -0
  599. package/src/images/pages/trade-explanation/es/high-close.svg +1 -0
  600. package/src/images/pages/trade-explanation/es/high-low.svg +1 -0
  601. package/src/images/pages/trade-explanation/es/high-tick.svg +1 -0
  602. package/src/images/pages/trade-explanation/es/higher.svg +1 -0
  603. package/src/images/pages/trade-explanation/es/low-tick.svg +1 -0
  604. package/src/images/pages/trade-explanation/es/lower.svg +1 -0
  605. package/src/images/pages/trade-explanation/es/matches.svg +1 -0
  606. package/src/images/pages/trade-explanation/es/no-touch.svg +1 -0
  607. package/src/images/pages/trade-explanation/es/odd.svg +1 -0
  608. package/src/images/pages/trade-explanation/es/only-downs.svg +1 -0
  609. package/src/images/pages/trade-explanation/es/only-ups.svg +1 -0
  610. package/src/images/pages/trade-explanation/es/over.svg +1 -0
  611. package/src/images/pages/trade-explanation/es/reset-call.svg +1 -0
  612. package/src/images/pages/trade-explanation/es/reset-put.svg +1 -0
  613. package/src/images/pages/trade-explanation/es/rises.svg +1 -0
  614. package/src/images/pages/trade-explanation/es/stays-between.svg +1 -0
  615. package/src/images/pages/trade-explanation/es/touch.svg +1 -0
  616. package/src/images/pages/trade-explanation/es/under.svg +1 -0
  617. package/src/images/pages/trade-explanation/es/up.svg +1 -0
  618. package/src/images/pages/trade-explanation/fr/close-low.svg +1 -0
  619. package/src/images/pages/trade-explanation/fr/differs.svg +1 -0
  620. package/src/images/pages/trade-explanation/fr/down.svg +1 -0
  621. package/src/images/pages/trade-explanation/fr/ends-between.svg +1 -0
  622. package/src/images/pages/trade-explanation/fr/ends-outside.svg +1 -0
  623. package/src/images/pages/trade-explanation/fr/even.svg +1 -0
  624. package/src/images/pages/trade-explanation/fr/falls.svg +1 -0
  625. package/src/images/pages/trade-explanation/fr/goes-outside.svg +1 -0
  626. package/src/images/pages/trade-explanation/fr/high-close.svg +1 -0
  627. package/src/images/pages/trade-explanation/fr/high-low.svg +1 -0
  628. package/src/images/pages/trade-explanation/fr/high-tick.svg +1 -0
  629. package/src/images/pages/trade-explanation/fr/higher.svg +1 -0
  630. package/src/images/pages/trade-explanation/fr/low-tick.svg +1 -0
  631. package/src/images/pages/trade-explanation/fr/lower.svg +1 -0
  632. package/src/images/pages/trade-explanation/fr/matches.svg +1 -0
  633. package/src/images/pages/trade-explanation/fr/no-touch.svg +1 -0
  634. package/src/images/pages/trade-explanation/fr/odd.svg +1 -0
  635. package/src/images/pages/trade-explanation/fr/only-downs.svg +1 -0
  636. package/src/images/pages/trade-explanation/fr/only-ups.svg +1 -0
  637. package/src/images/pages/trade-explanation/fr/over.svg +1 -0
  638. package/src/images/pages/trade-explanation/fr/reset-call.svg +1 -0
  639. package/src/images/pages/trade-explanation/fr/reset-put.svg +1 -0
  640. package/src/images/pages/trade-explanation/fr/rises.svg +1 -0
  641. package/src/images/pages/trade-explanation/fr/stays-between.svg +1 -0
  642. package/src/images/pages/trade-explanation/fr/touch.svg +1 -0
  643. package/src/images/pages/trade-explanation/fr/under.svg +1 -0
  644. package/src/images/pages/trade-explanation/fr/up.svg +1 -0
  645. package/src/images/pages/trade-explanation/id/close-low.svg +1 -0
  646. package/src/images/pages/trade-explanation/id/differs.svg +1 -0
  647. package/src/images/pages/trade-explanation/id/down.svg +1 -0
  648. package/src/images/pages/trade-explanation/id/ends-between.svg +1 -0
  649. package/src/images/pages/trade-explanation/id/ends-outside.svg +1 -0
  650. package/src/images/pages/trade-explanation/id/even.svg +1 -0
  651. package/src/images/pages/trade-explanation/id/falls.svg +1 -0
  652. package/src/images/pages/trade-explanation/id/goes-outside.svg +1 -0
  653. package/src/images/pages/trade-explanation/id/high-close.svg +1 -0
  654. package/src/images/pages/trade-explanation/id/high-low.svg +1 -0
  655. package/src/images/pages/trade-explanation/id/high-tick.svg +1 -0
  656. package/src/images/pages/trade-explanation/id/higher.svg +1 -0
  657. package/src/images/pages/trade-explanation/id/low-tick.svg +1 -0
  658. package/src/images/pages/trade-explanation/id/lower.svg +1 -0
  659. package/src/images/pages/trade-explanation/id/matches.svg +1 -0
  660. package/src/images/pages/trade-explanation/id/no-touch.svg +1 -0
  661. package/src/images/pages/trade-explanation/id/odd.svg +1 -0
  662. package/src/images/pages/trade-explanation/id/only-downs.svg +1 -0
  663. package/src/images/pages/trade-explanation/id/only-ups.svg +1 -0
  664. package/src/images/pages/trade-explanation/id/over.svg +1 -0
  665. package/src/images/pages/trade-explanation/id/reset-call.svg +1 -0
  666. package/src/images/pages/trade-explanation/id/reset-put.svg +1 -0
  667. package/src/images/pages/trade-explanation/id/rises.svg +1 -0
  668. package/src/images/pages/trade-explanation/id/stays-between.svg +1 -0
  669. package/src/images/pages/trade-explanation/id/touch.svg +1 -0
  670. package/src/images/pages/trade-explanation/id/under.svg +1 -0
  671. package/src/images/pages/trade-explanation/id/up.svg +1 -0
  672. package/src/images/pages/trade-explanation/it/close-low.svg +1 -0
  673. package/src/images/pages/trade-explanation/it/differs.svg +1 -0
  674. package/src/images/pages/trade-explanation/it/down.svg +1 -0
  675. package/src/images/pages/trade-explanation/it/ends-between.svg +1 -0
  676. package/src/images/pages/trade-explanation/it/ends-outside.svg +1 -0
  677. package/src/images/pages/trade-explanation/it/even.svg +1 -0
  678. package/src/images/pages/trade-explanation/it/falls.svg +1 -0
  679. package/src/images/pages/trade-explanation/it/goes-outside.svg +1 -0
  680. package/src/images/pages/trade-explanation/it/high-close.svg +1 -0
  681. package/src/images/pages/trade-explanation/it/high-low.svg +1 -0
  682. package/src/images/pages/trade-explanation/it/high-tick.svg +1 -0
  683. package/src/images/pages/trade-explanation/it/higher.svg +1 -0
  684. package/src/images/pages/trade-explanation/it/low-tick.svg +1 -0
  685. package/src/images/pages/trade-explanation/it/lower.svg +1 -0
  686. package/src/images/pages/trade-explanation/it/matches.svg +1 -0
  687. package/src/images/pages/trade-explanation/it/no-touch.svg +1 -0
  688. package/src/images/pages/trade-explanation/it/odd.svg +1 -0
  689. package/src/images/pages/trade-explanation/it/only-downs.svg +1 -0
  690. package/src/images/pages/trade-explanation/it/only-ups.svg +1 -0
  691. package/src/images/pages/trade-explanation/it/over.svg +1 -0
  692. package/src/images/pages/trade-explanation/it/reset-call.svg +1 -0
  693. package/src/images/pages/trade-explanation/it/reset-put.svg +1 -0
  694. package/src/images/pages/trade-explanation/it/rises.svg +1 -0
  695. package/src/images/pages/trade-explanation/it/stays-between.svg +1 -0
  696. package/src/images/pages/trade-explanation/it/touch.svg +1 -0
  697. package/src/images/pages/trade-explanation/it/under.svg +1 -0
  698. package/src/images/pages/trade-explanation/it/up.svg +1 -0
  699. package/src/images/pages/trade-explanation/pl/close-low.svg +1 -0
  700. package/src/images/pages/trade-explanation/pl/differs.svg +1 -0
  701. package/src/images/pages/trade-explanation/pl/down.svg +1 -0
  702. package/src/images/pages/trade-explanation/pl/ends-between.svg +1 -0
  703. package/src/images/pages/trade-explanation/pl/ends-outside.svg +1 -0
  704. package/src/images/pages/trade-explanation/pl/even.svg +1 -0
  705. package/src/images/pages/trade-explanation/pl/falls.svg +1 -0
  706. package/src/images/pages/trade-explanation/pl/goes-outside.svg +1 -0
  707. package/src/images/pages/trade-explanation/pl/high-close.svg +1 -0
  708. package/src/images/pages/trade-explanation/pl/high-low.svg +1 -0
  709. package/src/images/pages/trade-explanation/pl/high-tick.svg +1 -0
  710. package/src/images/pages/trade-explanation/pl/higher.svg +1 -0
  711. package/src/images/pages/trade-explanation/pl/low-tick.svg +1 -0
  712. package/src/images/pages/trade-explanation/pl/lower.svg +1 -0
  713. package/src/images/pages/trade-explanation/pl/matches.svg +1 -0
  714. package/src/images/pages/trade-explanation/pl/no-touch.svg +1 -0
  715. package/src/images/pages/trade-explanation/pl/odd.svg +1 -0
  716. package/src/images/pages/trade-explanation/pl/only-downs.svg +1 -0
  717. package/src/images/pages/trade-explanation/pl/only-ups.svg +1 -0
  718. package/src/images/pages/trade-explanation/pl/over.svg +1 -0
  719. package/src/images/pages/trade-explanation/pl/reset-call.svg +1 -0
  720. package/src/images/pages/trade-explanation/pl/reset-put.svg +1 -0
  721. package/src/images/pages/trade-explanation/pl/rises.svg +1 -0
  722. package/src/images/pages/trade-explanation/pl/stays-between.svg +1 -0
  723. package/src/images/pages/trade-explanation/pl/touch.svg +1 -0
  724. package/src/images/pages/trade-explanation/pl/under.svg +1 -0
  725. package/src/images/pages/trade-explanation/pl/up.svg +1 -0
  726. package/src/images/pages/trade-explanation/pt/close-low.svg +1 -0
  727. package/src/images/pages/trade-explanation/pt/differs.svg +1 -0
  728. package/src/images/pages/trade-explanation/pt/down.svg +1 -0
  729. package/src/images/pages/trade-explanation/pt/ends-between.svg +1 -0
  730. package/src/images/pages/trade-explanation/pt/ends-outside.svg +1 -0
  731. package/src/images/pages/trade-explanation/pt/even.svg +1 -0
  732. package/src/images/pages/trade-explanation/pt/falls.svg +1 -0
  733. package/src/images/pages/trade-explanation/pt/goes-outside.svg +1 -0
  734. package/src/images/pages/trade-explanation/pt/high-close.svg +1 -0
  735. package/src/images/pages/trade-explanation/pt/high-low.svg +1 -0
  736. package/src/images/pages/trade-explanation/pt/high-tick.svg +1 -0
  737. package/src/images/pages/trade-explanation/pt/higher.svg +1 -0
  738. package/src/images/pages/trade-explanation/pt/low-tick.svg +1 -0
  739. package/src/images/pages/trade-explanation/pt/lower.svg +1 -0
  740. package/src/images/pages/trade-explanation/pt/matches.svg +1 -0
  741. package/src/images/pages/trade-explanation/pt/no-touch.svg +1 -0
  742. package/src/images/pages/trade-explanation/pt/odd.svg +1 -0
  743. package/src/images/pages/trade-explanation/pt/only-downs.svg +1 -0
  744. package/src/images/pages/trade-explanation/pt/only-ups.svg +1 -0
  745. package/src/images/pages/trade-explanation/pt/over.svg +1 -0
  746. package/src/images/pages/trade-explanation/pt/reset-call.svg +1 -0
  747. package/src/images/pages/trade-explanation/pt/reset-put.svg +1 -0
  748. package/src/images/pages/trade-explanation/pt/rises.svg +1 -0
  749. package/src/images/pages/trade-explanation/pt/stays-between.svg +1 -0
  750. package/src/images/pages/trade-explanation/pt/touch.svg +1 -0
  751. package/src/images/pages/trade-explanation/pt/under.svg +1 -0
  752. package/src/images/pages/trade-explanation/pt/up.svg +1 -0
  753. package/src/images/pages/trade-explanation/ru/close-low.svg +1 -0
  754. package/src/images/pages/trade-explanation/ru/differs.svg +1 -0
  755. package/src/images/pages/trade-explanation/ru/down.svg +1 -0
  756. package/src/images/pages/trade-explanation/ru/ends-between.svg +1 -0
  757. package/src/images/pages/trade-explanation/ru/ends-outside.svg +1 -0
  758. package/src/images/pages/trade-explanation/ru/even.svg +1 -0
  759. package/src/images/pages/trade-explanation/ru/falls.svg +1 -0
  760. package/src/images/pages/trade-explanation/ru/goes-outside.svg +1 -0
  761. package/src/images/pages/trade-explanation/ru/high-close.svg +1 -0
  762. package/src/images/pages/trade-explanation/ru/high-low.svg +1 -0
  763. package/src/images/pages/trade-explanation/ru/high-tick.svg +1 -0
  764. package/src/images/pages/trade-explanation/ru/higher.svg +1 -0
  765. package/src/images/pages/trade-explanation/ru/low-tick.svg +1 -0
  766. package/src/images/pages/trade-explanation/ru/lower.svg +1 -0
  767. package/src/images/pages/trade-explanation/ru/matches.svg +1 -0
  768. package/src/images/pages/trade-explanation/ru/no-touch.svg +1 -0
  769. package/src/images/pages/trade-explanation/ru/odd.svg +1 -0
  770. package/src/images/pages/trade-explanation/ru/only-downs.svg +1 -0
  771. package/src/images/pages/trade-explanation/ru/only-ups.svg +1 -0
  772. package/src/images/pages/trade-explanation/ru/over.svg +1 -0
  773. package/src/images/pages/trade-explanation/ru/reset-call.svg +1 -0
  774. package/src/images/pages/trade-explanation/ru/reset-put.svg +1 -0
  775. package/src/images/pages/trade-explanation/ru/rises.svg +1 -0
  776. package/src/images/pages/trade-explanation/ru/stays-between.svg +1 -0
  777. package/src/images/pages/trade-explanation/ru/touch.svg +1 -0
  778. package/src/images/pages/trade-explanation/ru/under.svg +1 -0
  779. package/src/images/pages/trade-explanation/ru/up.svg +1 -0
  780. package/src/images/pages/trade-explanation/th/close-low.svg +1 -0
  781. package/src/images/pages/trade-explanation/th/differs.svg +1 -0
  782. package/src/images/pages/trade-explanation/th/down.svg +1 -0
  783. package/src/images/pages/trade-explanation/th/ends-between.svg +1 -0
  784. package/src/images/pages/trade-explanation/th/ends-outside.svg +1 -0
  785. package/src/images/pages/trade-explanation/th/even.svg +1 -0
  786. package/src/images/pages/trade-explanation/th/falls.svg +1 -0
  787. package/src/images/pages/trade-explanation/th/goes-outside.svg +1 -0
  788. package/src/images/pages/trade-explanation/th/high-close.svg +1 -0
  789. package/src/images/pages/trade-explanation/th/high-low.svg +1 -0
  790. package/src/images/pages/trade-explanation/th/high-tick.svg +1 -0
  791. package/src/images/pages/trade-explanation/th/higher.svg +1 -0
  792. package/src/images/pages/trade-explanation/th/low-tick.svg +1 -0
  793. package/src/images/pages/trade-explanation/th/lower.svg +1 -0
  794. package/src/images/pages/trade-explanation/th/matches.svg +1 -0
  795. package/src/images/pages/trade-explanation/th/no-touch.svg +1 -0
  796. package/src/images/pages/trade-explanation/th/odd.svg +1 -0
  797. package/src/images/pages/trade-explanation/th/only-downs.svg +1 -0
  798. package/src/images/pages/trade-explanation/th/only-ups.svg +1 -0
  799. package/src/images/pages/trade-explanation/th/over.svg +1 -0
  800. package/src/images/pages/trade-explanation/th/reset-call.svg +1 -0
  801. package/src/images/pages/trade-explanation/th/reset-put.svg +1 -0
  802. package/src/images/pages/trade-explanation/th/rises.svg +1 -0
  803. package/src/images/pages/trade-explanation/th/stays-between.svg +1 -0
  804. package/src/images/pages/trade-explanation/th/touch.svg +1 -0
  805. package/src/images/pages/trade-explanation/th/under.svg +1 -0
  806. package/src/images/pages/trade-explanation/th/up.svg +1 -0
  807. package/src/images/pages/trade-explanation/vi/close-low.svg +1 -0
  808. package/src/images/pages/trade-explanation/vi/differs.svg +1 -0
  809. package/src/images/pages/trade-explanation/vi/down.svg +1 -0
  810. package/src/images/pages/trade-explanation/vi/ends-between.svg +1 -0
  811. package/src/images/pages/trade-explanation/vi/ends-outside.svg +1 -0
  812. package/src/images/pages/trade-explanation/vi/even.svg +1 -0
  813. package/src/images/pages/trade-explanation/vi/falls.svg +1 -0
  814. package/src/images/pages/trade-explanation/vi/goes-outside.svg +1 -0
  815. package/src/images/pages/trade-explanation/vi/high-close.svg +1 -0
  816. package/src/images/pages/trade-explanation/vi/high-low.svg +1 -0
  817. package/src/images/pages/trade-explanation/vi/high-tick.svg +1 -0
  818. package/src/images/pages/trade-explanation/vi/higher.svg +1 -0
  819. package/src/images/pages/trade-explanation/vi/low-tick.svg +1 -0
  820. package/src/images/pages/trade-explanation/vi/lower.svg +1 -0
  821. package/src/images/pages/trade-explanation/vi/matches.svg +1 -0
  822. package/src/images/pages/trade-explanation/vi/no-touch.svg +1 -0
  823. package/src/images/pages/trade-explanation/vi/odd.svg +1 -0
  824. package/src/images/pages/trade-explanation/vi/only-downs.svg +1 -0
  825. package/src/images/pages/trade-explanation/vi/only-ups.svg +1 -0
  826. package/src/images/pages/trade-explanation/vi/over.svg +1 -0
  827. package/src/images/pages/trade-explanation/vi/reset-call.svg +1 -0
  828. package/src/images/pages/trade-explanation/vi/reset-put.svg +1 -0
  829. package/src/images/pages/trade-explanation/vi/rises.svg +1 -0
  830. package/src/images/pages/trade-explanation/vi/stays-between.svg +1 -0
  831. package/src/images/pages/trade-explanation/vi/touch.svg +1 -0
  832. package/src/images/pages/trade-explanation/vi/under.svg +1 -0
  833. package/src/images/pages/trade-explanation/vi/up.svg +1 -0
  834. package/src/images/pages/trade-explanation/zh_cn/close-low.svg +1 -0
  835. package/src/images/pages/trade-explanation/zh_cn/differs.svg +1 -0
  836. package/src/images/pages/trade-explanation/zh_cn/down.svg +1 -0
  837. package/src/images/pages/trade-explanation/zh_cn/ends-between.svg +1 -0
  838. package/src/images/pages/trade-explanation/zh_cn/ends-outside.svg +1 -0
  839. package/src/images/pages/trade-explanation/zh_cn/even.svg +1 -0
  840. package/src/images/pages/trade-explanation/zh_cn/falls.svg +1 -0
  841. package/src/images/pages/trade-explanation/zh_cn/goes-outside.svg +1 -0
  842. package/src/images/pages/trade-explanation/zh_cn/high-close.svg +1 -0
  843. package/src/images/pages/trade-explanation/zh_cn/high-low.svg +1 -0
  844. package/src/images/pages/trade-explanation/zh_cn/high-tick.svg +1 -0
  845. package/src/images/pages/trade-explanation/zh_cn/higher.svg +1 -0
  846. package/src/images/pages/trade-explanation/zh_cn/low-tick.svg +1 -0
  847. package/src/images/pages/trade-explanation/zh_cn/lower.svg +1 -0
  848. package/src/images/pages/trade-explanation/zh_cn/matches.svg +1 -0
  849. package/src/images/pages/trade-explanation/zh_cn/no-touch.svg +1 -0
  850. package/src/images/pages/trade-explanation/zh_cn/odd.svg +1 -0
  851. package/src/images/pages/trade-explanation/zh_cn/only-downs.svg +1 -0
  852. package/src/images/pages/trade-explanation/zh_cn/only-ups.svg +1 -0
  853. package/src/images/pages/trade-explanation/zh_cn/over.svg +1 -0
  854. package/src/images/pages/trade-explanation/zh_cn/reset-call.svg +1 -0
  855. package/src/images/pages/trade-explanation/zh_cn/reset-put.svg +1 -0
  856. package/src/images/pages/trade-explanation/zh_cn/rises.svg +1 -0
  857. package/src/images/pages/trade-explanation/zh_cn/stays-between.svg +1 -0
  858. package/src/images/pages/trade-explanation/zh_cn/touch.svg +1 -0
  859. package/src/images/pages/trade-explanation/zh_cn/under.svg +1 -0
  860. package/src/images/pages/trade-explanation/zh_cn/up.svg +1 -0
  861. package/src/images/pages/trade-explanation/zh_tw/close-low.svg +1 -0
  862. package/src/images/pages/trade-explanation/zh_tw/differs.svg +1 -0
  863. package/src/images/pages/trade-explanation/zh_tw/down.svg +1 -0
  864. package/src/images/pages/trade-explanation/zh_tw/ends-between.svg +1 -0
  865. package/src/images/pages/trade-explanation/zh_tw/ends-outside.svg +1 -0
  866. package/src/images/pages/trade-explanation/zh_tw/even.svg +1 -0
  867. package/src/images/pages/trade-explanation/zh_tw/falls.svg +1 -0
  868. package/src/images/pages/trade-explanation/zh_tw/goes-outside.svg +1 -0
  869. package/src/images/pages/trade-explanation/zh_tw/high-close.svg +1 -0
  870. package/src/images/pages/trade-explanation/zh_tw/high-low.svg +1 -0
  871. package/src/images/pages/trade-explanation/zh_tw/high-tick.svg +1 -0
  872. package/src/images/pages/trade-explanation/zh_tw/higher.svg +1 -0
  873. package/src/images/pages/trade-explanation/zh_tw/low-tick.svg +1 -0
  874. package/src/images/pages/trade-explanation/zh_tw/lower.svg +1 -0
  875. package/src/images/pages/trade-explanation/zh_tw/matches.svg +1 -0
  876. package/src/images/pages/trade-explanation/zh_tw/no-touch.svg +1 -0
  877. package/src/images/pages/trade-explanation/zh_tw/odd.svg +1 -0
  878. package/src/images/pages/trade-explanation/zh_tw/only-downs.svg +1 -0
  879. package/src/images/pages/trade-explanation/zh_tw/only-ups.svg +1 -0
  880. package/src/images/pages/trade-explanation/zh_tw/over.svg +1 -0
  881. package/src/images/pages/trade-explanation/zh_tw/reset-call.svg +1 -0
  882. package/src/images/pages/trade-explanation/zh_tw/reset-put.svg +1 -0
  883. package/src/images/pages/trade-explanation/zh_tw/rises.svg +1 -0
  884. package/src/images/pages/trade-explanation/zh_tw/stays-between.svg +1 -0
  885. package/src/images/pages/trade-explanation/zh_tw/touch.svg +1 -0
  886. package/src/images/pages/trade-explanation/zh_tw/under.svg +1 -0
  887. package/src/images/pages/trade-explanation/zh_tw/up.svg +1 -0
  888. package/src/javascript/README.md +147 -0
  889. package/src/javascript/_autogenerated/ach.js +2 -0
  890. package/src/javascript/_autogenerated/app_2/ach.js +2 -0
  891. package/src/javascript/_autogenerated/app_2/de.js +2 -0
  892. package/src/javascript/_autogenerated/app_2/en.js +2 -0
  893. package/src/javascript/_autogenerated/app_2/es.js +2 -0
  894. package/src/javascript/_autogenerated/app_2/fr.js +2 -0
  895. package/src/javascript/_autogenerated/app_2/id.js +2 -0
  896. package/src/javascript/_autogenerated/app_2/it.js +2 -0
  897. package/src/javascript/_autogenerated/app_2/ja.js +2 -0
  898. package/src/javascript/_autogenerated/app_2/ko.js +2 -0
  899. package/src/javascript/_autogenerated/app_2/pl.js +2 -0
  900. package/src/javascript/_autogenerated/app_2/pt.js +2 -0
  901. package/src/javascript/_autogenerated/app_2/ru.js +2 -0
  902. package/src/javascript/_autogenerated/app_2/th.js +2 -0
  903. package/src/javascript/_autogenerated/app_2/vi.js +2 -0
  904. package/src/javascript/_autogenerated/app_2/zh_cn.js +2 -0
  905. package/src/javascript/_autogenerated/app_2/zh_tw.js +2 -0
  906. package/src/javascript/_autogenerated/de.js +2 -0
  907. package/src/javascript/_autogenerated/en.js +2 -0
  908. package/src/javascript/_autogenerated/es.js +2 -0
  909. package/src/javascript/_autogenerated/fr.js +2 -0
  910. package/src/javascript/_autogenerated/id.js +2 -0
  911. package/src/javascript/_autogenerated/it.js +2 -0
  912. package/src/javascript/_autogenerated/ko.js +2 -0
  913. package/src/javascript/_autogenerated/pl.js +2 -0
  914. package/src/javascript/_autogenerated/pt.js +2 -0
  915. package/src/javascript/_autogenerated/ru.js +2 -0
  916. package/src/javascript/_autogenerated/th.js +2 -0
  917. package/src/javascript/_autogenerated/vi.js +2 -0
  918. package/src/javascript/_autogenerated/zh_cn.js +2 -0
  919. package/src/javascript/_autogenerated/zh_tw.js +2 -0
  920. package/src/javascript/_common/__tests__/check_new_release.js +16 -0
  921. package/src/javascript/_common/__tests__/common_functions.js +90 -0
  922. package/src/javascript/_common/__tests__/language.js +68 -0
  923. package/src/javascript/_common/__tests__/string_util.js +80 -0
  924. package/src/javascript/_common/__tests__/tests_common.js +22 -0
  925. package/src/javascript/_common/__tests__/url.js +142 -0
  926. package/src/javascript/_common/__tests__/utility.js +175 -0
  927. package/src/javascript/_common/analytics.js +21 -0
  928. package/src/javascript/_common/auth.js +174 -0
  929. package/src/javascript/_common/base/__tests__/client_base.js +299 -0
  930. package/src/javascript/_common/base/__tests__/currency_base.js +126 -0
  931. package/src/javascript/_common/base/client_base.js +517 -0
  932. package/src/javascript/_common/base/currency_base.js +182 -0
  933. package/src/javascript/_common/base/elevio.js +148 -0
  934. package/src/javascript/_common/base/gtm.js +13 -0
  935. package/src/javascript/_common/base/livechat.js +136 -0
  936. package/src/javascript/_common/base/login.js +64 -0
  937. package/src/javascript/_common/base/network_monitor_base.js +151 -0
  938. package/src/javascript/_common/base/server_time.js +66 -0
  939. package/src/javascript/_common/base/socket_base.js +325 -0
  940. package/src/javascript/_common/base/socket_cache.js +132 -0
  941. package/src/javascript/_common/base/subscription_manager.js +248 -0
  942. package/src/javascript/_common/chat.js +57 -0
  943. package/src/javascript/_common/check_new_release.js +35 -0
  944. package/src/javascript/_common/check_password.js +103 -0
  945. package/src/javascript/_common/common_functions.js +104 -0
  946. package/src/javascript/_common/crowdin.js +34 -0
  947. package/src/javascript/_common/gtm.js +7 -0
  948. package/src/javascript/_common/language.js +98 -0
  949. package/src/javascript/_common/lib/guide.enjoyhint.js +1034 -0
  950. package/src/javascript/_common/lib/jquery.sparkline.js +3085 -0
  951. package/src/javascript/_common/lib/loadCSS.js +32 -0
  952. package/src/javascript/_common/lib/loadJS.js +13 -0
  953. package/src/javascript/_common/lib/mmenu/jquery.mmenu.min.all.js +84 -0
  954. package/src/javascript/_common/lib/plugins.js +55 -0
  955. package/src/javascript/_common/lib/polyfills/array.includes.js +28 -0
  956. package/src/javascript/_common/lib/polyfills/element.closest.js +11 -0
  957. package/src/javascript/_common/lib/polyfills/element.matches.js +14 -0
  958. package/src/javascript/_common/lib/polyfills/nodelist.foreach.js +8 -0
  959. package/src/javascript/_common/lib/polyfills/string.includes.js +6 -0
  960. package/src/javascript/_common/lib/zxcvbn/zxcvbn.js +30 -0
  961. package/src/javascript/_common/lib/zxcvbn/zxcvbn.js.map +27 -0
  962. package/src/javascript/_common/localize.js +55 -0
  963. package/src/javascript/_common/menu_selector.js +69 -0
  964. package/src/javascript/_common/os_detect.js +72 -0
  965. package/src/javascript/_common/remote_config.json +2 -0
  966. package/src/javascript/_common/scroll.js +124 -0
  967. package/src/javascript/_common/scroll_to_anchor.js +99 -0
  968. package/src/javascript/_common/storage.js +274 -0
  969. package/src/javascript/_common/string_util.js +50 -0
  970. package/src/javascript/_common/tab_selector.js +196 -0
  971. package/src/javascript/_common/third_party_links.js +96 -0
  972. package/src/javascript/_common/url.js +199 -0
  973. package/src/javascript/_common/utility.js +317 -0
  974. package/src/javascript/app/base/__tests__/client.js +49 -0
  975. package/src/javascript/app/base/binary_loader.js +290 -0
  976. package/src/javascript/app/base/binary_pages.js +151 -0
  977. package/src/javascript/app/base/binary_pjax.js +231 -0
  978. package/src/javascript/app/base/callback.js +16 -0
  979. package/src/javascript/app/base/client.js +207 -0
  980. package/src/javascript/app/base/clock.js +53 -0
  981. package/src/javascript/app/base/contents.js +16 -0
  982. package/src/javascript/app/base/header.js +1572 -0
  983. package/src/javascript/app/base/logged_in.js +338 -0
  984. package/src/javascript/app/base/menu.js +66 -0
  985. package/src/javascript/app/base/network_monitor.js +32 -0
  986. package/src/javascript/app/base/page.js +307 -0
  987. package/src/javascript/app/base/redirect.js +27 -0
  988. package/src/javascript/app/base/socket.js +4 -0
  989. package/src/javascript/app/base/socket_general.js +181 -0
  990. package/src/javascript/app/common/__tests__/active_symbols.js +166 -0
  991. package/src/javascript/app/common/__tests__/content_visibility.js +127 -0
  992. package/src/javascript/app/common/__tests__/get_app_details.js +29 -0
  993. package/src/javascript/app/common/account_opening.js +333 -0
  994. package/src/javascript/app/common/active_symbols.js +273 -0
  995. package/src/javascript/app/common/attach_dom/birth_date_picker.js +25 -0
  996. package/src/javascript/app/common/attach_dom/date_to.js +87 -0
  997. package/src/javascript/app/common/attach_dom/dialog.js +97 -0
  998. package/src/javascript/app/common/attach_dom/flextable.js +71 -0
  999. package/src/javascript/app/common/attach_dom/language_dropdown.js +36 -0
  1000. package/src/javascript/app/common/attach_dom/popup.js +77 -0
  1001. package/src/javascript/app/common/attach_dom/table.js +120 -0
  1002. package/src/javascript/app/common/cashier_modal.js +795 -0
  1003. package/src/javascript/app/common/chart_settings.js +254 -0
  1004. package/src/javascript/app/common/content_visibility.js +194 -0
  1005. package/src/javascript/app/common/contract_type_icons.js +76 -0
  1006. package/src/javascript/app/common/country_base.js +36 -0
  1007. package/src/javascript/app/common/currency.js +46 -0
  1008. package/src/javascript/app/common/data_manager.js +165 -0
  1009. package/src/javascript/app/common/deriv_banner.js +67 -0
  1010. package/src/javascript/app/common/deriv_cashier_service.js +124 -0
  1011. package/src/javascript/app/common/disclaimer.js +74 -0
  1012. package/src/javascript/app/common/event_handler.js +16 -0
  1013. package/src/javascript/app/common/form_manager.js +164 -0
  1014. package/src/javascript/app/common/form_validation.js +397 -0
  1015. package/src/javascript/app/common/getFeatureFlag.js +18 -0
  1016. package/src/javascript/app/common/get_app_details.js +37 -0
  1017. package/src/javascript/app/common/guide.js +136 -0
  1018. package/src/javascript/app/common/helpers.js +151 -0
  1019. package/src/javascript/app/common/open_positions_modal.js +160 -0
  1020. package/src/javascript/app/common/request_middleware.js +89 -0
  1021. package/src/javascript/app/common/session_duration_limit.js +66 -0
  1022. package/src/javascript/app/common/statements_modal.js +197 -0
  1023. package/src/javascript/app/common/telegram_auth.js +682 -0
  1024. package/src/javascript/app/common/trade_reports_modal.js +665 -0
  1025. package/src/javascript/app/common/traffic_source.js +88 -0
  1026. package/src/javascript/app/components/date_picker.js +156 -0
  1027. package/src/javascript/app/components/loading-spinner.js +46 -0
  1028. package/src/javascript/app/components/time_picker.js +146 -0
  1029. package/src/javascript/app/hooks/events.js +88 -0
  1030. package/src/javascript/app/hooks/useFreshChat.js +42 -0
  1031. package/src/javascript/app/hooks/useGrowthbookGetFeatureValue.js +36 -0
  1032. package/src/javascript/app/hooks/useInterComChat.js +22 -0
  1033. package/src/javascript/app/hooks/useRemoteConfig.js +59 -0
  1034. package/src/javascript/app/pages/bottom/data/explanation.js +347 -0
  1035. package/src/javascript/app/pages/bottom/explanation.jsx +231 -0
  1036. package/src/javascript/app/pages/bottom/graph.jsx +35 -0
  1037. package/src/javascript/app/pages/bottom/tabs.jsx +71 -0
  1038. package/src/javascript/app/pages/callback/callback.jsx +145 -0
  1039. package/src/javascript/app/pages/endpoint.js +32 -0
  1040. package/src/javascript/app/pages/form/barrier-fields.jsx +136 -0
  1041. package/src/javascript/app/pages/form/contract-form-wrapper.jsx +10 -0
  1042. package/src/javascript/app/pages/form/currency-dropdown.jsx +49 -0
  1043. package/src/javascript/app/pages/form/dropdown-component.jsx +47 -0
  1044. package/src/javascript/app/pages/form/form-component.jsx +786 -0
  1045. package/src/javascript/app/pages/form/numbers-dropdown.jsx +75 -0
  1046. package/src/javascript/app/pages/form/time-selection.jsx +102 -0
  1047. package/src/javascript/app/pages/livechat.jsx +61 -0
  1048. package/src/javascript/app/pages/loader.jsx +15 -0
  1049. package/src/javascript/app/pages/portal.jsx +24 -0
  1050. package/src/javascript/app/pages/trade/__tests__/common.test.js +244 -0
  1051. package/src/javascript/app/pages/trade/analysis.js +231 -0
  1052. package/src/javascript/app/pages/trade/barriers.js +244 -0
  1053. package/src/javascript/app/pages/trade/callputspread.js +241 -0
  1054. package/src/javascript/app/pages/trade/charts/digit_info.js +274 -0
  1055. package/src/javascript/app/pages/trade/charts/highchart.js +781 -0
  1056. package/src/javascript/app/pages/trade/charts/highchart.ui.js +66 -0
  1057. package/src/javascript/app/pages/trade/charts/webtrader_chart.js +278 -0
  1058. package/src/javascript/app/pages/trade/common.js +4501 -0
  1059. package/src/javascript/app/pages/trade/common_independent.js +160 -0
  1060. package/src/javascript/app/pages/trade/contract.js +263 -0
  1061. package/src/javascript/app/pages/trade/contracts.jsx +195 -0
  1062. package/src/javascript/app/pages/trade/currency.js +29 -0
  1063. package/src/javascript/app/pages/trade/defaults.js +108 -0
  1064. package/src/javascript/app/pages/trade/digit_grid.js +119 -0
  1065. package/src/javascript/app/pages/trade/digit_ticker.js +457 -0
  1066. package/src/javascript/app/pages/trade/digit_trade.js +174 -0
  1067. package/src/javascript/app/pages/trade/duration.js +799 -0
  1068. package/src/javascript/app/pages/trade/event.js +475 -0
  1069. package/src/javascript/app/pages/trade/get_active_tab.js +25 -0
  1070. package/src/javascript/app/pages/trade/get_ticks.js +88 -0
  1071. package/src/javascript/app/pages/trade/guide.jsx +43 -0
  1072. package/src/javascript/app/pages/trade/last_digit.jsx +39 -0
  1073. package/src/javascript/app/pages/trade/lookback.js +59 -0
  1074. package/src/javascript/app/pages/trade/markets/contracts-dropdown.jsx +114 -0
  1075. package/src/javascript/app/pages/trade/markets/market-selector.jsx +97 -0
  1076. package/src/javascript/app/pages/trade/markets/markets-dropdown.jsx +671 -0
  1077. package/src/javascript/app/pages/trade/markets.jsx +705 -0
  1078. package/src/javascript/app/pages/trade/notifications.js +58 -0
  1079. package/src/javascript/app/pages/trade/price.js +521 -0
  1080. package/src/javascript/app/pages/trade/process.js +454 -0
  1081. package/src/javascript/app/pages/trade/purchase/contract-details.jsx +280 -0
  1082. package/src/javascript/app/pages/trade/purchase/contract-table.jsx +256 -0
  1083. package/src/javascript/app/pages/trade/purchase/purchase.jsx +1806 -0
  1084. package/src/javascript/app/pages/trade/purchase.js +429 -0
  1085. package/src/javascript/app/pages/trade/reset.js +87 -0
  1086. package/src/javascript/app/pages/trade/starttime.js +146 -0
  1087. package/src/javascript/app/pages/trade/symbols.js +116 -0
  1088. package/src/javascript/app/pages/trade/tick.js +218 -0
  1089. package/src/javascript/app/pages/trade/tick_trade.js +415 -0
  1090. package/src/javascript/app/pages/trade/tradepage.js +125 -0
  1091. package/src/javascript/app/pages/trade/update_values.js +78 -0
  1092. package/src/javascript/app/pages/user/account/__tests__/portfolio.js +91 -0
  1093. package/src/javascript/app/pages/user/account/portfolio/portfolio.init.js +243 -0
  1094. package/src/javascript/app/pages/user/account/portfolio/portfolio.js +57 -0
  1095. package/src/javascript/app/pages/user/account/settings/professional_client.js +140 -0
  1096. package/src/javascript/app/pages/user/account/settings/self_exclusion.js +408 -0
  1097. package/src/javascript/app/pages/user/account/top_up_virtual/pop_up.js +118 -0
  1098. package/src/javascript/app/pages/user/account/top_up_virtual/top_up_virtual.js +44 -0
  1099. package/src/javascript/app/pages/user/get_currency.js +110 -0
  1100. package/src/javascript/app/pages/user/reality_check/reality_check.data.js +87 -0
  1101. package/src/javascript/app/pages/user/reality_check/reality_check.js +43 -0
  1102. package/src/javascript/app/pages/user/reality_check/reality_check.ui.js +144 -0
  1103. package/src/javascript/app/pages/user/update_balance.js +109 -0
  1104. package/src/javascript/app/pages/user/update_total.js +39 -0
  1105. package/src/javascript/app/pages/user/view_popup/view_popup.js +1155 -0
  1106. package/src/javascript/app/pages/user/view_popup/view_popup.ui.js +194 -0
  1107. package/src/javascript/app/theme/palette.ts +71 -0
  1108. package/src/javascript/config.js +162 -0
  1109. package/src/javascript/index.js +114 -0
  1110. package/src/javascript/landing_pages/.eslintrc.js +11 -0
  1111. package/src/javascript/landing_pages/common.js +205 -0
  1112. package/src/javascript/manifest.json +66 -0
  1113. package/src/root_files/_common/404.html +105 -0
  1114. package/src/root_files/_common/robots.txt +2 -0
  1115. package/src/root_files/app/index.html +97 -0
  1116. package/src/root_files/app/sitemap.id.xml +37 -0
  1117. package/src/root_files/app/sitemap.xml +14 -0
  1118. package/src/sass/README.md +120 -0
  1119. package/src/sass/_common/base/animations.scss +48 -0
  1120. package/src/sass/_common/base/constants-deriv.scss +139 -0
  1121. package/src/sass/_common/base/constants.scss +66 -0
  1122. package/src/sass/_common/base/functions.scss +64 -0
  1123. package/src/sass/_common/base/language_base.scss +202 -0
  1124. package/src/sass/_common/base/media-queries.scss +72 -0
  1125. package/src/sass/_common/base/mixin.scss +175 -0
  1126. package/src/sass/_common/base/reset.scss +46 -0
  1127. package/src/sass/_common/base/theme.scss +348 -0
  1128. package/src/sass/_common/common.scss +1155 -0
  1129. package/src/sass/_common/common_import.scss +7 -0
  1130. package/src/sass/_common/components.scss +562 -0
  1131. package/src/sass/_common/external/_grid-settings-flex.scss +57 -0
  1132. package/src/sass/_common/external/_grid-settings.scss +60 -0
  1133. package/src/sass/_common/external/_variables.scss +28 -0
  1134. package/src/sass/_common/external/grid-flex.scss +42 -0
  1135. package/src/sass/_common/external/grid-mixins.scss +64 -0
  1136. package/src/sass/_common/external/grid.scss +63 -0
  1137. package/src/sass/_common/external/gridle/_api.scss +814 -0
  1138. package/src/sass/_common/external/gridle/_default-states.scss +37 -0
  1139. package/src/sass/_common/external/gridle/_driver-default.scss +432 -0
  1140. package/src/sass/_common/external/gridle/_driver-flex.scss +378 -0
  1141. package/src/sass/_common/external/gridle/_flexbox.scss +422 -0
  1142. package/src/sass/_common/external/gridle/_functions.scss +1108 -0
  1143. package/src/sass/_common/external/gridle/_generate-mixins.scss +645 -0
  1144. package/src/sass/_common/external/gridle/_gridle-flex.scss +60 -0
  1145. package/src/sass/_common/external/gridle/_gridle.scss +59 -0
  1146. package/src/sass/_common/external/gridle/_init.scss +147 -0
  1147. package/src/sass/_common/external/gridle/_mixins.scss +469 -0
  1148. package/src/sass/_common/external/gridle/_settings-mixins.scss +387 -0
  1149. package/src/sass/_common/external/gridle/_settings.scss +127 -0
  1150. package/src/sass/_common/external/mmenu/jquery.mmenu.all.scss +1276 -0
  1151. package/src/sass/_common/external/style.scss +361 -0
  1152. package/src/sass/_common/external/tests.scss +519 -0
  1153. package/src/sass/_common/external/third-party.scss +57 -0
  1154. package/src/sass/_common/external/tools/_reset.scss +47 -0
  1155. package/src/sass/_common/footer.scss +188 -0
  1156. package/src/sass/_common/header.scss +1799 -0
  1157. package/src/sass/_common/icons.scss +29 -0
  1158. package/src/sass/_common/img_lightbox.scss +59 -0
  1159. package/src/sass/_common/jquery_elements.scss +117 -0
  1160. package/src/sass/_common/reskin.scss +3928 -0
  1161. package/src/sass/_common/table.scss +104 -0
  1162. package/src/sass/_common/wallet_header.scss +224 -0
  1163. package/src/sass/app/components/account_transfer.scss +93 -0
  1164. package/src/sass/app/components/cashier-modal.scss +614 -0
  1165. package/src/sass/app/components/contract.scss +166 -0
  1166. package/src/sass/app/components/market.scss +442 -0
  1167. package/src/sass/app/components/peek_box.scss +391 -0
  1168. package/src/sass/app/components/stats-dialog.scss +46 -0
  1169. package/src/sass/app/components/trade-reports-modal.scss +771 -0
  1170. package/src/sass/app/reality_check.scss +99 -0
  1171. package/src/sass/app/sell_popup.scss +387 -0
  1172. package/src/sass/app/trade.scss +5012 -0
  1173. package/src/sass/app/trading.scss +127 -0
  1174. package/src/sass/app/websocket_pages.scss +210 -0
  1175. package/src/sass/app.scss +16 -0
  1176. package/src/sass/common.scss +27 -0
  1177. package/src/sass/reset.scss +27 -0
  1178. package/src/sass/static/animate-ui.css +215 -0
  1179. package/src/sass/static/guide.enjoyhint.scss +308 -0
  1180. package/src/sass/static/guide.scss +31 -0
  1181. package/src/sass/static/pages.scss +299 -0
  1182. package/src/sass/static.scss +5 -0
  1183. package/src/templates/.eslintrc.js +6 -0
  1184. package/src/templates/README.md +105 -0
  1185. package/src/templates/_common/_layout/head.jsx +61 -0
  1186. package/src/templates/_common/_layout/header.jsx +182 -0
  1187. package/src/templates/_common/_layout/layout.jsx +212 -0
  1188. package/src/templates/_common/_layout/wallet-header.jsx +121 -0
  1189. package/src/templates/_common/brand.config.js +25 -0
  1190. package/src/templates/_common/components/box_row.jsx +45 -0
  1191. package/src/templates/_common/components/cashier_modal.jsx +486 -0
  1192. package/src/templates/_common/components/elements.jsx +294 -0
  1193. package/src/templates/_common/components/forms.jsx +241 -0
  1194. package/src/templates/_common/components/html_comment.jsx +7 -0
  1195. package/src/templates/_common/components/language-menu-modal.jsx +17 -0
  1196. package/src/templates/_common/components/list_multiline.jsx +22 -0
  1197. package/src/templates/_common/components/list_nested.jsx +17 -0
  1198. package/src/templates/_common/components/loading.jsx +28 -0
  1199. package/src/templates/_common/components/mobile_menu.jsx +164 -0
  1200. package/src/templates/_common/components/notification.jsx +26 -0
  1201. package/src/templates/_common/components/open_positions_modal.jsx +55 -0
  1202. package/src/templates/_common/components/separator_line.jsx +27 -0
  1203. package/src/templates/_common/components/sidebar.jsx +42 -0
  1204. package/src/templates/_common/components/statements_modal.jsx +65 -0
  1205. package/src/templates/_common/components/step.jsx +15 -0
  1206. package/src/templates/_common/components/tabs.jsx +67 -0
  1207. package/src/templates/_common/components/title.jsx +8 -0
  1208. package/src/templates/_common/components/trade_reports_modal.jsx +213 -0
  1209. package/src/templates/_common/includes/anti_clickjack.jsx +20 -0
  1210. package/src/templates/_common/includes/elevio.jsx +23 -0
  1211. package/src/templates/_common/includes/favicons.jsx +42 -0
  1212. package/src/templates/_common/includes/google_optimizer.jsx +7 -0
  1213. package/src/templates/_common/includes/gtm.jsx +8 -0
  1214. package/src/templates/_common/includes/livechat.jsx +21 -0
  1215. package/src/templates/app/callback.jsx +30 -0
  1216. package/src/templates/app/dialog.jsx +23 -0
  1217. package/src/templates/app/endpoint.jsx +50 -0
  1218. package/src/templates/app/logged_in.jsx +337 -0
  1219. package/src/templates/app/trade/analysis.jsx +51 -0
  1220. package/src/templates/app/trade/explanation.jsx +336 -0
  1221. package/src/templates/app/trade/price-chart.jsx +103 -0
  1222. package/src/templates/app/trade/trading.jsx +1829 -0
  1223. package/src/templates/app/user/portfolio.jsx +59 -0
  1224. package/src/templates/app/user/reality_check/deriv_summary.jsx +77 -0
  1225. package/src/templates/app/user/reality_check/form.jsx +22 -0
  1226. package/src/templates/app/user/reality_check/frequency.jsx +13 -0
  1227. package/src/templates/app/user/reality_check/summary.jsx +53 -0
  1228. package/src/templates/app/user/reality_check/wrapper.jsx +15 -0
  1229. package/src/templates/static/404.jsx +22 -0
  1230. package/src/translations/ach_UG.po +1860 -0
  1231. package/src/translations/ar_SA.po +1860 -0
  1232. package/src/translations/bn_BD.po +1860 -0
  1233. package/src/translations/de_DE.po +1860 -0
  1234. package/src/translations/en.po +14817 -0
  1235. package/src/translations/es_ES.po +1860 -0
  1236. package/src/translations/fr_FR.po +1860 -0
  1237. package/src/translations/id_ID.po +3069 -0
  1238. package/src/translations/it_IT.po +1860 -0
  1239. package/src/translations/km_KH.po +1860 -0
  1240. package/src/translations/ko_KR.po +1860 -0
  1241. package/src/translations/messages.pot +1901 -0
  1242. package/src/translations/mn_MN.po +1860 -0
  1243. package/src/translations/pl_PL.po +1860 -0
  1244. package/src/translations/pt_PT.po +1860 -0
  1245. package/src/translations/ru_RU.po +1917 -0
  1246. package/src/translations/si_LK.po +1860 -0
  1247. package/src/translations/sw_KE.po +1860 -0
  1248. package/src/translations/th_TH.po +1860 -0
  1249. package/src/translations/tr_TR.po +1860 -0
  1250. package/src/translations/uz_UZ.po +1860 -0
  1251. package/src/translations/vi_VN.po +1860 -0
  1252. package/src/translations/zh_CN.po +1860 -0
  1253. package/src/translations/zh_TW.po +1860 -0
  1254. package/stagewise.json +6 -0
  1255. package/styles.scss +8 -0
  1256. package/vendor/deriv-com-analytics/LICENSE +21 -0
  1257. package/vendor/deriv-com-analytics/README.md +112 -0
  1258. package/vendor/deriv-com-analytics/lib/analytics.d.ts +58 -0
  1259. package/vendor/deriv-com-analytics/lib/analytics.js +258 -0
  1260. package/vendor/deriv-com-analytics/lib/growthbook.d.ts +29 -0
  1261. package/vendor/deriv-com-analytics/lib/growthbook.js +144 -0
  1262. package/vendor/deriv-com-analytics/lib/index.d.ts +2 -0
  1263. package/vendor/deriv-com-analytics/lib/index.js +5 -0
  1264. package/vendor/deriv-com-analytics/lib/rudderstack.d.ts +52 -0
  1265. package/vendor/deriv-com-analytics/lib/rudderstack.js +162 -0
  1266. package/vendor/deriv-com-analytics/lib/types.d.ts +334 -0
  1267. package/vendor/deriv-com-analytics/lib/types.js +2 -0
  1268. package/vendor/deriv-com-analytics/package.json +42 -0
  1269. package/vercel.dr.json +5 -0
  1270. package/vercel.json +8 -0
@@ -0,0 +1,1361 @@
1
+ const crypto = require('crypto')
2
+
3
+ const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN
4
+ const FRONTEND_URL = process.env.SMARTANALYZER_FRONTEND_URL || 'https://smartanalizer.vercel.app'
5
+ const FRONTEND_AUTH_PATH = process.env.SMARTANALYZER_FRONTEND_AUTH_PATH || '/auth'
6
+ const TELEGRAM_MINI_APP_URL = process.env.TELEGRAM_MINI_APP_URL || null
7
+ const DERIV_APP_ID = process.env.DERIV_APP_ID || process.env.DERIV_APPID || '1'
8
+ const DERIV_OAUTH_URL = process.env.DERIV_OAUTH_URL || 'https://oauth.deriv.com/oauth2/authorize'
9
+ const DERIV_WS_URL = process.env.DERIV_WS_URL || `wss://ws.derivws.com/websockets/v3?app_id=${DERIV_APP_ID}`
10
+ const DERIV_TIMEOUT_MS = Number(process.env.DERIV_API_TIMEOUT_MS || 10000)
11
+ const FRONTEND_CALLBACK_PATH = process.env.SMARTANALYZER_FRONTEND_CALLBACK_PATH || '/callback'
12
+ const FRONTEND_DEFAULT_LOCALE = (process.env.SMARTANALYZER_DEFAULT_LOCALE || 'en').toLowerCase()
13
+
14
+ const WebSocket = global.WebSocket || require('ws')
15
+ const WS_STATE = {
16
+ CONNECTING: typeof WebSocket.CONNECTING === 'number' ? WebSocket.CONNECTING : 0,
17
+ OPEN : typeof WebSocket.OPEN === 'number' ? WebSocket.OPEN : 1,
18
+ }
19
+ const {
20
+ loadSession,
21
+ deleteSession,
22
+ } = require('../_lib/telegram_session_store')
23
+ const {
24
+ checkUserSubscription,
25
+ hasActiveSubscription,
26
+ buildSubscriptionStatusMessage,
27
+ buildSubscriptionInlineKeyboard,
28
+ getSubscribeLink,
29
+ getPrimarySubscriptionLabel,
30
+ } = require('../_lib/telegram_subscription')
31
+
32
+ const COMMANDS = {
33
+ START : '/start',
34
+ AUTH : '🔐 Авторизация',
35
+ CHECK : '📡 Проверка подключения',
36
+ CLEAR : '🚪 Очистить авторизацию',
37
+ BALANCE : '💰 Баланс Deriv',
38
+ ACCOUNTS: '📂 Открытые счета',
39
+ TRADES : '📜 Пять последних сделок',
40
+ SUBSCRIBE: '💳 Подписаться',
41
+ SUBSCRIPTION_STATUS: '📦 Проверить подписку',
42
+ }
43
+
44
+ const normalizeCommandKey = (value) => {
45
+ if (!value && value !== 0) {
46
+ return ''
47
+ }
48
+
49
+ return String(value)
50
+ .normalize('NFKD')
51
+ .replace(/[\u0300-\u036f]/g, '')
52
+ .toLowerCase()
53
+ .replace(/[^a-z0-9\u0400-\u04ff/]+/gu, ' ')
54
+ .trim()
55
+ .replace(/\s+/g, ' ')
56
+ }
57
+
58
+ const COMMAND_ALIAS_MAP = new Map()
59
+
60
+ const MAX_ACTIVE_CHAT_MESSAGES = 4
61
+ const ACTIVE_CHAT_MESSAGES = new Map()
62
+
63
+ const registerCommandAlias = (alias, command) => {
64
+ const key = normalizeCommandKey(alias)
65
+ if (!key || COMMAND_ALIAS_MAP.has(key)) {
66
+ return
67
+ }
68
+
69
+ COMMAND_ALIAS_MAP.set(key, command)
70
+ }
71
+
72
+ [
73
+ [COMMANDS.AUTH, COMMANDS.AUTH],
74
+ ['авторизация', COMMANDS.AUTH],
75
+ ['авторизоваться', COMMANDS.AUTH],
76
+ ['auth', COMMANDS.AUTH],
77
+ ['authorize', COMMANDS.AUTH],
78
+ ['authorization', COMMANDS.AUTH],
79
+ ['authorisation', COMMANDS.AUTH],
80
+ ['login', COMMANDS.AUTH],
81
+ ['log in', COMMANDS.AUTH],
82
+ ['войти', COMMANDS.AUTH],
83
+ ['вход', COMMANDS.AUTH],
84
+ ['refresh', COMMANDS.AUTH],
85
+ ['renew', COMMANDS.AUTH],
86
+
87
+ [COMMANDS.CHECK, COMMANDS.CHECK],
88
+ ['проверка подключения', COMMANDS.CHECK],
89
+ ['проверка', COMMANDS.CHECK],
90
+ ['check connection', COMMANDS.CHECK],
91
+ ['connection', COMMANDS.CHECK],
92
+ ['check', COMMANDS.CHECK],
93
+
94
+ [COMMANDS.CLEAR, COMMANDS.CLEAR],
95
+ ['очистить авторизацию', COMMANDS.CLEAR],
96
+ ['очистить', COMMANDS.CLEAR],
97
+ ['logout', COMMANDS.CLEAR],
98
+ ['log out', COMMANDS.CLEAR],
99
+ ['выйти', COMMANDS.CLEAR],
100
+ ['разлогиниться', COMMANDS.CLEAR],
101
+ ['reset', COMMANDS.CLEAR],
102
+
103
+ [COMMANDS.BALANCE, COMMANDS.BALANCE],
104
+ ['баланс', COMMANDS.BALANCE],
105
+ ['баланс deriv', COMMANDS.BALANCE],
106
+ ['balance', COMMANDS.BALANCE],
107
+
108
+ [COMMANDS.ACCOUNTS, COMMANDS.ACCOUNTS],
109
+ ['открытые счета', COMMANDS.ACCOUNTS],
110
+ ['счета', COMMANDS.ACCOUNTS],
111
+ ['аккаунты', COMMANDS.ACCOUNTS],
112
+ ['аккаунт', COMMANDS.ACCOUNTS],
113
+ ['accounts', COMMANDS.ACCOUNTS],
114
+ ['account', COMMANDS.ACCOUNTS],
115
+
116
+ [COMMANDS.TRADES, COMMANDS.TRADES],
117
+ ['сделки', COMMANDS.TRADES],
118
+ ['история', COMMANDS.TRADES],
119
+ ['trades', COMMANDS.TRADES],
120
+ ['statement', COMMANDS.TRADES],
121
+ ['history', COMMANDS.TRADES],
122
+
123
+ [COMMANDS.SUBSCRIBE, COMMANDS.SUBSCRIBE],
124
+ ['подписаться', COMMANDS.SUBSCRIBE],
125
+ ['подписка', COMMANDS.SUBSCRIBE],
126
+ ['subscribe', COMMANDS.SUBSCRIBE],
127
+
128
+ [COMMANDS.SUBSCRIPTION_STATUS, COMMANDS.SUBSCRIPTION_STATUS],
129
+ ['проверить подписку', COMMANDS.SUBSCRIPTION_STATUS],
130
+ ['проверка подписки', COMMANDS.SUBSCRIPTION_STATUS],
131
+ ['subscription status', COMMANDS.SUBSCRIPTION_STATUS],
132
+ ['status', COMMANDS.SUBSCRIPTION_STATUS],
133
+ ['check subscription', COMMANDS.SUBSCRIPTION_STATUS],
134
+ ].forEach(([alias, command]) => registerCommandAlias(alias, command))
135
+
136
+ const resolveCommandAlias = (value) => {
137
+ const key = normalizeCommandKey(value)
138
+ if (!key) {
139
+ return null
140
+ }
141
+
142
+ return COMMAND_ALIAS_MAP.get(key) || null
143
+ }
144
+
145
+ const decodeStartPayloadJson = (value) => {
146
+ if (typeof value !== 'string' || !value) {
147
+ return null
148
+ }
149
+
150
+ try {
151
+ const normalized = value
152
+ .replace(/-/g, '+')
153
+ .replace(/_/g, '/')
154
+ const padding = normalized.length % 4 ? 4 - (normalized.length % 4) : 0
155
+ const padded = normalized + '='.repeat(padding)
156
+ const decoded = Buffer.from(padded, 'base64').toString('utf8')
157
+ const parsed = JSON.parse(decoded)
158
+ if (parsed && typeof parsed === 'object') {
159
+ return parsed
160
+ }
161
+ } catch (error) {
162
+ // ignore malformed payloads
163
+ }
164
+
165
+ return null
166
+ }
167
+
168
+ const extractStartPayload = (text) => {
169
+ if (typeof text !== 'string') {
170
+ return null
171
+ }
172
+
173
+ if (!text.startsWith(COMMANDS.START)) {
174
+ return null
175
+ }
176
+
177
+ const payload = text.slice(COMMANDS.START.length).trim()
178
+ return payload || null
179
+ }
180
+
181
+ const interpretStartPayload = (payload) => {
182
+ if (!payload) {
183
+ return null
184
+ }
185
+
186
+ const trimmed = payload.trim()
187
+ if (!trimmed) {
188
+ return null
189
+ }
190
+
191
+ const colonIndex = trimmed.indexOf(':')
192
+ const head = colonIndex > -1 ? trimmed.slice(0, colonIndex) : trimmed
193
+ const remainder = colonIndex > -1 ? trimmed.slice(colonIndex + 1).trim() : ''
194
+
195
+ const alias = resolveCommandAlias(head)
196
+ if (alias) {
197
+ return { command: alias, payload: trimmed, argument: remainder }
198
+ }
199
+
200
+ const aliasFull = resolveCommandAlias(trimmed)
201
+ if (aliasFull) {
202
+ return { command: aliasFull, payload: trimmed, argument: '' }
203
+ }
204
+
205
+ const decoded = decodeStartPayloadJson(trimmed)
206
+ if (decoded) {
207
+ const candidates = [decoded.command, decoded.action, decoded.cmd, decoded.type]
208
+ for (const candidate of candidates) {
209
+ const decodedAlias = resolveCommandAlias(candidate)
210
+ if (decodedAlias) {
211
+ return { command: decodedAlias, payload: trimmed, argument: '', data: decoded }
212
+ }
213
+ }
214
+
215
+ return { command: null, payload: trimmed, argument: '', data: decoded }
216
+ }
217
+
218
+ const normalized = resolveCommandAlias(remainder)
219
+ if (normalized) {
220
+ return { command: normalized, payload: trimmed, argument: remainder }
221
+ }
222
+
223
+ return { command: null, payload: trimmed, argument: remainder }
224
+ }
225
+
226
+ const extractCommandFromText = (text) => {
227
+ if (!text) {
228
+ return { command: null, startPayload: null }
229
+ }
230
+
231
+ if (text.startsWith(COMMANDS.START)) {
232
+ return { command: COMMANDS.START, startPayload: extractStartPayload(text) }
233
+ }
234
+
235
+ const alias = resolveCommandAlias(text)
236
+ if (alias) {
237
+ return { command: alias, startPayload: null }
238
+ }
239
+
240
+ return { command: text, startPayload: null }
241
+ }
242
+
243
+ const formatAmount = (value) => {
244
+ if (typeof value === 'number' && Number.isFinite(value)) {
245
+ return value.toFixed(2)
246
+ }
247
+
248
+ if (typeof value === 'string') {
249
+ const parsed = Number.parseFloat(value)
250
+ if (Number.isFinite(parsed)) {
251
+ return parsed.toFixed(2)
252
+ }
253
+ }
254
+
255
+ return null
256
+ }
257
+
258
+ const buildReplyKeyboard = (session, subscription) => {
259
+ const subscriptionActive = hasActiveSubscription(subscription)
260
+
261
+ if (!subscriptionActive) {
262
+ return {
263
+ keyboard: [
264
+ [{ text: COMMANDS.SUBSCRIPTION_STATUS }],
265
+ [{ text: COMMANDS.SUBSCRIBE }],
266
+ ],
267
+ resize_keyboard : true,
268
+ one_time_keyboard : false,
269
+ input_field_placeholder: 'Оформите подписку, чтобы продолжить',
270
+ }
271
+ }
272
+
273
+ const keyboard = [
274
+ [{ text: COMMANDS.AUTH }],
275
+ [{ text: COMMANDS.CLEAR }],
276
+ ]
277
+
278
+ if (session) {
279
+ keyboard.push(
280
+ [{ text: COMMANDS.BALANCE }, { text: COMMANDS.ACCOUNTS }],
281
+ [{ text: COMMANDS.TRADES }],
282
+ )
283
+ }
284
+
285
+ keyboard.push([{ text: COMMANDS.SUBSCRIPTION_STATUS }])
286
+
287
+ return {
288
+ keyboard,
289
+ resize_keyboard : true,
290
+ one_time_keyboard : false,
291
+ input_field_placeholder: session ? 'Выберите действие' : 'Авторизуйтесь через Deriv',
292
+ }
293
+ }
294
+
295
+ const deleteMessage = async (chatId, messageId) => {
296
+ if (!chatId || !messageId) return
297
+
298
+ try {
299
+ await fetch(`https://api.telegram.org/bot${BOT_TOKEN}/deleteMessage`, {
300
+ method : 'POST',
301
+ headers: { 'Content-Type': 'application/json' },
302
+ body : JSON.stringify({ chat_id: chatId, message_id: messageId }),
303
+ })
304
+ } catch (error) {
305
+ console.warn(`⚠️ Failed to delete message ${messageId} in chat ${chatId}:`, error)
306
+ }
307
+ }
308
+
309
+ const registerChatMessage = async (chatId, messageId) => {
310
+ if (!chatId || !messageId) return
311
+
312
+ const history = ACTIVE_CHAT_MESSAGES.get(chatId) || []
313
+ history.push(messageId)
314
+
315
+ while (history.length > MAX_ACTIVE_CHAT_MESSAGES) {
316
+ const outdatedMessageId = history.shift()
317
+ if (outdatedMessageId) {
318
+ await deleteMessage(chatId, outdatedMessageId)
319
+ }
320
+ }
321
+
322
+ ACTIVE_CHAT_MESSAGES.set(chatId, history)
323
+ }
324
+
325
+ const sendMessage = async (chatId, text, { replyMarkup = null, parseMode = null } = {}) => {
326
+ const payload = {
327
+ chat_id: chatId,
328
+ text,
329
+ disable_web_page_preview: true,
330
+ }
331
+
332
+ if (parseMode) {
333
+ payload.parse_mode = parseMode
334
+ }
335
+
336
+ if (replyMarkup) {
337
+ payload.reply_markup = replyMarkup
338
+ }
339
+
340
+ try {
341
+ const response = await fetch(`https://api.telegram.org/bot${BOT_TOKEN}/sendMessage`, {
342
+ method : 'POST',
343
+ headers: { 'Content-Type': 'application/json' },
344
+ body : JSON.stringify(payload),
345
+ })
346
+
347
+ const data = await response.json().catch(() => null)
348
+
349
+ if (data?.ok && data?.result?.message_id) {
350
+ await registerChatMessage(chatId, data.result.message_id)
351
+ }
352
+
353
+ return data?.result || null
354
+ } catch (error) {
355
+ console.error('❌ Failed to send Telegram message:', error)
356
+ return null
357
+ }
358
+ }
359
+
360
+ const safeLocale = (value) => {
361
+ if (typeof value !== 'string' || !value.trim()) {
362
+ return FRONTEND_DEFAULT_LOCALE
363
+ }
364
+
365
+ return value.trim().toLowerCase().split(/[_-]/)[0] || FRONTEND_DEFAULT_LOCALE
366
+ }
367
+
368
+ const normalizePath = (value) => {
369
+ if (!value) return '/'
370
+ return value.startsWith('/') ? value : `/${value}`
371
+ }
372
+
373
+ const generateIntentId = () => {
374
+ if (typeof crypto.randomUUID === 'function') {
375
+ return crypto.randomUUID()
376
+ }
377
+
378
+ return `tg_${Date.now()}_${Math.random().toString(36).slice(2, 10)}`
379
+ }
380
+
381
+ const appendSessionTokens = (params, session) => {
382
+ if (!session) return
383
+
384
+ const accounts = Array.isArray(session.accounts) ? session.accounts : []
385
+
386
+ accounts
387
+ .filter(account => account && account.loginid && account.token)
388
+ .forEach((account, index) => {
389
+ const position = index + 1
390
+ params.set(`acct${position}`, account.loginid)
391
+ params.set(`token${position}`, account.token)
392
+ if (account.currency) {
393
+ params.set(`currency${position}`, account.currency)
394
+ }
395
+ })
396
+
397
+ if (session.active_loginid) {
398
+ params.set('active_loginid', session.active_loginid)
399
+ }
400
+
401
+ if (session.locale) {
402
+ params.set('lang', safeLocale(session.locale))
403
+ }
404
+
405
+ if (session.redirect_url) {
406
+ params.set('redirect_url', session.redirect_url)
407
+ }
408
+
409
+ if (session.intent_id) {
410
+ params.set('intent_id', session.intent_id)
411
+ }
412
+ }
413
+
414
+ const buildMiniAppLoginUrl = (chatId, session) => {
415
+ if (!TELEGRAM_MINI_APP_URL) {
416
+ return null
417
+ }
418
+
419
+ try {
420
+ const url = new URL(TELEGRAM_MINI_APP_URL)
421
+ const params = url.searchParams
422
+
423
+ if (chatId) {
424
+ params.set('tg_chat_id', String(chatId))
425
+ }
426
+
427
+ params.set('source', 'telegram_bot')
428
+ params.set('mode', session ? 'authorized' : 'authorize')
429
+
430
+ appendSessionTokens(params, session)
431
+
432
+ return url.toString()
433
+ } catch (error) {
434
+ console.warn('⚠️ Failed to build mini-app URL', error)
435
+ return null
436
+ }
437
+ }
438
+
439
+ const buildLoggedInUrl = (chatId, session) => {
440
+ if (!session) {
441
+ return null
442
+ }
443
+
444
+ try {
445
+ const locale = safeLocale(session.locale)
446
+ const path = `/${locale}${normalizePath('logged_in')}`
447
+ const url = new URL(path, FRONTEND_URL)
448
+ const params = url.searchParams
449
+
450
+ appendSessionTokens(params, session)
451
+
452
+ if (chatId) {
453
+ params.set('tg_chat_id', String(chatId))
454
+ }
455
+
456
+ params.set('from', 'telegram_bot')
457
+
458
+ return url.toString()
459
+ } catch (error) {
460
+ console.warn('⚠️ Failed to build logged_in URL', error)
461
+ return null
462
+ }
463
+ }
464
+
465
+ const buildFrontendCallbackUrl = ({ chatId, intentId, locale }) => {
466
+ try {
467
+ const normalizedLocale = safeLocale(locale)
468
+ const callbackPath = `/${normalizedLocale}${normalizePath(FRONTEND_CALLBACK_PATH)}`
469
+ const url = new URL(callbackPath, FRONTEND_URL)
470
+
471
+ if (chatId) {
472
+ url.searchParams.set('chat_id', String(chatId))
473
+ url.searchParams.set('tg_chat_id', String(chatId))
474
+ }
475
+
476
+ if (intentId) {
477
+ url.searchParams.set('intent_id', intentId)
478
+ url.searchParams.set('telegram_intent', intentId)
479
+ url.searchParams.set('tg_intent', intentId)
480
+ }
481
+
482
+ url.searchParams.set('source', 'telegram_bot')
483
+
484
+ return url.toString()
485
+ } catch (error) {
486
+ console.warn('⚠️ Failed to build callback URL', error)
487
+ return null
488
+ }
489
+ }
490
+
491
+ const buildDerivAuthorizeUrl = ({ chatId, locale }) => {
492
+ const intentId = generateIntentId()
493
+ const callbackUrl = buildFrontendCallbackUrl({ chatId, intentId, locale })
494
+
495
+ try {
496
+ const url = new URL(DERIV_OAUTH_URL)
497
+ url.searchParams.set('app_id', DERIV_APP_ID)
498
+
499
+ const loginLocale = safeLocale(locale)
500
+ if (loginLocale) {
501
+ url.searchParams.set('l', loginLocale)
502
+ }
503
+
504
+ if (callbackUrl) {
505
+ url.searchParams.set('redirect_uri', callbackUrl)
506
+ }
507
+
508
+ url.searchParams.set('state', intentId)
509
+
510
+ return { intentId, authorizeUrl: url.toString(), callbackUrl }
511
+ } catch (error) {
512
+ console.warn('⚠️ Failed to build Deriv authorize URL', error)
513
+ return { intentId, authorizeUrl: null, callbackUrl }
514
+ }
515
+ }
516
+
517
+ const buildAuthorizeInlineKeyboard = (chatId, { locale } = {}) => {
518
+ const inline_keyboard = []
519
+ const { authorizeUrl } = buildDerivAuthorizeUrl({ chatId, locale })
520
+ const miniAppUrl = authorizeUrl ? null : buildMiniAppLoginUrl(chatId, null)
521
+
522
+ const miniAppButtonUrl = authorizeUrl || miniAppUrl
523
+
524
+ if (miniAppButtonUrl) {
525
+ inline_keyboard.push([{ text: 'Открыть мини-приложение', web_app: { url: miniAppButtonUrl } }])
526
+ }
527
+
528
+ return inline_keyboard.length ? { inline_keyboard } : null
529
+ }
530
+
531
+ const buildAuthorizedAccessKeyboard = (chatId, session) => {
532
+ if (!session) {
533
+ return null
534
+ }
535
+
536
+ const inline_keyboard = []
537
+ const miniAppUrl = buildMiniAppLoginUrl(chatId, session)
538
+ const loggedInUrl = buildLoggedInUrl(chatId, session)
539
+
540
+ if (miniAppUrl) {
541
+ inline_keyboard.push([{ text: 'Открыть мини-приложение', web_app: { url: miniAppUrl } }])
542
+ }
543
+
544
+ if (loggedInUrl) {
545
+ inline_keyboard.push([{ text: 'Открыть SmartAnalizer', url: loggedInUrl }])
546
+ }
547
+
548
+ return inline_keyboard.length ? { inline_keyboard } : null
549
+ }
550
+
551
+ const sendAuthorizedAccessLinks = async (chatId, subscription, session, message) => {
552
+ if (!hasActiveSubscription(subscription) || !session) {
553
+ return
554
+ }
555
+
556
+ const inlineKeyboard = buildAuthorizedAccessKeyboard(chatId, session)
557
+ if (!inlineKeyboard?.inline_keyboard?.length) {
558
+ return
559
+ }
560
+
561
+ await sendMessage(chatId,
562
+ message || 'Используйте кнопки ниже, чтобы открыть SmartAnalizer.',
563
+ { replyMarkup: inlineKeyboard })
564
+ }
565
+
566
+ const getSessionForReply = (session, subscription) => (hasActiveSubscription(subscription) ? session : null)
567
+
568
+ const sendSubscriptionRequired = async (chatId, subscription, { intro = null } = {}) => {
569
+ const parts = []
570
+ if (intro) {
571
+ parts.push(intro)
572
+ }
573
+
574
+ const subscribeLink = subscription?.subscribeLink || getSubscribeLink()
575
+ const channelLabel = getPrimarySubscriptionLabel()
576
+ const subscribeInstruction = subscribeLink
577
+ ? `Подпишитесь на канал ${channelLabel}: ${subscribeLink}`
578
+ : `Подпишитесь на канал ${channelLabel} и повторите проверку.`
579
+
580
+ if (subscription?.ok) {
581
+ parts.push('Для доступа к SmartAnalizer требуется активная подписка.')
582
+ parts.push(`${subscribeInstruction} После подписки нажмите «📦 Проверить подписку».`)
583
+ } else if (subscription?.message) {
584
+ parts.push(subscription.message)
585
+ parts.push(`${subscribeInstruction} После подписки повторите проверку.`)
586
+ } else {
587
+ parts.push('Не удалось проверить подписку. Попробуйте позже или обратитесь в поддержку.')
588
+ parts.push(subscribeInstruction)
589
+ }
590
+
591
+ const message = parts.filter(Boolean).join('\n\n')
592
+ await sendMessage(chatId,
593
+ message || 'Для продолжения требуется активная подписка на SmartAnalizer.',
594
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
595
+
596
+ const inlineKeyboard = buildSubscriptionInlineKeyboard(subscription)
597
+ if (inlineKeyboard) {
598
+ const followUp = subscription?.ok
599
+ ? 'Нажмите кнопку ниже, чтобы перейти в канал и оформить подписку. После подписки используйте «📦 Проверить подписку». '
600
+ : 'Если проблема сохраняется, попробуйте ещё раз позже или обратитесь в поддержку.'
601
+
602
+ await sendMessage(chatId,
603
+ followUp,
604
+ { replyMarkup: inlineKeyboard })
605
+ }
606
+ }
607
+
608
+ const ensureSubscriptionOrNotify = async (chatId, subscription, intro) => {
609
+ if (hasActiveSubscription(subscription)) {
610
+ return true
611
+ }
612
+
613
+ await sendSubscriptionRequired(chatId, subscription, { intro })
614
+ return false
615
+ }
616
+
617
+ const getSessionSafe = async (chatId) => {
618
+ try {
619
+ const session = await loadSession(chatId)
620
+ return { session }
621
+ } catch (error) {
622
+ console.error('❌ Failed to load Telegram session:', error)
623
+ return { session: null, error }
624
+ }
625
+ }
626
+
627
+ const resolveSessionForIds = async (ids) => {
628
+ const uniqueIds = Array.from(new Set(
629
+ ids
630
+ .filter(id => id !== undefined && id !== null)
631
+ .map(id => String(id))
632
+ .filter(id => id.length > 0),
633
+ ))
634
+
635
+ for (const id of uniqueIds) {
636
+ const { session, error } = await getSessionSafe(id)
637
+ if (error) {
638
+ return { session: null, sessionError: error, identifiers: uniqueIds }
639
+ }
640
+ if (session) {
641
+ return { session, sessionError: null, identifiers: uniqueIds, resolvedId: id }
642
+ }
643
+ }
644
+
645
+ return { session: null, sessionError: null, identifiers: uniqueIds, resolvedId: null }
646
+ }
647
+
648
+ const deleteSessionSafe = async (chatId) => {
649
+ try {
650
+ const deleted = await deleteSession(chatId)
651
+ return { ok: true, deleted }
652
+ } catch (error) {
653
+ console.error('❌ Failed to delete Telegram session:', error)
654
+ return { ok: false, error }
655
+ }
656
+ }
657
+
658
+ const pickPrimaryAccount = (session) => {
659
+ if (!session || !Array.isArray(session.accounts) || !session.accounts.length) {
660
+ return null
661
+ }
662
+
663
+ if (session.active_loginid) {
664
+ const byActive = session.accounts.find(account => account.loginid === session.active_loginid)
665
+ if (byActive) {
666
+ return byActive
667
+ }
668
+ }
669
+
670
+ return session.accounts[0]
671
+ }
672
+
673
+ const formatTimestampUtc = (value) => {
674
+ if (!value) {
675
+ return null
676
+ }
677
+
678
+ const date = new Date(Number(value))
679
+ if (!Number.isFinite(date.getTime())) {
680
+ return null
681
+ }
682
+
683
+ return date.toISOString().replace('T', ' ').replace(/\.\d+Z$/, ' UTC')
684
+ }
685
+
686
+ const getMiniAppPreferences = (session) => {
687
+ if (!session || !session.chart || typeof session.chart !== 'object') {
688
+ return null
689
+ }
690
+
691
+ const keys = Object.keys(session.chart)
692
+ if (!keys.length) {
693
+ return null
694
+ }
695
+
696
+ return session.chart
697
+ }
698
+
699
+ const formatGranularity = (value) => {
700
+ const numeric = Number(value)
701
+ if (!Number.isFinite(numeric) || numeric < 0) {
702
+ return null
703
+ }
704
+
705
+ if (numeric === 0) {
706
+ return 'тики'
707
+ }
708
+
709
+ const DAY_SECONDS = 24 * 60 * 60
710
+ const HOUR_SECONDS = 60 * 60
711
+ const MINUTE_SECONDS = 60
712
+
713
+ if (numeric % DAY_SECONDS === 0) {
714
+ const days = numeric / DAY_SECONDS
715
+ return `${days} д`
716
+ }
717
+
718
+ if (numeric % HOUR_SECONDS === 0) {
719
+ const hours = numeric / HOUR_SECONDS
720
+ return `${hours} ч`
721
+ }
722
+
723
+ if (numeric % MINUTE_SECONDS === 0) {
724
+ const minutes = numeric / MINUTE_SECONDS
725
+ return `${minutes} мин`
726
+ }
727
+
728
+ return `${numeric} с`
729
+ }
730
+
731
+ const describeMiniAppStatus = (session) => {
732
+ const preferences = getMiniAppPreferences(session)
733
+ if (!preferences) {
734
+ return null
735
+ }
736
+
737
+ const details = []
738
+
739
+ const theme = session?.ui_theme || preferences.theme
740
+ if (theme) {
741
+ details.push(`тема ${theme}`)
742
+ }
743
+
744
+ const chartType = preferences.chart_type
745
+ if (chartType) {
746
+ details.push(`тип ${chartType}`)
747
+ }
748
+
749
+ const layout = preferences.layout && typeof preferences.layout === 'object'
750
+ ? preferences.layout
751
+ : null
752
+
753
+ if (layout) {
754
+ const symbol = layout.active_symbol || layout.symbol
755
+ if (symbol) {
756
+ details.push(`символ ${symbol}`)
757
+ }
758
+
759
+ const granularity = formatGranularity(layout.granularity)
760
+ if (granularity) {
761
+ details.push(`таймфрейм ${granularity}`)
762
+ }
763
+ }
764
+
765
+ const style = preferences.style && typeof preferences.style === 'object'
766
+ ? preferences.style
767
+ : null
768
+
769
+ if (style?.key) {
770
+ details.push(`стиль ${style.key}`)
771
+ }
772
+
773
+ if (!details.length) {
774
+ return '📊 Мини-приложение SmartAnalizer активно.'
775
+ }
776
+
777
+ return `📊 Мини-приложение активно (${details.join(', ')}).`
778
+ }
779
+
780
+ const checkDerivConnection = async (account) => {
781
+ if (!account || !account.token) {
782
+ return { ok: false, error: new Error('Токен авторизации не найден.') }
783
+ }
784
+
785
+ try {
786
+ await withDerivRequest(account.token, { ping: 1 }, 'ping')
787
+ return { ok: true }
788
+ } catch (error) {
789
+ return { ok: false, error }
790
+ }
791
+ }
792
+
793
+ const withDerivRequest = (token, payload, expectedType) => new Promise((resolve, reject) => {
794
+ if (!token) {
795
+ reject(new Error('Token is missing'))
796
+ return
797
+ }
798
+
799
+ const ws = new WebSocket(DERIV_WS_URL)
800
+ let isAuthorized = false
801
+ const timeout = setTimeout(() => {
802
+ cleanup()
803
+ reject(new Error('Deriv API timeout'))
804
+ }, DERIV_TIMEOUT_MS)
805
+
806
+ const cleanup = () => {
807
+ clearTimeout(timeout)
808
+ if (ws.readyState === WS_STATE.OPEN || ws.readyState === WS_STATE.CONNECTING) {
809
+ try { ws.close() } catch (err) {
810
+ // ignore errors on close
811
+ }
812
+ }
813
+ }
814
+
815
+ ws.on('open', () => {
816
+ ws.send(JSON.stringify({ authorize: token }))
817
+ })
818
+
819
+ ws.on('error', (error) => {
820
+ cleanup()
821
+ reject(error)
822
+ })
823
+
824
+ ws.on('close', () => {
825
+ clearTimeout(timeout)
826
+ })
827
+
828
+ ws.on('message', (raw) => {
829
+ let message
830
+ try {
831
+ message = JSON.parse(raw)
832
+ } catch (error) {
833
+ console.warn('⚠️ Failed to parse Deriv message', error)
834
+ return
835
+ }
836
+
837
+ if (message.error) {
838
+ cleanup()
839
+ reject(new Error(message.error.message || 'Deriv API error'))
840
+ return
841
+ }
842
+
843
+ if (!isAuthorized) {
844
+ if (message.msg_type === 'authorize') {
845
+ isAuthorized = true
846
+ ws.send(JSON.stringify(payload))
847
+ }
848
+ return
849
+ }
850
+
851
+ if (!expectedType || message.msg_type === expectedType) {
852
+ cleanup()
853
+ resolve(message)
854
+ }
855
+ })
856
+ })
857
+
858
+ const handleStart = async (chatId, session, sessionError, subscription) => {
859
+ if (!hasActiveSubscription(subscription)) {
860
+ await sendSubscriptionRequired(chatId, subscription, {
861
+ intro: '👋 Добро пожаловать в SmartAnalizer! Для продолжения активируйте подписку.',
862
+ })
863
+ return
864
+ }
865
+
866
+ if (sessionError) {
867
+ await sendMessage(chatId,
868
+ '⚠️ Не удалось получить данные авторизации. Попробуйте позже или обратитесь в поддержку.',
869
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
870
+ return
871
+ }
872
+
873
+ if (session) {
874
+ const activeAccount = pickPrimaryAccount(session)
875
+ const accountInfo = activeAccount
876
+ ? `Активный аккаунт Deriv: ${activeAccount.loginid}`
877
+ : 'Авторизация выполнена.'
878
+ await sendMessage(chatId,
879
+ `✅ Бот SmartAnalizer готов к работе!\n${accountInfo}`,
880
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
881
+ await sendAuthorizedAccessLinks(chatId, subscription, session,
882
+ '➡️ Откройте авторизованный SmartAnalizer через кнопки ниже.')
883
+ } else {
884
+ await sendMessage(chatId,
885
+ '👋 Добро пожаловать в SmartAnalizer!\nДля начала авторизуйтесь через Deriv.',
886
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
887
+
888
+ const inlineKeyboard = buildAuthorizeInlineKeyboard(chatId, { locale: subscription?.locale })
889
+ if (inlineKeyboard) {
890
+ await sendMessage(chatId,
891
+ '🔐 Нажмите кнопку ниже, чтобы открыть страницу авторизации Deriv.',
892
+ { replyMarkup: inlineKeyboard })
893
+ }
894
+ }
895
+ }
896
+
897
+ const handleAuthorization = async (chatId, session, sessionError, subscription) => {
898
+ const allowed = await ensureSubscriptionOrNotify(chatId, subscription,
899
+ '🔐 Авторизация доступна только при активной подписке.')
900
+ if (!allowed) {
901
+ return
902
+ }
903
+
904
+ if (sessionError) {
905
+ await sendMessage(chatId,
906
+ '⚠️ Не удалось проверить текущий статус авторизации. Попробуйте позже.',
907
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
908
+ return
909
+ }
910
+
911
+ if (session) {
912
+ const activeAccount = pickPrimaryAccount(session)
913
+ const accountText = activeAccount ? `Аккаунт ${activeAccount.loginid} уже авторизован.` : 'Авторизация уже выполнена.'
914
+ await sendMessage(chatId,
915
+ `✅ ${accountText}\nЕсли требуется сменить аккаунт, выполните авторизацию в мини-приложении снова.`,
916
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
917
+ await sendAuthorizedAccessLinks(chatId, subscription, session,
918
+ '➡️ Используйте кнопки ниже, чтобы открыть авторизованный SmartAnalizer.')
919
+ return
920
+ }
921
+
922
+ await sendMessage(chatId,
923
+ '🔐 Для авторизации откройте страницу Deriv и выполните вход в аккаунт.',
924
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
925
+
926
+ const inlineKeyboard = buildAuthorizeInlineKeyboard(chatId)
927
+ if (inlineKeyboard) {
928
+ await sendMessage(chatId,
929
+ '⬇️ Нажмите кнопку ниже, чтобы перейти к авторизации Deriv.',
930
+ { replyMarkup: inlineKeyboard })
931
+ }
932
+ }
933
+
934
+ const handleConnectionCheck = async (chatId, session, sessionError, subscription) => {
935
+ const allowed = await ensureSubscriptionOrNotify(chatId, subscription,
936
+ '📡 Проверка подключения доступна только при активной подписке.')
937
+ if (!allowed) {
938
+ return
939
+ }
940
+
941
+ if (sessionError) {
942
+ await sendMessage(chatId,
943
+ '⚠️ Не удалось проверить подключение к Deriv. Попробуйте позже.',
944
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
945
+ return
946
+ }
947
+
948
+ if (!session) {
949
+ await sendMessage(chatId,
950
+ '❌ Авторизация отсутствует. Нажмите «🔐 Авторизация», чтобы связать аккаунт Deriv.',
951
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
952
+ return
953
+ }
954
+
955
+ const activeAccount = pickPrimaryAccount(session)
956
+ const accountInfo = activeAccount ? `Аккаунт: ${activeAccount.loginid}` : 'Аккаунт: не выбран.'
957
+ const miniAppReady = Boolean(getMiniAppPreferences(session))
958
+ const miniAppStatus = describeMiniAppStatus(session)
959
+ const { ok: connectionOk, error: connectionError } = await checkDerivConnection(activeAccount)
960
+
961
+ const lines = []
962
+ if (connectionOk) {
963
+ lines.push('✅ Авторизация активна и подключение к Deriv подтверждено.')
964
+ } else if (miniAppReady) {
965
+ lines.push('✅ Авторизация выполнена, мини-приложение SmartAnalizer уже активно.')
966
+ if (connectionError) {
967
+ console.warn('⚠️ Deriv connection check failed:', connectionError)
968
+ lines.push(`⚠️ Не удалось подтвердить подключение к Deriv со стороны бота: ${connectionError.message || 'неизвестная ошибка.'}`)
969
+ lines.push('Если мини-приложение продолжает работать, дополнительная авторизация не требуется.')
970
+ } else {
971
+ lines.push('⚠️ Не удалось подтвердить подключение к Deriv со стороны бота.')
972
+ }
973
+ } else if (connectionError) {
974
+ console.warn('⚠️ Deriv connection check failed:', connectionError)
975
+ lines.push(`⚠️ Авторизация найдена, но не удалось подтвердить подключение к Deriv: ${connectionError.message || 'неизвестная ошибка.'}`)
976
+ lines.push('Попробуйте заново авторизоваться через «🔐 Авторизация», чтобы восстановить подключение.')
977
+ } else {
978
+ lines.push('⚠️ Авторизация найдена, но не удалось подтвердить подключение к Deriv.')
979
+ lines.push('Попробуйте заново авторизоваться через «🔐 Авторизация», чтобы восстановить подключение.')
980
+ }
981
+
982
+ lines.push(accountInfo)
983
+
984
+ if (miniAppStatus) {
985
+ lines.push(miniAppStatus)
986
+ }
987
+
988
+ const expiresAtText = formatTimestampUtc(session.expires_at)
989
+ if (expiresAtText) {
990
+ lines.push(`⏳ Сессия действует до ${expiresAtText}.`)
991
+ }
992
+
993
+ await sendMessage(chatId,
994
+ lines.join('\n'),
995
+ { replyMarkup: buildReplyKeyboard(getSessionForReply((connectionOk || miniAppReady) ? session : null, subscription), subscription) })
996
+
997
+ if (connectionOk || miniAppReady) {
998
+ await sendAuthorizedAccessLinks(chatId, subscription, session,
999
+ '➡️ Используйте кнопки ниже, чтобы открыть авторизованный SmartAnalizer.')
1000
+ }
1001
+ }
1002
+
1003
+ const handleClearAuthorization = async (chatId, identifiers = [], subscription) => {
1004
+ const targets = Array.from(new Set([
1005
+ ...identifiers,
1006
+ chatId !== undefined && chatId !== null ? String(chatId) : null,
1007
+ ].filter(Boolean)))
1008
+
1009
+ if (!targets.length) {
1010
+ await sendMessage(chatId,
1011
+ 'ℹ️ Активной авторизации не найдено.',
1012
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
1013
+ return
1014
+ }
1015
+
1016
+ let deleted = false
1017
+ let hadError = false
1018
+
1019
+ for (const id of targets) {
1020
+ const result = await deleteSessionSafe(id)
1021
+ if (!result.ok) {
1022
+ hadError = true
1023
+ continue
1024
+ }
1025
+ deleted = deleted || Boolean(result.deleted)
1026
+ }
1027
+
1028
+ if (hadError && !deleted) {
1029
+ await sendMessage(chatId,
1030
+ '❌ Не удалось очистить авторизацию. Попробуйте ещё раз позже.',
1031
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
1032
+ return
1033
+ }
1034
+
1035
+ if (deleted) {
1036
+ await sendMessage(chatId,
1037
+ '🔓 Авторизация удалена. Нажмите «🔐 Авторизация», чтобы подключить Deriv снова.',
1038
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
1039
+ } else {
1040
+ await sendMessage(chatId,
1041
+ 'ℹ️ Активной авторизации не найдено.',
1042
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
1043
+ }
1044
+ }
1045
+
1046
+ const handleBalance = async (chatId, session, sessionError, subscription) => {
1047
+ const allowed = await ensureSubscriptionOrNotify(chatId, subscription,
1048
+ '💰 Просмотр баланса доступен только при активной подписке.')
1049
+ if (!allowed) {
1050
+ return
1051
+ }
1052
+
1053
+ if (sessionError) {
1054
+ await sendMessage(chatId,
1055
+ '⚠️ Не удалось получить данные для проверки баланса. Попробуйте позже.',
1056
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1057
+ return
1058
+ }
1059
+
1060
+ if (!session) {
1061
+ await sendMessage(chatId,
1062
+ '❌ Баланс недоступен. Выполните авторизацию через Deriv.',
1063
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
1064
+ return
1065
+ }
1066
+
1067
+ const account = pickPrimaryAccount(session)
1068
+ if (!account) {
1069
+ await sendMessage(chatId,
1070
+ '❌ Не удалось определить аккаунт Deriv. Выполните авторизацию повторно.',
1071
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1072
+ return
1073
+ }
1074
+
1075
+ try {
1076
+ const response = await withDerivRequest(account.token, { balance: 1 }, 'balance')
1077
+ const balanceData = response?.balance
1078
+ const amountValue = formatAmount(balanceData?.balance)
1079
+ const amount = amountValue !== null ? amountValue : 'недоступен'
1080
+ const currency = balanceData?.currency || account.currency || ''
1081
+ await sendMessage(chatId,
1082
+ `💰 Баланс аккаунта ${account.loginid}: ${amount} ${currency}`.trim(),
1083
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1084
+ } catch (error) {
1085
+ console.error('❌ Failed to fetch Deriv balance:', error)
1086
+ await sendMessage(chatId,
1087
+ `❌ Не удалось получить баланс: ${error.message || 'неизвестная ошибка'}`,
1088
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1089
+ }
1090
+ }
1091
+
1092
+ const handleAccounts = async (chatId, session, sessionError, subscription) => {
1093
+ const allowed = await ensureSubscriptionOrNotify(chatId, subscription,
1094
+ '📂 Просмотр связанных аккаунтов доступен только при активной подписке.')
1095
+ if (!allowed) {
1096
+ return
1097
+ }
1098
+
1099
+ if (sessionError) {
1100
+ await sendMessage(chatId,
1101
+ '⚠️ Не удалось загрузить список аккаунтов. Попробуйте позже.',
1102
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1103
+ return
1104
+ }
1105
+
1106
+ if (!session || !Array.isArray(session.accounts) || !session.accounts.length) {
1107
+ await sendMessage(chatId,
1108
+ '❌ Аккаунты не найдены. Выполните авторизацию через Deriv.',
1109
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1110
+ return
1111
+ }
1112
+
1113
+ const lines = session.accounts.map((account, index) => {
1114
+ const parts = [`${index + 1}. ${account.loginid}`]
1115
+ if (account.currency) parts.push(`валюта: ${account.currency}`)
1116
+ if (account.is_virtual) parts.push('демо')
1117
+ else parts.push('реальный')
1118
+ if (account.account_type) parts.push(`тип: ${account.account_type}`)
1119
+ return parts.join(' — ')
1120
+ })
1121
+
1122
+ await sendMessage(chatId,
1123
+ `📂 Связанные аккаунты Deriv:\n${lines.join('\n')}`,
1124
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1125
+ }
1126
+
1127
+ const formatStatementLine = (transaction) => {
1128
+ const date = transaction?.transaction_time
1129
+ ? new Date(transaction.transaction_time * 1000).toLocaleString('ru-RU')
1130
+ : 'время неизвестно'
1131
+ const action = transaction?.action_type || 'операция'
1132
+ const amountValue = formatAmount(transaction?.amount)
1133
+ const amount = amountValue !== null
1134
+ ? `${amountValue} ${transaction?.currency || ''}`.trim()
1135
+ : 'сумма неизвестна'
1136
+ const description = transaction?.description || ''
1137
+
1138
+ return [`• ${action}`, `сумма: ${amount}`, description ? `описание: ${description}` : null, `время: ${date}`]
1139
+ .filter(Boolean)
1140
+ .join('\n')
1141
+ }
1142
+
1143
+ const handleTrades = async (chatId, session, sessionError, subscription) => {
1144
+ const allowed = await ensureSubscriptionOrNotify(chatId, subscription,
1145
+ '📜 История сделок доступна только при активной подписке.')
1146
+ if (!allowed) {
1147
+ return
1148
+ }
1149
+
1150
+ if (sessionError) {
1151
+ await sendMessage(chatId,
1152
+ '⚠️ Не удалось получить историю сделок. Попробуйте позже.',
1153
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1154
+ return
1155
+ }
1156
+
1157
+ if (!session) {
1158
+ await sendMessage(chatId,
1159
+ '❌ История сделок недоступна. Выполните авторизацию через Deriv.',
1160
+ { replyMarkup: buildReplyKeyboard(null, subscription) })
1161
+ return
1162
+ }
1163
+
1164
+ const account = pickPrimaryAccount(session)
1165
+ if (!account) {
1166
+ await sendMessage(chatId,
1167
+ '❌ Не удалось определить аккаунт Deriv для запроса истории.',
1168
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1169
+ return
1170
+ }
1171
+
1172
+ try {
1173
+ const response = await withDerivRequest(account.token, { statement: 1, limit: 5, description: 1 }, 'statement')
1174
+ const transactions = response?.statement?.transactions
1175
+ if (!Array.isArray(transactions) || !transactions.length) {
1176
+ await sendMessage(chatId,
1177
+ 'ℹ️ За последние операции ничего не найдено.',
1178
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1179
+ return
1180
+ }
1181
+
1182
+ const lines = transactions.map(formatStatementLine)
1183
+ await sendMessage(chatId,
1184
+ `📜 Последние сделки аккаунта ${account.loginid}:\n\n${lines.join('\n\n')}`,
1185
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1186
+ } catch (error) {
1187
+ console.error('❌ Failed to fetch Deriv statement:', error)
1188
+ await sendMessage(chatId,
1189
+ `❌ Не удалось получить историю сделок: ${error.message || 'неизвестная ошибка'}`,
1190
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1191
+ }
1192
+
1193
+ await sendSubscriptionRequired(chatId, subscription, {
1194
+ intro: '🔔 Для доступа к возможностям SmartAnalizer необходимо оформить подписку.',
1195
+ })
1196
+ }
1197
+
1198
+ const handleSubscriptionCheckCommand = async (chatId, userId, session, subscription) => {
1199
+ const latestStatus = await checkUserSubscription({ userId, forceRefresh: true })
1200
+ const message = buildSubscriptionStatusMessage(latestStatus)
1201
+ const replySession = getSessionForReply(session, latestStatus)
1202
+
1203
+ await sendMessage(chatId,
1204
+ message,
1205
+ { replyMarkup: buildReplyKeyboard(replySession, latestStatus) })
1206
+
1207
+ if (!hasActiveSubscription(latestStatus)) {
1208
+ const inlineKeyboard = buildSubscriptionInlineKeyboard(latestStatus)
1209
+ if (inlineKeyboard) {
1210
+ await sendMessage(chatId,
1211
+ 'После оформления подписки нажмите «📦 Проверить подписку», чтобы обновить статус.',
1212
+ { replyMarkup: inlineKeyboard })
1213
+ }
1214
+ }
1215
+ }
1216
+
1217
+ const handleSubscribe = async (chatId, session, subscription) => {
1218
+ if (hasActiveSubscription(subscription)) {
1219
+ await sendMessage(chatId,
1220
+ '✅ Подписка уже активна. Используйте команды ниже для работы.',
1221
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1222
+ return
1223
+ }
1224
+
1225
+ await sendSubscriptionRequired(chatId, subscription, {
1226
+ intro: '🔔 Для доступа к возможностям SmartAnalizer необходимо оформить подписку.',
1227
+ })
1228
+ }
1229
+
1230
+ const handleUnknown = async (chatId, session, subscription, { originalText = null } = {}) => {
1231
+ let reference = originalText
1232
+ if (typeof reference === 'string' && reference.length > 120) {
1233
+ reference = `${reference.slice(0, 117)}…`
1234
+ }
1235
+
1236
+ const details = reference
1237
+ ? `Команда «${reference}» не распознана.`
1238
+ : 'Команда не распознана.'
1239
+
1240
+ await sendMessage(chatId,
1241
+ `⚙️ ${details} Используйте меню, чтобы выбрать действие.`,
1242
+ { replyMarkup: buildReplyKeyboard(getSessionForReply(session, subscription), subscription) })
1243
+ }
1244
+
1245
+ const executeCommand = async (command, {
1246
+ chatId,
1247
+ session,
1248
+ sessionError,
1249
+ subscription,
1250
+ sessionIdentifiers,
1251
+ userId,
1252
+ originalText = null,
1253
+ } = {}) => {
1254
+ if (!command || !chatId) {
1255
+ return
1256
+ }
1257
+
1258
+ switch (command) {
1259
+ case COMMANDS.START:
1260
+ await handleStart(chatId, session, sessionError, subscription)
1261
+ break
1262
+ case COMMANDS.AUTH:
1263
+ await handleAuthorization(chatId, session, sessionError, subscription)
1264
+ break
1265
+ case COMMANDS.CHECK:
1266
+ await handleConnectionCheck(chatId, session, sessionError, subscription)
1267
+ break
1268
+ case COMMANDS.CLEAR:
1269
+ await handleClearAuthorization(chatId, sessionIdentifiers, subscription)
1270
+ break
1271
+ case COMMANDS.BALANCE:
1272
+ await handleBalance(chatId, session, sessionError, subscription)
1273
+ break
1274
+ case COMMANDS.ACCOUNTS:
1275
+ await handleAccounts(chatId, session, sessionError, subscription)
1276
+ break
1277
+ case COMMANDS.TRADES:
1278
+ await handleTrades(chatId, session, sessionError, subscription)
1279
+ break
1280
+ case COMMANDS.SUBSCRIPTION_STATUS:
1281
+ await handleSubscriptionCheckCommand(chatId, userId || chatId, session, subscription)
1282
+ break
1283
+ case COMMANDS.SUBSCRIBE:
1284
+ await handleSubscribe(chatId, session, subscription)
1285
+ break
1286
+ default:
1287
+ await handleUnknown(chatId, session, subscription, { originalText })
1288
+ break
1289
+ }
1290
+ }
1291
+
1292
+ const processStartFollowUp = async (startPayload, context) => {
1293
+ if (!startPayload) {
1294
+ return
1295
+ }
1296
+
1297
+ const info = interpretStartPayload(startPayload)
1298
+ if (!info || !info.command || info.command === COMMANDS.START) {
1299
+ return
1300
+ }
1301
+
1302
+ await executeCommand(info.command, {
1303
+ ...context,
1304
+ originalText: info.payload || startPayload,
1305
+ })
1306
+ }
1307
+
1308
+ export default async function webhookHandler(req, res) {
1309
+ try {
1310
+ if (req.method !== 'POST') {
1311
+ return res.status(405).json({ ok: false, error: 'Method Not Allowed' })
1312
+ }
1313
+
1314
+ const body = req.body
1315
+
1316
+ if (!body || !body.message) {
1317
+ console.log('⚠️ Empty Telegram payload:', body)
1318
+ return res.status(200).json({ ok: true })
1319
+ }
1320
+
1321
+ const chatId = body.message.chat?.id
1322
+ const userId = body.message.from?.id
1323
+ const text = body.message.text?.trim() || ''
1324
+
1325
+ if (!chatId || !text) {
1326
+ console.log('⚠️ Unsupported Telegram message:', body.message)
1327
+ return res.status(200).json({ ok: true })
1328
+ }
1329
+
1330
+ console.log(`📩 Message from ${chatId}: ${text}`)
1331
+
1332
+ const { command, startPayload } = extractCommandFromText(text)
1333
+ const { session, sessionError, identifiers: sessionIdentifiers } = await resolveSessionForIds([chatId, userId])
1334
+ const subscription = await checkUserSubscription({
1335
+ userId : userId || chatId,
1336
+ forceRefresh : command === COMMANDS.START,
1337
+ })
1338
+
1339
+ const context = {
1340
+ chatId,
1341
+ session,
1342
+ sessionError,
1343
+ subscription,
1344
+ sessionIdentifiers,
1345
+ userId,
1346
+ originalText: text,
1347
+ }
1348
+
1349
+ await executeCommand(command, context)
1350
+
1351
+ if (command === COMMANDS.START && startPayload) {
1352
+ await processStartFollowUp(startPayload, { ...context, originalText: startPayload })
1353
+ }
1354
+
1355
+ return res.status(200).json({ ok: true })
1356
+
1357
+ } catch (err) {
1358
+ console.error('❌ Telegram webhook error:', err)
1359
+ return res.status(500).json({ ok: false, error: String(err) })
1360
+ }
1361
+ }