Compare commits

...
Author SHA1 Message Date
Superalgos Bot a55a9d811f Changes in User Profile done by Profile Owner Luis-Fernando-Molina automatically merged by Superalgos.
Contribution: Teams Weight Voting
2021-12-05 20:04:38 +01:00
Luis Fernando Molina d639fde539 Teams Weight Voting 2021-12-05 20:03:57 +01:00
Superalgos Bot b4b68df0ae Changes in User Profile done by Profile Owner PLuv automatically merged by Superalgos.
User-Profile - Day 3
2021-12-05 19:50:38 +01:00
Philip Love 981b6406c0 User-Profile - Day 3 2021-12-05 13:48:46 -05:00
Luis Fernando Molina 5e199cfa0b Merge pull request #2913 from Luis-Fernando-Molina/develop
Contribution: Revert Bug Fix of side panels because it disables the workspace panel
2021-12-05 14:01:29 -04:00
Luis Fernando Molina 6eb6d385a4 Revert "Give Side Space precedence on mouse click"
This reverts commit bb43bedd1b.
2021-12-05 19:00:04 +01:00
Luis Fernando Molina 39d402049c Merge pull request #2912 from Luis-Fernando-Molina/develop
Contribution: Signal sent from Task reaching the P2P Network
2021-12-05 13:51:57 -04:00
Luis Fernando Molina 9cf78dc536 Signal sent from Task reaching the P2P Network 2021-12-05 18:51:00 +01:00
Luis Fernando Molina fb93911abd Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-05 18:44:21 +01:00
Luis Fernando Molina 49e665774b Merge pull request #2908 from whtv/develop
Give Side Space precedence on mouse click
2021-12-05 13:35:05 -04:00
Luis Fernando Molina 25eda48a3e Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-05 18:23:01 +01:00
Luis Fernando Molina 83121a9276 Removing Comments 2021-12-05 17:57:35 +01:00
Luis Fernando Molina 28216a08d0 axios working 2021-12-05 17:46:31 +01:00
Superalgos Bot c684505ebf Changes in User Profile done by Profile Owner prepheadrus automatically merged by Superalgos.
Contribution: Position votes
2021-12-05 15:51:36 +01:00
prepheadrus 07a15f62bc Contribution: Position votes 2021-12-05 17:50:36 +03:00
Superalgos Bot 33d2011a27 Changes in User Profile done by Profile Owner harrellbm automatically merged by Superalgos.
Update weights
2021-12-05 14:23:36 +01:00
harrellbm 3548df523b Update weights 2021-12-05 07:23:21 -06:00
Superalgos Bot e7d8be2a22 Changes in User Profile done by Profile Owner julian-molina automatically merged by Superalgos.
Contribution: Position votes
2021-12-05 14:01:35 +01:00
Julian Molina ce833e16c2 Position votes 2021-12-05 14:00:53 +01:00
whtv bb43bedd1b Give Side Space precedence on mouse click 2021-12-05 13:38:47 +01:00
Julian Molina 78c5a4d7bf Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-05 13:28:07 +01:00
Julian Molina 0029c4c6d2 Merge pull request #2885 from julian-molina/develop
Contribution: Profile weight votes
2021-12-05 13:27:36 +01:00
Superalgos Bot 243948cf49 Changes in User Profile done by Profile Owner buddies2705 automatically merged by Superalgos.
Contribution: profile update
2021-12-05 13:25:35 +01:00
Guarav Agrawal f5b7cda053 profile update 2021-12-05 17:47:27 +05:30
Superalgos Bot c41fc95f00 Changes in User Profile done by Profile Owner prepheadrus automatically merged by Superalgos.
Update User Profile prepheadrus
2021-12-05 13:04:34 +01:00
prepheadrus e83805b300 Update User Profile prepheadrus 2021-12-05 15:04:16 +03:00
Superalgos Bot 72672dfcdf Changes in User Profile done by Profile Owner whtv automatically merged by Superalgos.
Weight votes
2021-12-05 12:57:34 +01:00
whtv 01ebdeece7 Weight votes 2021-12-05 12:56:31 +01:00
Julian Molina 3804b350b0 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-05 12:00:23 +01:00
Luis Fernando Molina a90c8256ac Signal Sent via HTTP 2021-12-05 11:41:37 +01:00
Luis Fernando Molina cbb1de0747 Waiting for Trading Session to be ran 2021-12-05 11:21:04 +01:00
Superalgos Bot 31c13515f0 Changes in User Profile done by Profile Owner end-debug automatically merged by Superalgos.
Update end-debug.json
2021-12-05 11:08:34 +01:00
SIFISO KHUMALO e26c21ec6a Update end-debug.json 2021-12-05 12:06:23 +02:00
Luis Fernando Molina 4f4539934c Ready to Debug 2021-12-05 10:57:27 +01:00
Luis Fernando Molina 65a141da5c Some refactoring and comments added to code 2021-12-05 10:36:41 +01:00
Luis Fernando Molina 22317a454d Merge pull request #2884 from whtv/develop
Fix dragging nodes out of bounds
2021-12-05 03:50:14 -04:00
Luis Fernando Molina e620174fa1 File name too long 2021-12-05 08:31:41 +01:00
Luis Fernando Molina 49d33649df Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-05 08:29:34 +01:00
Superalgos Bot 9fbf37481b Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-05 03:30:30 +01:00
cozed-gh 0cea547c4f User-Profile cozed-gh 2021-12-05 03:30:12 +01:00
Superalgos Bot 6e251f7173 Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-05 02:59:30 +01:00
cozed-gh ef91cf73a8 User-Profile cozed-gh 2021-12-05 02:59:22 +01:00
Superalgos Bot fad5d9842f Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-05 02:28:29 +01:00
cozed-gh 9f26001bc8 User-Profile cozed-gh 2021-12-05 02:27:57 +01:00
Julian Molina bcb9781035 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-04 23:38:28 +01:00
Superalgos Bot 70189e5d59 Changes in User Profile done by Profile Owner PLuv automatically merged by Superalgos.
User-Profile - Day 2 - Round 2
2021-12-04 20:05:26 +01:00
Philip Love e40d3d1b04 User-Profile - Day 2 - Round 2 2021-12-04 14:04:14 -05:00
Luis Fernando Molina a5ab8472a9 P2P Network Head 2021-12-04 18:20:25 +01:00
Luis Fernando Molina f2bdfb14c9 HttpNetworkClient 2021-12-04 17:55:23 +01:00
Julian Molina b4e0bfae0a Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-04 17:12:31 +01:00
whtv 2c13f6dcb3 Fix dragging nodes out of bounds 2021-12-04 16:23:23 +01:00
Superalgos Bot cd8b0e7093 Changes in User Profile done by Profile Owner Raplh2502 automatically merged by Superalgos.
Contribution: profile update
2021-12-04 16:05:24 +01:00
Raplh2502 250ce9b4c4 profile update 2021-12-04 16:04:02 +01:00
Superalgos Bot 334233b8b4 Changes in User Profile done by Profile Owner julian-molina automatically merged by Superalgos.
Contribution: Pool and position votes
2021-12-04 14:06:24 +01:00
Julian Molina b2d7d9d14d Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-04 14:06:16 +01:00
Julian Molina 5603603668 This is my contribution to Superalgos 2021-12-04 14:05:31 +01:00
Superalgos Bot 74c946175b Changes in User Profile done by Profile Owner end-debug automatically merged by Superalgos.
Contribution: This is my contribution to Superalgos
2021-12-04 13:30:23 +01:00
SIFISO KHUMALO 915e66bd59 This is my contribution to Superalgos 2021-12-04 14:29:56 +02:00
Julian Molina 9b741d7ec0 Merge pull request #2880 from julian-molina/develop
Contribution: Index file message
2021-12-04 13:06:11 +01:00
Julian Molina 561379dac2 Index file message 2021-12-04 12:49:43 +01:00
Superalgos Bot 3074dfd9ae Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-03 22:41:03 +01:00
Superalgos Bot 1bfd5c9ff9 Changes in User Profile done by Profile Owner prepheadrus automatically merged by Superalgos.
Update prepheadrus.json
2021-12-03 22:40:58 +01:00
Superalgos Bot 22a45b74e4 Changes in User Profile done by Profile Owner NAmorim automatically merged by Superalgos.
User Profile: Team pool voting
2021-12-03 22:40:54 +01:00
Superalgos Bot 0ea255a2a3 Changes in User Profile done by Profile Owner harrellbm automatically merged by Superalgos.
Position Weight Votes
2021-12-03 22:40:40 +01:00
Superalgos Bot 2d67fb19aa Changes in User Profile done by Profile Owner whtv automatically merged by Superalgos.
Position weights vote
2021-12-03 22:40:35 +01:00
Superalgos Bot 229d704bb1 Changes in User Profile done by Profile Owner alexandrustefan automatically merged by Superalgos.
alexandrustefan position voting
2021-12-03 22:40:30 +01:00
Superalgos Bot 3a77f3c766 Changes in User Profile done by Profile Owner julian-molina automatically merged by Superalgos.
Contribution: Position weight votes
2021-12-03 22:40:26 +01:00
Superalgos Bot 7dee9083bf Changes in User Profile done by Profile Owner Raplh2502 automatically merged by Superalgos.
Contribution: profile update
2021-12-03 22:40:21 +01:00
Luis Fernando Molina 0c27d7d9bd Merge pull request #2878 from Luis-Fernando-Molina/develop
Contribution: Governance Workspace Fixed
2021-12-03 17:39:30 -04:00
Luis Fernando Molina 0ea1c5b379 Governance Workspace Fixed 2021-12-03 22:39:08 +01:00
Luis Fernando Molina f4c4fc430b Merge pull request #2876 from Luis-Fernando-Molina/develop
Contribution: BUG FIX: Negative Percentage Enabled Creating Token Power
2021-12-03 17:12:21 -04:00
Luis Fernando Molina 38706a4615 Deep Scan Bug Fixes 2021-12-03 22:02:16 +01:00
Luis Fernando Molina c6f34e97e1 Deep Scan Bug Fixes 2021-12-03 21:52:18 +01:00
Luis Fernando Molina babc2e0a42 Deep Scan Bug Fixes 2021-12-03 21:51:21 +01:00
Luis Fernando Molina b83801cd1d BUG FIX: Negative Percentage Enabled Creating Token Power 2021-12-03 21:47:01 +01:00
Raplh2502 ab4c934b26 profile update 2021-12-03 21:18:14 +01:00
Julian Molina 6b74a02b30 Position weight votes 2021-12-03 21:14:40 +01:00
Alexandru Stefan cdb1f790c6 alexandrustefa team voting 2021-12-03 19:55:04 +00:00
whtv b4bf7ee4d1 Position weight vote 2021-12-03 18:52:02 +01:00
Brenden Harrell d7a9ee6fd1 Position Weight Votes 2021-12-03 10:43:18 -07:00
NAmorim 5d97e97a02 User Profile: Team pool voting 2021-12-03 14:23:22 +00:00
prepheadrus 46ab81d988 Update prepheadrus.json 2021-12-03 14:08:14 +03:00
cozed-gh 986a709b06 User-Profile cozed-gh 2021-12-03 12:04:53 +01:00
Superalgos Bot eaab261be9 Changes in User Profile done by Profile Owner prepheadrus automatically merged by Superalgos.
Update prepheadrus.json
2021-12-03 10:37:55 +01:00
prepheadrus b5920e7d76 Update prepheadrus.json 2021-12-03 12:37:21 +03:00
Superalgos Bot 9cebcace5a Changes in User Profile done by Profile Owner prepheadrus automatically merged by Superalgos.
Contribution: This is my contribution to Superalgos
2021-12-03 10:08:55 +01:00
prepheadrus 5497d301ef This is my contribution to Superalgos 2021-12-03 12:07:52 +03:00
Luis Fernando Molina b47f852c7f Merge pull request #2819 from DJ05GaZ/develop
Develop
2021-12-03 04:28:53 -04:00
Luis Fernando Molina 05681171df Merge pull request #2833 from maxah/develop
Contribution: 'Docs in Russian - Docs Basics - complete'
2021-12-03 04:28:10 -04:00
Luis Fernando Molina 1cb463b85f Merge pull request #2847 from gitforkgit/develop
Contribution: (quick fix)
2021-12-03 04:22:32 -04:00
Luis Fernando Molina 8ba6ef7870 Merge pull request #2854 from Neobii/develop
Contribution: "spelling check in comments for platform and network folders"
2021-12-03 04:21:04 -04:00
Superalgos Bot 80ddb1fd5f Changes in User Profile done by Profile Owner BlaaSwe automatically merged by Superalgos.
Contribution: User Profile BlaaSwe
2021-12-03 07:05:54 +01:00
BlaaSwe f9010b3041 User Profile BlaaSwe 2021-12-03 07:03:51 +01:00
BlaaSwe 5382f56c89 User Profile BlaaSwe 2021-12-03 06:57:55 +01:00
BlaaSwe ab80400e05 User Profile BlaaSwe 2021-12-03 06:47:27 +01:00
BlaaSwe 2807a9a019 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-03 06:45:58 +01:00
Neobii f212f570b5 "spelling check in comments for platform and network folders" 2021-12-02 23:45:50 -06:00
Superalgos Bot 6d84915363 Changes in User Profile done by Profile Owner Neobii automatically merged by Superalgos.
Contribution: This is my contribution to Superalgos
2021-12-03 06:10:53 +01:00
Neobii 725c1bf71e This is my contribution to Superalgos 2021-12-02 23:09:58 -06:00
Superalgos Bot e4f3dfc970 Changes in User Profile done by Profile Owner Neobii automatically merged by Superalgos.
Contribution: This is my contribution to Superalgos
2021-12-03 03:00:51 +01:00
Neobii b5253a6bc0 This is my contribution to Superalgos 2021-12-02 20:00:28 -06:00
Superalgos Bot edc2939d62 Changes in User Profile done by Profile Owner piyanthak automatically merged by Superalgos.
user profile
2021-12-03 00:50:50 +01:00
piyanthak 6c66ad4264 user profile 2021-12-03 05:19:57 +05:30
gitforkgit be12ca902a (another small thing) 2021-12-03 00:21:07 +01:00
Superalgos Bot 532336c95f Changes in User Profile done by Profile Owner gustavohcorradi automatically merged by Superalgos.
Contribution: testing delegation
2021-12-03 00:17:50 +01:00
gustavohcorradi 4760951963 testing delegation 2021-12-03 00:17:16 +01:00
gitforkgit 49170e8ba4 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-03 00:09:15 +01:00
gitforkgit 51cb76965a (quick fix) 2021-12-03 00:08:23 +01:00
B Harrell 5d8d8fda64 Merge pull request #2844 from gitforkgit/develop 2021-12-02 16:55:13 -06:00
gitforkgit 901155057d (revived a link in: "How to contribute icons") 2021-12-02 23:52:49 +01:00
Superalgos Bot e7cc80f9c6 Changes in User Profile done by Profile Owner superharoun automatically merged by Superalgos.
November 2021 Token Distribution
2021-12-02 23:22:51 +01:00
Haroun 19214d2c92 Merge branch 'Superalgos:develop' into develop 2021-12-02 23:20:31 +01:00
Superalgos Bot b3f8dc4f39 Changes in User Profile done by Profile Owner gitforkgit automatically merged by Superalgos.
Contribution: (user profile gitforkgit)#
2021-12-02 23:15:50 +01:00
gitforkgit c27e0498e3 (user profile gitforkgit)# 2021-12-02 23:15:19 +01:00
Haroun f90b9a192c November 2021 Token Distribution 2021-12-02 23:09:20 +01:00
Superalgos Bot 4783c97432 Changes in User Profile done by Profile Owner Raplh2502 automatically merged by Superalgos.
Contribution: profile update
2021-12-02 22:49:50 +01:00
Raplh2502 c47bb6dc12 profile update 2021-12-02 22:48:28 +01:00
Superalgos Bot 5599962713 Changes in User Profile done by Profile Owner julian-molina automatically merged by Superalgos.
Contribution: Profile pools weight votes
2021-12-02 22:32:49 +01:00
Julian Molina 82d82a7487 Profile pools weight votes 2021-12-02 22:32:04 +01:00
BlaaSwe 4628e4d51d User Profile BlaaSwe 2021-12-02 22:24:56 +01:00
BlaaSwe b19a3e8a2a user profile BlaaSwe 2021-12-02 22:17:15 +01:00
Superalgos Bot 1ca7c2f734 Changes in User Profile done by Profile Owner whtv automatically merged by Superalgos.
Weight votes on pools
2021-12-02 22:10:49 +01:00
whtv 1a17308ebc Weight votes on pools 2021-12-02 22:06:05 +01:00
Luis Fernando Molina bb3ee67256 Merge pull request #2836 from Luis-Fernando-Molina/develop
Contribution: Pool Voting + Positions Final Version
2021-12-02 16:57:57 -04:00
Luis Fernando Molina e2c19a5c3f Pool Voting + Positions Final Version 2021-12-02 21:57:46 +01:00
Superalgos Bot 6f3a254a52 Changes in User Profile done by Profile Owner alexst90 automatically merged by Superalgos.
Contribution: userprofile alexst90
2021-12-02 20:56:49 +01:00
alexst90 58d0f59832 create user profile 2021-12-02 21:56:31 +02:00
Superalgos Bot 13947616f2 Changes in User Profile done by Profile Owner edwardsjohn automatically merged by Superalgos.
User profile edwardsjohn
2021-12-02 19:32:48 +01:00
edwardsjohn 933b58e2e5 User profile edwardsjohn 2021-12-03 00:01:17 +05:30
maxah e882e4aa17 'Docs in Russian - Docs Basics - complete' 2021-12-02 20:47:29 +03:00
Superalgos Bot 48ead9b9fc Changes in User Profile done by Profile Owner PLuv automatically merged by Superalgos.
User-Profile Day 1
2021-12-02 18:27:47 +01:00
Philip Love 9f7ee32765 User-Profile Day 1 2021-12-02 12:26:46 -05:00
Superalgos Bot d34d8125c5 Changes in User Profile done by Profile Owner PLuv automatically merged by Superalgos.
User-Profile Update - Day 1
2021-12-02 18:09:47 +01:00
Philip Love 64f3832257 User-Profile Update - Day 1 2021-12-02 12:09:23 -05:00
Superalgos Bot 71cf4c580f Changes in User Profile done by Profile Owner harrellbm automatically merged by Superalgos.
Profile Update
2021-12-02 16:28:46 +01:00
harrellbm e4f46da8f9 Finished pool weight votes (for now lol) 2021-12-02 09:27:57 -06:00
Superalgos Bot acad839530 Changes in User Profile done by Profile Owner PLuv automatically merged by Superalgos.
User-Profile Update
2021-12-02 15:55:46 +01:00
Philip Love 46f06c8da1 User-Profile Update 2021-12-02 09:54:53 -05:00
harrellbm 9205cd7410 Profile Update 2021-12-02 08:24:02 -06:00
maxah 770383635f Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-02 17:11:51 +03:00
Luis Fernando Molina 6c6ab09596 Merge pull request #2828 from Luis-Fernando-Molina/develop
Contribution: 2 More Teams added / updated
2021-12-02 10:10:31 -04:00
Luis Fernando Molina 5e5eb236f1 2 More Teams added / updated 2021-12-02 15:09:52 +01:00
B Harrell 3f4609d2a2 Merge pull request #2784 from maxah/develop
This looks good to go!
Contribution: This is my contribution to Superalgos
2021-12-02 07:56:05 -06:00
Superalgos Bot fb119ec3a3 Changes in User Profile done by Profile Owner NAmorim automatically merged by Superalgos.
User Profile: Weight votes
2021-12-02 14:49:51 +01:00
Superalgos Bot 2589171a3e Changes in User Profile done by Profile Owner Tentacule23 automatically merged by Superalgos.
Contribution: Profile Tentacule23
2021-12-02 14:49:46 +01:00
Tentacule23 1b65ead4be Profile Tentacule23 2021-12-02 08:49:14 -05:00
Nuno Amorim eebe11c094 Merge branch 'Superalgos:develop' into develop 2021-12-02 13:48:04 +00:00
NAmorim 88164a3e93 User Profile - Weight votes 2021-12-02 13:47:38 +00:00
Superalgos Bot 5292bbecf6 Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-02 14:20:46 +01:00
cozed-gh e9e780a3ce User-Profile cozed-gh 2021-12-02 14:20:31 +01:00
Superalgos Bot b796fd2581 Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-02 14:06:45 +01:00
cozed-gh e3415ca597 User-Profile cozed-gh 2021-12-02 14:05:43 +01:00
Superalgos Bot a02d7a2553 Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-02 14:01:46 +01:00
cozed-gh 0f1b6b083b User-Profile cozed-gh 2021-12-02 14:01:36 +01:00
Superalgos Bot c8e1090610 Changes in User Profile done by Profile Owner julian-molina automatically merged by Superalgos.
Contribution: Profile pools weight votes
2021-12-02 13:46:45 +01:00
Julian Molina ddb5cec68b Profile pools weight votes 2021-12-02 13:45:39 +01:00
Superalgos Bot bd3536ffb9 Changes in User Profile done by Profile Owner alexandrustefan automatically merged by Superalgos.
alexandrustefan pool voting
2021-12-02 13:00:45 +01:00
Alexandru Stefan d41c1ee841 alexandrustefan pool voting 2021-12-02 11:57:22 +00:00
DJ05GaZ ce1d11b55a Merge branch 'Superalgos:develop' into develop 2021-12-02 10:19:18 +00:00
Luis Fernando Molina 6f38d7cb1c Merge pull request #2817 from Luis-Fernando-Molina/develop
Contribution: Positions / Teams ready for voting
2021-12-02 05:15:30 -04:00
Luis Fernando Molina 1d364a3cc1 Positions / Teams ready for voting 2021-12-02 10:15:08 +01:00
Luis Fernando Molina f3eae752e7 Merge pull request #2813 from PLuv/develop
Portfolio-Management PR - Ready for Next Steps
2021-12-02 03:58:41 -04:00
Luis Fernando Molina f44fdf84f8 Merge pull request #2816 from Smidy13/develop
Bug Fix: isLoading Parameter Not Set Correctly For Workspace Switch
2021-12-02 03:58:24 -04:00
Smidy13 044b0cd9c4 Bug Fix: isLoading Parameter Not Set Correctly For Workspace Switch 2021-12-02 20:45:30 +13:00
Superalgos Bot 052d173ca1 Changes in User Profile done by Profile Owner Smidy13 automatically merged by Superalgos.
Profile: Smidy13 Profile Weight Votes
2021-12-02 08:22:20 +01:00
Smidy13 c412be02c8 Profile: Smidy13 Profile Weight Votes 2021-12-02 20:19:08 +13:00
maxah daf931a5c1 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-02 08:08:56 +03:00
Superalgos Bot f48db81990 Changes in User Profile done by Profile Owner ssplatt automatically merged by Superalgos.
update ssplatt profile
2021-12-02 04:41:18 +01:00
ssplatt 968dc9d8d7 update ssplatt profile 2021-12-01 22:39:28 -05:00
Philip Love 1ce0be81c7 PM TaskServer plumbing 2021-12-01 22:33:17 -05:00
Philip Love c325df7d21 Update to Portfolio-Management-Demo Workspace 2021-12-01 22:32:17 -05:00
Philip Love 77ec0a7fa6 PM Schema Modifications 2021-12-01 22:31:39 -05:00
Philip Love d991d3c6d8 Merge remote-tracking branch 'upstream/develop' into develop 2021-12-01 22:20:54 -05:00
Superalgos Bot 330a4419da Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-01 22:58:16 +01:00
cozed-gh eec316ef37 User-Profile cozed-gh 2021-12-01 22:57:20 +01:00
Superalgos Bot 6c83ccf15f Changes in User Profile done by Profile Owner EvaMaria70 automatically merged by Superalgos.
Contribution: This is my contribution to Superalgos
2021-12-01 22:11:15 +01:00
EvaMaria70 ab57e73c85 This is my contribution to Superalgos 2021-12-01 22:10:44 +01:00
Superalgos Bot 939365f7f4 Changes in User Profile done by Profile Owner Tentacule23 automatically merged by Superalgos.
Contribution: userprofile Tentacule23
2021-12-01 21:37:46 +01:00
Tentacule23 b32831853a userprofile Tentacule23 2021-12-01 15:36:58 -05:00
Luis Fernando Molina 2d8b1a472c Merge pull request #2806 from Loui-Molina/develop
Add an initial implementation of the desktop app migrated to react and using express as middleware to the network
2021-12-01 16:09:24 -04:00
Loui Molina 34bd7d3456 Merge branch 'Superalgos:develop' into develop 2021-12-01 12:06:08 -08:00
Axel bae4a48ed2 Update Routes 2021-12-01 16:28:32 -03:00
Axel fe4e66a405 Re-add social trading interfaces 2021-12-01 16:16:53 -03:00
Luis Fernando Molina 5173efe21d Merge pull request #2795 from Neobii/develop
Contribution: This is my contribution to Superalgos
2021-12-01 15:15:27 -04:00
Luis Fernando Molina e94dc8f0bc Merge pull request #2796 from liteir/develop
my contribution to superalgos
2021-12-01 15:12:49 -04:00
Luis Fernando Molina edcfba0948 Merge pull request #2769 from mx57/develop
Translation into Russian Chapter XI tutorial docs steps 10-20
2021-12-01 14:40:24 -04:00
Axel dbc0bda0d2 Add desktop react start script to package.json 2021-12-01 15:39:10 -03:00
Axel 69a6d0c684 Merge remote-tracking branch 'superalgos/develop' into develop 2021-12-01 15:34:11 -03:00
Axel 38f7164dca Rename project to allow previously existing desktop to coexist 2021-12-01 15:33:44 -03:00
Superalgos Bot b25d7ed939 Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User Profile cozed-gh
2021-12-01 18:41:45 +01:00
cozed-gh 8cc4873063 User Profile cozed-gh 2021-12-01 18:41:31 +01:00
Superalgos Bot 9c416977cc Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User Profile cozed-gh
2021-12-01 18:21:45 +01:00
cozed-gh df26b33c79 User Profile cozed-gh 2021-12-01 18:21:11 +01:00
maxah ccf61b13f5 'Docs in Russian - Chapter III - 5-Testing Trading Tasks Section' 2021-12-01 20:02:52 +03:00
Philip Love 7e29e89eec updating p-m events-formulas schemas 2021-12-01 11:43:48 -05:00
DJ05GaZ 5163f1cee0 Add files via upload 2021-12-01 16:31:17 +00:00
Neobii 7427253fb3 This is my contribution to Superalgos 2021-12-01 09:54:18 -06:00
Neobii 7f4ee3df34 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-01 09:51:08 -06:00
Superalgos Bot b56e857c8f Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-01 16:27:44 +01:00
cozed-gh a3f6bc8bc4 User-Profile cozed-gh 2021-12-01 16:27:00 +01:00
Neobii f1833b6ba5 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-12-01 09:26:46 -06:00
Superalgos Bot 89d5e93f0e Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-01 15:00:43 +01:00
cozed-gh a7af71f158 User-Profile cozed-gh 2021-12-01 15:00:24 +01:00
maxah a64801809a 'Docs in Russian - Chapter III - 3-Indicator and Sensor Bot Instances' 2021-12-01 16:51:20 +03:00
Superalgos Bot 0ef5b9635e Changes in User Profile done by Profile Owner cozed-gh automatically merged by Superalgos.
Contribution: User-Profile cozed-gh
2021-12-01 13:36:42 +01:00
cozed-gh 7cf8719d3f User-Profile cozed-gh 2021-12-01 13:36:17 +01:00
maxah 285387f39a 'Docs in Russian - Chapter III - 2-Organization of Tasks, 3-Data Tasks Section' 2021-12-01 15:10:34 +03:00
maxah adc9f2d49d 'Docs in Russian - Chapter III - 1 -LAN Network Hierarchy' 2021-12-01 14:03:50 +03:00
maxah cc9d943769 'Docs in Russian - Chapter II - Design Space - complete' 2021-12-01 13:07:59 +03:00
Luis Fernando Molina c3aaf097fc Merge pull request #2798 from Luis-Fernando-Molina/develop
Contribution: Bugs Fixes + Save Plugin
2021-12-01 05:34:16 -04:00
Luis Fernando Molina 69f78d5f76 Bugs Fixes + Save Plugin 2021-12-01 10:34:04 +01:00
Luis Fernando Molina a69c8cb53c Bug Fixes + Saving Plugins 2021-12-01 10:31:48 +01:00
maxah b96b5476cd 'Docs in Russian - Chapter I - Introduction - complete' 2021-12-01 11:43:31 +03:00
Luis Fernando Molina 708024605b Merge pull request #2797 from Luis-Fernando-Molina/develop
Contribution: Token-Distribution-Superalgos Plugin Workspace for next Distribution
2021-12-01 03:46:08 -04:00
Luis Fernando Molina b495a0142a Token-Distribution-Superalgos Plugin Workspace for next Distribution 2021-12-01 08:45:54 +01:00
Luis Fernando Molina 4c85b86231 Bug fixes 2021-12-01 08:36:30 +01:00
liteir e46c37c7a2 my contribution to superalgos 2021-12-01 00:07:49 -06:00
Neobii 35e1d8c2eb Fixed typo as per https://youtu.be/NsSYH0TZzys 2021-11-30 21:02:37 -06:00
Loui Molina 2832cd657b Delete Loui-Molina.json 2021-11-30 20:09:34 -03:00
Loui Molina 00bdb0bf55 remove user profile 2021-11-30 20:06:19 -03:00
Loui Molina 8b4b2ecb18 Remove user profile 2021-11-30 20:01:31 -03:00
Loui Molina d2c15d88d7 Merge remote-tracking branch 'superalgos/develop' into develop 2021-11-30 19:53:35 -03:00
Loui Molina 04343af119 Add follow and unfollow functionality to desktop server 2021-11-30 19:52:04 -03:00
Loui Molina e771458a32 Add error handling to desktop server
Change desktop paths
refactor desktop file structure
move WebApp functionalities to express server
Remove unused interfaces
2021-11-30 19:30:58 -03:00
Superalgos Bot 733cd009aa Changes in User Profile done by Profile Owner CoffeeNights09 automatically merged by Superalgos.
User Profile CoffeeNights09
2021-11-30 23:14:06 +01:00
CoffeeNights09 91ce33f075 User Profile CoffeeNights09 2021-11-30 23:46:58 +02:00
maxah 0f451562a3 'Docs in Russian - Docs-Concepts - U' 2021-11-30 22:24:03 +03:00
maxah e99bae6b62 'Docs in Russian - Docs-Concepts - S,T' 2021-11-30 22:17:10 +03:00
maxah cfbf99befa 'Docs in Russian - Docs-Concepts - O,P,R' 2021-11-30 21:17:32 +03:00
Axel c600f77b84 Refactor frontend
Add express server for desktop backend
2021-11-30 14:33:37 -03:00
maxah cbe390f0ba 'Docs in Russian - Docs-Concepts - L,M,N' 2021-11-30 18:35:57 +03:00
maxah b689983799 Merge branch 'develop' of https://github.com/maxah/Superalgos into develop 2021-11-30 18:10:37 +03:00
maxah 8cf817342d 'Docs in Russian - Docs-Concepts - E,F,I' 2021-11-30 18:04:25 +03:00
Raidho 0e5ab4fc9c Merge branch 'develop' into develop 2021-11-30 18:02:56 +03:00
B Harrell 3216188a7e Merge pull request #2786 from harrellbm/develop
Update Readme title
2021-11-30 08:44:06 -06:00
maxah f2369f10e9 'Docs in Russian - Docs-Concepts - D' 2021-11-30 17:37:23 +03:00
B Harrell 03283c3746 Update table of contents 2021-11-30 08:35:32 -06:00
B Harrell af860e0084 Update title to "Contributors Installation" 2021-11-30 08:34:11 -06:00
B Harrell 2e6e2815d6 Merge pull request #2751 from gitforkgit/develop
Contribution: (Translation into german: rest of "Trading Farms - Set Up a Network of Nodes")
2021-11-30 08:24:10 -06:00
gitforkgit 9ba5cb776c (It shoould work now) 2021-11-30 15:21:50 +01:00
gitforkgit cb592731c5 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-30 15:21:38 +01:00
maxah 82f1f64d65 'Docs in Russian - Docs-Concepts - B,C' 2021-11-30 17:12:17 +03:00
maxah a7adaa8abd 'Docs in Russian - Docs-Concepts - A' 2021-11-30 16:53:37 +03:00
Superalgos Bot ce49da77ac Changes in User Profile done by Profile Owner MatthewDin automatically merged by Superalgos.
user profile MatthewDin
2021-11-30 12:51:01 +01:00
MatthewDin 0e8bc6b0e1 user profile MatthewDin 2021-11-30 17:20:02 +05:30
gitforkgit 2f95b6e7c8 (now it should work) 2021-11-30 11:14:58 +01:00
gitforkgit 762517f448 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-30 11:14:26 +01:00
maxah 201dd62c81 Merge branch 'translated-2' into develop 2021-11-30 13:00:54 +03:00
maxah f6ea959c01 Squashed commit of the following:
commit 7590fd7418
Author: maxah <maxah84@gmail.com>
Date:   Fri Nov 26 21:35:08 2021 +0300

    'Docs in Russian - part 1'
2021-11-30 12:51:58 +03:00
Luis Fernando Molina 1d71efeccc Merge pull request #2768 from maxah/develop
Contribution: This is my contribution to Superalgos
2021-11-30 05:25:48 -04:00
Luis Fernando Molina 93310265a2 Merge pull request #2764 from liteir/develop
Contribution: Updates to Kucoin
2021-11-30 05:24:30 -04:00
Luis Fernando Molina 3803169987 Merge pull request #2781 from NAmorim/develop
Update README for packaged apps
2021-11-30 05:23:30 -04:00
Superalgos Bot 173a4a0aa0 Changes in User Profile done by Profile Owner BlaaSwe automatically merged by Superalgos.
Contribution: user profile BlaaSwe
2021-11-30 10:15:04 +01:00
maxah 4a21ea2b1a Merge branch 'develop' of https://github.com/maxah/Superalgos into develop 2021-11-30 07:46:00 +03:00
maxah 002c7002e7 This is my contribution to Superalgos 2021-11-30 07:44:21 +03:00
maxah c9382e0c15 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-30 07:40:39 +03:00
Raidho 68318ba410 Merge branch 'Superalgos:develop' into develop 2021-11-30 07:33:45 +03:00
Axel 9def104a84 Restore web server files 2021-11-29 23:00:23 -03:00
Axel c52629cda2 Change WebAppPreLoader
Test and refactor
Updated own user-profile
2021-11-29 21:44:46 -03:00
NAmorim 95b763d9ed Update README for packaged apps 2021-11-29 22:34:40 +00:00
Axel 7ed3876d19 add validation to ProfileConstructor addSigningAccounts to work when no nodes are defined 2021-11-29 18:35:22 -03:00
Axel 2935e989f7 Remove unnecessary files 2021-11-29 18:33:28 -03:00
BlaaSwe 5f182b7fb6 user profile BlaaSwe 2021-11-29 22:26:55 +01:00
Luis Fernando Molina fdc7198274 Merge pull request #2767 from markinho91/develop
Contribution: This is my contribution to Superalgos
2021-11-29 16:38:35 -04:00
Superalgos Bot d779b98eda Changes in User Profile done by Profile Owner Raplh2502 automatically merged by Superalgos.
Contribution: profile update
2021-11-29 21:18:38 +01:00
Raplh2502 74a4c7da77 profile update 2021-11-29 21:17:19 +01:00
Superalgos Bot c24227daab Changes in User Profile done by Profile Owner hokaheh111 automatically merged by Superalgos.
Contribution: This is my contribution to Superalgos
2021-11-29 17:40:36 +01:00
B Harrell 5695d038ce Merge pull request #2761 from harrellbm/develop
Update install instructions for Readme
2021-11-29 10:37:58 -06:00
Andreja 87fcc7793b This is my contribution to Superalgos 2021-11-29 17:35:05 +01:00
B Harrell 9597fef6d4 Finish updating installations methods section of README 2021-11-29 10:34:59 -06:00
Andreja 04fc3f89f4 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-29 17:13:29 +01:00
Luis Fernando Molina c276d6d9b8 Merge pull request #2777 from Luis-Fernando-Molina/develop
Contribution:  Governance Plugin Workspace Updated
2021-11-29 11:51:09 -04:00
Luis Fernando Molina 58663b6968 Governance Plugin Workspace Updated 2021-11-29 16:50:33 +01:00
Luis Fernando Molina 0bea7d4ff4 Merge pull request #2776 from Luis-Fernando-Molina/develop
Contribution: Integration of Trading Bot with Portfolio Manager Part 1
2021-11-29 11:43:59 -04:00
Luis Fernando Molina e12959b97d DeepScan Bug Fixes 2021-11-29 16:42:05 +01:00
Luis Fernando Molina b966f2e6a5 Integration of Trading Bot with Portfolio Manager Part 1 2021-11-29 16:39:24 +01:00
Luis Fernando Molina 772c4fe326 askPortfolioEventsManager function implemented 2021-11-29 15:06:51 +01:00
B Harrell e2e0784a4a Merge branch 'Superalgos:develop' into develop 2021-11-29 07:49:28 -06:00
Luis Fernando Molina b577dcc3d5 New Modules for Outgoing Signals and Portfolio Manager Client 2021-11-29 13:47:50 +01:00
Luis Fernando Molina c741f8b2c4 Workspace Demo for Portfolio Management 2021-11-29 11:14:56 +01:00
Luis Fernando Molina 09cb005c7a Merge pull request #2774 from Luis-Fernando-Molina/develop
Contribution: Bug Fixes with Secrets File
2021-11-29 06:08:44 -04:00
Luis Fernando Molina c4aa0fd4b1 Merge pull request #2773 from Superalgos/portfolio-management
Portfolio management into Develop
2021-11-29 06:05:19 -04:00
Luis Fernando Molina 50b1a9d422 Bug fixed with not having Secrets 2021-11-29 10:56:55 +01:00
Luis Fernando Molina 4205a510ca Bug Fixed Superalgos-Bpt 2021-11-29 10:41:47 +01:00
mx57 d8dd7f6f17 Translation into Russian Chapter XI tutorial docs steps 10-20 2021-11-29 11:57:17 +03:00
maxah 333220bc4a This is my contribution to Superalgos 2021-11-29 08:28:18 +03:00
Marcos Rivas 4b3654d4a4 Data Mining Español 2021-11-29 00:30:59 -03:00
Marcos Rivas 2da3d2955e This is my contribution to Superalgos 2021-11-28 22:45:35 -03:00
Marcos Rivas 3bde6ee880 This is my contribution to Superalgos 2021-11-28 22:38:03 -03:00
Axel 1bbe09a7d0 Merge remote-tracking branch 'superalgos/develop' into develop
# Conflicts:
#	package-lock.json
#	package.json
2021-11-28 21:11:55 -03:00
Axel 577fb7cfab Integrate React frontend for desktop app
* Added component files
    * Added dependencies and settings on package.json
    * Updated package-lock.json to match new dependencies
    * Added react scripts and config files
2021-11-28 19:55:43 -03:00
liteir d4df6f7b78 Updates to Kucoin 2021-11-28 15:33:26 -06:00
Marcos Rivas cf121c24b6 This is my contribution to Superalgos 2021-11-28 16:27:22 -03:00
Marcos Rivas 690f4a7a76 This is my contribution to Superalgos 2021-11-28 16:21:11 -03:00
B Harrell 56ed632842 First pass at updating install instructions for Readme 2021-11-28 11:46:04 -06:00
Luis Fernando Molina 314386131f Simplification of Governance 2021-11-28 16:44:49 +01:00
gitforkgit c2a6938339 (Current projects) 2021-11-28 16:36:51 +01:00
gitforkgit 4433eadae3 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-28 16:08:46 +01:00
gitforkgit 11d9ce5a53 (small fix) 2021-11-27 23:43:11 +01:00
gitforkgit 90813f382f (New Docs Article: Technical term overview) 2021-11-27 23:33:19 +01:00
gitforkgit 44e9bb95c5 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-27 20:33:08 +01:00
gitforkgit 4eb633389d (Translation into german: "Staking Program") 2021-11-27 20:31:19 +01:00
gitforkgit 0b17ec8bd9 (Translation into german: "Automating Actions - Adding your Function") 2021-11-27 19:49:53 +01:00
gitforkgit 14d4ba3c6c (Translation into german: "App Update Command") 2021-11-27 19:37:09 +01:00
gitforkgit 15997b3136 (Translation into german: "App Message - Update Done - New Version Found") 2021-11-27 19:33:31 +01:00
gitforkgit 55abcc302e (Translation into german: "App Message - Updating Your Local App") 2021-11-27 19:21:47 +01:00
gitforkgit 326186e7e8 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-27 19:18:22 +01:00
gitforkgit 8c89eabc2c (Translation into german: "Debugging - Start Your Processes") 2021-11-27 19:15:12 +01:00
gitforkgit 6bd88aeaae (Translation into german: rest of "Trading Farms - Set Up a Network of Nodes") 2021-11-27 17:38:58 +01:00
gitforkgit fae6f15d19 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-27 16:27:27 +01:00
maxah 7590fd7418 'Docs in Russian - part 1' 2021-11-26 21:35:08 +03:00
gitforkgit 69d8b89783 Merge branch 'develop' of https://github.com/Superalgos/Superalgos into develop 2021-11-26 00:20:01 +01:00
Andreja 5309042a27 My Superalgos Review 2021-11-25 20:36:29 +01:00
398 changed files with 299904 additions and 189127 deletions

No files matched your search

+1
View File
@@ -20,3 +20,4 @@ launch.json
package-lock.json
.idea
dist
/nbproject/private/
+7 -7
View File
@@ -2,7 +2,7 @@ exports.newDesktopApp = function newDesktopApp() {
let thisObject = {
userProfiles: undefined,
p2pNetworkClient: undefined,
p2pNetworkClientIdentity: undefined,
p2pNetwork: undefined,
p2pNetworkPeers: undefined,
webSocketsInterface: undefined,
@@ -25,13 +25,13 @@ exports.newDesktopApp = function newDesktopApp() {
/*
We set up ourselves as a Network Client.
*/
thisObject.p2pNetworkClient = SA.projects.network.modules.p2pNetworkClient.newNetworkModulesP2PNetworkClient()
await thisObject.p2pNetworkClient.initialize()
thisObject.p2pNetworkClientIdentity = SA.projects.network.modules.p2pNetworkClientIdentity.newNetworkModulesP2PNetworkClientIdentity()
await thisObject.p2pNetworkClientIdentity.initialize()
/*
We will read all user profiles plugins and get from there our network identity.
*/
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
await thisObject.userProfiles.initialize(global.env.DESKTOP_APP_SIGNING_ACCOUNT, thisObject.p2pNetworkClient)
await thisObject.userProfiles.initialize(global.env.DESKTOP_APP_SIGNING_ACCOUNT, thisObject.p2pNetworkClientIdentity)
/*
We set up the P2P Network.
*/
@@ -43,7 +43,7 @@ exports.newDesktopApp = function newDesktopApp() {
thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers()
await thisObject.p2pNetworkPeers.initialize(
'Network Client',
thisObject.p2pNetworkClient,
thisObject.p2pNetworkClientIdentity,
thisObject.p2pNetwork,
global.env.DESKTOP_APP_MAX_OUTGOING_PEERS
)
@@ -68,11 +68,11 @@ exports.newDesktopApp = function newDesktopApp() {
*/
thisObject.webSocketsInterface = DK.projects.socialTrading.modules.webSocketsInterface.newDesktopModulesWebSocketsInterface()
thisObject.webSocketsInterface.initialize()
console.log('Desktop Client Web Sockets Interface ......................................... Listening at port ' + JSON.parse(DK.desktopApp.p2pNetworkClient.node.config).webSocketsPort)
console.log('Desktop Client Web Sockets Interface ......................................... Listening at port ' + JSON.parse(DK.desktopApp.p2pNetworkClientIdentity.node.config).webSocketsPort)
thisObject.httpInterface = DK.projects.socialTrading.modules.httpInterface.newDesktopModulesHttpInterface()
thisObject.httpInterface.initialize()
console.log('Desktop Client Http Interface ................................................ Listening at port ' + JSON.parse(DK.desktopApp.p2pNetworkClient.node.config).webPort)
console.log('Desktop Client Http Interface ................................................ Listening at port ' + JSON.parse(DK.desktopApp.p2pNetworkClientIdentity.node.config).webPort)
}
}
}
+81
View File
@@ -0,0 +1,81 @@
const express = require("./backend/src/index");
exports.newDesktopApp = function newDesktopApp() {
let thisObject = {
userProfiles: undefined,
p2pNetworkClientIdentity: undefined,
p2pNetwork: undefined,
p2pNetworkPeers: undefined,
webSocketsInterface: undefined,
webAppInterface: undefined,
p2pNetworkInterface: undefined,
socialGraph: undefined,
run: run
}
DK.desktopApp = thisObject
return thisObject
async function run() {
await setupNetwork()
await setupServices()
async function setupNetwork() {
/*
We set up ourselves as a Network Client.
*/
thisObject.p2pNetworkClientIdentity = SA.projects.network.modules.p2pNetworkClientIdentity.newNetworkModulesP2PNetworkClientIdentity()
await thisObject.p2pNetworkClientIdentity.initialize()
/*
We will read all user profiles plugins and get from there our network identity.
*/
thisObject.userProfiles = SA.projects.network.modules.userProfiles.newNetworkModulesUserProfiles()
await thisObject.userProfiles.initialize(global.env.DESKTOP_APP_SIGNING_ACCOUNT, thisObject.p2pNetworkClientIdentity)
/*
We set up the P2P Network.
*/
thisObject.p2pNetwork = SA.projects.network.modules.p2pNetwork.newNetworkModulesP2PNetwork()
await thisObject.p2pNetwork.initialize('Network Client')
/*
Set up the connections to network nodes.
*/
thisObject.p2pNetworkPeers = SA.projects.network.modules.p2pNetworkPeers.newNetworkModulesP2PNetworkPeers()
await thisObject.p2pNetworkPeers.initialize(
'Network Client',
thisObject.p2pNetworkClientIdentity,
thisObject.p2pNetwork,
global.env.DESKTOP_APP_MAX_OUTGOING_PEERS
)
}
async function setupServices() {
/*
This is where we will process all the messages comming from our web app.
*/
thisObject.webAppInterface = DK.projects.socialTrading.modules.webAppInterface.newSocialTradingModulesWebAppInterface() // this sends events to the p2p network
/*
This is where we will process all the events comming from the p2p network.
*/
thisObject.p2pNetworkInterface = DK.projects.socialTrading.modules.p2pNetworkInterface.newSocialTradingModulesP2PNetworkInterface() // this receives events from p2p network
/*
This is the Personal Social Graph for the user running this App.
*/
thisObject.socialGraph = DK.projects.socialTrading.modules.socialGraph.newSocialTradingModulesSocialGraph() //
await thisObject.socialGraph.initialize()
let express = require('./backend/src/index')
let expressPort = JSON.parse(DK.desktopApp.p2pNetworkClientIdentity.node.config).webPort;
express.startExpress(expressPort,SA);
console.log('express Interface ................................................ Listening at port ' + expressPort);
/*TODO change this to have a definite port number*/
let react = require('./frontend/scripts/start')
let reactPort = (+JSON.parse(DK.desktopApp.p2pNetworkClientIdentity.node.config).webPort + 1);
react.start(reactPort);
console.log('react Interface ................................................ Listening at port ' + reactPort);
}
}
}
+367
View File
@@ -0,0 +1,367 @@
function newWebApp() {
/*
In it's current state of development, the Web App only has one module.
Everything is being coded here until some structure emerges.
*/
let thisObject = {
messageReceived: messageReceived,
initialize: initialize,
finalize: finalize
}
return thisObject
function finalize() {
}
async function initialize() {
try {
setupRootObject(UI, 'UI')
setupRootObject(SA, 'SA')
await UI.projects.socialTrading.modules.webSocketsWebAppClient.initialize()
loadWUserProfileTimeline()
loadWhoToFollow()
setupEventHandlers()
} catch (err) {
console.log('[ERROR] initialize -> err.stack = ' + err.stack)
}
}
/*
function setupRootObject(rootObject, rootObjectName) {
/!*
Here we will setup the UI object, with all the
projects and spaces.
*!/
for (let i = 0; i < UI.schemas.projectSchema.length; i++) {
let projectDefinition = UI.schemas.projectSchema[i]
rootObject.projects[projectDefinition.propertyName] = {}
let projectInstance = rootObject.projects[projectDefinition.propertyName]
projectInstance.utilities = {}
projectInstance.globals = {}
projectInstance.functionLibraries = {}
projectInstance.modules = {}
if (projectDefinition[rootObjectName] === undefined) {
continue
}
/!* Set up Globals of this Project *!/
if (projectDefinition[rootObjectName].globals !== undefined) {
for (let j = 0; j < projectDefinition[rootObjectName].globals.length; j++) {
let globalDefinition = projectDefinition[rootObjectName].globals[j]
if (exports[globalDefinition.functionName] === undefined) {
projectInstance.globals[globalDefinition.propertyName] = eval(globalDefinition.functionName + '()')
} else {
projectInstance.globals[globalDefinition.propertyName] = eval('exports.' + globalDefinition.functionName + '()')
}
}
}
/!* Set up Utilities of this Project *!/
if (projectDefinition[rootObjectName].utilities !== undefined) {
for (let j = 0; j < projectDefinition[rootObjectName].utilities.length; j++) {
let utilityDefinition = projectDefinition[rootObjectName].utilities[j]
if (exports[utilityDefinition.functionName] === undefined) {
projectInstance.utilities[utilityDefinition.propertyName] = eval(utilityDefinition.functionName + '()')
} else {
projectInstance.utilities[utilityDefinition.propertyName] = eval('exports.' + utilityDefinition.functionName + '()')
}
}
}
/!* Set up Function Libraries of this Project *!/
if (projectDefinition[rootObjectName].functionLibraries !== undefined) {
for (let j = 0; j < projectDefinition[rootObjectName].functionLibraries.length; j++) {
let functionLibraryDefinition = projectDefinition[rootObjectName].functionLibraries[j]
if (exports[functionLibraryDefinition.functionName] === undefined) {
projectInstance.functionLibraries[functionLibraryDefinition.propertyName] = eval(functionLibraryDefinition.functionName + '()')
} else {
projectInstance.functionLibraries[functionLibraryDefinition.propertyName] = eval('exports.' + functionLibraryDefinition.functionName + '()')
}
}
}
/!* Set up Modules of this Project *!/
if (projectDefinition[rootObjectName].modules !== undefined) {
for (let j = 0; j < projectDefinition[rootObjectName].modules.length; j++) {
let functionLibraryDefinition = projectDefinition[rootObjectName].modules[j]
if (exports[functionLibraryDefinition.functionName] === undefined) {
projectInstance.modules[functionLibraryDefinition.propertyName] = eval(functionLibraryDefinition.functionName + '()')
} else {
projectInstance.modules[functionLibraryDefinition.propertyName] = eval('exports.' + functionLibraryDefinition.functionName + '()')
}
}
}
}
}
*/
/*
async function loadWUserProfileTimeline() {
let queryMessage = {
queryType: SA.projects.socialTrading.globals.queryTypes.EVENTS,
emitterUserProfileId: undefined,
initialIndex: SA.projects.socialTrading.globals.queryConstants.INITIAL_INDEX_LAST,
amountRequested: 100,
direction: SA.projects.socialTrading.globals.queryConstants.DIRECTION_PAST
}
let query = {
requestType: 'Query',
queryMessage: JSON.stringify(queryMessage)
}
await UI.projects.socialTrading.modules.webSocketsWebAppClient.sendMessage(
JSON.stringify(query)
)
.then(console.log)
.catch(onError)
function onError(errorMessage) {
console.log('[ERROR] Query not executed. ' + errorMessage)
console.log('[ERROR] query = ' + JSON.stringify(query))
}
function addToContentDiv(events) {
try {
let contentDiv = document.getElementById('content-div')
/!*
Delete al current content.
*!/
while (contentDiv.childNodes.length > 4) {
let childToRemove = contentDiv.childNodes[contentDiv.childNodes.length - 1]
contentDiv.removeChild(childToRemove)
}
/!*
Render the timeline.
*!/
for (let i = 0; i < events.length; i++) {
let event = events[i]
let postDiv = document.createElement("div")
postDiv.setAttribute("class", "post-div")
let textNode
switch (event.eventType) {
case SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST: {
textNode = document.createTextNode(event.emitterUserProfile.userProfileHandle + " POSTED " + event.postText)
break
}
case SA.projects.socialTrading.globals.eventTypes.FOLLOW_USER_PROFILE: {
textNode = document.createTextNode(event.emitterUserProfile.userProfileHandle + " FOLLOWED " + event.targetUserProfile.userProfileHandle)
break
}
case SA.projects.socialTrading.globals.eventTypes.UNFOLLOW_USER_PROFILE: {
textNode = document.createTextNode(event.emitterUserProfile.userProfileHandle + " UNFOLLOWED " + event.targetUserProfile.userProfileHandle)
break
}
}
postDiv.appendChild(textNode)
contentDiv.appendChild(postDiv)
}
}
catch (err) {
console.log('[ERROR] err.stack = ' + err.stack)
}
}
}
*/
/*
async function loadWhoToFollow() {
let queryMessage = {
queryType: SA.projects.socialTrading.globals.queryTypes.UNFOLLOWED_USER_PROFILES,
emitterUserProfileId: undefined,
initialIndex: SA.projects.socialTrading.globals.queryConstants.INITIAL_INDEX_FIRST,
amountRequested: 3,
direction: SA.projects.socialTrading.globals.queryConstants.DIRECTION_UP
}
let query = {
requestType: 'Query',
queryMessage: JSON.stringify(queryMessage)
}
await UI.projects.socialTrading.modules.webSocketsWebAppClient.sendMessage(
JSON.stringify(query)
)
.then(addWhoToFollowTable)
.catch(onError)
function onError(errorMessage) {
console.log('[ERROR] Query not executed. ' + errorMessage)
console.log('[ERROR] query = ' + JSON.stringify(query))
}
}
*/
function setupEventHandlers() {
/*
Add events to process button clicks , and mouseWheel.
*/
document.addEventListener("click", onClick)
document.addEventListener('mousewheel', onMouseWheel, false)
async function onClick(event) {
if (event.target && event.target.nodeName === "BUTTON") {
switch (event.target.name) {
case 'New Post': {
let textArea = document.getElementById("new-post-text-area")
await sendNewPostEvent(
textArea.value
)
.then(updateTextArea)
.catch(onError)
function updateTextArea() {
textArea.value = ""
}
break
}
case 'Follow Profile': {
await sendTargetUserProfileEvent(
event.target.userProfileId,
SA.projects.socialTrading.globals.eventTypes.FOLLOW_USER_PROFILE
)
.then(updateButton)
.catch(onError)
function updateButton() {
let span = document.getElementById('profile-to-follow-span-' + event.target.userProfileId)
let button = document.getElementById('profile-to-follow-button-' + event.target.userProfileId)
span.setAttribute("class", "profile-to-unfollow-span")
button.setAttribute("class", "profile-to-unfollow-button")
button.name = 'Unfollow Profile'
}
break
}
case 'Unfollow Profile': {
await sendTargetUserProfileEvent(
event.target.userProfileId,
SA.projects.socialTrading.globals.eventTypes.UNFOLLOW_USER_PROFILE
)
.then(updateButton)
.catch(onError)
/*
function updateButton() {
let span = document.getElementById('profile-to-follow-span-' + event.target.userProfileId)
let button = document.getElementById('profile-to-follow-button-' + event.target.userProfileId)
span.setAttribute("class", "profile-to-follow-span")
button.setAttribute("class", "profile-to-follow-button")
button.name = 'Follow Profile'
}
*/
break
}
}
}
/*
Error Handling
*/
function onError(errorMessage) {
console.log('[ERROR] Click event failed. ' + errorMessage)
}
}
function onMouseWheel(event) {
let scrollDiv = document.getElementById("scroll-div")
scrollDiv.scrollTop = scrollDiv.scrollTop + event.deltaY
}
}
async function sendTargetUserProfileEvent(
userProfileId,
eventType
) {
return new Promise((resolve, reject) => {
asyncCall(resolve, reject)
})
async function asyncCall(resolve, reject) {
let eventMessage
let event
eventMessage = {
eventType: eventType,
eventId: SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId(),
targetUserProfileId: userProfileId,
timestamp: (new Date()).valueOf()
}
event = {
requestType: 'Event',
eventMessage: JSON.stringify(eventMessage)
}
await UI.projects.socialTrading.modules.webSocketsWebAppClient.sendMessage(
JSON.stringify(event)
)
.then(resolve)
.catch(onError)
function onError(errorMessage) {
console.log('[ERROR] Event not executed. ' + errorMessage)
console.log('[ERROR] event = ' + JSON.stringify(event))
reject(errorMessage)
}
}
}
async function sendNewPostEvent(
postText
) {
return new Promise((resolve, reject) => {
asyncCall(resolve, reject)
})
async function asyncCall(resolve, reject) {
let eventMessage
let event
eventMessage = {
eventType: SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST,
eventId: SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId(),
postText: postText,
timestamp: (new Date()).valueOf()
}
event = {
requestType: 'Event',
eventMessage: JSON.stringify(eventMessage)
}
await UI.projects.socialTrading.modules.webSocketsWebAppClient.sendMessage(
JSON.stringify(event)
)
.then(resolve)
.catch(onError)
function onError(errorMessage) {
console.log('[ERROR] Event not executed. ' + errorMessage)
console.log('[ERROR] event = ' + JSON.stringify(event))
reject(errorMessage)
}
}
}
function messageReceived(message) {
window.alert(message)
}
}
+116
View File
@@ -0,0 +1,116 @@
exports.startExpress = (port, SA) => {
const express = require("express");
const app = express();
const webAppInterface = DK.projects.socialTrading.modules.webAppInterface.newSocialTradingModulesWebAppInterface();
app.use(express.json());
// define a route handler for the default home page
app.get("/health-check", (req, res) => {
res.send("all good");
});
app.get("/profiles", async (req, res) => {
let profiles = await whoToFollow();
console.log(profiles)
res.send(profiles);
});
app.post("/follow", async (req, res) => {
let follow = followProfile(req.body.userProfileId, SA.projects.socialTrading.globals.eventTypes.FOLLOW_USER_PROFILE);
res.send("Followed")
});
app.post("/unFollow", async (req, res) => {
let follow = followProfile(req.body.userProfileId, SA.projects.socialTrading.globals.eventTypes.UNFOLLOW_USER_PROFILE);
res.send("UnFollow")
});
app.post("/post", async (req, res) => {
console.log(req)
let post = createPost(req);
res.send(post)
});
// start the Express server
app.listen(port, () => {
console.log(`server started at http://localhost:${port}`);
});
async function createPost(postText) {
try {
let eventMessage;
let event;
eventMessage = {
eventType: SA.projects.socialTrading.globals.eventTypes.NEW_USER_POST,
eventId: SA.projects.foundations.utilities.miscellaneousFunctions.genereteUniqueId(),
postText: postText,
timestamp: (new Date()).valueOf()
}
event = {
requestType: 'Event',
eventMessage: JSON.stringify(eventMessage)
}
return await webAppInterface.sendMessage(
JSON.stringify(event)
);
} catch (e) {
console.log(e);
return {};
}
}
async function whoToFollow() {
try {
let queryMessage = {
queryType: SA.projects.socialTrading.globals.queryTypes.UNFOLLOWED_USER_PROFILES,
emitterUserProfileId: undefined,
initialIndex: SA.projects.socialTrading.globals.queryConstants.INITIAL_INDEX_FIRST,
amountRequested: 3,
direction: SA.projects.socialTrading.globals.queryConstants.DIRECTION_UP
}
let query = {
requestType: 'Query',
queryMessage: JSON.stringify(queryMessage)
}
return await webAppInterface.messageReceived(
JSON.stringify(query)
);
} catch (e) {
console.log(e);
return [];
}
}
async function followProfile(userProfileId, eventType) {
try {
let queryMessage = {
queryType: SA.projects.socialTrading.globals.queryTypes.UNFOLLOWED_USER_PROFILES,
emitterUserProfileId: undefined,
initialIndex: SA.projects.socialTrading.globals.queryConstants.INITIAL_INDEX_FIRST,
amountRequested: 3,
direction: SA.projects.socialTrading.globals.queryConstants.DIRECTION_UP
}
let query = {
requestType: 'Query',
queryMessage: JSON.stringify(queryMessage)
}
return await webAppInterface.messageReceived(
JSON.stringify(query)
);
} catch (e) {
console.log(e);
return {};
}
}
}
+106
View File
@@ -0,0 +1,106 @@
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
// Make sure that including paths.js after env.js will read .env variables.
delete require.cache[require.resolve('./paths')];
const NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV) {
throw new Error(
'The NODE_ENV environment variable is required but was not specified.'
);
}
// https://github.com/bkeepers/dotenv#what-other-env-files-can-i-use
const dotenvFiles = [
`${paths.dotenv}.${NODE_ENV}.local`,
// Don't include `.env.local` for `test` environment
// since normally you expect tests to produce the same
// results for everyone
NODE_ENV !== 'test' && `${paths.dotenv}.local`,
`${paths.dotenv}.${NODE_ENV}`,
paths.dotenv,
].filter(Boolean);
// Load environment variables from .env* files. Suppress warnings using silent
// if this file is missing. dotenv will never modify any environment variables
// that have already been set. Variable expansion is supported in .env files.
// https://github.com/motdotla/dotenv
// https://github.com/motdotla/dotenv-expand
dotenvFiles.forEach(dotenvFile => {
if (fs.existsSync(dotenvFile)) {
require('dotenv-expand')(
require('dotenv').config({
path: dotenvFile,
})
);
}
});
// We support resolving modules according to `NODE_PATH`.
// This lets you use absolute paths in imports inside large monorepos:
// https://github.com/facebook/create-react-app/issues/253.
// It works similar to `NODE_PATH` in Node itself:
// https://nodejs.org/api/modules.html#modules_loading_from_the_global_folders
// Note that unlike in Node, only *relative* paths from `NODE_PATH` are honored.
// Otherwise, we risk importing Node.js core modules into an app instead of webpack shims.
// https://github.com/facebook/create-react-app/issues/1023#issuecomment-265344421
// We also resolve them to make sure all tools using them work consistently.
const appDirectory = fs.realpathSync(process.cwd());
process.env.NODE_PATH = (process.env.NODE_PATH || '')
.split(path.delimiter)
.filter(folder => folder && !path.isAbsolute(folder))
.map(folder => path.resolve(appDirectory, folder))
.join(path.delimiter);
// Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be
// injected into the application via DefinePlugin in webpack configuration.
const REACT_APP = /^REACT_APP_/i;
function getClientEnvironment(publicUrl) {
const raw = Object.keys(process.env)
.filter(key => REACT_APP.test(key))
.reduce(
(env, key) => {
env[key] = process.env[key];
return env;
},
{
// Useful for determining whether we’re running in production mode.
// Most importantly, it switches React into the correct mode.
NODE_ENV: process.env.NODE_ENV || 'development',
// Useful for resolving the correct path to static assets in `public`.
// For example, <img src={process.env.PUBLIC_URL + '/img/logo.png'} />.
// This should only be used as an escape hatch. Normally you would put
// images into the `src` and `import` them in code to get their paths.
PUBLIC_URL: publicUrl,
// We support configuring the sockjs pathname during development.
// These settings let a developer run multiple simultaneous projects.
// They are used as the connection `hostname`, `pathname` and `port`
// in webpackHotDevClient. They are used as the `sockHost`, `sockPath`
// and `sockPort` options in webpack-dev-server.
WDS_SOCKET_HOST: process.env.WDS_SOCKET_HOST,
WDS_SOCKET_PATH: process.env.WDS_SOCKET_PATH,
WDS_SOCKET_PORT: process.env.WDS_SOCKET_PORT,
// Whether or not react-refresh is enabled.
// react-refresh is not 100% stable at this time,
// which is why it's disabled by default.
// It is defined here so it is available in the webpackHotDevClient.
FAST_REFRESH: process.env.FAST_REFRESH !== 'false',
}
);
// Stringify all values so we can feed into webpack DefinePlugin
const stringified = {
'process.env': Object.keys(raw).reduce((env, key) => {
env[key] = JSON.stringify(raw[key]);
return env;
}, {}),
};
return { raw, stringified };
}
module.exports = getClientEnvironment;
@@ -0,0 +1,66 @@
const fs = require('fs');
const path = require('path');
const crypto = require('crypto');
const chalk = require('react-dev-utils/chalk');
const paths = require('./paths');
// Ensure the certificate and key provided are valid and if not
// throw an easy to debug error
function validateKeyAndCerts({ cert, key, keyFile, crtFile }) {
let encrypted;
try {
// publicEncrypt will throw an error with an invalid cert
encrypted = crypto.publicEncrypt(cert, Buffer.from('test'));
} catch (err) {
throw new Error(
`The certificate "${chalk.yellow(crtFile)}" is invalid.\n${err.message}`
);
}
try {
// privateDecrypt will throw an error with an invalid key
crypto.privateDecrypt(key, encrypted);
} catch (err) {
throw new Error(
`The certificate key "${chalk.yellow(keyFile)}" is invalid.\n${
err.message
}`
);
}
}
// Read file and throw an error if it doesn't exist
function readEnvFile(file, type) {
if (!fs.existsSync(file)) {
throw new Error(
`You specified ${chalk.cyan(
type
)} in your env, but the file "${chalk.yellow(file)}" can't be found.`
);
}
return fs.readFileSync(file);
}
// Get the https config
// Return cert files if provided in env, otherwise just true or false
function getHttpsConfig() {
const { SSL_CRT_FILE, SSL_KEY_FILE, HTTPS } = process.env;
const isHttps = HTTPS === 'true';
if (isHttps && SSL_CRT_FILE && SSL_KEY_FILE) {
const crtFile = path.resolve(paths.appPath, SSL_CRT_FILE);
const keyFile = path.resolve(paths.appPath, SSL_KEY_FILE);
const config = {
cert: readEnvFile(crtFile, 'SSL_CRT_FILE'),
key: readEnvFile(keyFile, 'SSL_KEY_FILE'),
};
validateKeyAndCerts({ ...config, keyFile, crtFile });
return config;
}
return isHttps;
}
module.exports = getHttpsConfig;
+134
View File
@@ -0,0 +1,134 @@
const fs = require('fs');
const path = require('path');
const paths = require('./paths');
const chalk = require('react-dev-utils/chalk');
const resolve = require('resolve');
/**
* Get additional module paths based on the baseUrl of a compilerOptions object.
*
* @param {Object} options
*/
function getAdditionalModulePaths(options = {}) {
const baseUrl = options.baseUrl;
if (!baseUrl) {
return '';
}
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
// We don't need to do anything if `baseUrl` is set to `node_modules`. This is
// the default behavior.
if (path.relative(paths.appNodeModules, baseUrlResolved) === '') {
return null;
}
// Allow the user set the `baseUrl` to `appSrc`.
if (path.relative(paths.appSrc, baseUrlResolved) === '') {
return [paths.appSrc];
}
// If the path is equal to the root directory we ignore it here.
// We don't want to allow importing from the root directly as source files are
// not transpiled outside of `src`. We do allow importing them with the
// absolute path (e.g. `src/Components/Button.js`) but we set that up with
// an alias.
if (path.relative(paths.appPath, baseUrlResolved) === '') {
return null;
}
// Otherwise, throw an error.
throw new Error(
chalk.red.bold(
"Your project's `baseUrl` can only be set to `src` or `node_modules`." +
' Create React App does not support other values at this time.'
)
);
}
/**
* Get webpack aliases based on the baseUrl of a compilerOptions object.
*
* @param {*} options
*/
function getWebpackAliases(options = {}) {
const baseUrl = options.baseUrl;
if (!baseUrl) {
return {};
}
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
if (path.relative(paths.appPath, baseUrlResolved) === '') {
return {
src: paths.appSrc,
};
}
}
/**
* Get jest aliases based on the baseUrl of a compilerOptions object.
*
* @param {*} options
*/
function getJestAliases(options = {}) {
const baseUrl = options.baseUrl;
if (!baseUrl) {
return {};
}
const baseUrlResolved = path.resolve(paths.appPath, baseUrl);
if (path.relative(paths.appPath, baseUrlResolved) === '') {
return {
'^src/(.*)$': '<rootDir>/src/$1',
};
}
}
function getModules() {
// Check if TypeScript is setup
const hasTsConfig = fs.existsSync(paths.appTsConfig);
const hasJsConfig = fs.existsSync(paths.appJsConfig);
if (hasTsConfig && hasJsConfig) {
throw new Error(
'You have both a tsconfig.json and a jsconfig.json. If you are using TypeScript please remove your jsconfig.json file.'
);
}
let config;
// If there's a tsconfig.json we assume it's a
// TypeScript project and set up the config
// based on tsconfig.json
if (hasTsConfig) {
const ts = require(resolve.sync('typescript', {
basedir: paths.appNodeModules,
}));
config = ts.readConfigFile(paths.appTsConfig, ts.sys.readFile).config;
// Otherwise we'll check if there is jsconfig.json
// for non TS projects.
} else if (hasJsConfig) {
config = require(paths.appJsConfig);
}
config = config || {};
const options = config.compilerOptions || {};
const additionalModulePaths = getAdditionalModulePaths(options);
return {
additionalModulePaths: additionalModulePaths,
webpackAliases: getWebpackAliases(options),
jestAliases: getJestAliases(options),
hasTsConfig,
};
}
module.exports = getModules();
+68
View File
@@ -0,0 +1,68 @@
const path = require('path');
const fs = require('fs');
const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath');
const {appPublic} = require("./paths");
// Make sure any symlinks in the project folder are resolved:
// https://github.com/facebook/create-react-app/issues/637
const appDirectory = fs.realpathSync(process.cwd());
const resolveApp = relativePath => path.resolve(appDirectory, relativePath);
// We use `PUBLIC_URL` environment variable or "homepage" field to infer
// "public path" at which the app is served.
// webpack needs to know it to put the right <script> hrefs into HTML even in
// single-page apps that may serve index.html for nested URLs like /todos/42.
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
const publicUrlOrPath = getPublicUrlOrPath(
process.env.NODE_ENV === 'development',
require(resolveApp('package.json')).homepage,
process.env.PUBLIC_URL
);
const buildPath = process.env.BUILD_PATH || 'DesktopReact/build';
const moduleFileExtensions = [
'web.mjs',
'mjs',
'web.js',
'js',
'web.ts',
'ts',
'web.tsx',
'tsx',
'json',
'web.jsx',
'jsx',
];
// Resolve file paths in the same order as webpack
const resolveModule = (resolveFn, filePath) => {
const extension = moduleFileExtensions.find(extension =>
fs.existsSync(resolveFn(`${filePath}.${extension}`))
);
if (extension) {
return resolveFn(`${filePath}.${extension}`);
}
return resolveFn(`${filePath}.js`);
};
// config after eject: we're in ./config/
module.exports = {
dotenv: resolveApp('.env'),
appPath: resolveApp('.'),
appBuild: resolveApp(buildPath),
appPublic: resolveApp('DesktopReact/frontend/public'),
appHtml: resolveApp('DesktopReact/frontend/public/index.html'),
appIndexJs: resolveModule(resolveApp, 'DesktopReact/frontend/src/index'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('DesktopReact/frontend/src'),
appNodeModules: resolveApp('node_modules'),
publicUrlOrPath,
};
module.exports.moduleFileExtensions = moduleFileExtensions;
+35
View File
@@ -0,0 +1,35 @@
const { resolveModuleName } = require('ts-pnp');
exports.resolveModuleName = (
typescript,
moduleName,
containingFile,
compilerOptions,
resolutionHost
) => {
return resolveModuleName(
moduleName,
containingFile,
compilerOptions,
resolutionHost,
typescript.resolveModuleName
);
};
exports.resolveTypeReferenceDirective = (
typescript,
moduleName,
containingFile,
compilerOptions,
resolutionHost
) => {
return resolveModuleName(
moduleName,
containingFile,
compilerOptions,
resolutionHost,
typescript.resolveTypeReferenceDirective
);
};
@@ -0,0 +1,757 @@
const fs = require('fs');
const path = require('path');
const webpack = require('webpack');
const resolve = require('resolve');
const PnpWebpackPlugin = require('pnp-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const ESLintPlugin = require('eslint-webpack-plugin');
const paths = require('./paths');
const modules = require('./modules');
const getClientEnvironment = require('./env');
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
const postcssNormalize = require('postcss-normalize');
const appPackageJson = require(paths.appPackageJson);
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
const webpackDevClientEntry = require.resolve(
'react-dev-utils/webpackHotDevClient'
);
const reactRefreshOverlayEntry = require.resolve(
'react-dev-utils/refreshOverlayInterop'
);
// Some apps do not need the benefits of saving a web request, so not inlining the chunk
// makes for a smoother build process.
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === 'true';
const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === 'true';
const imageInlineSizeLimit = parseInt(
process.env.IMAGE_INLINE_SIZE_LIMIT || '10000'
);
// Check if TypeScript is setup
const useTypeScript = fs.existsSync(paths.appTsConfig);
// Get the path to the uncompiled service worker (if it exists).
const swSrc = paths.swSrc;
// style files regexes
const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;
const hasJsxRuntime = (() => {
if (process.env.DISABLE_NEW_JSX_TRANSFORM === 'true') {
return false;
}
try {
require.resolve('react/jsx-runtime');
return true;
} catch (e) {
return false;
}
})();
// This is the production and development configuration.
// It is focused on developer experience, fast rebuilds, and a minimal bundle.
module.exports = function (webpackEnv) {
const isEnvDevelopment = webpackEnv === 'development';
const isEnvProduction = webpackEnv === 'production';
// Variable used for enabling profiling in Production
// passed into alias object. Uses a flag if passed into the build command
const isEnvProductionProfile =
isEnvProduction && process.argv.includes('--profile');
// We will provide `paths.publicUrlOrPath` to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_URL%/xyz looks better than %PUBLIC_URL%xyz.
// Get environment variables to inject into our app.
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
const shouldUseReactRefresh = env.raw.FAST_REFRESH;
// common function to get style loaders
const getStyleLoaders = (cssOptions, preProcessor) => {
const loaders = [
isEnvDevelopment && require.resolve('style-loader'),
isEnvProduction && {
loader: MiniCssExtractPlugin.loader,
// css is located in `static/css`, use '../../' to locate index.html folder
// in production `paths.publicUrlOrPath` can be a relative path
options: paths.publicUrlOrPath.startsWith('.')
? { publicPath: '../../' }
: {},
},
{
loader: require.resolve('css-loader'),
options: cssOptions,
},
{
// Options for PostCSS as we reference these options twice
// Adds vendor prefixing based on your specified browser support in
// package.json
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebook/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
require('postcss-preset-env')({
autoprefixer: {
flexbox: 'no-2009',
},
stage: 3,
}),
// Adds PostCSS Normalize as the reset css with default options,
// so that it honors browserslist config in package.json
// which in turn let's users customize the target behavior as per their needs.
postcssNormalize(),
],
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
},
},
].filter(Boolean);
if (preProcessor) {
loaders.push(
{
loader: require.resolve('resolve-url-loader'),
options: {
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
root: paths.appSrc,
},
},
{
loader: require.resolve(preProcessor),
options: {
sourceMap: true,
},
}
);
}
return loaders;
};
return {
mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
// Stop compilation early in production
bail: isEnvProduction,
devtool: isEnvProduction
? shouldUseSourceMap
? 'source-map'
: false
: isEnvDevelopment && 'cheap-module-source-map',
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
entry:
isEnvDevelopment && !shouldUseReactRefresh
? [
// Include an alternative client for WebpackDevServer. A client's job is to
// connect to WebpackDevServer by a socket and get notified about changes.
// When you save a file, the client will either apply hot updates (in case
// of CSS changes), or refresh the page (in case of JS changes). When you
// make a syntax error, this client will display a syntax error overlay.
// Note: instead of the default WebpackDevServer client, we use a custom one
// to bring better experience for Create React App users. You can replace
// the line below with these two lines if you prefer the stock client:
//
// require.resolve('webpack-dev-server/client') + '?/',
// require.resolve('webpack/hot/dev-server'),
//
// When using the experimental react-refresh integration,
// the webpack plugin takes care of injecting the dev client for us.
webpackDevClientEntry,
// Finally, this is your app's code:
paths.appIndexJs,
// We include the app code last so that if there is a runtime error during
// initialization, it doesn't blow up the WebpackDevServer client, and
// changing JS code would still trigger a refresh.
]
: paths.appIndexJs,
output: {
// The build folder.
path: isEnvProduction ? paths.appBuild : undefined,
// Add /* filename */ comments to generated require()s in the output.
pathinfo: isEnvDevelopment,
// There will be one main bundle, and one file per asynchronous chunk.
// In development, it does not produce real files.
filename: isEnvProduction
? 'static/js/[name].[contenthash:8].js'
: isEnvDevelopment && 'static/js/bundle.js',
// TODO: remove this when upgrading to webpack 5
futureEmitAssets: true,
// There are also additional JS chunk files if you use code splitting.
chunkFilename: isEnvProduction
? 'static/js/[name].[contenthash:8].chunk.js'
: isEnvDevelopment && 'static/js/[name].chunk.js',
// webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: paths.publicUrlOrPath,
// Point sourcemap entries to original disk location (format as URL on Windows)
devtoolModuleFilenameTemplate: isEnvProduction
? info =>
path
.relative(paths.appSrc, info.absoluteResourcePath)
.replace(/\\/g, '/')
: isEnvDevelopment &&
(info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
// Prevents conflicts when multiple webpack runtimes (from different apps)
// are used on the same page.
jsonpFunction: `webpackJsonp${appPackageJson.name}`,
// this defaults to 'window', but by setting it to 'this' then
// module chunks which are built will work in web workers as well.
globalObject: 'this',
},
optimization: {
minimize: isEnvProduction,
minimizer: [
// This is only used in production mode
new TerserPlugin({
terserOptions: {
parse: {
// We want terser to parse ecma 8 code. However, we don't want it
// to apply any minification steps that turns valid ecma 5 code
// into invalid ecma 5 code. This is why the 'compress' and 'output'
// sections only apply transformations that are ecma 5 safe
// https://github.com/facebook/create-react-app/pull/4234
ecma: 8,
},
compress: {
ecma: 5,
warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebook/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
// Disabled because of an issue with Terser breaking valid code:
// https://github.com/facebook/create-react-app/issues/5250
// Pending further investigation:
// https://github.com/terser-js/terser/issues/120
inline: 2,
},
mangle: {
safari10: true,
},
// Added for profiling in devtools
keep_classnames: isEnvProductionProfile,
keep_fnames: isEnvProductionProfile,
output: {
ecma: 5,
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebook/create-react-app/issues/2488
ascii_only: true,
},
},
sourceMap: shouldUseSourceMap,
}),
// This is only used in production mode
new OptimizeCSSAssetsPlugin({
cssProcessorOptions: {
parser: safePostCssParser,
map: shouldUseSourceMap
? {
// `inline: false` forces the sourcemap to be output into a
// separate file
inline: false,
// `annotation: true` appends the sourceMappingURL to the end of
// the css file, helping the browser find the sourcemap
annotation: true,
}
: false,
},
cssProcessorPluginOptions: {
preset: ['default', { minifyFontValues: { removeQuotes: false } }],
},
}),
],
// Automatically split vendor and commons
// https://twitter.com/wSokra/status/969633336732905474
// https://medium.com/webpack/webpack-4-code-splitting-chunk-graph-and-the-splitchunks-optimization-be739a861366
splitChunks: {
chunks: 'all',
name: isEnvDevelopment,
},
// Keep the runtime chunk separated to enable long term caching
// https://twitter.com/wSokra/status/969679223278505985
// https://github.com/facebook/create-react-app/issues/5358
runtimeChunk: {
name: entrypoint => `runtime-${entrypoint.name}`,
},
},
resolve: {
// This allows you to set a fallback for where webpack should look for modules.
// We placed these paths second because we want `node_modules` to "win"
// if there are any conflicts. This matches Node resolution mechanism.
// https://github.com/facebook/create-react-app/issues/253
modules: ['node_modules', paths.appNodeModules].concat(
modules.additionalModulePaths || []
),
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebook/create-react-app/issues/290
// `web` extension prefixes have been added for better support
// for React Native Web.
extensions: paths.moduleFileExtensions
.map(ext => `.${ext}`)
.filter(ext => useTypeScript || !ext.includes('ts')),
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
// Allows for better profiling with ReactDevTools
...(isEnvProductionProfile && {
'react-dom$': 'react-dom/profiling',
'scheduler/tracing': 'scheduler/tracing-profiling',
}),
...(modules.webpackAliases || {}),
},
plugins: [
// Adds support for installing with Plug'n'Play, leading to faster installs and adding
// guards against forgotten dependencies and such.
PnpWebpackPlugin,
// Prevents users from importing files from outside of src/ (or node_modules/).
// This often causes confusion because we only process files within src/ with babel.
// To fix this, we prevent you from importing files out of src/ -- if you'd like to,
// please link the files into your node_modules/ and let module-resolution kick in.
// Make sure your source files are compiled, as they will not be processed in any way.
new ModuleScopePlugin(paths.appSrc, [
paths.appPackageJson,
reactRefreshOverlayEntry,
]),
],
},
resolveLoader: {
plugins: [
// Also related to Plug'n'Play, but this time it tells webpack to load its loaders
// from the current package.
PnpWebpackPlugin.moduleLoader(module),
],
},
module: {
strictExportPresence: true,
rules: [
// Disable require.ensure as it's not a standard language feature.
{ parser: { requireEnsure: false } },
{
// "oneOf" will traverse all following loaders until one will
// match the requirements. When no loader matches it will fall
// back to the "file" loader at the end of the loader list.
oneOf: [
// TODO: Merge this config once `image/avif` is in the mime-db
// https://github.com/jshttp/mime-db
{
test: [/\.avif$/],
loader: require.resolve('url-loader'),
options: {
limit: imageInlineSizeLimit,
mimetype: 'image/avif',
name: 'static/media/[name].[hash:8].[ext]',
},
},
// "url" loader works like "file" loader except that it embeds assets
// smaller than specified limit in bytes as data URLs to avoid requests.
// A missing `test` is equivalent to a match.
{
test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
loader: require.resolve('url-loader'),
options: {
limit: imageInlineSizeLimit,
name: 'static/media/[name].[hash:8].[ext]',
},
},
// Process application JS with Babel.
// The preset includes JSX, Flow, TypeScript, and some ESnext features.
{
test: /\.(js|mjs|jsx|ts|tsx)$/,
include: paths.appSrc,
loader: require.resolve('babel-loader'),
options: {
customize: require.resolve(
'babel-preset-react-app/webpack-overrides'
),
presets: [
[
require.resolve('babel-preset-react-app'),
{
runtime: hasJsxRuntime ? 'automatic' : 'classic',
},
],
],
plugins: [
[
require.resolve('babel-plugin-named-asset-import'),
{
loaderMap: {
svg: {
ReactComponent:
'@svgr/webpack?-svgo,+titleProp,+ref![path]',
},
},
},
],
isEnvDevelopment &&
shouldUseReactRefresh &&
require.resolve('react-refresh/babel'),
].filter(Boolean),
// This is a feature of `babel-loader` for webpack (not Babel itself).
// It enables caching results in ./node_modules/.cache/babel-loader/
// directory for faster rebuilds.
cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled
cacheCompression: false,
compact: isEnvProduction,
},
},
// Process any JS outside of the app with Babel.
// Unlike the application JS, we only compile the standard ES features.
{
test: /\.(js|mjs)$/,
exclude: /@babel(?:\/|\\{1,2})runtime/,
loader: require.resolve('babel-loader'),
options: {
babelrc: false,
configFile: false,
compact: false,
presets: [
[
require.resolve('babel-preset-react-app/dependencies'),
{ helpers: true },
],
],
cacheDirectory: true,
// See #6846 for context on why cacheCompression is disabled
cacheCompression: false,
// Babel sourcemaps are needed for debugging into node_modules
// code. Without the options below, debuggers like VSCode
// show incorrect code and set breakpoints on the wrong lines.
sourceMaps: shouldUseSourceMap,
inputSourceMap: shouldUseSourceMap,
},
},
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader turns CSS into JS modules that inject <style> tags.
// In production, we use MiniCSSExtractPlugin to extract that CSS
// to a file, but in development "style" loader enables hot editing
// of CSS.
// By default we support CSS Modules with the extension .module.css
{
test: cssRegex,
exclude: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
}),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
// using the extension .module.css
{
test: cssModuleRegex,
use: getStyleLoaders({
importLoaders: 1,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
}),
},
// Opt-in support for SASS (using .scss or .sass extensions).
// By default we support SASS Modules with the
// extensions .module.scss or .module.sass
{
test: sassRegex,
exclude: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
},
'sass-loader'
),
// Don't consider CSS imports dead code even if the
// containing package claims to have no side effects.
// Remove this when webpack adds a warning or an error for this.
// See https://github.com/webpack/webpack/issues/6571
sideEffects: true,
},
// Adds support for CSS Modules, but using SASS
// using the extension .module.scss or .module.sass
{
test: sassModuleRegex,
use: getStyleLoaders(
{
importLoaders: 3,
sourceMap: isEnvProduction
? shouldUseSourceMap
: isEnvDevelopment,
modules: {
getLocalIdent: getCSSModuleLocalIdent,
},
},
'sass-loader'
),
},
// "file" loader makes sure those assets get served by WebpackDevServer.
// When you `import` an asset, you get its (virtual) filename.
// In production, they would get copied to the `build` folder.
// This loader doesn't use a "test" so it will catch all modules
// that fall through the other loaders.
{
loader: require.resolve('file-loader'),
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
options: {
name: 'static/media/[name].[hash:8].[ext]',
},
},
// ** STOP ** Are you adding a new loader?
// Make sure to add the new loader(s) before the "file" loader.
],
},
],
},
plugins: [
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin(
Object.assign(
{},
{
inject: true,
template: paths.appHtml,
},
isEnvProduction
? {
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}
: undefined
)
),
// Inlines the webpack runtime script. This script is too small to warrant
// a network request.
// https://github.com/facebook/create-react-app/issues/5358
isEnvProduction &&
shouldInlineRuntimeChunk &&
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// It will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
// This gives some necessary context to module not found errors, such as
// the requesting resource.
new ModuleNotFoundPlugin(paths.appPath),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV is set to production
// during a production build.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified),
// This is necessary to emit hot updates (CSS and Fast Refresh):
isEnvDevelopment && new webpack.HotModuleReplacementPlugin(),
// Experimental hot reloading for React .
// https://github.com/facebook/react/tree/master/packages/react-refresh
isEnvDevelopment &&
shouldUseReactRefresh &&
new ReactRefreshWebpackPlugin({
overlay: {
entry: webpackDevClientEntry,
// The expected exports are slightly different from what the overlay exports,
// so an interop is included here to enable feedback on module-level errors.
module: reactRefreshOverlayEntry,
// Since we ship a custom dev client and overlay integration,
// the bundled socket handling logic can be eliminated.
sockIntegration: false,
},
}),
// Watcher doesn't work well if you mistype casing in a path so we use
// a plugin that prints an error when you attempt to do this.
// See https://github.com/facebook/create-react-app/issues/240
isEnvDevelopment && new CaseSensitivePathsPlugin(),
// If you require a missing module and then `npm install` it, you still have
// to restart the development server for webpack to discover it. This plugin
// makes the discovery automatic so you don't have to restart.
// See https://github.com/facebook/create-react-app/issues/186
isEnvDevelopment &&
new WatchMissingNodeModulesPlugin(paths.appNodeModules),
isEnvProduction &&
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: 'static/css/[name].[contenthash:8].css',
chunkFilename: 'static/css/[name].[contenthash:8].chunk.css',
}),
// Generate an asset manifest file with the following content:
// - "files" key: Mapping of all asset filenames to their corresponding
// output file so that tools can pick it up without having to parse
// `index.html`
// - "entrypoints" key: Array of files which are included in `index.html`,
// can be used to reconstruct the HTML if necessary
new ManifestPlugin({
fileName: 'asset-manifest.json',
publicPath: paths.publicUrlOrPath,
generate: (seed, files, entrypoints) => {
const manifestFiles = files.reduce((manifest, file) => {
manifest[file.name] = file.path;
return manifest;
}, seed);
const entrypointFiles = entrypoints.main.filter(
fileName => !fileName.endsWith('.map')
);
return {
files: manifestFiles,
entrypoints: entrypointFiles,
};
},
}),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
// Generate a service worker script that will precache, and keep up to date,
// the HTML & assets that are part of the webpack build.
isEnvProduction &&
fs.existsSync(swSrc) &&
new WorkboxWebpackPlugin.InjectManifest({
swSrc,
dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
// Bump up the default maximum size (2mb) that's precached,
// to make lazy-loading failure scenarios less likely.
// See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
}),
// TypeScript type checking
useTypeScript &&
new ForkTsCheckerWebpackPlugin({
typescript: resolve.sync('typescript', {
basedir: paths.appNodeModules,
}),
async: isEnvDevelopment,
checkSyntacticErrors: true,
resolveModuleNameModule: process.versions.pnp
? `${__dirname}/pnpTs.js`
: undefined,
resolveTypeReferenceDirectiveModule: process.versions.pnp
? `${__dirname}/pnpTs.js`
: undefined,
tsconfig: paths.appTsConfig,
reportFiles: [
// This one is specifically to match during CI tests,
// as micromatch doesn't match
// '../cra-template-typescript/template/src/App.tsx'
// otherwise.
'../**/src/**/*.{ts,tsx}',
'**/src/**/*.{ts,tsx}',
'!**/src/**/__tests__/**',
'!**/src/**/?(*.)(spec|test).*',
'!**/src/setupProxy.*',
'!**/src/setupTests.*',
],
silent: true,
// The formatter is invoked directly in WebpackDevServerUtils during development
formatter: isEnvProduction ? typescriptFormatter : undefined,
}),
!disableESLintPlugin &&
new ESLintPlugin({
// Plugin options
extensions: ['js', 'mjs', 'jsx', 'ts', 'tsx'],
formatter: require.resolve('react-dev-utils/eslintFormatter'),
eslintPath: require.resolve('eslint'),
failOnError: !(isEnvDevelopment && emitErrorsAsWarnings),
context: paths.appSrc,
cache: true,
cacheLocation: path.resolve(
paths.appNodeModules,
'.cache/.eslintcache'
),
// ESLint class options
cwd: paths.appPath,
resolvePluginsRelativeTo: __dirname,
baseConfig: {
extends: [require.resolve('eslint-config-react-app/base')],
rules: {
...(!hasJsxRuntime && {
'react/react-in-jsx-scope': 'error',
}),
},
},
}),
].filter(Boolean),
// Some libraries import Node modules but don't use them in the browser.
// Tell webpack to provide empty mocks for them so importing them works.
node: {
module: 'empty',
dgram: 'empty',
dns: 'mock',
fs: 'empty',
http2: 'empty',
net: 'empty',
tls: 'empty',
child_process: 'empty',
},
// Turn off performance processing because we utilize
// our own hints via the FileSizeReporter
performance: false,
};
};
@@ -0,0 +1,130 @@
const fs = require('fs');
const errorOverlayMiddleware = require('react-dev-utils/errorOverlayMiddleware');
const evalSourceMapMiddleware = require('react-dev-utils/evalSourceMapMiddleware');
const noopServiceWorkerMiddleware = require('react-dev-utils/noopServiceWorkerMiddleware');
const ignoredFiles = require('react-dev-utils/ignoredFiles');
const redirectServedPath = require('react-dev-utils/redirectServedPathMiddleware');
const paths = require('./paths');
const getHttpsConfig = require('./getHttpsConfig');
const host = process.env.HOST || '0.0.0.0';
const sockHost = process.env.WDS_SOCKET_HOST;
const sockPath = process.env.WDS_SOCKET_PATH; // default: '/sockjs-node'
const sockPort = process.env.WDS_SOCKET_PORT;
module.exports = function (proxy, allowedHost) {
return {
// WebpackDevServer 2.4.3 introduced a security fix that prevents remote
// websites from potentially accessing local content through DNS rebinding:
// https://github.com/webpack/webpack-dev-server/issues/887
// https://medium.com/webpack/webpack-dev-server-middleware-security-issues-1489d950874a
// However, it made several existing use cases such as development in cloud
// environment or subdomains in development significantly more complicated:
// https://github.com/facebook/create-react-app/issues/2271
// https://github.com/facebook/create-react-app/issues/2233
// While we're investigating better solutions, for now we will take a
// compromise. Since our WDS configuration only serves files in the `public`
// folder we won't consider accessing them a vulnerability. However, if you
// use the `proxy` feature, it gets more dangerous because it can expose
// remote code execution vulnerabilities in backends like Django and Rails.
// So we will disable the host check normally, but enable it if you have
// specified the `proxy` setting. Finally, we let you override it if you
// really know what you're doing with a special environment variable.
disableHostCheck:
!proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true',
// Enable gzip compression of generated files.
compress: true,
// Silence WebpackDevServer's own logs since they're generally not useful.
// It will still show compile warnings and errors with this setting.
clientLogLevel: 'none',
// By default WebpackDevServer serves physical files from current directory
// in addition to all the virtual build products that it serves from memory.
// This is confusing because those files won’t automatically be available in
// production build folder unless we copy them. However, copying the whole
// project directory is dangerous because we may expose sensitive files.
// Instead, we establish a convention that only files in `public` directory
// get served. Our build script will copy `public` into the `build` folder.
// In `index.html`, you can get URL of `public` folder with %PUBLIC_URL%:
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
// In JavaScript code, you can access it with `process.env.PUBLIC_URL`.
// Note that we only recommend to use `public` folder as an escape hatch
// for files like `favicon.ico`, `manifest.json`, and libraries that are
// for some reason broken when imported through webpack. If you just want to
// use an image, put it in `src` and `import` it from JavaScript instead.
contentBase: paths.appPublic,
contentBasePublicPath: paths.publicUrlOrPath,
// By default files from `contentBase` will not trigger a page reload.
watchContentBase: true,
// Enable hot reloading server. It will provide WDS_SOCKET_PATH endpoint
// for the WebpackDevServer client so it can learn when the files were
// updated. The WebpackDevServer client is included as an entry point
// in the webpack development configuration. Note that only changes
// to CSS are currently hot reloaded. JS changes will refresh the browser.
hot: true,
// Use 'ws' instead of 'sockjs-node' on server since we're using native
// websockets in `webpackHotDevClient`.
transportMode: 'ws',
// Prevent a WS client from getting injected as we're already including
// `webpackHotDevClient`.
injectClient: false,
// Enable custom sockjs pathname for websocket connection to hot reloading server.
// Enable custom sockjs hostname, pathname and port for websocket connection
// to hot reloading server.
sockHost,
sockPath,
sockPort,
// It is important to tell WebpackDevServer to use the same "publicPath" path as
// we specified in the webpack config. When homepage is '.', default to serving
// from the root.
// remove last slash so user can land on `/test` instead of `/test/`
publicPath: paths.publicUrlOrPath.slice(0, -1),
// WebpackDevServer is noisy by default so we emit custom message instead
// by listening to the compiler events with `compiler.hooks[...].tap` calls above.
quiet: true,
// Reportedly, this avoids CPU overload on some systems.
// https://github.com/facebook/create-react-app/issues/293
// src/node_modules is not ignored to support absolute imports
// https://github.com/facebook/create-react-app/issues/1065
watchOptions: {
ignored: ignoredFiles(paths.appSrc),
},
https: getHttpsConfig(),
host,
overlay: false,
historyApiFallback: {
// Paths with dots should still use the history fallback.
// See https://github.com/facebook/create-react-app/issues/387.
disableDotRule: true,
index: paths.publicUrlOrPath,
},
public: allowedHost,
// `proxy` is run between `before` and `after` `webpack-dev-server` hooks
proxy,
before(app, server) {
// Keep `evalSourceMapMiddleware` and `errorOverlayMiddleware`
// middlewares before `redirectServedPath` otherwise will not have any effect
// This lets us fetch source contents from webpack for the error overlay
app.use(evalSourceMapMiddleware(server));
// This lets us open files from the runtime error overlay.
app.use(errorOverlayMiddleware());
if (fs.existsSync(paths.proxySetup)) {
// This registers user provided middleware for proxy reasons
require(paths.proxySetup)(app);
}
},
after(app) {
// Redirect to `PUBLIC_URL` or `homepage` from `package.json` if url not match
app.use(redirectServedPath(paths.publicUrlOrPath));
// This service worker file is effectively a 'no-op' that will reset any
// previous service worker registered for the same host:port combination.
// We do this in development to avoid hitting the production cache if
// it used the same host and port.
// https://github.com/facebook/create-react-app/issues/2272#issuecomment-302832432
app.use(noopServiceWorkerMiddleware(paths.publicUrlOrPath));
},
};
};
Binary file not shown.
Binary file not shown.
+30
View File
@@ -0,0 +1,30 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Superalgos Desktop</title>
<meta name="description" content="Free and Open Source Crypto Social Trading">
<link rel="icon" href="%PUBLIC_URL%/favicon.ico"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="manifest" href="%PUBLIC_URL%/manifest.json"/>
<script type="text/javascript">
function loadApp() {
// Prevent click-jacking
try {
if (window === window.top || window.chrome && chrome.app && chrome.app.window) {
document.documentElement.style.display = 'block'
} else {
top.location = self.location
}
} catch (e) {
console.error('CJ protection', e)
}
}
</script>
</head>
<body id="body" onload="loadApp()">
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
@@ -0,0 +1,25 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
},
{
"src": "logo192.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}
+3
View File
@@ -0,0 +1,3 @@
# https://www.robotstxt.org/robotstxt.html
User-agent: *
Disallow:
+212
View File
@@ -0,0 +1,212 @@
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'production';
process.env.NODE_ENV = 'production';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
const path = require('path');
const chalk = require('react-dev-utils/chalk');
const fs = require('fs-extra');
const bfj = require('bfj');
const webpack = require('webpack');
const configFactory = require('../config/webpack.config');
const paths = require('../config/paths');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages');
const printHostingInstructions = require('react-dev-utils/printHostingInstructions');
const FileSizeReporter = require('react-dev-utils/FileSizeReporter');
const printBuildError = require('react-dev-utils/printBuildError');
const measureFileSizesBeforeBuild =
FileSizeReporter.measureFileSizesBeforeBuild;
const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild;
const useYarn = fs.existsSync(paths.yarnLockFile);
// These sizes are pretty large. We'll warn for bundles exceeding them.
const WARN_AFTER_BUNDLE_GZIP_SIZE = 512 * 1024;
const WARN_AFTER_CHUNK_GZIP_SIZE = 1024 * 1024;
const isInteractive = process.stdout.isTTY;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
const argv = process.argv.slice(2);
const writeStatsJson = argv.indexOf('--stats') !== -1;
// Generate configuration
const config = configFactory('production');
// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const { checkBrowsers } = require('react-dev-utils/browsersHelper');
checkBrowsers(paths.appPath, isInteractive)
.then(() => {
// First, read the current file sizes in build directory.
// This lets us display how much they changed later.
return measureFileSizesBeforeBuild(paths.appBuild);
})
.then(previousFileSizes => {
// Remove all content but keep the directory so that
// if you're in it, you don't end up in Trash
fs.emptyDirSync(paths.appBuild);
// Merge with the public folder
copyPublicFolder();
// Start the webpack build
return build(previousFileSizes);
})
.then(
({ stats, previousFileSizes, warnings }) => {
if (warnings.length) {
console.log(chalk.yellow('Compiled with warnings.\n'));
console.log(warnings.join('\n\n'));
console.log(
'\nSearch for the ' +
chalk.underline(chalk.yellow('keywords')) +
' to learn more about each warning.'
);
console.log(
'To ignore, add ' +
chalk.cyan('// eslint-disable-next-line') +
' to the line before.\n'
);
} else {
console.log(chalk.green('Compiled successfully.\n'));
}
console.log('File sizes after gzip:\n');
printFileSizesAfterBuild(
stats,
previousFileSizes,
paths.appBuild,
WARN_AFTER_BUNDLE_GZIP_SIZE,
WARN_AFTER_CHUNK_GZIP_SIZE
);
console.log();
const appPackage = require(paths.appPackageJson);
const publicUrl = paths.publicUrlOrPath;
const publicPath = config.output.publicPath;
const buildFolder = path.relative(process.cwd(), paths.appBuild);
printHostingInstructions(
appPackage,
publicUrl,
publicPath,
buildFolder,
useYarn
);
},
err => {
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
if (tscCompileOnError) {
console.log(
chalk.yellow(
'Compiled with the following type errors (you may want to check these before deploying your app):\n'
)
);
printBuildError(err);
} else {
console.log(chalk.red('Failed to compile.\n'));
printBuildError(err);
process.exit(1);
}
}
)
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});
// Create the production build and print the deployment instructions.
function build(previousFileSizes) {
console.log('Creating an optimized production build...');
const compiler = webpack(config);
return new Promise((resolve, reject) => {
compiler.run((err, stats) => {
let messages;
if (err) {
if (!err.message) {
return reject(err);
}
let errMessage = err.message;
// Add additional information for postcss errors
if (Object.prototype.hasOwnProperty.call(err, 'postcssNode')) {
errMessage +=
'\nCompileError: Begins at CSS selector ' +
err['postcssNode'].selector;
}
messages = formatWebpackMessages({
errors: [errMessage],
warnings: [],
});
} else {
messages = formatWebpackMessages(
stats.toJson({ all: false, warnings: true, errors: true })
);
}
if (messages.errors.length) {
// Only keep the first error. Others are often indicative
// of the same problem, but confuse the reader with noise.
if (messages.errors.length > 1) {
messages.errors.length = 1;
}
return reject(new Error(messages.errors.join('\n\n')));
}
if (
process.env.CI &&
(typeof process.env.CI !== 'string' ||
process.env.CI.toLowerCase() !== 'false') &&
messages.warnings.length
) {
console.log(
chalk.yellow(
'\nTreating warnings as errors because process.env.CI = true.\n' +
'Most CI servers set it automatically.\n'
)
);
return reject(new Error(messages.warnings.join('\n\n')));
}
const resolveArgs = {
stats,
previousFileSizes,
warnings: messages.warnings,
};
if (writeStatsJson) {
return bfj
.write(paths.appBuild + '/bundle-stats.json', stats.toJson())
.then(() => resolve(resolveArgs))
.catch(error => reject(new Error(error)));
}
return resolve(resolveArgs);
});
});
}
function copyPublicFolder() {
fs.copySync(paths.appPublic, paths.appBuild, {
dereference: true,
filter: file => file !== paths.appHtml,
});
}
+162
View File
@@ -0,0 +1,162 @@
exports.start = (port) => {
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'development';
process.env.NODE_ENV = 'development';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
const fs = require('fs');
const chalk = require('react-dev-utils/chalk');
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const clearConsole = require('react-dev-utils/clearConsole');
const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles');
const {
choosePort,
createCompiler,
prepareProxy,
prepareUrls,
} = require('react-dev-utils/WebpackDevServerUtils');
const openBrowser = require('react-dev-utils/openBrowser');
const semver = require('semver');
const paths = require('../config/paths');
const configFactory = require('../config/webpack.config');
const createDevServerConfig = require('../config/webpackDevServer.config');
const getClientEnvironment = require('../config/env');
const react = require(require.resolve('react', {paths: [paths.appPath]}));
const env = getClientEnvironment(paths.publicUrlOrPath.slice(0, -1));
const useYarn = fs.existsSync(paths.yarnLockFile);
const isInteractive = process.stdout.isTTY;
// Warn and crash if required files are missing
if (!checkRequiredFiles([paths.appHtml, paths.appIndexJs])) {
process.exit(1);
}
// Tools like Cloud9 rely on this.
const DEFAULT_PORT = port;
const HOST = '0.0.0.0';
if (process.env.HOST) {
console.log(
chalk.cyan(
`Attempting to bind to HOST environment variable: ${chalk.yellow(
chalk.bold(process.env.HOST)
)}`
)
);
console.log();
}
// We require that you explicitly set browsers and do not fall back to
// browserslist defaults.
const {checkBrowsers} = require('react-dev-utils/browsersHelper');
checkBrowsers(paths.appPath, isInteractive)
.then(() => {
// We attempt to use the default port but if it is busy, we offer the user to
// run on a different port. `choosePort()` Promise resolves to the next free port.
return choosePort(HOST, DEFAULT_PORT);
})
.then(port => {
if (port == null) {
// We have not found a port.
return;
}
const config = configFactory('development');
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http';
const appName = require(paths.appPackageJson).name;
const useTypeScript = fs.existsSync(paths.appTsConfig);
const tscCompileOnError = process.env.TSC_COMPILE_ON_ERROR === 'true';
const urls = prepareUrls(
protocol,
HOST,
port,
paths.publicUrlOrPath.slice(0, -1)
);
const devSocket = {
warnings: warnings =>
devServer.sockWrite(devServer.sockets, 'warnings', warnings),
errors: errors =>
devServer.sockWrite(devServer.sockets, 'errors', errors),
};
// Create a webpack compiler that is configured with custom messages.
const compiler = createCompiler({
appName,
config,
devSocket,
urls,
useYarn,
useTypeScript,
tscCompileOnError,
webpack,
});
// Load proxy config
const proxySetting = require(paths.appPackageJson).proxy;
const proxyConfig = prepareProxy(
proxySetting,
paths.appPublic,
paths.publicUrlOrPath
);
// Serve webpack assets generated by the compiler over a web server.
const serverConfig = createDevServerConfig(
proxyConfig,
urls.lanUrlForConfig
);
const devServer = new WebpackDevServer(compiler, serverConfig);
// Launch WebpackDevServer.
devServer.listen(port, HOST, err => {
if (err) {
return console.log(err);
}
if (isInteractive) {
clearConsole();
}
if (env.raw.FAST_REFRESH && semver.lt(react.version, '16.10.0')) {
console.log(
chalk.yellow(
`Fast Refresh requires React 16.10 or higher. You are using React ${react.version}.`
)
);
}
console.log(chalk.cyan('Starting the development server...\n'));
openBrowser(urls.localUrlForBrowser);
});
['SIGINT', 'SIGTERM'].forEach(function (sig) {
process.on(sig, function () {
devServer.close();
process.exit();
});
});
if (process.env.CI !== 'true') {
// Gracefully exit when stdin ends
process.stdin.on('end', function () {
devServer.close();
process.exit();
});
}
})
.catch(err => {
if (err && err.message) {
console.log(err.message);
}
process.exit(1);
});
}
+53
View File
@@ -0,0 +1,53 @@
// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'test';
process.env.NODE_ENV = 'test';
process.env.PUBLIC_URL = '';
// Makes the script crash on unhandled rejections instead of silently
// ignoring them. In the future, promise rejections that are not handled will
// terminate the Node.js process with a non-zero exit code.
process.on('unhandledRejection', err => {
throw err;
});
// Ensure environment variables are read.
require('../config/env');
const jest = require('jest');
const execSync = require('child_process').execSync;
let argv = process.argv.slice(2);
function isInGitRepository() {
try {
execSync('git rev-parse --is-inside-work-tree', { stdio: 'ignore' });
return true;
} catch (e) {
return false;
}
}
function isInMercurialRepository() {
try {
execSync('hg --cwd . root', { stdio: 'ignore' });
return true;
} catch (e) {
return false;
}
}
// Watch unless on CI or explicitly running all tests
if (
!process.env.CI &&
argv.indexOf('--watchAll') === -1 &&
argv.indexOf('--watchAll=false') === -1
) {
// https://github.com/facebook/create-react-app/issues/5210
const hasSourceControl = isInGitRepository() || isInMercurialRepository();
argv.push(hasSourceControl ? '--watch' : '--watchAll');
}
jest.run(argv);
+28
View File
@@ -0,0 +1,28 @@
const baseURL = 'http://localhost:33249'
const GET = 'GET'
const POST = 'POST'
const DELETE = 'DELETE'
const UPDATE = 'UPDATE'
function getProfiles(){
return call('/profiles', GET);
}
function getClientNode(){
return call('/ClientNode', GET);
}
function call(endpoint, method, body){
return new Promise(async(resolve, reject) => {
fetch(baseURL + endpoint, { method:method, body:body })
.then(response => resolve(response))
.catch(error => reject(error))
})
}
export {
getProfiles,
getClientNode
}
@@ -0,0 +1,31 @@
import React from 'react';
import {BrowserRouter, Route, Routes} from 'react-router-dom';
import App from './home/App';
import UserProfile from "./userProfile/UserProfile";
import NotFound from "./notFound/NotFound";
import Feed from "./feed/Feed";
import PostPlaceholder from "./postPlaceholder/PostPlaceholder";
const Root = () => {
return (
<BrowserRouter>
<Routes>
<Route path='/' element={<App/>}>
<Route path='' element={<Feed/>}/>
<Route path='Profile' element={<UserProfile/>}>
{/*<Route path=':profileId' element={<UserProfile/>}/>*/}
</Route>
<Route path='Post' element={<PostPlaceholder/>}/>
</Route>
<Route
path="*"
element={
<NotFound/>
}
/>
</Routes>
</BrowserRouter>)
}
export default Root;
@@ -0,0 +1,17 @@
.followButton {
margin: 0.5rem;
width: 3rem;
max-height: 1.5rem;
}
.userCard {
display: flex;
flex-direction: row;
align-items: center;
padding: 0.25rem 1rem;
}
.avatar {
height: 3rem;
width: 3rem;
}
@@ -0,0 +1,30 @@
import "./UserCard.css"
import React, {useEffect} from 'react';
import {Button, Card, CardContent, CardMedia, Typography} from "@mui/material";
import pic from "../../images/superalgos.png"
const UserCard = ({name, id,followCallback}) => {
useEffect(() => {
console.log(`created user with id ${id}`)
}, [id]);
return (
<Card className="userCard" variant="outlined">
<CardMedia className="avatar"
component="img"
image={pic}
alt="PP"
/>
<CardContent>
<Typography variant="body2">{name}</Typography>
</CardContent>
<Button className="followButton" size="small" disableElevation variant="outlined" onClick={followCallback}>
Follow
</Button>
</Card>
);
};
export default UserCard;
@@ -0,0 +1,4 @@
.showMore {
width: 100%;
text-align: center;
}
@@ -0,0 +1,23 @@
import './UsersSidebar.css';
import {Stack} from "@mui/material";
import SearchBox from "../searchBox/SearchBox";
import SuggestedUsers from "../suggestedUsers/SuggestedUsers";
const UsersSidebar = () => {
const showMoreCallback = () => console.log("clicked show more");
return (
<Stack direction="column"
justifyContent="flex-start"
alignItems="center"
spacing={2}
sx={{minWidth: "max-content"}}>
<SearchBox/>
<SuggestedUsers showMoreCallback={showMoreCallback}/>
</Stack>
);
}
export default UsersSidebar;
@@ -0,0 +1,11 @@
.feed {
width: 40rem;
height: 95vh;
overflow: auto;
-ms-overflow-style: none; /* Hide scrollbar for IE and Edge */
scrollbar-width: none; /* Hide scrollbar for Firefox */
}
.feed::-webkit-scrollbar { /* Hide scrollbar for Chrome, Safari and Opera */
display: none;
}
@@ -0,0 +1,14 @@
import './Feed.css';
import PostPlaceholder from "../postPlaceholder/PostPlaceholder";
import PostsFeed from "../postsFeed/PostsFeed";
const Feed = () => {
return (
<div className="feed">
<PostPlaceholder/>
<PostsFeed/>
</div>
);
}
export default Feed;
@@ -0,0 +1,7 @@
.app {
height: 100%;
}
.middleSection{
width: 40rem;
}
@@ -0,0 +1,27 @@
import './App.css';
import Sidebar from "../sidebar/Sidebar";
import UsersSidebar from "../UsersSidebar/UsersSidebar";
import {Stack} from "@mui/material";
import {Outlet} from "react-router-dom";
import {getProfiles} from '../../api/service'
function App() {
getProfiles().then( response => {
console.log(response)
});
return (
<div className="app">
<Stack className="app"
direction="row"
justifyContent="space-around">
<Sidebar/>
<Outlet className="middleSection"/>
<UsersSidebar/>
</Stack>
</div>
);
}
export default App;
@@ -0,0 +1,10 @@
/*noinspection CssInvalidPropertyValue*/
.logo {
display: inline-flex;
align-items: center;
height: 3rem;
width: 100%;
}
.icon {
margin: 0 0.5rem;
}
@@ -0,0 +1,17 @@
import './Logo.css';
import React from 'react';
import {Avatar, Stack} from "@mui/material";
import pic from "../../images/superalgos.png"
const Logo = props => {
/* TODO add on click redirect to / */
return (
<Stack direction="row" className="logo">
<Avatar className="icon" alt="SuperAlgos" src={pic}/>
<div>SuperAlgos</div>
</Stack>
);
};
export default Logo;
@@ -0,0 +1,10 @@
import React, {useEffect} from 'react';
import {useNavigate} from "react-router-dom";
const NotFound = () => {
let navigate = useNavigate();
useEffect(() => navigate("/"), [navigate])
return null;
};
export default NotFound;
@@ -0,0 +1,49 @@
.post {
min-width: 5rem; /* todo needs to set a minimum width, but overriding from parent*/
max-width: 100%;
min-height: 5rem; /* todo needs tbd. needed actually? */
max-height: 100%; /* todo need to be 8rem, but is collapsing without scroll. need fix*/
padding: 0.5rem;
}
.postAvatarContainer {
display: flex;
justify-content: center;
align-items: center;
width: 3rem;
height: 3rem;
}
.postBody {
max-width: 100%;
min-width: 1.5rem;
min-height: 1.5rem;
padding-left: 2.8rem;
overflow: auto;
}
.postUserName {
padding: 0.75rem;
justify-content: center;
align-items: center;
}
.postFooterContainer {
justify-content: flex-start;
display: flex;
width: 100%;
padding-top: 0.50rem;
padding-bottom: 0.50rem;
}
.postFooterLikeDislike {
justify-content: space-evenly;
display: flex;
width: 30%;
padding-left: 0.50rem;
}
.postFooterRepost {
justify-content: flex-end;
display: flex;
width: 65%;
}
@@ -0,0 +1,64 @@
import "./Post.css"
import React, {useState} from 'react';
import {Avatar, Card, IconButton, Stack, Typography} from "@mui/material";
import {Autorenew, ThumbDown, ThumbUp} from "@mui/icons-material";
import pic from "../../images/superalgos.png"
const Post = () => {
const userName = "User Name",
postBody = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
const [count, setCount] = useState(0); /* todo define one more for dislike button */
function onLikeButtonClick() { {/* todo console log print need a fix */}
console.log("Liked " + count + " times")
}
function onButtonClick(){ /* todo dislike button function necessary? */
console.log("Liked " + count + " times")
}
return (
<Card className="post">
<Stack direction="row">
<Stack className="postAvatarContainer">
<Avatar src={pic}/>
</Stack>
<Stack className="postUserName">
{userName}
</Stack>
</Stack>
<Stack className="postBody">
{postBody}
</Stack>
<Stack className="postFooterContainer" direction="row">
<Stack className="postFooterLikeDislike" direction="row">
<IconButton
onClick={() => setCount(count + 1)}
>
<ThumbUp/>
</IconButton><Typography>{count}</Typography>
<IconButton
onClick={() => {/* TODO remove unnecessary arrow function*/
onButtonClick()
}}
>
<ThumbDown/>
</IconButton>
</Stack>
<Stack className="postFooterRepost" direction="row">
<IconButton
onClick={() => {/* TODO remove unnecessary arrow function*/
onButtonClick()
}}
>
<Autorenew/>
</IconButton>
</Stack>
</Stack>
</Card>
);
};
export default Post;
@@ -0,0 +1,47 @@
.postPlaceholder {
width: 39rem;
padding: 0.5rem;
}
.postPlaceholderContainer {
min-width: 100%;
max-width: 100%;
}
.postPlaceholderInputBoxContainer {
}
.postPlaceholderAvatar {
display: flex;
justify-content: center;
align-items: center;
width: 3rem;
height: 3rem;
}
.postPlaceholderTextField {
width: 90%;
border: 5px;
}
.postPlaceholderInputBox {
width: auto;
padding: 0.5rem;
}
.postFeedAccountCircle {
}
.postPlaceholderButtonStyle {
padding: 0.75rem;
display: flex;
width: auto;
justify-content: flex-end;
}
.postPlaceholderButton {
height: 1.5rem;
width: 5rem;
}
@@ -0,0 +1,54 @@
import "./PostPlaceholder.css"
import React from 'react';
import {Avatar, Button, Card, Stack, TextField, Typography} from "@mui/material";
import pic from "../../images/superalgos.png"
const PostPlaceholder = () => {
function onButtonClick() {
console.log("Clicked Post button");
}
return (
<div className="postPlaceholder">
<h4>Posts</h4>
<div className="postPlaceholderContainer">
<Card>
<Stack
className="postPlaceholderInputBox"
direction="row"
justifyContent="flex-start"
alignItems="center"
spacing={1}
justify="flex-end">
<Stack className="postPlaceholderAvatar">
<Avatar src={pic}/>
</Stack>
<Stack className="postPlaceholderTextField">
<Typography gutterBottom variant="subtitle1" component="div">
<TextField
id="outlined-multiline-flexible"
label="what's happening?"
fullWidth
multiline
maxRows={6}
/>
</Typography>
</Stack>
</Stack>
<Stack className="postPlaceholderButtonStyle" direction="row">
<Button
onClick={() => { /* TODO remove unnecessary arrow function call*/
onButtonClick()
}}
className="postPlaceholderButton" variant="outlined">
Post
</Button>
</Stack>
</Card>
</div>
</div>
);
};
export default PostPlaceholder;
@@ -0,0 +1,5 @@
.postFeedContainer {
max-width: 39rem;
padding: 0.5rem ;
width: 100%;
}
@@ -0,0 +1,25 @@
import './PostsFeed.css';
import React from 'react';
import {Stack} from "@mui/material";
import Post from "../post/Post";
const PostsFeed = () => {
const postFeed = [1, 2, 3, 4, 5];
const posts = postFeed.map(
value => {
return <Post key={value} id={value} name={`user${value}`}/>
}
)
return (
<div className="postFeedContainer">
<Stack direction="column"
spacing={2}>
{posts}
</Stack>
</div>
);
};
export default PostsFeed;
@@ -0,0 +1,3 @@
.searchIcon {
margin: 1rem 0.5rem;
}
@@ -0,0 +1,16 @@
import React from 'react';
import {Box, TextField} from "@mui/material";
import {Search} from "@mui/icons-material";
const SearchBox = () => {
return (
<div>
<Box sx={{display: 'flex', alignItems: 'flex-end'}}>
<Search className="searchIcon"/>
<TextField id="users-search" label="Search" variant="standard" type="search"/>
</Box>
</div>
);
};
export default SearchBox;
@@ -0,0 +1,16 @@
import React from 'react';
import {Link} from "@mui/material";
const ShowMoreUsers = ({showMoreCallback}) => {
return (
<Link
component="button"
variant="body2"
onClick={showMoreCallback}>
Show more
</Link>
);
};
export default ShowMoreUsers;
@@ -0,0 +1,3 @@
.sidebar{
height: 100%;
}
@@ -0,0 +1,42 @@
import './Sidebar.css';
import {Divider, Stack} from "@mui/material";
import SidebarItem from "../sidebarItem/SidebarItem";
import Logo from "../logo/Logo";
import HomeIcon from '@mui/icons-material/Home';
import PostAddIcon from '@mui/icons-material/PostAdd';
import PersonIcon from '@mui/icons-material/Person';
const Sidebar = props => {
const menuOptions = [{name: "Home", icon: HomeIcon},
{name: "Profile", icon: PersonIcon},
{name: "Post", icon: PostAddIcon}
/*, "Explore", "Notifications", "Messages", "Bookmarks", "Lists", "More"*/]
const menuItems = menuOptions.map(option => {
return <SidebarItem key={option.name} Icon={option.icon} value={option.name}/>
})
return (
<div className="sidebar">
<Stack direction="column"
justifyContent="flex-start"
alignItems="center"
spacing={5}
sx={{minWidth: "max-content"}}>
<Logo/>
<Stack
direction="column"
justifyContent="space-between"
alignItems="center"
spacing={2}
divider={<Divider orientation="horizontal" flexItem/>}>
{menuItems}
</Stack>
</Stack>
</div>
);
}
export default Sidebar;
@@ -0,0 +1,21 @@
.sidebarItem {
/*TODO add on hover*/
/*TODO add breakpoints*/
width: 15vw;
}
.sidebarText {
/*TODO hide when too small*/
width: auto;
text-align: center;
}
.sidebarIcon {
width: auto;
padding: 0 1rem;
}
@@ -0,0 +1,22 @@
import './SidebarItem.css';
import {Stack} from "@mui/material";
import {useNavigate} from "react-router-dom";
const SidebarItem = ({value, Icon}) => {
let navigate = useNavigate();
const handleClick = () => {
navigate(`/${value}`)
}
return (
<div className="sidebarItem" onClick={handleClick}>
<Stack direction="row">
<Icon className="sidebarIcon"/>
<div className="sidebarText"> {value} </div>
</Stack>
</div>
);
}
export default SidebarItem;
Whitespace-only changes.
@@ -0,0 +1,32 @@
import "./SuggestedUsers.css"
import React, {useEffect} from 'react';
import UserCard from "../User/UserCard";
import ShowMoreUsers from "../showMoreUsers/ShowMoreUsers";
import {Stack} from "@mui/material";
const SuggestedUsers = ({showMoreCallback}) => {
const usersIds = [1, 2, 3, 4, 5];
const users = usersIds.map(value => {
let callBack = () => console.log(`Clicked follow on user${value}`);
return <UserCard key={value} id={value} name={`user${value}`} followCallback={callBack}/>
})
useEffect(() => {
console.log("SuggestedUsersConstructor called")
}, []);
return (
<Stack direction="column"
justifyContent="flex-start"
alignItems="center"
spacing={1}>
{users}
<ShowMoreUsers showMoreCallback={showMoreCallback}/>
</Stack>
);
};
export default SuggestedUsers;
@@ -0,0 +1,41 @@
.userSection {
margin-top: 50px;
}
.banner {
height: 10rem;
}
.profileAvatar {
height: 7rem !important;
width: 7rem !important;
border-radius: 50%;
}
.profilePicBG {
display: flex;
align-items: center;
justify-content: center;
background: none no-repeat scroll 0 0 #fff;
position: relative;
height: 8rem !important;
width: 8rem !important;
border-radius: 50%;
}
.profileCard {
margin-top: -50px;
display: flex;
flex-direction: row;
height: 8rem;
}
.profileSection {
width: 100%;
overflow: initial !important; /* TODO check this is needed */
height: 15rem;
}
.middleSection {
width: 39rem;
}
@@ -0,0 +1,28 @@
import "./UserProfile.css"
import React from 'react';
import UserProfileHeader from "../userProfileHeader/UserProfileHeader";
import {Stack} from "@mui/material";
import PostsFeed from "../postsFeed/PostsFeed";
const UserProfile = () => {
/*TODO finish this shit*/
let actualUser = 'Loui Molina';
return (
<Stack direction="column"
justifyContent="flex-start"
alignItems="center"
spacing={1}
className="middleSection">
<UserProfileHeader actualUser={actualUser}/>
<PostsFeed/>
</Stack>
);
};
export default UserProfile;
@@ -0,0 +1,30 @@
import React from 'react';
import {Card, CardContent, CardMedia, Typography} from "@mui/material";
import banner from "../../images/banner.jpg";
import pfp from "../../images/superalgos.png";
const UserProfileHeader = ({actualUser}) => {
return (
<Card className="profileSection">
<CardMedia className="banner"
component="img"
image={banner}
alt="PP"
/>
<div className="profileCard">
<div className="profilePicBG">
<CardMedia className="profileAvatar"
component="img"
image={pfp}
alt="ProfilePic"
/>
</div>
<CardContent className="userSection">
<Typography variant="h5">{actualUser}</Typography>
</CardContent>
</div>
</Card>
);
};
export default UserProfileHeader;
Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

+13
View File
@@ -0,0 +1,13 @@
body {
margin: 2.5vh 5vw;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
height: 95vh !important;
}
#root {
height: inherit;
}
+17
View File
@@ -0,0 +1,17 @@
import './index.css';
import React from 'react';
import ReactDOM from 'react-dom';
import {Provider} from "react-redux";
import reducers from "./store";
import Root from "./components/Root";
ReactDOM.render(
<React.StrictMode>
<Provider store={reducers}>
<Root/>
</Provider>
</React.StrictMode>,
document.getElementById('root')
);
+309
View File
@@ -0,0 +1,309 @@
/* latin */
@font-face {
font-family: 'Saira';
font-style: normal;
font-weight: 300;
src: local('Saira Light'), local('Saira-Light'), url(Fonts/Saira.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin */
@font-face {
font-family: 'Saira Condensed';
font-style: normal;
font-weight: 300;
src: local('Saira Condensed Light'), local('SairaCondensed-Light'), url(Fonts/Saira-Condensed.woff2) format('woff2');
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: segoeui;
src: url(Fonts/segoeui.woff) format('woff');
font-weight: normal;
font-style: normal;
}
.body{
overflow-y: hidden;
overflow-x: hidden;
}
.scroll-div {
position:absolute;
overflow-y: scroll;
overflow-x: hidden;
top:0px;
left:0px;
vertical-align: top;
height: 100%;
width: 100%;
color: #000;
border-color: blue;
background-color: transparent;
border-width: 0px;
}
.static-div {
position: fixed;
top:0px;
left:18%;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
color: #000;
background:transparent;
border-width: 0px;
border-collapse: collapse;
}
.content-div {
position:relative;
vertical-align: top;
height: 100%;
width: 30%;
left: 31.2%;
color: #000;
border-color: blue;
background-color:transparent;
border-width: 1px;
}
.post-placeholder {
vertical-align: top;
height: 50px;
width: 100%;
color: #000;
border-color: blue;
background-color: transparent;
border-width: 0px;
}
.post-div {
vertical-align: top;
height: 300px;
width: 100%;
color: #000;
border-color: blue;
background-color: transparent;
border-width: 0px;
}
.new-post-div {
vertical-align: top;
height: 300px;
width: 100%;
color: #000;
border-color: blue;
background-color: transparent;
border-width: 0px;
}
.page-table {
top:0px;
left:18%;
width: 64%;
height: 100%;
padding: 0;
margin: 0;
color: #000;
background:transparent;
border-width: 0px;
border-collapse: collapse;
}
.left-column {
position:relative;
top:0px;
width: 20%;
height: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.middle-column {
position:relative;
top:0px;
width: 50%;
height: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.right-column {
position:relative;
top:0px;
left:0px;
width: 30%;
height: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.left-table {
position:relative;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
border-collapse: collapse;
}
.logo-cell {
vertical-align: top;
width: 100%;
height: 70px;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.menu-cell {
vertical-align: top;
width: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.profile-cell {
vertical-align: bottom;
width: 100%;
height: 50px;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.middle-table {
position:relative;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
border-collapse: collapse;
}
.content-title-cell {
vertical-align: top;
width: 100%;
height: 50px;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
background-color: #ffffff;
}
.content-cell {
vertical-align: top;
width: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.right-table {
position:relative;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
border-collapse: collapse;
}
.search-cell {
vertical-align: top;
width: 100%;
height: 50px;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.context-cell {
vertical-align: top;
width: 100%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
background:transparent;
}
.menu-table {
position:relative;
width: 100%;
height: 65%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
border-collapse: collapse;
}
.menu-item-cell {
vertical-align: top;
width: 100%;
height: 50px;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
}
.who-to-follow-table {
position:relative;
width: 100%;
height: 30%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
border-collapse: collapse;
}
.profile-to-follow-table {
position:relative;
width: 100%;
height: 30%;
padding: 0;
margin: 0;
color: #000;
border-width: 0px;
border-collapse: collapse;
}
.profile-to-follow-span {
float: right;
}
.profile-to-follow-button {
float: right;
background-color: green;
}
.profile-to-unfollow-span {
float: right;
}
.profile-to-unfollow-button {
float: right;
background-color: red;
}
@@ -0,0 +1,13 @@
const reportWebVitals = onPerfEntry => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;
+9
View File
@@ -0,0 +1,9 @@
import { configureStore } from '@reduxjs/toolkit';
import ExampleReducer from './slices/Globals'
export default configureStore({
reducer:{
example: ExampleReducer
}
})
@@ -0,0 +1,27 @@
import {createSlice} from '@reduxjs/toolkit'
export const Globals = createSlice({
name: 'globals',
initialState: {
UI: {
projects: {},
schemas: {projectSchema: undefined},
environment: undefined,
clientNode: undefined,
webApp: undefined
},
SA: {projects: {}}
},
reducers: {
exampleAction: (state, action) => {
state.userName = action.payload;
},
},
})
// Action creators are generated for each case reducer function
export const {exampleAction} = Globals.actions
export default Globals.reducer
+12 -4
View File
@@ -58,13 +58,21 @@ exports.newDesktopRoot = function newDesktopRoot() {
/*
Setting up Secrets.
*/
SA.secrets = {
array: require('./My-Secrets/Secrets.json').secrets,
map: new Map()
try {
SA.secrets = {
array: require('./My-Secrets/Secrets.json').secrets,
map: new Map()
}
} catch (err) {
SA.secrets = {
array: [],
map: new Map()
}
}
for (let i = 0; i < SA.secrets.array.length; i++) {
let secret = SA.secrets.array[i]
SA.secrets.map.set (secret.nodeCodeName, secret)
SA.secrets.map.set(secret.nodeCodeName, secret)
}
run()
+86
View File
@@ -0,0 +1,86 @@
exports.newDesktopRoot = function newDesktopRoot() {
/*
This module represents the execution root of the Desktop App.
We use this module that is outside the Desktop folder to
load all node dependencies and get them ready to the actual App.
*/
let thisObject = {
run: run
}
return thisObject
async function run(debugSettings) {
/*
The DK object is accessible everywhere at the Superalgos Desktop App.
It provides access to all modules built for this App.
*/
global.DK = {}
/*
The SA object is accessible everywhere at the Superalgos Desktop App.
It provides access to all modules built for Superalgos in general.
*/
global.SA = {}
/* Load Environment Variables */
let ENVIRONMENT = require('./Environment.js');
let ENVIRONMENT_MODULE = ENVIRONMENT.newEnvironment()
global.env = ENVIRONMENT_MODULE
if (debugSettings !== undefined && debugSettings.DESKTOP_APP_SIGNING_ACCOUNT !== undefined) {
global.env.DESKTOP_APP_SIGNING_ACCOUNT = debugSettings.DESKTOP_APP_SIGNING_ACCOUNT
}
/*
First thing is to load the project schema file.
*/
global.PROJECTS_SCHEMA = require(global.env.PATH_TO_PROJECT_SCHEMA)
/*
Setting up the modules that will be available, defined at the Project Schema file.
*/
let MULTI_PROJECT = require('./MultiProject.js');
let MULTI_PROJECT_MODULE = MULTI_PROJECT.newMultiProject()
MULTI_PROJECT_MODULE.initialize(DK, 'DK')
MULTI_PROJECT_MODULE.initialize(SA, 'SA')
/*
Setting up external dependencies.
*/
SA.nodeModules = {
fs: require('fs'),
util: require('util'),
path: require('path'),
web3: require('web3'),
ws: require('ws'),
open: require('open'),
http: require('http'),
octokit: require("@octokit/rest"),
simpleGit: require('simple-git'),
nodeFetch: require('node-fetch')
}
/*
Setting up Secrets.
*/
try {
SA.secrets = {
array: require('./My-Secrets/Secrets.json').secrets,
map: new Map()
}
} catch (err) {
SA.secrets = {
array: [],
map: new Map()
}
}
for (let i = 0; i < SA.secrets.array.length; i++) {
let secret = SA.secrets.array[i]
SA.secrets.map.set(secret.nodeCodeName, secret)
}
run()
async function run() {
DK.app = require('./DesktopReact/DesktopApp.js').newDesktopApp()
await DK.app.run()
console.log('Superalgos Desktop App is Running!')
}
}
}
+3 -2
View File
@@ -33,13 +33,14 @@ exports.newEnvironment = function () {
DESKTOP_APP_SIGNING_ACCOUNT: 'Social-Trading-Desktop-App-1',
DESKTOP_APP_MAX_OUTGOING_PEERS: 1,
TASK_SERVER_APP_MAX_OUTGOING_PEERS: 1,
TASK_SERVER_APP_MAX_OUTGOING_HEADS: 1,
MOBILE_APP_SIGNING_ACCOUNT: 'Social-Trading-Mobile-App-1',
SERVER_APP_SIGNING_ACCOUNT: 'Social-Trading-Server-App-1',
PLATFORM_APP_SIGNING_ACCOUNT: 'Algo-Traders-Platform-1',
P2P_NETWORK_NODE_SIGNING_ACCOUNT: 'P2P-Network-Node-1',
P2P_NETWORK_NODE_MAX_INCOMING_CLIENTS: 1,
P2P_NETWORK_NODE_MAX_INCOMING_PEERS: 2,
P2P_NETWORK_NODE_MAX_OUTGOING_PEERS: 2
P2P_NETWORK_NODE_MAX_INCOMING_PEERS: 0,
P2P_NETWORK_NODE_MAX_OUTGOING_PEERS: 0
}
if (process.env.DATA_PATH) {
+1 -1
View File
@@ -1,5 +1,5 @@
exports.newMultiProject = function () {
/* TODO add init method to DK*/
let thisObject = {
initialize: initialize
}
+1 -1
View File
@@ -56,7 +56,7 @@ exports.newNetworkNode = function newNetworkNode() {
thisObject.socialGraphService = NT.projects.socialTrading.modules.socialGraph.newNetworkModulesSocialGraph()
await thisObject.socialGraphService.initialize()
/*
The Sotrage deals with persisting the Social Graph.
The Storage deals with persisting the Social Graph.
*/
thisObject.storage = NT.projects.socialTrading.modules.storage.newSocialTradingModulesStorage()
thisObject.storage.initialize()
+12 -4
View File
@@ -47,7 +47,7 @@ exports.newNetworkRoot = function newNetworkRoot() {
fs: require('fs'),
path: require('path'),
util: require('util'),
http: require('http'),
http: require('http'),
nodeFetch: require('node-fetch'),
web3: require('web3'),
ws: require('ws'),
@@ -56,10 +56,18 @@ exports.newNetworkRoot = function newNetworkRoot() {
/*
Setting up Secrets.
*/
SA.secrets = {
array: require('./My-Secrets/Secrets.json').secrets,
map: new Map()
try {
SA.secrets = {
array: require('./My-Secrets/Secrets.json').secrets,
map: new Map()
}
} catch (err) {
SA.secrets = {
array: [],
map: new Map()
}
}
for (let i = 0; i < SA.secrets.array.length; i++) {
let secret = SA.secrets.array[i]
SA.secrets.map.set(secret.nodeCodeName, secret)
+4 -3
View File
@@ -210,7 +210,7 @@ exports.newGithubServer = function newGithubServer() {
token = unescape(token)
const repository = 'Superalgos'
/* Unsavping # */
/* Unsaving # */
for (let i = 0; i < 10; i++) {
commitMessage = commitMessage.replace('_SLASH_', '/')
commitMessage = commitMessage.replace('_HASHTAG_', '#')
@@ -331,6 +331,7 @@ exports.newGithubServer = function newGithubServer() {
let lastPage = false
while (lastPage === false) {
page++
await PL.projects.foundations.utilities.asyncFunctions.sleep(GITHUB_API_WAITING_TIME)
let listResponse = await octokit.rest.pulls.listFiles({
owner: owner,
@@ -365,8 +366,8 @@ exports.newGithubServer = function newGithubServer() {
if (await validateUserProfileSigningAccountsDoesNotBelongtoAnotherUserProfile() === false) { continue }
/*
TODO: We need to check before merging a User Profile that none of id of the node of the profile hierearchy exists at any other
User Profile already at the repository, to avoid atacts of users highjacking references of other user profiles.
TODO: We need to check before merging a User Profile that none of id of the node of the profile hierarchy exists at any other
User Profile already at the repository, to avoid attacks of users hijacking references of other user profiles.
*/
if (await mergePullRequest() === false) {
+2 -2
View File
@@ -1588,7 +1588,7 @@ exports.newHttpInterface = function newHttpInterface() {
try {
SA.projects.foundations.utilities.httpResponses.respondWithContent(JSON.stringify(error), httpResponse)
} catch (err) {
// we just try to reponnd to the web app, but maybe the response has already been sent.
// we just try to respond to the web app, but maybe the response has already been sent.
}
}
}
@@ -2231,7 +2231,7 @@ exports.newHttpInterface = function newHttpInterface() {
break
case 'Storage': {
let pathToFile = httpRequest.url.substring(9)
/* Unsavping # */
/* Unsaving # */
for (let i = 0; i < 10; i++) {
pathToFile = pathToFile.replace('_HASHTAG_', '#')
}
+1 -1
View File
@@ -188,7 +188,7 @@ function newFrame() {
function isThisPointHere(point, outsideViewPort, dontTransform, padding) {
// The second parameter is useful when you want to check a point that you already know is outside the viewport.
// The padding is a distance to the borders of the container. Can be either negative (outside, to increase the container size) or positive (inside to decrease the cointainer size)
// The padding is a distance to the borders of the container. Can be either negative (outside, to increase the container size) or positive (inside to decrease the container size)
if (padding === undefined) { padding = 0 }
@@ -2,7 +2,7 @@
* FlexSearch.js v0.7.2 (Bundle)
* Copyright 2018-2021 Nextapps GmbH
* Author: Thomas Wilkerling
* Licence: Apache-2.0
* License: Apache-2.0
* https://github.com/nextapps-de/flexsearch
*/
(function _f(self){'use strict';try{if(module)self=module}catch(e){}self._factory=_f;var t;function u(a){return"undefined"!==typeof a?a:!0}function aa(a){const b=Array(a);for(let c=0;c<a;c++)b[c]=v();return b}function v(){return Object.create(null)}function ba(a,b){return b.length-a.length}function x(a){return"string"===typeof a}function C(a){return"object"===typeof a}function D(a){return"function"===typeof a};function ca(a,b){var c=da;if(a&&(b&&(a=E(a,b)),this.H&&(a=E(a,this.H)),this.J&&1<a.length&&(a=E(a,this.J)),c||""===c)){a=a.split(c);if(this.filter){b=this.filter;c=a.length;const d=[];for(let e=0,f=0;e<c;e++){const g=a[e];g&&!b[g]&&(d[f++]=g)}a=d}return a}return a}const da=/[\p{Z}\p{S}\p{P}\p{C}]+/u,ea=/[\u0300-\u036f]/g;
+2 -2
View File
@@ -76,9 +76,9 @@
function drawSplashText() {
const splashTextArray = [
{
"splashTextLine1Html": '<span class="credits-red">Every month, 10M SA tokens, with a market value of more than 500,000 USD are distributed between everyone contributing to the project during that month. </span>'
"splashTextLine1Html": '<span class="credits-red">Every month, the project distributes 10M SA tokens with an approximate market value of $500,000 among contributors. </span>'
,
"splashTextLine2Html": 'In October 2021 we counted around 50 contributors, with an average mining reward of 10,000 USD for each one. Contributing to Superalgos now is like mining Bitcoin in 2010 where there were no more than 50 people mining it. Ask the community moderators how to join a team an participate in the next distribution.'
"splashTextLine2Html": 'The October 2021 distribution counted around 50 contributors, with an average mining reward of $10,000 each. Contributing to Superalgos today is like mining Bitcoin in 2010! Ask Community Mods how to join a team to participate in the next distribution!'
,
"splashTextLine3Html": ''
} /*,
@@ -7,6 +7,11 @@
"language": "ES",
"text": "La jerarquia trading engine es la estructura de datos utilizada por el robot comercial para mantener la información en tiempo de ejecución altamente accesible y expuesta a otros.",
"updated": 1624452474129
},
{
"language": "RU",
"text": "Trading Engine - это структура данных, используемая торговым ботом для обеспечения высокого доступа к информации во время выполнения и ее доступности для других торговых ботов.",
"updated": 1638338951505
}
]
},
@@ -17,50 +22,127 @@
},
{
"style": "Text",
"text": "You will use this hierarchy for two main purposes:"
"text": "You will use this hierarchy for two main purposes:",
"translations": [
{
"language": "RU",
"text": "Вы будете использовать эту иерархию для двух основных целей:",
"updated": 1638338966721
}
]
},
{
"style": "List",
"text": "To let your trading systems access the information processed by the trading bot. This allows strategies to keep track of and react to current and past events&mdash;including those involving the exchange, such as orders placed or filled&mdash;as the bot is running."
"text": "To let your trading systems access the information processed by the trading bot. This allows strategies to keep track of and react to current and past events&mdash;including those involving the exchange, such as orders placed or filled&mdash;as the bot is running.",
"translations": [
{
"language": "RU",
"text": "Чтобы позволить вашим торговым системам получить доступ к информации, обрабатываемой торговым ботом. Это позволяет стратегиям отслеживать и реагировать на текущие и прошлые события, в том числе связанные с обменом, такие как размещенные или исполненные заявки, во время работы бота.",
"updated": 1638339042173
}
]
},
{
"style": "List",
"text": "To keep track of the actions of the trading bot via the design space visual environment and panels over the charts. By analyzing runtime information, you may gain a detailed understanding of what happens, when, and why, throughout a trading session."
"text": "To keep track of the actions of the trading bot via the design space visual environment and panels over the charts. By analyzing runtime information, you may gain a detailed understanding of what happens, when, and why, throughout a trading session.",
"translations": [
{
"language": "RU",
"text": "Для отслеживания действий торгового бота через визуальную среду Design Space и панели над графиками. Анализируя информацию о времени выполнения, вы можете получить подробное представление о том, что происходит, когда и почему в течение торговой сессии.",
"updated": 1638339093835
}
]
},
{
"style": "Title",
"text": "Frequently Asked Questions"
"text": "Frequently Asked Questions",
"translations": [
{
"language": "RU",
"text": "Часто задаваемые вопросы",
"updated": 1638339158409
}
]
},
{
"style": "Subtitle",
"text": "Can a Trading Engine be shared between two Trading Bots?"
"text": "Can a Trading Engine be shared between two Trading Bots?",
"translations": [
{
"language": "RU",
"text": "Может ли Trading Engine использоваться совместно двумя торговыми ботами?",
"updated": 1638339236191
}
]
},
{
"style": "Text",
"text": "The same trading engine can be used from multiple trading sessions, because it is just a node-based representation of a data structure.",
"updated": 1621987910896
"updated": 1621987910896,
"translations": [
{
"language": "RU",
"text": "Один и тот же торговый движок можно использовать в нескольких торговых сессиях, потому что это просто представление структуры данных на основе узлов.",
"updated": 1638339266880
}
]
},
{
"style": "Text",
"text": "Every time a Task is ran, a snapshot of that data structure, together with a snapshot of the Network and the Bots definitions at their Data Mine is sent from the UI to the Task Server, and from there is consumed by the running Bot. That means that a second Bot can receive the same Trading Engine snapshot and it will never know if other bots were fed with the same information or not.",
"updated": 1621987965915
"updated": 1621987965915,
"translations": [
{
"language": "RU",
"text": "Каждый раз, когда запускается задача Task, снимок этой структуры данных вместе со снимком сети и определениями ботов в их Data Mine отправляется из UI на сервер задач Task Server, а оттуда используется запущенным ботом. Это означает, что второй бот может получить тот же снимок состояния Trading Engine, и он никогда не узнает, были ли другие боты загружены той же информацией или нет.",
"updated": 1638339437677
}
]
},
{
"style": "Subtitle",
"text": "Do I need to change something at the Trading Engine?"
"text": "Do I need to change something at the Trading Engine?",
"translations": [
{
"language": "RU",
"text": "Нужно ли мне что-то менять в Trading Engine?",
"updated": 1638339586902
}
]
},
{
"style": "Text",
"text": "You don't need to physically change anything inside trading engine via the UI. The trading engine is a visual representation of the data structure that the trading system uses to store its values, so to speak."
"text": "You don't need to physically change anything inside trading engine via the UI. The trading engine is a visual representation of the data structure that the trading system uses to store its values, so to speak.",
"translations": [
{
"language": "RU",
"text": "Вам не нужно ничего физически менять внутри Trading Engine через UI. Trading Engine - это визуальное представление структуры данных, которую торговая система использует, так сказать, для хранения своих значений.",
"updated": 1638339666496
}
]
},
{
"style": "Subtitle",
"text": "Can I change the values inside the Trading Engine?"
"text": "Can I change the values inside the Trading Engine?",
"translations": [
{
"language": "RU",
"text": "Могу ли я изменить значения в Trading Engine?",
"updated": 1638339692515
}
]
},
{
"style": "Text",
"text": "You access the Trading Engine from within your trading system if there is something in there you would like to change. This is the whole purpose of the User Defined Code node.",
"updated": 1621988418300
"updated": 1621988418300,
"translations": [
{
"language": "RU",
"text": "Вы получаете доступ к Trading Engine из своей торговой системы, если в ней есть что-то, что вы хотели бы изменить. В этом вся цель узла User Defined Code.",
"updated": 1638339838848
}
]
}
]
}
@@ -7,6 +7,11 @@
"language": "ES",
"text": "Un trading mine es una jerarquía que contiene definiciones de trading bots y sus conspiradores. Estas definiciones constituyen los programas reales de dichos bots: el código fuente.",
"updated": 1628906153772
},
{
"language": "RU",
"text": "Trading Mine - это иерархия, которая содержит определения торговых ботов и их плоттеры. Эти определения составляют фактические программы таких ботов - исходный код.",
"updated": 1638338598326
}
]
},
@@ -17,16 +22,37 @@
},
{
"style": "Text",
"text": "Altough Superalgos is starting out with a single trading bot, the system is prepared to feature as many trading bots as developers are willing to create. As such, a trading mine is a catalog of trading bots."
"text": "Altough Superalgos is starting out with a single trading bot, the system is prepared to feature as many trading bots as developers are willing to create. As such, a trading mine is a catalog of trading bots.",
"translations": [
{
"language": "RU",
"text": "Хотя Superalgos начинает с одного торгового бота, система готова включать в себя столько торговых ботов, сколько разработчики готовы создать. Таким образом, Trading Mine представляет собой каталог торговых ботов.",
"updated": 1638338508685
}
]
},
{
"style": "Text",
"text": "Notice that, in the context of Superalgos, a trading bot has nothing to do with the trading logic. Think of trading logic as the business rules which—in Superalgos—are defined in trading systems. Anyone may build a Trading System, meaning that creating trading systems and the trading strategies within does not require coding.",
"updated": 1609861342619
"updated": 1609861342619,
"translations": [
{
"language": "RU",
"text": "Обратите внимание, что в контексте Superalgos торговый бот не имеет ничего общего с торговой логикой. Думайте о торговой логике как о бизнес-правилах, которые - в Superalgos - определены в торговых системах. Любой может создать торговую систему, а это означает, что создание торговых систем и торговых стратегий внутри нее не требует программирования.",
"updated": 1638338537661
}
]
},
{
"style": "Text",
"text": "Trading mines work similarly to data mines in the sense that they provide the same kind of tools to structure the definitions of bots, including process definitions, product definitions, and plotters."
"text": "Trading mines work similarly to data mines in the sense that they provide the same kind of tools to structure the definitions of bots, including process definitions, product definitions, and plotters.",
"translations": [
{
"language": "RU",
"text": "Trading Mine работает аналогично Data Mine в том смысле, что они предоставляют те же инструменты для структурирования определений ботов, включая определения процессов, определения продуктов и плоттеры.",
"updated": 1638338689173
}
]
},
{
"style": "Block",
@@ -35,7 +61,14 @@
{
"style": "Title",
"text": "Trading Mine Configuration",
"updated": 1609861240385
"updated": 1609861240385,
"translations": [
{
"language": "RU",
"text": "Настройка Trading Mine",
"updated": 1638338789550
}
]
}
]
}
@@ -10,8 +10,8 @@
},
{
"language": "RU",
"text": "Торговая система - это структура, управляющая логикой низкого уровня, которая служит для структурирования процессов и методов, используемых для реализации и развертывания торговых стратегий.",
"updated": 1636194401995
"text": "Trading System - это структура, управляющая логикой низкого уровня, которая служит для структурирования процессов и методов, используемых для реализации и развертывания торговых стратегий.",
"updated": 1638338041020
},
{
"language": "DE",
@@ -33,6 +33,11 @@
"language": "ES",
"text": "En términos prácticos, un Trading System es una disposición jerárquica que organiza los aspectos procesables de su plan de inversión. Esta jerarquía contiene definiciones respecto a un sinnúmero de estrategias de trading, todas operando en el mismo mercado y compartiendo la misma asignación de capital inicial.",
"updated": 1637880963165
},
{
"language": "RU",
"text": "С практической точки зрения торговая система - это иерархическая структура, организующая практические аспекты вашего инвестиционного плана. Иерархия содержит определения относительно любого количества торговых стратегий, работающих на одном рынке и имеющих одинаковое начальное распределение капитала.",
"updated": 1638338066276
}
]
},
@@ -44,6 +49,11 @@
"language": "ES",
"text": "Se utiliza un Trading System para definir estrategias acorde al protocolo de Superalgos, dividiendo a éstas en cuatro etapas: activación, apertura, gestión y cierre.",
"updated": 1637880976135
},
{
"language": "RU",
"text": "Вы используете торговую систему для определения стратегий в соответствии с протоколом Superalgos, разделяя стратегии на четыре этапа: запуск, открытие, управление и закрытие.",
"updated": 1638338085462
}
]
},
@@ -55,6 +65,11 @@
"language": "ES",
"text": "El concepto de describir estrategias en etapas es fundamental para el aspecto metódico del Trading System, ya que provee la infraestructura necesaria para ejecutar cualquier estrategia con la misma infraestructura. Esto contribuye a desarrollar Trading Systems escalables, que pueden alcanzar innumerable cantidad de estrategias.",
"updated": 1637880986625
},
{
"language": "RU",
"text": "Концепция поэтапного описания стратегий является фундаментальной для методического аспекта торговой системы, поскольку она обеспечивает основу для запуска каждой стратегии с одной и той же структурой, что способствует разработке масштабируемых торговых систем, которые могут расширяться до любого количества стратегий.",
"updated": 1638338107057
}
]
},
@@ -66,6 +81,11 @@
"language": "ES",
"text": "Cuando un Trading System ofrece más de una estrategia, la primera estrategia tiene prioridad sobre la segunda, la segunda sobre la tercera, y así sucesivamente. Esto significa que las estrategias son analizadas de manera secuencial. Cuando una estrategia dada es activada, las estrategias restantes no serán analizadas hasta que ésta se desactive. En otras palabras, cuando se implementan múltiples estrategias bajo un único Trading System, solo una estrategia puede operar en un momento dado, y la prioridad está dada por el orden especificado en el Nodo del Trading System.",
"updated": 1637881003253
},
{
"language": "RU",
"text": "Когда торговая система использует более одной стратегии, первая стратегия имеет приоритет над второй, вторая над третьей и так далее. Это означает, что стратегии оцениваются последовательно. Когда данная стратегия срабатывает, оставшиеся в очереди стратегии больше не оцениваются, пока стратегия не сработает. Другими словами, когда несколько стратегий развернуты в одной торговой системе, только одна стратегия может торговать в любой момент времени, а приоритет отдается порядку, установленному вокруг узла торговой системы.",
"updated": 1638338139127
}
]
},
@@ -77,6 +97,11 @@
"language": "ES",
"text": "Como complemento a lo anterior, si se desea configurar estrategias que operen sobre diferentes mercados, o estrategias que tengan la posibilidad de abrir posiciones de forma simultánea, entonces se las deberá configurar bajo Trading Systems distintos.",
"updated": 1637881023208
},
{
"language": "RU",
"text": "Как следствие вышесказанного, если вы хотите, чтобы стратегии работали на разных рынках, или вы хотите, чтобы стратегии могли открывать позиции одновременно, вы должны настроить эти стратегии в разных торговых системах.",
"updated": 1638338156830
}
]
}
@@ -208,7 +208,7 @@ exports.newAlgorithmicTradingBotModulesOrdersSimulations = function (processInde
case tradingSystemOrder.type === 'Market Buy Order' || tradingSystemOrder.type === 'Limit Buy Order': {
if (tradingEngineOrder.orderStatistics.actualRate.value > tradingEngine.tradingCurrent.tradingEpisode.candle.max.value) {
const message = 'Simulating - Actual Rate Too Hight'
const message = 'Simulating - Actual Rate Too High'
let docs = {
project: 'Foundations',
category: 'Topic',
@@ -25,6 +25,8 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let tradingPositionModuleObject = TS.projects.algorithmicTrading.botModules.tradingPosition.newAlgorithmicTradingBotModulesTradingPosition(processIndex)
let tradingExecutionModuleObject = TS.projects.algorithmicTrading.botModules.tradingExecution.newAlgorithmicTradingBotModulesTradingExecution(processIndex)
let announcementsModuleObject = TS.projects.socialBots.botModules.announcements.newSocialBotsBotModulesAnnouncements(processIndex)
let outgoingTradingSignalsModuleObject = TS.projects.tradingSignals.modules.outgoingTradingSignals.newTradingSignalsModulesOutgoingTradingSignals(processIndex)
let portfolioManagerClient = TS.projects.portfolioManagement.modules.portfolioManagerClient.newPortfolioManagementModulesPortfolioManagerClient(processIndex)
let snapshotsModuleObject = TS.projects.algorithmicTrading.botModules.snapshots.newAlgorithmicTradingBotModulesSnapshots(processIndex)
let tradingEpisodeModuleObject = TS.projects.algorithmicTrading.botModules.tradingEpisode.newAlgorithmicTradingBotModulesTradingEpisode(processIndex)
@@ -97,15 +99,15 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingPositionModuleObject.cycleBasedStatistics()
}
function runTriggerStage() {
async function runTriggerStage() {
/*
We check if we will be triggering on, off or taking position.
*/
checkTriggerOn()
checkTriggerOff()
checkTakePosition()
await checkTriggerOn()
await checkTriggerOff()
await checkTakePosition()
function checkTriggerOn() {
async function checkTriggerOn() {
if (
tradingEngine.tradingCurrent.strategy.index.value === tradingEngine.tradingCurrent.strategy.index.config.initialValue
) {
@@ -137,7 +139,12 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.triggerOn, passed)
passed = response.raiseEvent
if (passed) {
tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.triggerOn.id)
tradingSystem.highlights.push(triggerStage.id)
@@ -147,6 +154,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Initialize this */
tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOn.value = 1
await outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.triggerOn)
announcementsModuleObject.makeAnnouncements(triggerStage.triggerOn)
if (TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.type === 'Backtesting Session') {
@@ -156,9 +164,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
}
changeStageStatus('Trigger Stage', 'Open')
}
}
}
@@ -167,7 +173,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function checkTriggerOff() {
async function checkTriggerOff() {
if (tradingEngine.tradingCurrent.strategyTriggerStage.status.value === 'Open') {
checkUserDefinedCode('Trigger Stage', 'Running', 'first');
@@ -188,12 +194,18 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.triggerOff, passed)
passed = response.raiseEvent
if (passed) {
tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.triggerOff.id)
tradingSystem.highlights.push(triggerStage.id)
tradingEngine.tradingCurrent.tradingEpisode.distanceToTradingEvent.triggerOff.value = 1
outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.triggerOff)
announcementsModuleObject.makeAnnouncements(triggerStage.triggerOff)
changeStageStatus('Trigger Stage', 'Closed', 'Trigger Off Event')
tradingStrategyModuleObject.closeStrategy('Trigger Off')
@@ -204,7 +216,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function checkTakePosition() {
async function checkTakePosition() {
if (
tradingEngine.tradingCurrent.strategyTriggerStage.status.value === 'Open'
) {
@@ -212,7 +224,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let triggerStage = strategy.triggerStage
tradingSystem.evalConditions(strategy, 'Take Position Event')
tradingSystem.evalFormulas(strategy, 'Take Position Event')
await tradingSystem.evalFormulas(strategy, 'Take Position Event')
if (triggerStage !== undefined) {
if (triggerStage.takePosition !== undefined) {
@@ -226,6 +238,10 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
passed = tradingSystem.checkConditions(situation, passed)
tradingSystem.values.push([situation.id, passed])
let response = await portfolioManagerClient.askPortfolioEventsManager(triggerStage.takePosition, passed)
passed = response.raiseEvent
if (passed) {
tradingSystem.highlights.push(situation.id)
tradingSystem.highlights.push(triggerStage.takePosition.id)
@@ -233,6 +249,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingPositionModuleObject.openPosition(situation.name)
outgoingTradingSignalsModuleObject.broadcastSignal(triggerStage.takePosition)
announcementsModuleObject.makeAnnouncements(triggerStage.takePosition)
if (TS.projects.foundations.globals.processConstants.CONSTANTS_BY_PROCESS_INDEX_MAP.get(processIndex).SESSION_NODE.type === 'Backtesting Session') {
@@ -259,14 +276,14 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
async function runOpenStage() {
checkIfWeNeedToAbortTheStage()
runWhenStatusIsOpening()
await runWhenStatusIsOpening()
await runWhenStatusIsOpen()
await runWhenStatusIsClosing()
function checkIfWeNeedToAbortTheStage() {
/* Abort Open Stage Check */
if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Open' &&
(tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Opening' || tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Open') ){
(tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Opening' || tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Open')) {
/*
if the Close stage is opened while the open stage is still open that means that
we need to stop placing orders, check what happened to the orders already placed,
@@ -276,7 +293,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function runWhenStatusIsOpening() {
async function runWhenStatusIsOpening() {
/* Opening Status Procedure */
if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Opening') {
/*
@@ -298,7 +315,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
TS.projects.foundations.globals.processModuleObjects.MODULE_OBJECTS_BY_PROCESS_INDEX_MAP.get(processIndex).TRADING_ENGINE_MODULE_OBJECT.initializeNode(tradingEngine.exchangeOrders)
/* Entry Position size and rate */
tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
await tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
tradingPositionModuleObject.initialTargets(tradingSystemStage, tradingEngineStage)
initializeStageTargetSize()
@@ -321,7 +338,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Evaluate conditions and formulas so they are ready during the execution run */
tradingSystem.evalConditions(executionNode, 'Open Execution')
tradingSystem.evalFormulas(executionNode, 'Open Execution')
await tradingSystem.evalFormulas(executionNode, 'Open Execution')
await tradingExecutionModuleObject.runExecution(
executionNode,
@@ -331,7 +348,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* User Defined Code if runWhileAtStage==true */
if (tradingEngine.tradingCurrent.strategyOpenStage.status.value === 'Open') {
checkUserDefinedCode('Open Stage', 'Running', 'last');
checkUserDefinedCode('Open Stage', 'Running', 'last');
}
}
}
@@ -351,7 +368,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
and cancel the ones that were not.
*/
tradingSystem.evalConditions(tradingSystemStage, 'Open Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Open Execution')
await tradingSystem.evalFormulas(tradingSystemStage, 'Open Execution')
await tradingExecutionModuleObject.runExecution(
executionNode,
@@ -407,12 +424,12 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function runManageStage() {
async function runManageStage() {
if (tradingEngine.tradingCurrent.tradingEpisode.cycle.value !== 'First') { return }
runWhenStatusIsOpening()
runWhenStatusIsOpen()
await runWhenStatusIsOpen()
function runWhenStatusIsOpening() {
/* Opening Status Procedure */
@@ -438,7 +455,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
}
}
function runWhenStatusIsOpen() {
async function runWhenStatusIsOpen() {
/* Open Status Procedure */
if (tradingEngine.tradingCurrent.strategyManageStage.status.value === 'Open') {
checkUserDefinedCode('Manage Stage', 'Running', 'first');
@@ -447,7 +464,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Evaluate all the stage conditions and formulas to have them ready */
tradingSystem.evalConditions(manageStage, 'Manage Stage')
tradingSystem.evalFormulas(manageStage, 'Manage Stage')
await tradingSystem.evalFormulas(manageStage, 'Manage Stage')
/* Stop Loss Management */
checkStopPhasesEvents()
@@ -464,7 +481,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* If User Defined Code exists check for runWhileAtStage */
if (tradingEngine.tradingCurrent.strategyManageStage.status.value === 'Open') {
checkUserDefinedCode('Manage Stage', 'Running', 'last');
checkUserDefinedCode('Manage Stage', 'Running', 'last');
}
}
@@ -696,6 +713,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingPositionModuleObject.updateTakeProfit(tradingEngine.tradingCurrent.position.takeProfit.takeProfitPhase.value + 1)
outgoingTradingSignalsModuleObject.broadcastSignal(nextPhaseEvent)
announcementsModuleObject.makeAnnouncements(nextPhaseEvent)
/* Reset this counter */
@@ -747,6 +765,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
continue
}
outgoingTradingSignalsModuleObject.broadcastSignal(moveToPhaseEvent)
announcementsModuleObject.makeAnnouncements(moveToPhaseEvent)
/* Reset this counter */
@@ -810,11 +829,11 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
async function runCloseStage() {
runWhenStatusIsOpening()
await runWhenStatusIsOpening()
await runWhenStatusIsOpen()
await runWhenStatusIsClosing()
function runWhenStatusIsOpening() {
async function runWhenStatusIsOpening() {
/* Opening Status Procedure */
if (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Opening') {
@@ -834,7 +853,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let tradingSystemStage = tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].closeStage
/* Exit Position size and rate */
tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
await tradingSystem.evalFormulas(tradingSystemStage, 'Initial Targets')
if (tradingPositionModuleObject.initialTargets(tradingSystemStage, tradingEngine.tradingCurrent.strategyCloseStage, 'Close Stage') === false) {
//console.log("No Close-Stage Target Asset to Trade: Strategy Closing.");
}
@@ -866,7 +885,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
let executionNode = tradingSystemStage.closeExecution
tradingSystem.evalConditions(tradingSystemStage, 'Close Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingExecutionModuleObject.runExecution(
executionNode,
@@ -876,7 +895,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
checkIfStageNeedsToBeClosed(tradingEngineStage, tradingSystemStage, 'Close Stage')
/* If User Defined Code exists check for runWhileAtStage */
if (tradingEngine.tradingCurrent.strategyCloseStage.status.value === 'Open') {
checkUserDefinedCode('Close Stage', 'Running', 'last');
checkUserDefinedCode('Close Stage', 'Running', 'last');
}
}
}
@@ -896,7 +915,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
and cancel the ones that were not.
*/
tradingSystem.evalConditions(tradingSystemStage, 'Close Execution')
tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingSystem.evalFormulas(tradingSystemStage, 'Close Execution')
await tradingExecutionModuleObject.runExecution(
executionNode,
@@ -1108,6 +1127,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingSystem.highlights.push(closeStageEvent.id)
tradingSystem.highlights.push(stage.id)
outgoingTradingSignalsModuleObject.broadcastSignal(closeStageEvent)
announcementsModuleObject.makeAnnouncements(closeStageEvent)
return true
}
@@ -1172,7 +1192,7 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* Recording the closing at the Trading Engine Data Structure */
stage.end.value = tradingEngine.tradingCurrent.tradingEpisode.cycle.lastEnd.value
stage.endRate.value = tradingEngine.tradingCurrent.tradingEpisode.candle.close.value
if (stageName === 'Open Stage') {
if (tradingEngine.tradingCurrent.strategyCloseStage.status.value !== 'Opening' && tradingEngine.tradingCurrent.strategyCloseStage.status.value !== 'Open' &&
tradingEngine.tradingCurrent.strategyManageStage.status.value !== 'Opening' && tradingEngine.tradingCurrent.strategyManageStage.status.value !== 'Open') {
@@ -1272,20 +1292,20 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
tradingSystemStage.userDefinedCode !== undefined) {
if (status === 'Running' && when !== tradingSystemStage.userDefinedCode.config.whileAtStageWhenToRun) { return; }
switch(status) {
case 'Open' : {
switch (status) {
case 'Open': {
if (tradingSystemStage.userDefinedCode.config.runWhenEnteringStage) {
tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code');
}
break;
}
case 'Running' : {
case 'Running': {
if (tradingSystemStage.userDefinedCode.config.runWhileAtStage) {
tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code');
}
break;
}
case 'Closed' : {
case 'Closed': {
if (tradingSystemStage.userDefinedCode.config.runWhenExitingStage) {
tradingSystem.evalUserCode(tradingSystemStage, 'User Defined Code');
}
@@ -1305,23 +1325,23 @@ exports.newAlgorithmicTradingBotModulesTradingStages = function (processIndex) {
/* getTradingSystemStage(): takes stage name returns stage object. */
function getTradingSystemStage(stage) {
switch(stage) {
case 'Trigger Stage' : {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].triggerStage;
break;
switch (stage) {
case 'Trigger Stage': {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].triggerStage;
break;
}
case 'Open Stage': {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].openStage;
break;
}
case 'Manage Stage': {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].manageStage;
break
}
case 'Close Stage': {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].closeStage;
break;
}
}
case 'Open Stage' : {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].openStage;
break;
}
case 'Manage Stage' : {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].manageStage;
break
}
case 'Close Stage' : {
return tradingSystem.tradingStrategies[tradingEngine.tradingCurrent.strategy.index.value].closeStage;
break;
}
}
}
}
@@ -27,6 +27,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
let dynamicIndicators
let tradingStagesModuleObject = TS.projects.algorithmicTrading.botModules.tradingStages.newAlgorithmicTradingBotModulesTradingStages(processIndex)
let portfolioManagerClient = TS.projects.portfolioManagement.modules.portfolioManagerClient.newPortfolioManagementModulesPortfolioManagerClient(processIndex)
let taskParameters = {
market: TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.baseAsset.referenceParent.config.codeName +
@@ -70,12 +71,12 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
evalNode(startingNode, 'Conditions', descendentOfNodeType)
}
tradingSystem.evalFormulas = function (startingNode, descendentOfNodeType) {
evalNode(startingNode, 'Formulas', descendentOfNodeType)
tradingSystem.evalFormulas = async function (startingNode, descendentOfNodeType) {
await evalNode(startingNode, 'Formulas', descendentOfNodeType)
}
tradingSystem.evalUserCode = function (startingNode, descendentOfNodeType) {
evalNode(startingNode, 'User Codes', descendentOfNodeType);
evalNode(startingNode, 'User Codes', descendentOfNodeType);
}
tradingSystem.addError = function (errorDataArray) {
@@ -203,13 +204,13 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
buildDynamicIndicators()
/* Run the Trigger Stage */
tradingStagesModuleObject.runTriggerStage()
await tradingStagesModuleObject.runTriggerStage()
/* Run the Open Stage */
await tradingStagesModuleObject.runOpenStage()
/* Run the Manage Stage */
tradingStagesModuleObject.runManageStage()
await tradingStagesModuleObject.runManageStage()
/* Run the Close Stage */
await tradingStagesModuleObject.runCloseStage()
@@ -234,7 +235,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
}
}
function evalNode(node, evaluating, descendentOfNodeType, isDescendent) {
async function evalNode(node, evaluating, descendentOfNodeType, isDescendent, parentNode) {
if (node === undefined) { return }
/* Verify if this node is descendent of the specified node type */
@@ -257,18 +258,18 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
if (node.code !== undefined) {
/* We will eval this formula */
if (isDescendent === true) {
evalFormula(node)
await evalFormula(node, parentNode)
}
}
}
/* Here we check if there is a User Defined-Javascript Code to be evaluated: */
if (node.type === 'Javascript Code' && evaluating === 'User Codes') {
if (node.code !== undefined) {
if (isDescendent === true) {
evalJSCode(node);
if (node.code !== undefined) {
if (isDescendent === true) {
evalJSCode(node);
}
}
}
}
/* Now we go down through all this node children */
@@ -284,7 +285,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
case 'node': {
if (property.name !== previousPropertyName) {
if (node[property.name] !== undefined) {
evalNode(node[property.name], evaluating, descendentOfNodeType, isDescendent)
await evalNode(node[property.name], evaluating, descendentOfNodeType, isDescendent, node)
}
previousPropertyName = property.name
}
@@ -294,7 +295,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
if (node[property.name] !== undefined) {
let nodePropertyArray = node[property.name]
for (let m = 0; m < nodePropertyArray.length; m++) {
evalNode(nodePropertyArray[m], evaluating, descendentOfNodeType, isDescendent)
await evalNode(nodePropertyArray[m], evaluating, descendentOfNodeType, isDescendent, node)
}
}
break
@@ -357,7 +358,7 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, '[INFO] evalCondition -> value = ' + value)
}
function evalFormula(node) {
async function evalFormula(node, parentNode) {
let value
let errorMessage
let docs
@@ -365,6 +366,10 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
try {
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, '[INFO] evalFormula -> ' + node.name + ' -> code = ' + node.code)
value = eval(node.code)
let response = await portfolioManagerClient.askPortfolioFormulaManager(parentNode, value)
value = response.value
} catch (err) {
/*
One possible error is that the formula references a .previous that is undefined. This
@@ -423,29 +428,29 @@ exports.newAlgorithmicTradingBotModulesTradingSystem = function (processIndex) {
}
function evalJSCode(node) {
let value
let errorMessage
let docs
let value
let errorMessage
let docs
try {
value = eval(node.code);
try {
value = eval(node.code);
} catch (err) {
value = 0
errorMessage = err.message
docs = {
project: 'Foundations',
category: 'Topic',
type: 'TS LF Trading Bot Error - Evaluating User Code Error',
placeholder: {}
} catch (err) {
value = 0
errorMessage = err.message
docs = {
project: 'Foundations',
category: 'Topic',
type: 'TS LF Trading Bot Error - Evaluating User Code Error',
placeholder: {}
}
TS.projects.education.utilities.docsFunctions.buildPlaceholder(docs, err, node.name, node.code, undefined)
}
TS.projects.education.utilities.docsFunctions.buildPlaceholder(docs, err, node.name, node.code, undefined)
}
if (errorMessage !== undefined) {
tradingSystem.addError([node.id, errorMessage, docs])
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, '[INFO] evalFormula -> errorMessage = ' + errorMessage)
return
}
if (errorMessage !== undefined) {
tradingSystem.addError([node.id, errorMessage, docs])
TS.projects.foundations.globals.loggerVariables.VARIABLES_BY_PROCESS_INDEX_MAP.get(processIndex).BOT_MAIN_LOOP_LOGGER_MODULE_OBJECT.write(MODULE_NAME, '[INFO] evalFormula -> errorMessage = ' + errorMessage)
return
}
}
}
@@ -584,9 +584,10 @@
}
function startLiveTrading() {
// Testing:
TS.projects.foundations.globals.processVariables.PM_COMMUNICATION_MODULE.beginListening();
TS.projects.foundations.globals.processVariables.PM_COMMUNICATION_MODULE.getQuoteAssetBalance();
/* Testing to be removed @PLUV: */
/*TS.projects.foundations.globals.processVariables.PM_COMMUNICATION_MODULE.beginListening();
TS.projects.foundations.globals.processVariables.PM_COMMUNICATION_MODULE.getQuoteAssetBalance();*/
/* End Testing */
return checkKey()
}
@@ -36,9 +36,9 @@
"relatedUiObjectProject": "Community-Plugins"
},
{
"action": "Save Plugin",
"action": "Save Plugin File",
"actionFunction": "payload.executeAction",
"label": "Save Plugin",
"label": "Save Plugin File",
"relatedUiObject": "Plugin File",
"actionProject": "Community-Plugins",
"relatedUiObjectProject": "Community-Plugins"
@@ -10,8 +10,8 @@
},
{
"language": "RU",
"text": "Иерархия плагинов определяет, какие плагины должны быть включены в текущую рабочую область. В контексте этой иерархии плагины представляют собой файлы JSON, содержащие описание иерархии, такой как шахта данных, торговая шахта, торговый механизм или торговая система.",
"updated": 1636194488881
"text": "Иерархия Plugins определяет, какие плагины должны быть включены в текущую рабочую область Workspace. В контексте этой иерархии плагины - это файлы JSON, содержащие описание иерархии, такой как Data Mine, Trading Mine, Trading Engine или Trading System.",
"updated": 1638340280833
}
]
},
@@ -22,12 +22,26 @@
},
{
"style": "Text",
"text": "In the context of a community-driven project, a plugin is a device that serves to distribute community-generated intelligence. The project distributes several plugins contributed by the community."
"text": "In the context of a community-driven project, a plugin is a device that serves to distribute community-generated intelligence. The project distributes several plugins contributed by the community.",
"translations": [
{
"language": "RU",
"text": "В контексте проекта, управляемого сообществом, плагин - это устройство, которое служит для распространения информации, созданной сообществом. Проект распространяет несколько плагинов, предоставленных сообществом.",
"updated": 1638340321953
}
]
},
{
"style": "Important",
"text": "Hierarchies included in the workspace as plugins are not saved at the workspace level. As such, changes made in those hierarchies do not persist. If you wish to modify a plugin and keep working with the modified version in the future, you must either clone or backup the plugin and work on the resulting copy instead.",
"updated": 1609866745275
"updated": 1609866745275,
"translations": [
{
"language": "RU",
"text": "Иерархии (Hierarchies), включенные в рабочую область как плагины, не сохраняются на уровне рабочей области. Таким образом, изменения, внесенные в эти иерархии, не сохраняются. Если вы хотите изменить плагин и продолжить работу с измененной версией в будущем, вы должны либо клонировать, либо сделать резервную копию плагина и вместо этого работать с полученной копией.",
"updated": 1638340382678
}
]
}
]
}
@@ -39,9 +39,9 @@ function newCommunityPluginsActionSwitch() {
}
break
case 'Add Specified Plugin Data Mine':
{
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.addSpecifiedPluginDataMine(action.node, action.rootNodes)
}
{
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.addSpecifiedPluginDataMine(action.node, action.rootNodes)
}
break
case 'Add Missing Plugin Trading Mines':
{
@@ -108,9 +108,14 @@ function newCommunityPluginsActionSwitch() {
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.disableSavingWithWorkspace(action.node, action.rootNodes, action.callBackFunction)
}
break
case 'Save Plugin File':
{
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.savePluginFile(action.node, action.rootNodes)
}
break
case 'Save Plugin':
{
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.savePlugin(action.node, action.rootNodes)
UI.projects.communityPlugins.functionLibraries.pluginsFunctions.savePluginHierarchy(action.node, action.rootNodes)
}
break
@@ -17,7 +17,8 @@ function newPluginsFunctionLibraryPluginsFunctions() {
addMissingPluginApiMaps: addMissingPluginApiMaps,
enableSavingWithWorkspace: enableSavingWithWorkspace,
disableSavingWithWorkspace: disableSavingWithWorkspace,
savePlugin: savePlugin,
savePluginFile: savePluginFile,
savePluginHierarchy: savePluginHierarchy,
installAsPlugin: installAsPlugin
}
return thisObject
@@ -283,8 +284,35 @@ function newPluginsFunctionLibraryPluginsFunctions() {
callBackFunction(GLOBAL.DEFAULT_OK_RESPONSE)
}
function savePlugin(node, rootNodes) {
UI.projects.communityPlugins.utilities.plugins.savePluginFile(node)
function savePluginFile(pluginFile, rootNodes) {
UI.projects.communityPlugins.utilities.plugins.savePluginFileAtClient(pluginFile)
}
function savePluginHierarchy(node, rootNodes) {
if (node.isPlugin !== true) { return }
let plugins = UI.projects.foundations.spaces.designSpace.workspace.getHierarchyHeadByNodeType('Plugins')
let pluginProject = UI.projects.visualScripting.utilities.nodeChildren.findChildByCodeName(plugins, node.project)
let pluginFolderName = UI.projects.communityPlugins.utilities.plugins.getPluginFolderNamesByNodeType(node.type)
let pluginForlderNodeType = 'Plugin ' + pluginFolderName.replaceAll('-', ' ')
let pluginFolderNode = UI.projects.visualScripting.utilities.nodeChildren.findChildByType(pluginProject, pluginForlderNodeType)
for (let i = 0; i < pluginFolderNode.pluginFiles.length; i++) {
let pluginFile = pluginFolderNode.pluginFiles[i]
let fileName = UI.projects.visualScripting.utilities.nodeConfig.loadConfigProperty(pluginFile.payload, 'fileName')
let codeName = UI.projects.visualScripting.utilities.nodeConfig.loadConfigProperty(node.payload, 'codeName')
if (codeName === fileName) {
UI.projects.communityPlugins.utilities.plugins.savePluginFileAtClient(pluginFile)
/*
Show nice message.
*/
node.payload.uiObject.setInfoMessage(
"Plugin Saved.",
UI.projects.governance.globals.designer.SET_INFO_COUNTER_FACTOR
)
return
}
}
}
function installAsPlugin(node, rootNodes) {
@@ -301,6 +329,8 @@ function newPluginsFunctionLibraryPluginsFunctions() {
return
}
UI.projects.communityPlugins.utilities.plugins.savePluginFile(pluginFile)
UI.projects.communityPlugins.utilities.plugins.savePluginFileAtClient(pluginFile)
}
}
@@ -5,7 +5,7 @@ function newPluginsUtilitiesPlugins() {
addMissingPluginFiles: addMissingPluginFiles,
addMissingPluginFile: addMissingPluginFile,
getProjectName: getProjectName,
savePluginFile: savePluginFile
savePluginFileAtClient: savePluginFileAtClient
}
return thisObject
@@ -119,7 +119,7 @@ function newPluginsUtilitiesPlugins() {
return config.codeName
}
function savePluginFile(pluginFile) {
function savePluginFileAtClient(pluginFile) {
let project = UI.projects.visualScripting.utilities.nodeConfig.loadConfigProperty(pluginFile.payload, 'project')
let fileName = UI.projects.visualScripting.utilities.nodeConfig.loadConfigProperty(pluginFile.payload, 'fileName')
let folderName = UI.projects.visualScripting.utilities.nodeConfig.loadConfigProperty(pluginFile.payload, 'folderName')
@@ -11,8 +11,8 @@
},
{
"language": "RU",
"text": "Шахта данных - это иерархия, содержащая определения датчиков и ботов-индикаторов, а также их плоттеров. Эти определения взяты из фактического кода таких ботов.\n",
"updated": 1636192911774
"text": "Data Mine - это иерархия, содержащая определения датчиков и ботов-индикаторов, а также их плоттеров. Эти определения взяты из фактического кода таких ботов.",
"updated": 1638275063658
}
]
},
@@ -23,11 +23,35 @@
},
{
"style": "Text",
"text": "In a way, data mines are catalogs of bots that anyone may create. This hierarchy provides all the tools required to create sensors, indicators, and plotters, with minimal coding required."
"text": "In a way, data mines are catalogs of bots that anyone may create. This hierarchy provides all the tools required to create sensors, indicators, and plotters, with minimal coding required.",
"translations": [
{
"language": "ES",
"text": "En cierto modo, los Data Mines son listas de bots que pueden ser creados por cualquier usuario. Esta jerarquía provee todas las herramientas necesarias para crear sensores, indicadores y gráficos, con un mínimo requerimiento de código.",
"updated": 1638150280351
},
{
"language": "RU",
"text": "В каком-то смысле Data Mine - это каталоги ботов, которые может создать каждый. Эта иерархия предоставляет все инструменты, необходимые для создания датчиков, индикаторов и плоттеров с минимальным кодированием.",
"updated": 1638339932741
}
]
},
{
"style": "Text",
"text": "Because the hierarchy provides definitions, it does not intervene in the execution of bots. Instead, the definitions in data mines are instantiated from the network hierarchy by bot instances. Bot instances and process instances are the ones running the code according to the definitions in the corresponding data mine."
"text": "Because the hierarchy provides definitions, it does not intervene in the execution of bots. Instead, the definitions in data mines are instantiated from the network hierarchy by bot instances. Bot instances and process instances are the ones running the code according to the definitions in the corresponding data mine.",
"translations": [
{
"language": "ES",
"text": "Debido a que la jerarquía solo proporciona definiciones, no interfiere en la ejecución de Bots. Sino que las definiciones en los Data Mines son instanciados desde la jerarquía Network por las instancias de los Bots. Las instancias de los Bots y las instancias de procesos son las encargadas de ejecutar el código acorde a las definiciones del Data Mine correspondiente.",
"updated": 1638150294294
},
{
"language": "RU",
"text": "Поскольку иерархия предоставляет определения, она не вмешивается в выполнение ботов. Вместо этого определения в Data Mine создаются экземплярами ботов из сетевой иерархии. Экземпляры ботов и экземпляры процессов - это те, которые запускают код в соответствии с определениями в соответствующем хранилище данных.",
"updated": 1638339974635
}
]
},
{
"style": "Block",
@@ -36,16 +60,37 @@
{
"style": "Title",
"text": "Data Mine Configuration",
"updated": 1609789108763
"updated": 1609789108763,
"translations": [
{
"language": "RU",
"text": "Конфигурирование Data Mine",
"updated": 1638340008131
}
]
},
{
"style": "Subtitle",
"text": "Properties",
"updated": 1609789116514
"updated": 1609789116514,
"translations": [
{
"language": "RU",
"text": "Свойства",
"updated": 1638340048023
}
]
},
{
"style": "List",
"text": "codeName is the name of the data mine as used within the code of the system."
"text": "codeName is the name of the data mine as used within the code of the system.",
"translations": [
{
"language": "RU",
"text": "codeName - это имя хранилища данных, используемое в коде системы.",
"updated": 1638340067608
}
]
}
]
}
@@ -65,7 +65,7 @@
let exchangeClass
/*
This is what we are going to do hereL
1. Parameters set by SA user at the Crypto Exchange node are extracted. There might be parameters for each supported method at the CCXT library.
2. The CCXT class for the configured exchange is instantiated, with whatever options where configured.
@@ -75,6 +75,12 @@
statusDependencies = pStatusDependencies;
exchangeId = TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.config.codeName
/*
maxRate - sets the maximum number of OHCLV that is pulled before the data is saved.
This is only to be used when the exchange is kicking out the data-mine randomly and alows the user to
save the data more often allowing for the data mining to move forward.
*/
maxRate = TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.config.maxRate
/* Applying the parameters defined by the user at the Exchange Node Config */
if (TS.projects.foundations.globals.taskConstants.TASK_NODE.parentNode.parentNode.parentNode.referenceParent.parentNode.parentNode.config.API !== undefined) {
@@ -578,6 +584,16 @@
let currentDate = new Date(since)
/*
maxRate - sets the maximum number of OHCLV that is pulled before the data is saved.
maxRate should only be used when the exchange is kicking out the data-mine randomly and alows the user to
save the data more often allowing for the data mining to move forward.
Check if we don't have a maxRate parameter and use global parameter instead
*/
if (!maxRate) {
maxRate = MAX_OHLCVs_PER_EXECUTION
}
/*
If we've pulled less OHLCVs than the limit, this either means:
(1) we reached the current date and are now pulling the latest
@@ -0,0 +1,34 @@
{
"type": "Current projects",
"definition": {
"text": "The table below contains all current projects to which you can add new docs-articles. Feel free to add projects if they are missing.",
"updated": 1638112235073
},
"paragraphs": [
{
"style": "Table",
"text": "|Project|Project Explanation|\n|Algorithmic-Trading|Project Explanation|\n|Community-Plugins|Project Explanation|\n|Data-Mining|Project Explanation|\n|Education|This Project is about building up and maintaining the Docs (-Articles)|\n|Ethereum|Project Explanation|\n|Foundations|Project Explanation|\n|Governance|Manages and organizes the Superalgos Project (All of us, the community)|\n|Machine-Learning|Project Explanation|\n|Network|Project Explanation|\n|Social-Bots|Project Explanation|\n|Social-Trading|Project Explanation|\n|TensorFlow|Project Explanation|\n|Visual-Scripting|Project Explanation|",
"updated": 1638116155258,
"translations": [
{
"language": "DE",
"text": "|Project|Project Explanation|\n|Algorithmic-Trading|Project Explanation|\n|Community-Plugins|Project Explanation|\n|Data-Mining|Project Explanation|\n|Education|This Project is about building up and maintaining the Docs (-Articles)|\n|Ethereum|Project Explanation|\n|Foundations|Project Explanation|\n|Governance|Manages and organizes the Superalgos Project (All of us, the community)|\n|Machine-Learning|Project Explanation|\n|Network|Project Explanation|\n|Social-Bots|Project Explanation|\n|Social-Trading|Project Explanation|\n|TensorFlow|Project Explanation|\n|Visual-Scripting|Project Explanation|",
"updated": 1638115499301
}
]
},
{
"style": "Text",
"text": "Created and maintained by gitforkgit.",
"updated": 1638112659687
},
{
"style": "Text",
"text": ""
},
{
"style": "Text",
"text": ""
}
]
}
@@ -0,0 +1,63 @@
{
"type": "Technical term overview",
"definition": {
"text": "This article was created to show you which terms you should not translate because they are a fixed term. An example is the word Node. Created and maintained by gitforkgit.",
"updated": 1638052921801,
"translations": [
{
"language": "DE",
"text": "This article was created to show you which terms you should not translate because they are a fixed term. An example is the word Node. Created and maintained by gitforkgit ",
"updated": 1638052964966
}
]
},
"paragraphs": [
{
"style": "Text",
"text": "One of our goals is to make Superalgos available for everyone for free and open source forever. For this, translations are extremely important and essential. However, there are some technical terms that should not be translated. Because otherwise it could be difficult when describing problems to others, start contributing, understanding superalgos...",
"updated": 1638052177612
},
{
"style": "Text",
"text": "\"Below here is a table in which the terms are listed. Here the translators can orient themselves and each Superalgos user add terms of which he thinks that they should not be translated. If you translate articles please look here from time to time to see which terms you should leave as they are in the original. Translations in brackets behind the terms themselves are of course legitimate and welcome by readers of the articles.",
"updated": 1638052195441
},
{
"style": "Success",
"text": "Feel free to add Terms in the table!",
"updated": 1638052209974
},
{
"style": "Note",
"text": "Terms that should remain original in the translations of articles:",
"updated": 1638052228369
},
{
"style": "Table",
"text": "|Workspace Terms|Node Terms|Other Technical Terms|Workspace Terms translation|Node Terms translation|Other Technical Terms translation|\n|Pin/Unpin|Node|add terms here|add Term translation here|add Term translation here|add Term translation here|\n|add terms here|Parent Node|add terms here|add Term translation here|add Term translation here|add Term translation here|\n|add terms here|Child Node|add terms here|add Term translation here|add Term translation here|add Term translation here|\n|add terms here|add terms here|add terms here|add Term translation here|add Term translation here|add Term translation here|",
"updated": 1638052333924
},
{
"style": "List",
"text": "Workspace terms -> all Technical Terms related to the Workspace",
"updated": 1638487168731
},
{
"style": "List",
"text": "node Terms -> all Technical Terms related to Nodes "
},
{
"style": "List",
"text": "Other Technical Terms -> all Technical Terms that dont fit the other categories"
},
{
"style": "Note",
"text": "In the columns with translation as their header you can add the translation into your language, if your language is selected in the footer, otherwise the translations would be globally in the table what isn`t the Goal.",
"updated": 1638486873653
},
{
"style": "Text",
"text": ""
}
]
}
@@ -18,8 +18,8 @@
},
{
"language": "RU",
"text": "Иерархия данного пособия содержит свободное расположение Tutorial Topic и узлов Tutorial Step, которые вместе составляют это учебное пособие. Каждый узел в иерархии, включая родительский узел пособия, представляет собой HTML-страницу, которая может быть наложена поверх Design Space и Charting Space.",
"updated": 1635509527381
"text": "Иерархия Tutorial содержит свободное расположение Tutorial Topic и узлов Tutorial Step, которые вместе составляют это учебное пособие. Каждый узел в иерархии, включая родительский узел пособия, представляет собой HTML-страницу, которая может быть наложена поверх Design Space и Charting Space.",
"updated": 1638340460215
}
]
},
@@ -38,6 +38,11 @@
"text": "Die Nodes in der Hierarchie können frei angeordnet werden, das heißt es können beliebig viele Tutorial-Themen (topic) und Tutorial-Steps vorhanden sein. Tutorial Themen können Tutorial Schritte aber auch andere Tutorial Themen enthalten. Dies erlaubt es verschachtelte Themen als Unterthemen verwendet werden.",
"updated": 1633975991952,
"style": "Text"
},
{
"language": "RU",
"text": "Узлы в иерархии могут быть расположены произвольно, что означает, что может быть столько обучающих тем и обучающих шагов, сколько необходимо. Темы учебного пособия могут содержать этапы обучения, а также другие разделы учебного пособия. Это позволяет использовать вложенные темы в качестве подтем.",
"updated": 1638340558172
}
]
},
@@ -51,6 +56,11 @@
"text": "Das System wertet die Hierarchie - wie üblich - im Uhrzeigersinn aus, beginnend mit dem Knoten rechts vom übergeordneten Tutorial-Knoten, zum tiefsten Knoten jedes Zweigs geht, bevor es zum nächsten geht.",
"updated": 1633976627129,
"style": "Text"
},
{
"language": "RU",
"text": "Система, как обычно, оценивает иерархию по часовой стрелке, начиная с узла справа от родительского узла Tutorial, и переходит к самому глубокому узлу каждой ветви перед переходом к следующему.",
"updated": 1638340581444
}
]
},
@@ -64,6 +74,11 @@
"text": "Im Allgemeinen verhalten sich alle nodes ähnlich in dem Sinne, dass jede node, unabhängig vom genauen Typ, für sich genommen einen Lernschritt darstellt. Das heißt, alle nodes, einschließlich der obersten Tutorial-node, der Tutorial Topic node und der Tutorial Step node können eine Inhaltsseite als Schritt im Tutorial anzeigen. Feinere Unterschiede sind gegebenenfalls hervorzuheben.",
"updated": 1633976586338,
"style": "Callout"
},
{
"language": "RU",
"text": "В общих чертах, все типы узлов ведут себя одинаково в том смысле, что каждый узел, независимо от конкретного типа, представляет собой учебный шаг сам по себе. То есть все узлы, включая узел верхнего уровня Tutorial, узел Tutorial Topic и узел Tutorial Step, могут отображать страницу содержимого в качестве шага в руководстве. При необходимости следует указать на незначительные различия.",
"updated": 1638340613514
}
]
},
@@ -77,6 +92,11 @@
"text": "Die wichtigste Gemeinsamkeit aller Knotentypen in der Hierarchie ist, dass sie alle Inhalte aus der Sammlung der Dokumentseiten des Tutorials beziehen können. Das heißt, jeder Knoten in der Hierarchie zeigt auf eine Docs Page (Dokumentationsseite), und es ist diese Seite in den Dokumenten, die den Inhalt für den gegebenen Schritt anzeigt. Der Zeiger wird in der Konfiguration jedes Knotens angegeben (siehe die Eigenschaft docs).",
"updated": 1633976778899,
"style": "Note"
},
{
"language": "RU",
"text": "Ключевое сходство между всеми типами узлов в иерархии заключается в том, что все они могут рисовать контент из коллекции страниц в Документах. То есть каждый узел в иерархии указывает на страницу Docs, и именно эта страница Docs Page содержит контент, отображаемый для данного шага. Указатель указывается в конфигурации каждого узла (см. Свойство docs).",
"updated": 1638340776119
}
]
},
@@ -94,6 +114,11 @@
"text": "Tutorial Konfiguration",
"updated": 1633976794872,
"style": "Title"
},
{
"language": "RU",
"text": "Конфигурация Tutorial",
"updated": 1638340822415
}
]
},
@@ -107,6 +132,11 @@
"text": "Die Konfiguration jedes Knotens in der Tutorial-Hierarchie bestimmt den Inhalt und das Verhalten der einzelnen Schritte. Alle node-typen haben die gleiche Grundkonfiguration. Tutorial Step nodes haben jedoch zusätzliche Eigenschaften, die auf der Seite \" Tutorial Step nodes \" beschrieben werden.",
"updated": 1633977045116,
"style": "Text"
},
{
"language": "RU",
"text": "Конфигурация каждого узла в иерархии учебника определяет содержание и поведение каждого шага. Все типы узлов имеют одинаковую базовую конфигурацию. Однако узлы Tutorial Step имеют дополнительные свойства, описанные на странице узла Tutorial Step.",
"updated": 1638340869518
}
]
},
@@ -120,6 +150,11 @@
"text": "Die auf dieser Seite beschriebenen Konfigurationseigenschaften gelten für alle Arten von Nodes in der Hierarchie.",
"updated": 1633977077545,
"style": "Success"
},
{
"language": "RU",
"text": "Свойства конфигурации, обсуждаемые на этой странице, применяются ко всем типам узлов в иерархии.",
"updated": 1638340885116
}
]
},
@@ -133,6 +168,11 @@
"text": "Das Layout der HTML-Seite folgt dem Layout der zugehörigen Seite in den Docs, wird aber innerhalb der Grenzen des Tutorial-Fensters angezeigt.",
"updated": 1633977110132,
"style": "Text"
},
{
"language": "RU",
"text": "Макет HTML-страницы соответствует макету связанной страницы в Docs, хотя отображается в пределах окна учебника.",
"updated": 1638340917482
}
]
},
@@ -146,6 +186,11 @@
"text": "Mit anderen Worten beeinflussen Sie das Layout des jeweiligen Schritts, indem Sie Inhalte schreiben und Stile auf einzelne Absätze in der zugehörigen Docs-Page anwenden.",
"updated": 1633977352460,
"style": "Callout"
},
{
"language": "RU",
"text": "Другими словами, вы влияете на макет конкретного шага, записывая содержимое и применяя стили к отдельным абзацам на связанной странице Docs Page.",
"updated": 1638340975740
}
]
},
@@ -159,6 +204,11 @@
"text": "Die HTML / Tutorial -Seite verfügt über einen begrenzten Platz und unterstützt kein Scrollen. Wenn zu viele Informationen in der zugehörigen Docs Page definiert werden, übersteigt der resultierende Inhalt den verfügbaren Platz im Tutorial-Fenster. Es gibt keine systemseitige Kontrolle, um mit solchen Text-Überläufen (in den Tutorial fenstern) umzugehen, so dass es an Ihnen liegt, die Informationen auf mehrere Schritte zu verteilen und jede Seite innerhalb ihrer Grenzen zu halten.",
"updated": 1633977528479,
"style": "Note"
},
{
"language": "RU",
"text": "HTML-страница имеет ограниченное пространство и не поддерживает прокрутку. Если на связанной странице Docs Page определено слишком много информации, результирующий контент будет переполнять доступное пространство в окне руководства. Нет никакого системного контроля, чтобы справиться с такими переполнениями, так что вам решать, распределять информацию по нескольким шагам и держать каждую страницу в своих пределах.",
"updated": 1638341066695
}
]
},
@@ -172,6 +222,11 @@
"text": "Eigenschaften der Konfiguration",
"updated": 1633977545673,
"style": "Title"
},
{
"language": "RU",
"text": "Свойства конфигурации",
"updated": 1638341097060
}
]
},
@@ -190,6 +245,11 @@
"text": "Das Eigenschaftssymbol benötigt zwei Definitionen:",
"updated": 1633977572877,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство \"icon\" требует двух определений:",
"updated": 1638341508736
}
]
},
@@ -202,6 +262,11 @@
"text": "Der \"name\" des Symbols ohne die Erweiterung;",
"updated": 1633977609627,
"style": "List"
},
{
"language": "RU",
"text": "Название \"name\" значка без расширения;",
"updated": 1638341578178
}
]
},
@@ -214,6 +279,11 @@
"text": "Das \"project\", zu dem das Symbol gehört.",
"updated": 1633977635502,
"style": "List"
},
{
"language": "RU",
"text": "Название пректа \"Project\", которому принадлежит значок.",
"updated": 1638341642470
}
]
},
@@ -226,6 +296,11 @@
"text": "Zu Ihrer Information: Die Icons (Symbole) werden unter folgendem Pfad gespeichert:",
"updated": 1633977674577,
"style": "Text"
},
{
"language": "RU",
"text": "Для справки, значки хранятся по следующему пути:",
"updated": 1638341659063
}
]
},
@@ -244,6 +319,11 @@
"text": "Verwenden Sie die vorhandene Sammlung von Icons (Symbolen), um jeden Schritt des Tutorials zu illustrieren. Diese Illustrationen tragen sehr viel zu einer überzeugenderen Kommunikation bei.",
"updated": 1633977745001,
"style": "Success"
},
{
"language": "RU",
"text": "Используйте существующую коллекцию значков, чтобы проиллюстрировать каждый шаг учебного пособия. Эти иллюстрации помогают сделать общение более убедительным.",
"updated": 1638341684555
}
]
},
@@ -257,6 +337,11 @@
"text": "Wenn die Konfiguration vorhanden ist, wird das Symbol in einer Tabelle neben dem Textblock platziert, der das Definitionsfeld der zugehörigen Docs Page bildet. Wenn kein Symbol vorhanden ist, nimmt die Definition die gesamte Breite der Seite ein.",
"updated": 1633977797138,
"style": "Text"
},
{
"language": "RU",
"text": "Когда конфигурация существует, значок помещается в таблицу рядом с текстовым блоком, который составляет поле определения связанной страницы Docs Page. Когда нет значка, определение занимает всю ширину страницы.",
"updated": 1638341729479
}
]
},
@@ -275,6 +360,11 @@
"text": "Die obige Konfiguration platziert das Symbol balance.png des Superalgos-Projekts in der Tabelle der entsprechenden Docs-Seite (siehe die docs Eigenschaft unten).",
"updated": 1633977851249,
"style": "Text"
},
{
"language": "RU",
"text": "Приведенная выше конфигурация помещает значок balance.png проекта Superalgos в таблицу на соответствующей странице Docs (см. Свойство docs ниже).",
"updated": 1638341767468
}
]
},
@@ -293,6 +383,11 @@
"text": "Die Eigenschaft \"position\" bestimmt die Position des fließenden HTML-Dokuments (Tutorial-Fensters). Es gibt drei Alternativen... \"Links\", \"Rechts\", oder lassen Sie das Feld leer, um die Seite in der Mitte des Bildschirms zu positionieren.",
"updated": 1633977968939,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство \"position\" определяет положение плавающего HTML. Есть три варианта: «Left», «Right» или оставьте поле пустым, чтобы разместить страницу в центре экрана.",
"updated": 1638341861917
}
]
},
@@ -311,6 +406,11 @@
"text": "Bei der obigen Konfiguration befindet sich das Tutorial-Fenster auf der linken Seite des Bildschirms.",
"updated": 1633978012441,
"style": "Text"
},
{
"language": "RU",
"text": "Приведенная выше конфигурация помещает шаг обучения в левой части экрана.",
"updated": 1638341886907
}
]
},
@@ -328,13 +428,25 @@
"text": "Die Eigenschaft slider bestimmt die Position des horizontalen Schiebereglers. Es gibt drei Alternativen... \"toTop\", \"toBottom\", \"toMiddle\".",
"updated": 1633978051324,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство \"slider\" определяет положение горизонтального ползунка. Есть три альтернативы: toTop, toBottom, toMiddle.",
"updated": 1638342086859
}
]
},
{
"style": "Json",
"text": "\"slider\": \"toBottom\" // Opens the Charting Space",
"updated": 1617624084984
"updated": 1617624084984,
"translations": [
{
"language": "RU",
"text": "\"slider\": \"toBottom\" // Открывает область графиков",
"updated": 1638342112119
}
]
},
{
"style": "Json",
@@ -360,6 +472,11 @@
"text": "Mit der Eigenschaft pressButton können Sie das Tutorial zwangsweise \"anhalten\", zum \"nächsten\" Schritt gehen, zum \"vorherigen\" Schritt gehen oder einen Schritt \"überspringen\". Wenn ein Schritt geladen wird und eine dieser Optionen in dieser Eigenschaft konfiguriert ist, wird die Aktion sofort ausgeführt.",
"updated": 1633978127988,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство pressButton позволяет принудительно остановить учебник «Stop», перейти к следующему шагу «Next», перейти к предыдущему шагу «Previous» или пропустить шаг «Skip». Когда шаг загружен и в этом свойстве настроен один из этих параметров, действие применяется немедленно.",
"updated": 1638342503229
}
]
},
@@ -373,6 +490,11 @@
"text": "Eine häufige Verwendung dieser Funktion ist das Überspringen eines Schrittes, z.B. einer Tutorial-topic-node, die ausschließlich für organisatorische Zwecke innerhalb der Hierarchie verwendet wird und daher keinen Inhalt hat. Lassen Sie das Feld leer, damit der Schritt auf die übliche Weise abgespielt wird.",
"updated": 1633978359504,
"style": "Note"
},
{
"language": "RU",
"text": "Обычно эта функция используется для пропуска шага, например, узла Tutorial Topic, который используется исключительно для организационных целей в иерархии и поэтому не содержит содержимого. Оставьте поле пустым, чтобы шаг играл обычным образом.",
"updated": 1638342559154
}
]
},
@@ -391,6 +513,11 @@
"text": "Die obige Konfiguration führt den Benutzer zum nächsten Schritt des Tutorials, ohne dass der Inhalt der betreffenden node angezeigt wird.",
"updated": 1633978461463,
"style": "Text"
},
{
"language": "RU",
"text": "Приведенная выше конфигурация переводит пользователя на следующий шаг в руководстве без отображения какого-либо содержимого для рассматриваемого узла.",
"updated": 1638342577730
}
]
},
@@ -404,6 +531,11 @@
"text": "Sie können Tutorial Topic nodes nur zu organisatorischen Zwecken verwenden, z.B. um die Hierarchie so anzuordnen, dass sie einfach zu lesen und zu pflegen ist. Themen mit zu vielen Schritten sind später schwieriger zu handhaben. Mit anderen Worten: Sie können einen Tutorial Topic node verwenden, um mehrere Schritte zu gruppieren, auch wenn Sie nicht beabsichtigen, dass die Tutorial Topic node irgendeinen Inhalt anzeigt. In solchen Fällen können Sie diese Eigenschaft verwenden, um den Schritt zu überspringen, der nicht für die Anzeige von Inhalten vorgesehen ist.",
"updated": 1633979074457,
"style": "Success"
},
{
"language": "RU",
"text": "Вы можете использовать узлы Tutorial Topic только для организационных целей, например, чтобы упорядочить иерархию таким образом, чтобы ее было легко читать и поддерживать. С темами, в которых слишком много шагов, потом будет труднее разбираться. Другими словами, вы можете использовать узел Tutorial Topic, чтобы сгруппировать несколько шагов, даже если вы не собираетесь в узле Tutorial Topic отображать какой-либо контент. В таких случаях вы можете использовать это свойство, чтобы пропустить шаг, не предназначенный для отображения содержимого.",
"updated": 1638343008771
}
]
},
@@ -422,6 +554,11 @@
"text": "Die docs-Eigenschaft wird verwendet, um auf die Docs Tutorial Page zu verweisen, die den Inhalt für den jeweiligen Tutorial-Schritt liefert. Die Definition erfordert den Namen des Project (Projekts), die Docs Page Category (Kategorie) welche immer \"Tutorial\" ist, und den vollständigen Namen der Docs Page, das heißt den \"Typ\", wie in der JSON-Datei angegeben.",
"updated": 1633979212224,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство \"docs\" используется для указания на страницу Docs Tutorial Page, которая передает контент на конкретный шаг учебного пособия. Для определения требуется имя проекта, категория страницы документов, которая всегда является «Tutorial», и полное имя страницы документов, то есть типа «type», как указано в файле JSON.",
"updated": 1638343213692
}
]
},
@@ -444,6 +581,11 @@
"text": "Die Eigenschaft wird verwendet, um das Verhalten des Docs-Panels zu steuern. Innerhalb von controlDocs sind mehrere Eigenschaften verfügbar, die alle optional sind. Sehen wir uns jede im Detail an.",
"updated": 1633979296433,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство используется для управления поведением панели Docs Panel. В controlDocs доступно несколько свойств, и все они являются необязательными. Рассмотрим подробно каждый.",
"updated": 1638343486932
}
]
},
@@ -457,6 +599,11 @@
"text": "Die Panel-Eigenschaft kann auf \"Öffnen\" oder \"Schließen\" eingestellt werden. Diese Eigenschaft steuert die Registerkarte, mit der Sie das Doku-Panel in einem Schritt öffnen und in einem anderen Schritt wieder schließen können, wenn es nicht mehr benötigt wird.",
"updated": 1633979356912,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство панели может быть установлено на «Open» или «Close». Это свойство управляет вкладкой, которая позволяет вам открыть панель документов за один шаг и закрыть ее на другом шаге, когда она больше не нужна.",
"updated": 1638343378776
}
]
},
@@ -479,6 +626,11 @@
"text": "Wenn das Docs Panel geschlossen ist, sind die restlichen Eigenschaften irgendwie irrelevant. Wenn das Docs-Panel jedoch geöffnet ist, steuern die restlichen Eigenschaften, was im Docs-Panel angezeigt wird.",
"updated": 1633979402232,
"style": "Success"
},
{
"language": "RU",
"text": "Если панель Docs Panel закрыта, остальные свойства не имеют значения. Однако, когда панель Docs Panel открыта, остальные свойства управляют тем, что отображается на панели Docs Panel.",
"updated": 1638343471175
}
]
},
@@ -492,6 +644,11 @@
"text": "Die Eigenschaft closeTutorialEditor kann den Docs-Editor ein- und ausschalten. Wenn die Eigenschaft auf false gesetzt ist oder wenn es keine Definition gibt und wenn keine spezifische Docs-Seite aufgerufen wird (siehe controlDocs unten), zeigt das Docs-Panel die Seite, die mit dem aktuellen Tutorial-Schritt im Bearbeitungsmodus verbunden ist.",
"updated": 1633979594120,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство closeTutorialEditor может включать и выключать редактор документов. Если установлено значение false или нет определения и при условии, что не вызывается конкретная страница Docs Page (см. ControlDocs ниже), на панели Docs Panel отображается страница, связанная с текущим этапом обучения в режиме редактирования.",
"updated": 1638343628965
}
]
},
@@ -510,6 +667,11 @@
"text": "Da diese Definition standardmäßig auf false gesetzt ist, ist dies das standardmäßige Verhalten. Das heißt, wenn das Docs-Bedienfeld geöffnet wird, während ein Tutorial-Schritt abgespielt wird, zeigt das Docs-Bedienfeld standardmäßig die Docs-Seite an, die mit dem jeweiligen Schritt verknüpft ist, so dass die Seite direkt an Ort und Stelle bearbeitet werden kann.",
"updated": 1633979921238,
"style": "Success"
},
{
"language": "RU",
"text": "Поскольку для этого определения по умолчанию установлено значение false, это обычное поведение. То есть по умолчанию, когда панель Docs Panel открывается во время выполнения шага обучения, на панели Docs Panel отображается страница Docs Page, связанная с конкретным шагом, так что страницу можно редактировать прямо сейчас.",
"updated": 1638343747105
}
]
},
@@ -523,6 +685,11 @@
"text": "Wenn die Eigenschaft closeTutorialEditor auf true gesetzt ist und keine Anforderung zum Öffnen einer Dokumentseite vorliegt (siehe Eigenschaft page weiter unten), dann zeigt das Dokumentseiten-Panel die Dokumentseite an, die im vorherigen Schritt angezeigt wurde.",
"updated": 1633979700958,
"style": "Text"
},
{
"language": "RU",
"text": "Если для свойства closeTutorialEditor установлено значение true и нет запроса на открытие страницы Docs (см. Свойство страницы ниже), тогда на панели Docs отображается любая страница Docs Page, отображаемая на предыдущем шаге.",
"updated": 1638343921788
}
]
},
@@ -541,6 +708,11 @@
"text": "Es kann sinnvoll sein, den Tutorial Editor zu schließen, wenn der Benutzer von einem Schritt zum nächsten mit den Docs interagieren soll. Nehmen wir zum Beispiel an, das Tutorial weist den Benutzer an, eine Suche durchzuführen und dieses Ergebnis im nächsten Schritt zu besprechen. In diesem Fall möchten Sie, dass der Editor des Tutorials geschlossen bleibt, da sonst die vom Benutzer durchgeführte Suche verloren ginge und stattdessen die Seite geladen würde, die dem neuen Schritt des Tutorials entspricht.",
"updated": 1633979902886,
"style": "Success"
},
{
"language": "RU",
"text": "Вы можете закрыть редактор учебника, когда пользователь должен взаимодействовать с Docs от одного шага к другому. Например, предположим, что учебник инструктирует пользователя выполнить поиск и обсуждает результаты поиска на следующем шаге. В этом случае вы захотите, чтобы редактор учебников оставался закрытым, иначе поиск, выполненный пользователем, будет потерян, и вместо этого будет загружена страница, соответствующая новому шагу руководства.",
"updated": 1638344026667
}
]
},
@@ -554,6 +726,11 @@
"text": "Die Eigenschaft searchPage überschreibt die Einstellungen des Tutorial-Editors und lädt die Hauptsuchseite mit dem Suchfeld in der Mitte.",
"updated": 1633979953175,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство searchPage выходит за пределы настроек редактора учебника и загружает домашнюю страницу поиска с полем поиска в центре.",
"updated": 1638344044257
}
]
},
@@ -572,6 +749,11 @@
"text": "Verwenden Sie die obige Einstellung, wenn Sie möchten, dass der Benutzer das saubere Suchfeld erhält, um eine Suche durchzuführen oder einen Befehl auszuführen.",
"updated": 1633980006636,
"style": "Success"
},
{
"language": "RU",
"text": "Используйте указанную выше настройку, если хотите, чтобы пользователь получил чистое поле поиска для выполнения поиска или выполнения команды.",
"updated": 1638344074943
}
]
},
@@ -585,6 +767,11 @@
"text": "Mit der page property legen Sie fest, welche Docs Page geladen werden soll. Sie müssen das Project (Projekt), die Docs Page Category (Kategorie) und den \"type\" (Typ), also den vollständigen Namen der Seite, angeben. Die optionale Eigenschaft anchor ermöglicht es Ihnen, den Benutzer mit dem Docs Anchor Style auf einen bestimmten Absatz der Seite zu verweisen.",
"updated": 1633980112889,
"style": "Text"
},
{
"language": "RU",
"text": "Свойство page - это то место, где вы определяете, какая страница Docs Page должна быть загружена. Вы должны указать проект Project, категорию страницы Docs Page Category и «type», который является полным именем страницы. Необязательная привязка свойства позволяет указать пользователю на определенный абзац на странице с помощью привязки Docs Anchor Style.",
"updated": 1638344326671
}
]
},
@@ -603,6 +790,11 @@
"text": "Verwenden Sie die obige Konfiguration, wenn Sie möchten, dass der Benutzer eine bestimmte Seite in den Docs liest.",
"updated": 1633980693215,
"style": "Success"
},
{
"language": "RU",
"text": "Используйте указанную выше конфигурацию, если хотите, чтобы пользователь читал определенную страницу в Docs.",
"updated": 1638344372113
}
]
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

File diff suppressed because it is too large. Load diff
@@ -11,12 +11,12 @@
},
{
"action": "Add UI Object",
"label": "Add Cancel Order Portfolio Event",
"label": "Add Ask Portfolio Events Manager",
"disableIfPropertyIsDefined": true,
"propertyToCheckFor": "cancelOrderPMEvent",
"relatedUiObject": "Cancel Order PM Event",
"propertyToCheckFor": "askPortfolioEventsManager",
"relatedUiObject": "Ask Portfolio Events Manager",
"actionFunction": "payload.executeAction",
"relatedUiObjectProject": "Foundations",
"relatedUiObjectProject": "Portfolio-Management",
"actionProject": "Visual-Scripting"
},
{
@@ -51,9 +51,9 @@
"autoAdd": true
},
{
"name": "cancelOrderPMEvent",
"name": "askPortfolioEventsManager",
"type": "node",
"childType": "Cancel Order PM Event"
"childType": "Ask Portfolio Events Manager"
},
{
"name": "announcements",
Loaded 100 of 398 files, more files were not shown because too many files have changed in this diff. Show more