From 709eacc980ab4e156d81b9e3554eb6b97926650a Mon Sep 17 00:00:00 2001 From: Spythere Date: Tue, 29 Dec 2020 01:48:10 +0100 Subject: [PATCH] =?UTF-8?q?Poprawki=20b=C5=82=C4=99d=C3=B3w=20(1.3.5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 80 +- src/assets/icon-select.svg | 8 +- src/components/Global/DonationModal.vue | 330 ++-- src/components/Global/SelectBox.vue | 216 +-- src/components/SceneryView/SceneryInfo.vue | 806 ++++----- .../SceneryView/SceneryTimetable.vue | 932 +++++----- src/components/StationsView/FilterCard.vue | 842 ++++----- src/components/StationsView/Options.vue | 280 +-- src/components/StationsView/StationCard.vue | 850 ++++----- src/components/StationsView/StationTable.vue | 788 ++++----- .../StationsView/StationTimetable.vue | 568 +++--- src/components/TrainsView/TrainSchedule.vue | 470 ++--- src/components/TrainsView/TrainSearch.vue | 244 +-- src/components/TrainsView/TrainSorter.vue | 346 ++-- src/components/TrainsView/TrainStats.vue | 642 +++---- src/components/TrainsView/TrainTable.vue | 968 +++++------ src/data/options.json | 320 ++-- src/data/stationData.json | 2 +- src/scripts/interfaces/ScheduledTrain.ts | 36 +- src/scripts/interfaces/Timetable.ts | 32 +- src/scripts/interfaces/Train.ts | 62 +- src/scripts/interfaces/TrainStop.ts | 56 +- src/scripts/stationFilterManager.ts | 278 ++- src/scripts/storageManager.ts | 84 +- src/store/store.ts | 1250 +++++++------- src/styles/global.scss | 464 ++--- src/styles/scenery_status.scss | 100 +- src/styles/user_badge.scss | 106 +- src/views/SceneryView.vue | 294 ++-- src/views/StationsView.vue | 746 ++++---- src/views/TimetableView.vue | 1538 ++++++++--------- src/views/TrainsView.vue | 332 ++-- vue.config.js | 6 +- 33 files changed, 7037 insertions(+), 7039 deletions(-) diff --git a/package.json b/package.json index 924dcf7..112d8bb 100644 --- a/package.json +++ b/package.json @@ -1,40 +1,40 @@ -{ - "name": "stacjownik", - "version": "0.1.0", - "private": true, - "scripts": { - "serve": "vue-cli-service serve", - "build": "vue-cli-service build", - "deploy": "npm run build && firebase deploy --only hosting" - }, - "dependencies": { - "core-js": "^3.6.5", - "dotenv": "^8.2.0", - "firestore": "^1.1.6", - "howler": "^2.2.1", - "vue": "^2.6.11", - "vue-class-component": "^7.2.5", - "vue-property-decorator": "^8.4.2", - "vue-router": "^3.4.3", - "vuex": "^3.4.0" - }, - "devDependencies": { - "@vue/cli-plugin-babel": "~4.4.0", - "@vue/cli-plugin-router": "~4.4.0", - "@vue/cli-plugin-typescript": "~4.4.0", - "@vue/cli-plugin-vuex": "~4.4.0", - "@vue/cli-service": "~4.4.0", - "axios": "^0.19.2", - "sass": "^1.26.10", - "sass-loader": "^8.0.2", - "typescript": "^3.9.7", - "vue-template-compiler": "^2.6.11", - "vuex-class": "^0.3.2", - "vuex-module-decorators": "^0.17.0" - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not dead" - ] -} +{ + "name": "stacjownik", + "version": "0.1.0", + "private": true, + "scripts": { + "serve": "vue-cli-service serve", + "build": "vue-cli-service build", + "deploy": "npm run build && firebase deploy --only hosting" + }, + "dependencies": { + "core-js": "^3.6.5", + "dotenv": "^8.2.0", + "firestore": "^1.1.6", + "howler": "^2.2.1", + "vue": "^2.6.11", + "vue-class-component": "^7.2.5", + "vue-property-decorator": "^8.4.2", + "vue-router": "^3.4.3", + "vuex": "^3.4.0" + }, + "devDependencies": { + "@vue/cli-plugin-babel": "~4.4.0", + "@vue/cli-plugin-router": "~4.4.0", + "@vue/cli-plugin-typescript": "~4.4.0", + "@vue/cli-plugin-vuex": "~4.4.0", + "@vue/cli-service": "~4.4.0", + "axios": "^0.19.2", + "sass": "^1.26.10", + "sass-loader": "^8.0.2", + "typescript": "^3.9.7", + "vue-template-compiler": "^2.6.11", + "vuex-class": "^0.3.2", + "vuex-module-decorators": "^0.17.0" + }, + "browserslist": [ + "> 1%", + "last 2 versions", + "not dead" + ] +} diff --git a/src/assets/icon-select.svg b/src/assets/icon-select.svg index 78de7f6..10f29cd 100644 --- a/src/assets/icon-select.svg +++ b/src/assets/icon-select.svg @@ -1,4 +1,4 @@ - - - - + + + + diff --git a/src/components/Global/DonationModal.vue b/src/components/Global/DonationModal.vue index 024ce62..b7575ac 100644 --- a/src/components/Global/DonationModal.vue +++ b/src/components/Global/DonationModal.vue @@ -1,166 +1,166 @@ - - - - - \ No newline at end of file diff --git a/src/components/Global/SelectBox.vue b/src/components/Global/SelectBox.vue index f3655d8..e434125 100644 --- a/src/components/Global/SelectBox.vue +++ b/src/components/Global/SelectBox.vue @@ -1,109 +1,109 @@ - - - - - \ No newline at end of file diff --git a/src/components/SceneryView/SceneryInfo.vue b/src/components/SceneryView/SceneryInfo.vue index 5be5107..7a92a6b 100644 --- a/src/components/SceneryView/SceneryInfo.vue +++ b/src/components/SceneryView/SceneryInfo.vue @@ -1,404 +1,404 @@ - - - - - \ No newline at end of file diff --git a/src/components/SceneryView/SceneryTimetable.vue b/src/components/SceneryView/SceneryTimetable.vue index f25a4de..4bdac11 100644 --- a/src/components/SceneryView/SceneryTimetable.vue +++ b/src/components/SceneryView/SceneryTimetable.vue @@ -1,467 +1,467 @@ - - - - - \ No newline at end of file diff --git a/src/components/StationsView/FilterCard.vue b/src/components/StationsView/FilterCard.vue index 95f1523..df4c505 100644 --- a/src/components/StationsView/FilterCard.vue +++ b/src/components/StationsView/FilterCard.vue @@ -1,422 +1,422 @@ - - - - - \ No newline at end of file diff --git a/src/components/StationsView/Options.vue b/src/components/StationsView/Options.vue index e46be8e..7df6583 100644 --- a/src/components/StationsView/Options.vue +++ b/src/components/StationsView/Options.vue @@ -1,141 +1,141 @@ - - - - - - \ No newline at end of file diff --git a/src/components/StationsView/StationCard.vue b/src/components/StationsView/StationCard.vue index d293b29..c05ef1c 100644 --- a/src/components/StationsView/StationCard.vue +++ b/src/components/StationsView/StationCard.vue @@ -1,426 +1,426 @@ - - - - - \ No newline at end of file diff --git a/src/components/StationsView/StationTable.vue b/src/components/StationsView/StationTable.vue index 22fcfed..e0665e8 100644 --- a/src/components/StationsView/StationTable.vue +++ b/src/components/StationsView/StationTable.vue @@ -1,395 +1,395 @@ - - - - - \ No newline at end of file diff --git a/src/components/StationsView/StationTimetable.vue b/src/components/StationsView/StationTimetable.vue index 5cf321c..6c815d4 100644 --- a/src/components/StationsView/StationTimetable.vue +++ b/src/components/StationsView/StationTimetable.vue @@ -1,285 +1,285 @@ - - - - - \ No newline at end of file diff --git a/src/components/TrainsView/TrainSchedule.vue b/src/components/TrainsView/TrainSchedule.vue index e053f34..527ee89 100644 --- a/src/components/TrainsView/TrainSchedule.vue +++ b/src/components/TrainsView/TrainSchedule.vue @@ -1,235 +1,235 @@ - - - - - + + + + + diff --git a/src/components/TrainsView/TrainSearch.vue b/src/components/TrainsView/TrainSearch.vue index f21c207..d179586 100644 --- a/src/components/TrainsView/TrainSearch.vue +++ b/src/components/TrainsView/TrainSearch.vue @@ -1,123 +1,123 @@ - - - - - \ No newline at end of file diff --git a/src/components/TrainsView/TrainSorter.vue b/src/components/TrainsView/TrainSorter.vue index 1bd2601..8e62178 100644 --- a/src/components/TrainsView/TrainSorter.vue +++ b/src/components/TrainsView/TrainSorter.vue @@ -1,173 +1,173 @@ - - - - - + + + + + diff --git a/src/components/TrainsView/TrainStats.vue b/src/components/TrainsView/TrainStats.vue index c383fa4..2060c80 100644 --- a/src/components/TrainsView/TrainStats.vue +++ b/src/components/TrainsView/TrainStats.vue @@ -1,322 +1,322 @@ - - - - - \ No newline at end of file diff --git a/src/components/TrainsView/TrainTable.vue b/src/components/TrainsView/TrainTable.vue index ea253bb..556a390 100644 --- a/src/components/TrainsView/TrainTable.vue +++ b/src/components/TrainsView/TrainTable.vue @@ -1,485 +1,485 @@ - - - - - \ No newline at end of file diff --git a/src/data/options.json b/src/data/options.json index 6d5dda8..9bdca24 100644 --- a/src/data/options.json +++ b/src/data/options.json @@ -1,161 +1,161 @@ -{ - "options": [{ - "id": "is-default", - "name": "default", - "section": "access", - "value": true, - "defaultValue": true, - "content": "W PACZCE" - }, - { - "id": "not-default", - "name": "notDefault", - "section": "access", - "value": true, - "defaultValue": true, - "content": "POZA PACZKĄ" - }, - { - "id": "non-public", - "name": "nonPublic", - "section": "access", - "value": true, - "defaultValue": true, - "content": "NIEPUBLICZNA" - }, - { - "id": "SPK", - "name": "SPK", - "section": "control", - "value": true, - "defaultValue": true, - "content": "SPK" - }, - { - "id": "SCS", - "name": "SCS", - "section": "control", - "value": true, - "defaultValue": true, - "content": "SCS" - }, - { - "id": "by-hand", - "name": "ręczne", - "section": "control", - "value": true, - "defaultValue": true, - "content": "RĘCZNE" - }, - { - "id": "levers", - "name": "mechaniczne", - "section": "control", - "value": true, - "defaultValue": true, - "content": "MECHANICZNE" - }, - { - "id": "modern", - "name": "współczesna", - "section": "signals", - "value": true, - "defaultValue": true, - "content": "WSPÓŁCZESNA" - }, - { - "id": "semaphore", - "name": "kształtowa", - "section": "signals", - "value": true, - "defaultValue": true, - "content": "KSZTAŁTOWA" - }, - { - "id": "mixed", - "name": "mieszana", - "section": "signals", - "value": true, - "defaultValue": true, - "content": "MIESZANA" - }, - { - "id": "historic", - "name": "historyczna", - "section": "signals", - "value": true, - "defaultValue": true, - "content": "HISTORYCZNA" - }, - { - "id": "free", - "name": "free", - "section": "status", - "value": false, - "defaultValue": false, - "content": "WOLNA" - }, - { - "id": "occupied", - "name": "occupied", - "section": "status", - "value": true, - "defaultValue": true, - "content": "ZAJĘTA" - }, - { - "id": "ending", - "name": "ending", - "section": "status", - "value": true, - "defaultValue": true, - "content": "KOŃCZY" - } - ], - "sliders": [{ - "id": "min-level", - "name": "minLevel", - "minRange": 0, - "maxRange": 20, - "value": 0, - "defaultValue": 0, - "content": "MINIMALNY WYMAGANY POZIOM DYŻURNEGO" - }, - { - "id": "min-oneway-e", - "name": "minOneWayCatenary", - "minRange": 0, - "maxRange": 5, - "value": 0, - "defaultValue": 0, - "content": "SZLAKI JEDNOTOROWE ZELEKTR. (MINIMUM)" - }, - { - "id": "min-oneway-ne", - "name": "minOneWay", - "minRange": 0, - "maxRange": 5, - "value": 0, - "defaultValue": 0, - "content": "SZLAKI JEDNOTOROWE NIEZELEKTR. (MINIMUM)" - }, - { - "id": "min-twoway-e", - "name": "minTwoWayCatenary", - "minRange": 0, - "maxRange": 5, - "value": 0, - "defaultValue": 0, - "content": "SZLAKI DWUTOROWE ZELEKTR. (MINIMUM)" - }, - { - "id": "min-twoway-ne", - "name": "minTwoWay", - "minRange": 0, - "maxRange": 5, - "value": 0, - "defaultValue": 0, - "content": "SZLAKI DWUTOROWE NIEZELEKTR. (MINIMUM)" - } - ] +{ + "options": [{ + "id": "is-default", + "name": "default", + "section": "access", + "value": true, + "defaultValue": true, + "content": "W PACZCE" + }, + { + "id": "not-default", + "name": "notDefault", + "section": "access", + "value": true, + "defaultValue": true, + "content": "POZA PACZKĄ" + }, + { + "id": "non-public", + "name": "nonPublic", + "section": "access", + "value": true, + "defaultValue": true, + "content": "NIEPUBLICZNA" + }, + { + "id": "SPK", + "name": "SPK", + "section": "control", + "value": true, + "defaultValue": true, + "content": "SPK" + }, + { + "id": "SCS", + "name": "SCS", + "section": "control", + "value": true, + "defaultValue": true, + "content": "SCS" + }, + { + "id": "by-hand", + "name": "ręczne", + "section": "control", + "value": true, + "defaultValue": true, + "content": "RĘCZNE" + }, + { + "id": "levers", + "name": "mechaniczne", + "section": "control", + "value": true, + "defaultValue": true, + "content": "MECHANICZNE" + }, + { + "id": "modern", + "name": "współczesna", + "section": "signals", + "value": true, + "defaultValue": true, + "content": "WSPÓŁCZESNA" + }, + { + "id": "semaphore", + "name": "kształtowa", + "section": "signals", + "value": true, + "defaultValue": true, + "content": "KSZTAŁTOWA" + }, + { + "id": "mixed", + "name": "mieszana", + "section": "signals", + "value": true, + "defaultValue": true, + "content": "MIESZANA" + }, + { + "id": "historic", + "name": "historyczna", + "section": "signals", + "value": true, + "defaultValue": true, + "content": "HISTORYCZNA" + }, + { + "id": "free", + "name": "free", + "section": "status", + "value": false, + "defaultValue": false, + "content": "WOLNA" + }, + { + "id": "occupied", + "name": "occupied", + "section": "status", + "value": true, + "defaultValue": true, + "content": "ZAJĘTA" + }, + { + "id": "ending", + "name": "ending", + "section": "status", + "value": true, + "defaultValue": true, + "content": "KOŃCZY" + } + ], + "sliders": [{ + "id": "min-level", + "name": "minLevel", + "minRange": 0, + "maxRange": 20, + "value": 0, + "defaultValue": 0, + "content": "MINIMALNY WYMAGANY POZIOM DYŻURNEGO" + }, + { + "id": "min-oneway-e", + "name": "minOneWayCatenary", + "minRange": 0, + "maxRange": 5, + "value": 0, + "defaultValue": 0, + "content": "SZLAKI JEDNOTOROWE ZELEKTR. (MINIMUM)" + }, + { + "id": "min-oneway-ne", + "name": "minOneWay", + "minRange": 0, + "maxRange": 5, + "value": 0, + "defaultValue": 0, + "content": "SZLAKI JEDNOTOROWE NIEZELEKTR. (MINIMUM)" + }, + { + "id": "min-twoway-e", + "name": "minTwoWayCatenary", + "minRange": 0, + "maxRange": 5, + "value": 0, + "defaultValue": 0, + "content": "SZLAKI DWUTOROWE ZELEKTR. (MINIMUM)" + }, + { + "id": "min-twoway-ne", + "name": "minTwoWay", + "minRange": 0, + "maxRange": 5, + "value": 0, + "defaultValue": 0, + "content": "SZLAKI DWUTOROWE NIEZELEKTR. (MINIMUM)" + } + ] } \ No newline at end of file diff --git a/src/data/stationData.json b/src/data/stationData.json index 0f7b5db..1d3a714 100644 --- a/src/data/stationData.json +++ b/src/data/stationData.json @@ -1 +1 @@ -[["Blaszki","https://td2.info.pl/scenerie/blaszki/","",null,"10","NIE","współczesna","SPK","","",1,1,2,0,null,null,true,false,false],["LCS Borowe","https://td2.info.pl/scenerie/lcs-borowe/","",null,"10","NIE","współczesna","SCS","TAK","TAK",1,0,3,0,["Borowe, podg.","Wysoka, podg.","Naprawa, podg.","Borowe Towarowe"],["Borowe, podg.","Wysoka, podg.","Naprawa, podg.","Borowe Towarowe"],false,false,false],["LCS Gdańsk","https://td2.info.pl/scenerie/lcs-gdansk/","9, 202, 227, 249, 250",null,"10","NIE","współczesna","SCS","TAK","TAK",3,0,3,0,["Gdańsk Główny","SKM Śródmieście","Gdańsk Południowy"],["Gdańsk Główny"],true,false,false],["Lębork","https://td2.info.pl/scenerie/lebork-5834/","202, 229, 237",null,"8","NIE","współczesna","mechaniczne+SCS","","",2,2,0,0,null,null,true,false,false],["Grabów Miasto","https://td2.info.pl/scenerie/grabow-miasto-v2/","",null,"6","NIE","współczesna","SCS","","TAK",2,1,1,0,["Grabów Miasto","Grabów Wieś"],null,true,false,false],["Parzęczewo","https://td2.info.pl/scenerie/parzeczewo/","",null,"6","NIE","mieszana","SCS","TAK","TAK",1,0,2,0,["Parzęczewo","Parzęczewo Miasto","Parzęczewo gt"],null,true,false,false],["Aleksandrów Kujawski","https://td2.info.pl/scenerie/aleksandrow-kujawski/","18, 245",null,"4","NIE","współczesna","SCS-SPK","","TAK",1,0,2,0,null,null,true,false,false],["Arkadia Zdrój 2012","https://td2.info.pl/scenerie/arkadia-zdroj/","",null,"4","NIE","mieszana","mechaniczne+SPK","","",1,0,2,0,null,null,true,false,false],["Buk 2018","https://td2.info.pl/scenerie/buk2/","",null,"4","NIE","współczesna","SCS-SPK","","TAK",2,0,1,0,null,null,true,false,false],["Jordanowo","https://td2.info.pl/scenerie/jordanowo/","",null,"4","NIE","mieszana","mechaniczne","","",3,2,0,0,null,null,true,false,false],["LCS Głowno","https://td2.info.pl/scenerie/glowno-(linia-nr-15-lka)/","15","ŁKA","4","NIE","współczesna","SCS","","",2,0,0,0,["Głowno","Domaniewice"],["Głowno"],true,false,false],["LCS Ozorków","https://td2.info.pl/scenerie/lcs-ozorkow/","16","ŁKA","4","NIE","współczesna","SCS","","",2,0,0,0,["Ozorków","Chociszew"],["Ozorków"],true,false,false],["LCS Skrzynki","https://td2.info.pl/scenerie/lcs-skrzynki/","25","ŁKA","4","NIE","współczesna","SCS-SPK","","TAK",0,0,2,0,["Skrzynki","Wykno"],["Skrzynki"],true,false,false],["Łask","https://td2.info.pl/scenerie/lask-w-ramach-lka/","14","ŁKA","4","NIE","współczesna","mechaniczne+SCS","","",0,0,2,0,null,null,true,false,false],["Naterki","https://td2.info.pl/scenerie/naterki/","353",null,"4","NIE","kształtowa","mechaniczne+SCS","","",0,0,2,0,null,null,true,false,false],["Santok Zdrój","https://td2.info.pl/scenerie/santok-zdroj/","",null,"4","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Testowo","https://td2.info.pl/scenerie/testowo-3581","",null,"4","NIE","współczesna","SPK","TAK (szlak Sl)","TAK",1,1,1,0,null,null,true,false,false],["Tłoki","https://td2.info.pl/scenerie/podg-tloki","",null,"4","NIE","współczesna","SCS-SPK","","TAK",1,0,2,0,null,["Tłoki, podg."],true,false,false],["Witaszyczki","https://td2.info.pl/scenerie/witaszyczki/","",null,"4","NIE","współczesna","SCS","","TAK",0,0,2,0,null,null,true,false,false],["Bydgowo","https://td2.info.pl/scenerie/bydgowo/","",null,"2","NIE","współczesna","SPK","TAK (szlak SK)","TAK",0,0,2,0,null,null,true,false,false],["Głębce","https://td2.info.pl/scenerie/glebce","",null,"2","NIE","współczesna","ręczne+SPK","","",1,0,0,0,null,null,true,false,false],["Hel","https://td2.info.pl/scenerie/hel/","213",null,"2","NIE","współczesna","SPK","","",0,1,0,0,null,null,true,false,false],["Kcynia","https://td2.info.pl/scenerie/kcynia","281, 356",null,"2","NIE","kształtowa","mechaniczne","","",0,4,0,0,null,null,true,false,false],["Lewków","https://td2.info.pl/scenerie/lewkow/","",null,"2","NIE","mieszana","mechaniczne+SCS","","TAK (szlak Ks)",0,0,2,0,null,null,true,false,false],["Cis 2013","https://td2.info.pl/scenerie/cis2","",null,"0","NIE","kształtowa","mechaniczne","","",2,0,0,0,null,null,true,false,false],["Cis 2018","https://td2.info.pl/scenerie/cis2","",null,"0","NIE","współczesna","SCS-SPK","","",2,0,0,0,null,null,true,false,false],["Glinnik","https://td2.info.pl/scenerie/glinnik-(projekt-lka)/","15","ŁKA","0","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Głogowo","https://td2.info.pl/scenerie/glogowo","",null,"0","NIE","współczesna","SCS","","",0,2,0,0,null,null,true,false,false],["Karszynek","https://td2.info.pl/scenerie/karszynek/","",null,"0","NIE","historyczna","mechaniczne","","",0,0,2,0,null,null,true,false,false],["Imielin 2015","https://td2.info.pl/scenerie/imielin-2015","138",null,"0","NIE","współczesna","mechaniczne+SCS","","TAK",0,0,2,0,null,null,true,false,false],["Kolsko","https://td2.info.pl/scenerie/kolsko/","",null,"0","NIE","kształtowa","mechaniczne","","",0,3,0,0,null,null,true,false,false],["LCS Bucz Wileński","https://td2.info.pl/scenerie/bucz-wilenski/","",null,"0","NIE","współczesna","SCS","TAK","TAK",0,0,1,0,null,["Bucz Wileński"],true,false,false],["Lisiczki","https://td2.info.pl/scenerie/lisiczki","",null,"6","NIE","współczesna","SCS-SPK","","",2,0,0,0,null,null,true,false,false],["Łęczyca","https://td2.info.pl/scenerie/leczyca-projekt-lka/","16","ŁKA","0","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Poreńsk","https://td2.info.pl/scenerie/porensk/","",null,"0","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Radowice","https://td2.info.pl/scenerie/radowice","",null,"0","NIE","kształtowa","mechaniczne","","",0,2,0,0,null,null,true,false,false],["Witonia","https://td2.info.pl/scenerie/witonia-(projekt-lka)/","16","ŁKA","0","NIE","współczesna","SCS","","",2,0,0,0,null,null,true,false,false],["Wola","https://td2.info.pl/scenerie/wola/","",null,"0","NIE","mieszana","mechaniczne+SCS","","",0,0,2,0,null,null,true,false,false],["Zgierz Kontrewers","https://td2.info.pl/scenerie/zgierz-kontrewers-6172/","16","ŁKA","0","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Bargowice","https://td2.info.pl/scenerie/bargowice-4441/","",null,"10","NIE","współczesna","SCS-SPK","","TAK",1,0,2,0,["Bargowice","Bargowice Zachód"],null,false,false,false],["Szklana Poręba","https://td2.info.pl/scenerie/szklana-poreba-gorna/","",null,"8","TAK","współczesna","mechaniczne","","",1,0,0,0,null,null,false,false,false],["Wschodna","https://td2.info.pl/scenerie/wschodna/","",null,"8","NIE","kształtowa","mechaniczne","","",1,0,2,0,null,null,false,false,false],["Zabłocie","https://td2.info.pl/scenerie/zablocie-3896","",null,"8","NIE","współczesna","SCS","","TAK",2,0,1,0,null,null,false,false,false],["Zdroje","https://td2.info.pl/scenerie/zdroje","",null,"8","NIE","kształtowa","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Grzybowo","https://td2.info.pl/scenerie/grzybowo","",null,"6","NIE","kształtowa","mechaniczne","","",0,0,2,0,null,null,false,false,false],["Zwardoń","https://td2.info.pl/scenerie/zwardon-4161","139",null,"6","TAK","współczesna","SCS","","",2,0,0,0,null,null,false,false,false],["Piaskowo","https://td2.info.pl/scenerie/piaskowo/","",null,"4","NIE","współczesna","SCS","TAK","TAK",0,0,2,0,null,null,false,false,false],["Rajcza","https://td2.info.pl/scenerie/rajcza/","139",null,"4","NIE","współczesna","SPK","","",2,0,0,0,null,null,false,false,false],["Brzezinka","https://td2.info.pl/scenerie/brzezinka/","",null,"3","NIE","współczesna","SCS-SPK","","TAK (szlak KSG)",0,0,2,0,null,null,false,false,false],["Torzyn","https://td2.info.pl/scenerie/torzyn/","",null,"3","NIE","współczesna","SCS","TAK","TAK",0,0,2,0,null,null,false,false,false],["Wola Nowska","https://td2.info.pl/scenerie/wola-nowska//","",null,"3","NIE","współczesna","SPK","","TAK",1,0,2,0,null,null,false,false,false],["Chełmik Wołowski","https://td2.info.pl/scenerie/chelmik-wolowski//","",null,"2","NIE","współczesna","SPK","","TAK",1,0,2,0,null,null,false,false,false],["Drzewko","https://td2.info.pl/w-trakcie-prac/drzewko/","",null,"2","NIE","współczesna","SCS","","TAK",0,0,2,0,null,null,false,false,false],["Krzemienice","https://td2.info.pl/scenerie/krzemienice/","",null,"2","NIE","współczesna","SCS","","TAK",3,0,1,0,null,null,false,false,false],["Milówka","https://td2.info.pl/scenerie/milowka/","139",null,"2","NIE","współczesna","SPK","","",2,0,0,0,null,null,false,false,false],["Orniki","https://td2.info.pl/scenerie/orniki/","",null,"2","NIE","współczesna","SPK","","TAK",1,1,2,0,null,null,false,false,false],["Otwocko","https://td2.info.pl/scenerie/otwocko/","",null,"2","NIE","współczesna","SCS","","TAK",0,0,2,0,null,null,false,false,false],["Skostomłoty","https://td2.info.pl/w-trakcie-prac/skostomloty/","",null,"2","NIE","współczesna","mechaniczne","","TAK",0,0,2,0,null,null,false,false,false],["Babimost","https://td2.info.pl/scenerie/babimost","358",null,"0","NIE","współczesna","mechaniczne","","",2,0,0,0,null,null,false,false,false],["Czerepy","https://td2.info.pl/scenerie/czerepy/","",null,"0","NIE","współczesna","SPK","TAK (szlak BO)","TAK",0,0,2,0,null,null,false,false,false],["Grabiny","https://td2.info.pl/scenerie/grabiny","",null,"0","NIE","współczesna","mechaniczne","","",2,0,0,0,null,null,false,false,false],["Kieły","https://td2.info.pl/scenerie/kiely-6224/","",null,"0","NIE","kształtowa","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Lutol Suchy","https://td2.info.pl/scenerie/lutol-suchy/","367",null,"0","NIE","współczesna","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Raki","https://td2.info.pl/scenerie/raki/","",null,"0","NIE","kształtowa","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Sieniawka","https://td2.info.pl/scenerie/sieniawka/","",null,"0","NIE","współczesna","mechaniczne","","",0,1,0,1,null,null,false,false,false],["Stefanowo","https://td2.info.pl/scenerie/stefanowo/","359",null,"0","NIE","kształtowa","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Szlichtyngowa","https://td2.info.pl/scenerie/szlichtyngowa//","",null,"0","NIE","współczesna","SPK","","TAK",0,0,2,0,null,null,false,false,false],["Tarnowo Górne","https://td2.info.pl/scenerie/tarnowo-gorne/","",null,"0","NIE","kształtowa","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Tartakowo 2013","https://td2.info.pl/w-trakcie-prac/tartakowo/","",null,"0","NIE","mieszana","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Wielgowo","https://td2.info.pl/scenerie/wielgowo/","",null,"0","NIE","współczesna","SPK","","",0,2,0,0,null,null,false,false,false],["Sulechów","https://td2.info.pl/scenerie/sulechow/","358",null,"0","NIE","mieszana","SPK","","",2,1,0,0,null,null,false,false,false],["Wilczyca","https://td2.info.pl/scenerie/wilczyca/","",null,"0","NIE","współczesna","SCS","","",0,2,0,0,null,null,false,false,false],["Sowi Bór","https://td2.info.pl/scenerie/sowi-bor/","",null,"3","NIE","współczesna","SPK","","",0,0,2,0,null,null,false,false,false],["Sól","https://td2.info.pl/scenerie/sol/","139",null,"2","NIE","współczesna","SPK","","",2,0,0,0,null,null,false,false,false],["Hetmanice","https://td2.info.pl/scenerie/hetmanice-stacja-dla-poczatkujacych/","",null,"0","NIE","współczesna","SCS-SPK","","",0,0,2,0,null,null,false,false,false],["Starzynki","https://td2.info.pl/w-trakcie-prac/starzynki/","",null,"3","NIE","współczesna","SPK","TAK (Szlak Ps)","TAK",2,0,1,0,null,null,false,false,false],["Głęboszów","https://td2.info.pl/scenerie/gleboszow/","",null,"3","NIE","współczesna","SCS","TAK (Szlaki Br oraz GO)","TAK",1,0,2,0,null,null,false,false,false],["Skawce","https://td2.info.pl/w-trakcie-prac/skawce-(projekt-zakopianka)/","97",null,"4","NIE","współczesna","SPK","","",2,0,0,0,null,null,false,false,true],["Sroka","https://td2.info.pl/scenerie/sroka-projekt-1001/","",null,"7","NIE","współczesna","SCS","","TAK",1,0,3,0,["Sroka, podg.","Sroka Południe, podg."],["Sroka, podg."],false,false,false],["Luzino","https://td2.info.pl/scenerie/luzino-6501/","202",null,"3","NIE","współczesna","mechaniczne","","TAK",2,0,0,0,null,null,false,false,false],["Zajączkowo","https://td2.info.pl/scenerie/zajaczkowo/","",null,"0","NIE","kształtowa","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Kudowa-Zdrój","https://td2.info.pl/scenerie/kudowa-zdroj-6616/","309",null,"4","NIE","współczesna","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Ciechany","https://td2.info.pl/w-trakcie-prac/ciechany/","",null,"3","NIE","współczesna","SCS","","",1,0,0,0,null,["Pawonki"],false,false,false],["Czermin","https://td2.info.pl/scenerie/czermin/","",null,"8","NIE","współczesna","SCS","TAK (szlaki Łk i Fw)","",2,0,2,0,null,null,false,false,false],["Rebrowo Dolne","https://td2.info.pl/scenerie/rebrowo-dolne/","",null,"2","NIE","współczesna","SPK","","",3,0,0,0,null,null,false,false,false],["Lublinek","https://td2.info.pl/scenerie/lublinek-projekt-lka/","14",null,"0","NIE","współczesna","mechaniczne","","",0,0,2,0,null,null,true,false,false],["Stryków","https://td2.info.pl/scenerie/strykow-projekt-lka/","14",null,"0","NIE","współczesna","mechaniczne","","",2,0,0,0,null,null,true,false,false],["Strączki","https://td2.info.pl/scenerie/straczki/","",null,"4","NIE","współczesna","mechaniczne","","",1,0,1,0,null,null,false,false,false],["Niedoradz","https://td2.info.pl/scenerie/niedoradz","",null,"0","NIE","współczesna","SPK","","",0,0,2,0,null,null,false,false,false],["Zgierz","https://td2.info.pl/scenerie/zgierz/","15,16",null,"12","TAK","współczesna","mechaniczne","","",3,0,1,0,null,null,false,false,false],["Łebnino","https://td2.info.pl/scenerie/lebnino-4511/","",null,"0","NIE","kształtowa","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Legno","https://td2.info.pl/scenerie/legno/","",null,"0","NIE","współczesna","SCS","TAK (szlak Mr)","TAK",0,0,2,0,null,null,false,false,false],["Buczek","https://td2.info.pl/scenerie/buczek/","",null,"0","NIE","współczesna","SCS","TAK","TAK",0,0,2,0,null,null,false,false,false],["Dziewoszyce","https://td2.info.pl/scenerie/dziewoszyce/","",null,"4","NIE","współczesna","SPK","","TAK",0,0,2,0,null,null,false,false,false],["Razemsko 2012","https://td2.info.pl/scenerie/razemsko-2012/","",null,"4","NIE","mieszana","mechaniczne","","",0,1,0,1,null,null,false,false,false],["Buskowo Zdrój","https://td2.info.pl/scenerie/buskowo-zdroj/","",null,"4","NIE","mieszana","mechaniczne","","",1,0,0,0,null,null,false,false,false],["Bełchów","https://td2.info.pl/scenerie/belchow-projekt-lka/","11","ŁKA","2","NIE","współczesna","SPK","","TAK",0,0,2,0,null,null,false,false,false],["Modlinków","https://td2.info.pl/scenerie/podg-modlinkow/","",null,"6","NIE","współczesna","SPK","","TAK",3,0,2,0,null,null,false,false,false],["Arkadia Zdrój 2019","https://td2.info.pl/scenerie/arkadia-zdroj-2016/","",null,"","NIE","współczesna","SCS","TAK (szlak wewn.)","TAK",1,0,2,0,null,null,false,true,false]] \ No newline at end of file +[["Blaszki","https://td2.info.pl/scenerie/blaszki/","",null,"10","NIE","współczesna","SPK","","",1,1,2,0,null,null,true,false,false],["LCS Borowe","https://td2.info.pl/scenerie/lcs-borowe/","",null,"10","NIE","współczesna","SCS","TAK","TAK",1,0,3,0,["Borowe, podg.","Wysoka, podg.","Naprawa, podg.","Borowe Towarowe"],["Borowe, podg.","Wysoka, podg.","Naprawa, podg.","Borowe Towarowe"],false,false,false],["LCS Gdańsk","https://td2.info.pl/scenerie/lcs-gdansk/","9, 202, 227, 249, 250",null,"10","NIE","współczesna","SCS","TAK","TAK",3,0,3,0,["Gdańsk Główny","SKM Śródmieście","Gdańsk Południowy"],["Gdańsk Główny"],true,false,false],["Lębork","https://td2.info.pl/scenerie/lebork-5834/","202, 229, 237",null,"8","NIE","współczesna","mechaniczne+SCS","","",2,2,0,0,null,null,true,false,false],["Grabów Miasto","https://td2.info.pl/scenerie/grabow-miasto-v2/","",null,"6","NIE","współczesna","SCS","","TAK",2,1,1,0,["Grabów Miasto","Grabów Wieś"],null,true,false,false],["Parzęczewo","https://td2.info.pl/scenerie/parzeczewo/","",null,"6","NIE","mieszana","SCS","TAK","TAK",1,0,2,0,["Parzęczewo","Parzęczewo Miasto","Parzęczewo gt"],null,true,false,false],["Aleksandrów Kujawski","https://td2.info.pl/scenerie/aleksandrow-kujawski/","18, 245",null,"4","NIE","współczesna","SCS-SPK","","TAK",1,0,2,0,null,null,true,false,false],["Arkadia Zdrój 2012","https://td2.info.pl/scenerie/arkadia-zdroj/","",null,"4","NIE","mieszana","mechaniczne+SPK","","",1,0,2,0,null,null,true,false,false],["Buk 2018","https://td2.info.pl/scenerie/buk2/","",null,"4","NIE","współczesna","SCS-SPK","","TAK",2,0,1,0,null,null,true,false,false],["Jordanowo","https://td2.info.pl/scenerie/jordanowo/","",null,"4","NIE","mieszana","mechaniczne","","",3,2,0,0,null,null,true,false,false],["LCS Głowno","https://td2.info.pl/scenerie/glowno-(linia-nr-15-lka)/","15","ŁKA","4","NIE","współczesna","SCS","","",2,0,0,0,["Głowno","Domaniewice"],["Głowno"],true,false,false],["LCS Ozorków","https://td2.info.pl/scenerie/lcs-ozorkow/","16","ŁKA","4","NIE","współczesna","SCS","","",2,0,0,0,["Ozorków","Chociszew"],["Ozorków"],true,false,false],["LCS Skrzynki","https://td2.info.pl/scenerie/lcs-skrzynki/","25","ŁKA","4","NIE","współczesna","SCS-SPK","","TAK",0,0,2,0,["Skrzynki","Wykno"],["Skrzynki"],true,false,false],["Łask","https://td2.info.pl/scenerie/lask-w-ramach-lka/","14","ŁKA","4","NIE","współczesna","mechaniczne+SCS","","",0,0,2,0,null,null,true,false,false],["Naterki","https://td2.info.pl/scenerie/naterki/","353",null,"4","NIE","kształtowa","mechaniczne+SCS","","",0,0,2,0,null,null,true,false,false],["Santok Zdrój","https://td2.info.pl/scenerie/santok-zdroj/","",null,"4","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Testowo","https://td2.info.pl/scenerie/testowo-3581","",null,"4","NIE","współczesna","SPK","TAK (szlak Sl)","TAK",1,1,1,0,null,null,true,false,false],["Tłoki","https://td2.info.pl/scenerie/podg-tloki","",null,"4","NIE","współczesna","SCS-SPK","","TAK",1,0,2,0,null,["Tłoki, podg."],true,false,false],["Witaszyczki","https://td2.info.pl/scenerie/witaszyczki/","",null,"4","NIE","współczesna","SCS","","TAK",0,0,2,0,null,null,true,false,false],["Bydgowo","https://td2.info.pl/scenerie/bydgowo/","",null,"2","NIE","współczesna","SPK","TAK (szlak SK)","TAK",0,0,2,0,null,null,true,false,false],["Głębce","https://td2.info.pl/scenerie/glebce","",null,"2","NIE","współczesna","ręczne+SPK","","",1,0,0,0,null,null,true,false,false],["Hel","https://td2.info.pl/scenerie/hel/","213",null,"2","NIE","współczesna","SPK","","",0,1,0,0,null,null,true,false,false],["Kcynia","https://td2.info.pl/scenerie/kcynia","281, 356",null,"2","NIE","kształtowa","mechaniczne","","",0,4,0,0,null,null,true,false,false],["Lewków","https://td2.info.pl/scenerie/lewkow/","",null,"2","NIE","mieszana","mechaniczne+SCS","","TAK (szlak Ks)",0,0,2,0,null,null,true,false,false],["Cis 2013","https://td2.info.pl/scenerie/cis2","",null,"0","NIE","kształtowa","mechaniczne","","",2,0,0,0,null,null,true,false,false],["Cis 2018","https://td2.info.pl/scenerie/cis2","",null,"0","NIE","współczesna","SCS-SPK","","",2,0,0,0,null,null,true,false,false],["Glinnik","https://td2.info.pl/scenerie/glinnik-(projekt-lka)/","15","ŁKA","0","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Głogowo","https://td2.info.pl/scenerie/glogowo","",null,"0","NIE","współczesna","SCS","","",0,2,0,0,null,null,true,false,false],["Karszynek","https://td2.info.pl/scenerie/karszynek/","",null,"0","NIE","historyczna","mechaniczne","","",0,0,2,0,null,null,true,false,false],["Imielin 2015","https://td2.info.pl/scenerie/imielin-2015","138",null,"0","NIE","współczesna","mechaniczne+SCS","","TAK",0,0,2,0,null,null,true,false,false],["Kolsko","https://td2.info.pl/scenerie/kolsko/","",null,"0","NIE","kształtowa","mechaniczne","","",0,3,0,0,null,null,true,false,false],["LCS Bucz Wileński","https://td2.info.pl/scenerie/bucz-wilenski/","",null,"0","NIE","współczesna","SCS","TAK","TAK",0,0,1,0,null,["Bucz Wileński"],true,false,false],["Lisiczki","https://td2.info.pl/scenerie/lisiczki","",null,"6","NIE","współczesna","SCS-SPK","","",2,0,0,0,null,null,true,false,false],["Łęczyca","https://td2.info.pl/scenerie/leczyca-projekt-lka/","16","ŁKA","0","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Poreńsk","https://td2.info.pl/scenerie/porensk/","",null,"0","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Radowice","https://td2.info.pl/scenerie/radowice","",null,"0","NIE","kształtowa","mechaniczne","","",0,2,0,0,null,null,true,false,false],["Witonia","https://td2.info.pl/scenerie/witonia-(projekt-lka)/","16","ŁKA","0","NIE","współczesna","SCS","","",2,0,0,0,null,null,true,false,false],["Wola","https://td2.info.pl/scenerie/wola/","",null,"0","NIE","mieszana","mechaniczne+SCS","","",0,0,2,0,null,null,true,false,false],["Zgierz Kontrewers","https://td2.info.pl/scenerie/zgierz-kontrewers-6172/","16","ŁKA","0","NIE","współczesna","SPK","","",2,0,0,0,null,null,true,false,false],["Bargowice","https://td2.info.pl/scenerie/bargowice-4441/","",null,"10","NIE","współczesna","SCS-SPK","","TAK",1,0,2,0,["Bargowice","Bargowice Zachód"],null,false,false,false],["Szklana Poręba","https://td2.info.pl/scenerie/szklana-poreba-gorna/","",null,"8","TAK","współczesna","mechaniczne","","",1,0,0,0,null,null,false,false,false],["Wschodna","https://td2.info.pl/scenerie/wschodna/","",null,"8","NIE","kształtowa","mechaniczne","","",1,0,2,0,null,null,false,false,false],["Zabłocie","https://td2.info.pl/scenerie/zablocie-3896","",null,"8","NIE","współczesna","SCS","","TAK",2,0,1,0,null,null,false,false,false],["Zdroje","https://td2.info.pl/scenerie/zdroje","",null,"8","NIE","kształtowa","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Grzybowo","https://td2.info.pl/scenerie/grzybowo","",null,"6","NIE","kształtowa","mechaniczne","","",0,0,2,0,null,null,false,false,false],["Zwardoń","https://td2.info.pl/scenerie/zwardon-4161","139",null,"6","TAK","współczesna","SCS","","",2,0,0,0,null,null,false,false,false],["Piaskowo","https://td2.info.pl/scenerie/piaskowo/","",null,"4","NIE","współczesna","SCS","TAK","TAK",0,0,2,0,null,null,false,false,false],["Rajcza","https://td2.info.pl/scenerie/rajcza/","139",null,"4","NIE","współczesna","SPK","","",2,0,0,0,null,null,false,false,false],["Brzezinka","https://td2.info.pl/scenerie/brzezinka/","",null,"3","NIE","współczesna","SCS-SPK","","TAK (szlak KSG)",0,0,2,0,null,null,false,false,false],["Torzyn","https://td2.info.pl/scenerie/torzyn/","",null,"3","NIE","współczesna","SCS","TAK","TAK",0,0,2,0,null,null,false,false,false],["Wola Nowska","https://td2.info.pl/scenerie/wola-nowska//","",null,"3","NIE","współczesna","SPK","","TAK",1,0,2,0,null,null,false,false,false],["Chełmik Wołowski","https://td2.info.pl/scenerie/chelmik-wolowski//","",null,"2","NIE","współczesna","SPK","","TAK",1,0,2,0,null,null,false,false,false],["Drzewko","https://td2.info.pl/w-trakcie-prac/drzewko/","",null,"2","NIE","współczesna","SCS","","TAK",0,0,2,0,null,null,false,false,false],["Krzemienice","https://td2.info.pl/scenerie/krzemienice/","",null,"2","NIE","współczesna","SCS","","TAK",3,0,1,0,null,null,false,false,false],["Milówka","https://td2.info.pl/scenerie/milowka/","139",null,"2","NIE","współczesna","SPK","","",2,0,0,0,null,null,false,false,false],["Orniki","https://td2.info.pl/scenerie/orniki/","",null,"2","NIE","współczesna","SPK","","TAK",1,1,2,0,null,null,false,false,false],["Otwocko","https://td2.info.pl/scenerie/otwocko/","",null,"2","NIE","współczesna","SCS","","TAK",0,0,2,0,null,null,false,false,false],["Skostomłoty","https://td2.info.pl/w-trakcie-prac/skostomloty/","",null,"2","NIE","współczesna","mechaniczne","","TAK",0,0,2,0,null,null,false,false,false],["Babimost","https://td2.info.pl/scenerie/babimost","358",null,"0","NIE","współczesna","mechaniczne","","",2,0,0,0,null,null,false,false,false],["Czerepy","https://td2.info.pl/scenerie/czerepy/","",null,"0","NIE","współczesna","SPK","TAK (szlak BO)","TAK",0,0,2,0,null,null,false,false,false],["Grabiny","https://td2.info.pl/scenerie/grabiny","",null,"0","NIE","współczesna","mechaniczne","","",2,0,0,0,null,null,false,false,false],["Kieły","https://td2.info.pl/scenerie/kiely-6224/","",null,"0","NIE","kształtowa","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Lutol Suchy","https://td2.info.pl/scenerie/lutol-suchy/","367",null,"0","NIE","współczesna","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Raki","https://td2.info.pl/scenerie/raki/","",null,"0","NIE","kształtowa","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Sieniawka","https://td2.info.pl/scenerie/sieniawka/","",null,"0","NIE","współczesna","mechaniczne","","",0,1,0,1,null,null,false,false,false],["Stefanowo","https://td2.info.pl/scenerie/stefanowo/","359",null,"0","NIE","kształtowa","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Szlichtyngowa","https://td2.info.pl/scenerie/szlichtyngowa//","",null,"0","NIE","współczesna","SPK","","TAK",0,0,2,0,null,null,false,false,false],["Tarnowo Górne","https://td2.info.pl/scenerie/tarnowo-gorne/","",null,"0","NIE","kształtowa","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Tartakowo 2013","https://td2.info.pl/w-trakcie-prac/tartakowo/","",null,"0","NIE","mieszana","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Wielgowo","https://td2.info.pl/scenerie/wielgowo/","",null,"0","NIE","współczesna","SPK","","",0,2,0,0,null,null,false,false,false],["Sulechów","https://td2.info.pl/scenerie/sulechow/","358",null,"0","NIE","mieszana","SPK","","",2,1,0,0,null,null,false,false,false],["Wilczyca","https://td2.info.pl/scenerie/wilczyca/","",null,"0","NIE","współczesna","SCS","","",0,2,0,0,null,null,false,false,false],["Sowi Bór","https://td2.info.pl/scenerie/sowi-bor/","",null,"3","NIE","współczesna","SPK","","",0,0,2,0,null,null,false,false,false],["Sól","https://td2.info.pl/scenerie/sol/","139",null,"2","NIE","współczesna","SPK","","",2,0,0,0,null,null,false,false,false],["Hetmanice","https://td2.info.pl/scenerie/hetmanice-stacja-dla-poczatkujacych/","",null,"0","NIE","współczesna","SCS-SPK","","",0,0,2,0,null,null,false,false,false],["Starzynki","https://td2.info.pl/w-trakcie-prac/starzynki/","",null,"3","NIE","współczesna","SPK","TAK (Szlak Ps)","TAK",2,0,1,0,null,null,false,false,false],["Głęboszów","https://td2.info.pl/scenerie/gleboszow/","",null,"3","NIE","współczesna","SCS","TAK (Szlaki Br oraz GO)","TAK",1,0,2,0,null,null,false,false,false],["Skawce","https://td2.info.pl/w-trakcie-prac/skawce-(projekt-zakopianka)/","97",null,"4","NIE","współczesna","SPK","","",2,0,0,0,null,null,false,false,true],["Sroka","https://td2.info.pl/scenerie/sroka-projekt-1001/","",null,"7","NIE","współczesna","SCS","","TAK",1,0,3,0,["Sroka, podg.","Sroka Południe, podg."],["Sroka, podg."],false,false,false],["Luzino","https://td2.info.pl/scenerie/luzino-6501/","202",null,"3","NIE","współczesna","mechaniczne","","TAK",2,0,0,0,null,null,false,false,false],["Zajączkowo","https://td2.info.pl/scenerie/zajaczkowo/","",null,"0","NIE","kształtowa","mechaniczne","","",0,2,0,0,null,null,false,false,false],["Kudowa-Zdrój","https://td2.info.pl/scenerie/kudowa-zdroj-6616/","309",null,"4","NIE","współczesna","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Ciechany","https://td2.info.pl/w-trakcie-prac/ciechany/","",null,"3","NIE","współczesna","SCS","","",1,0,0,0,null,["Pawonki"],false,false,false],["Czermin","https://td2.info.pl/scenerie/czermin/","",null,"8","NIE","współczesna","SCS","TAK (szlaki Łk i Fw)","",2,0,2,0,null,null,false,false,false],["Rebrowo Dolne","https://td2.info.pl/scenerie/rebrowo-dolne/","",null,"2","NIE","współczesna","SPK","","",3,0,0,0,null,null,false,false,false],["Lublinek","https://td2.info.pl/scenerie/lublinek-projekt-lka/","14",null,"0","NIE","współczesna","mechaniczne","","",0,0,2,0,null,null,true,false,false],["Stryków","https://td2.info.pl/scenerie/strykow-projekt-lka/","14",null,"0","NIE","współczesna","mechaniczne","","",2,0,0,0,null,null,true,false,false],["Strączki","https://td2.info.pl/scenerie/straczki/","",null,"4","NIE","współczesna","mechaniczne","","",1,0,1,0,null,null,false,false,false],["Niedoradz","https://td2.info.pl/scenerie/niedoradz","",null,"0","NIE","współczesna","SPK","","",0,0,2,0,null,null,false,false,false],["Zgierz","https://td2.info.pl/scenerie/zgierz/","15,16",null,"12","TAK","współczesna","mechaniczne","","",3,0,1,0,null,null,false,false,false],["Łebnino","https://td2.info.pl/scenerie/lebnino-4511/","",null,"0","NIE","kształtowa","mechaniczne","","",0,1,0,0,null,null,false,false,false],["Legno","https://td2.info.pl/scenerie/legno/","",null,"0","NIE","współczesna","SCS","TAK (szlak Mr)","TAK",0,0,2,0,null,null,false,false,false],["Buczek","https://td2.info.pl/scenerie/buczek/","",null,"0","NIE","współczesna","SCS","TAK","TAK",0,0,2,0,null,null,false,false,false],["Dziewoszyce","https://td2.info.pl/scenerie/dziewoszyce/","",null,"4","NIE","współczesna","SPK","","TAK",0,0,2,0,null,null,false,false,false],["Razemsko 2012","https://td2.info.pl/scenerie/razemsko-2012/","",null,"4","NIE","mieszana","mechaniczne","","",0,1,0,1,null,null,false,false,false],["Buskowo Zdrój","https://td2.info.pl/scenerie/buskowo-zdroj/","",null,"4","NIE","mieszana","mechaniczne","","",1,0,0,0,null,null,false,false,false],["Bełchów","https://td2.info.pl/scenerie/belchow-projekt-lka/","11","ŁKA","2","NIE","współczesna","SPK","","TAK",0,0,2,0,null,null,false,false,false],["Modlinków","https://td2.info.pl/scenerie/podg-modlinkow/","",null,"6","NIE","współczesna","SPK","","TAK",3,0,2,0,null,null,false,false,false],["Arkadia Zdrój 2019","https://td2.info.pl/scenerie/arkadia-zdroj-2016/","",null,"","NIE","współczesna","SCS","TAK (szlak wewn.)","TAK",1,0,2,0,null,null,false,false,false]] \ No newline at end of file diff --git a/src/scripts/interfaces/ScheduledTrain.ts b/src/scripts/interfaces/ScheduledTrain.ts index 01b2e34..5c4cd08 100644 --- a/src/scripts/interfaces/ScheduledTrain.ts +++ b/src/scripts/interfaces/ScheduledTrain.ts @@ -1,19 +1,19 @@ -import TrainStop from "./TrainStop"; - -export default interface ScheduledTrain { - trainNo: number; - driverName: string; - driverId: number; - currentStationName: string; - currentStationHash: string; - category: string; - stopInfo: TrainStop; - - terminatesAt: string; - beginsAt: string; - nearestStop: string; - - stopLabel: string; - stopStatus: string; - stopStatusID: number; +import TrainStop from "./TrainStop"; + +export default interface ScheduledTrain { + trainNo: number; + driverName: string; + driverId: number; + currentStationName: string; + currentStationHash: string; + category: string; + stopInfo: TrainStop; + + terminatesAt: string; + beginsAt: string; + nearestStop: string; + + stopLabel: string; + stopStatus: string; + stopStatusID: number; } \ No newline at end of file diff --git a/src/scripts/interfaces/Timetable.ts b/src/scripts/interfaces/Timetable.ts index fe2ef84..b6da1a1 100644 --- a/src/scripts/interfaces/Timetable.ts +++ b/src/scripts/interfaces/Timetable.ts @@ -1,16 +1,16 @@ -export default interface Timetable { - trainNo: number; - driverName: string; - category: string; - stopName: string; - stopType: string; - arrivalTime: number; - arrivalDelay: number; - departureTime: number; - departureDelay: number; - confirmed: boolean; - stopped: boolean; - stopTime: number; - beginsHere: boolean; - terminatesHere: boolean; -} +export default interface Timetable { + trainNo: number; + driverName: string; + category: string; + stopName: string; + stopType: string; + arrivalTime: number; + arrivalDelay: number; + departureTime: number; + departureDelay: number; + confirmed: boolean; + stopped: boolean; + stopTime: number; + beginsHere: boolean; + terminatesHere: boolean; +} diff --git a/src/scripts/interfaces/Train.ts b/src/scripts/interfaces/Train.ts index 0980403..0363502 100644 --- a/src/scripts/interfaces/Train.ts +++ b/src/scripts/interfaces/Train.ts @@ -1,31 +1,31 @@ -import TrainStop from '@/scripts/interfaces/TrainStop'; - -export default interface Train { - mass: number; - length: number; - speed: number; - signal: string; - distance: number; - connectedTrack: string; - driverId: number; - trainNo: number; - driverName: string; - currentStationName: string; - currentStationHash: string; - locoURL: string; - locoType: string; - online: boolean; - - timetableData?: { - timetableId: number; - category: string; - route: string; - followingStops: TrainStop[]; - TWR: boolean; - SKR: boolean; - routeDistance: number; - }; - - stopStatus: string; - stopLabel: string; -} +import TrainStop from '@/scripts/interfaces/TrainStop'; + +export default interface Train { + mass: number; + length: number; + speed: number; + signal: string; + distance: number; + connectedTrack: string; + driverId: number; + trainNo: number; + driverName: string; + currentStationName: string; + currentStationHash: string; + locoURL: string; + locoType: string; + online: boolean; + + timetableData?: { + timetableId: number; + category: string; + route: string; + followingStops: TrainStop[]; + TWR: boolean; + SKR: boolean; + routeDistance: number; + }; + + stopStatus: string; + stopLabel: string; +} diff --git a/src/scripts/interfaces/TrainStop.ts b/src/scripts/interfaces/TrainStop.ts index 9e30bd3..b46138e 100644 --- a/src/scripts/interfaces/TrainStop.ts +++ b/src/scripts/interfaces/TrainStop.ts @@ -1,28 +1,28 @@ -export default interface TrainStop { - stopName: string; - stopNameRAW: string; - stopType: string; - mainStop: boolean; - - arrivalLine: string; - arrivalTimeString: string; - arrivalTimestamp: number; - arrivalRealTimeString: string; - arrivalRealTimestamp: number; - arrivalDelay: number; - - departureLine: string; - departureTimeString: string; - departureTimestamp: number; - departureRealTimeString: string; - departureRealTimestamp: number; - departureDelay: number; - - comments?: any; - - beginsHere: boolean; - terminatesHere: boolean; - confirmed: boolean; - stopped: boolean; - stopTime: number; -} +export default interface TrainStop { + stopName: string; + stopNameRAW: string; + stopType: string; + mainStop: boolean; + + arrivalLine: string; + arrivalTimeString: string; + arrivalTimestamp: number; + arrivalRealTimeString: string; + arrivalRealTimestamp: number; + arrivalDelay: number; + + departureLine: string; + departureTimeString: string; + departureTimestamp: number; + departureRealTimeString: string; + departureRealTimestamp: number; + departureDelay: number; + + comments?: any; + + beginsHere: boolean; + terminatesHere: boolean; + confirmed: boolean; + stopped: boolean; + stopTime: number; +} diff --git a/src/scripts/stationFilterManager.ts b/src/scripts/stationFilterManager.ts index a5457e8..0cc5d1a 100644 --- a/src/scripts/stationFilterManager.ts +++ b/src/scripts/stationFilterManager.ts @@ -1,140 +1,138 @@ -import Station from '@/scripts/interfaces/Station'; - -export default class StationFilterManager { - private filterInitStates = { - default: false, - notDefault: false, - nonPublic: false, - SPK: false, - SCS: false, - ręczne: false, - mechaniczne: false, - współczesna: false, - kształtowa: false, - historyczna: false, - mieszana: false, - minLevel: 0, - minOneWayCatenary: 0, - minOneWay: 0, - minTwoWayCatenary: 0, - minTwoWay: 0, - 'no-1track': false, - 'no-2track': false, - free: true, - occupied: false, - ending: false, - }; - - private filters = { ...this.filterInitStates }; - - private sorter: { index: number; dir: number } = { index: 0, dir: 1 }; - - filteredStationList(stationList: Station[]): Station[] { - return stationList - .filter(station => { - if (!station.reqLevel || station.reqLevel == '-1') return true; - - if ((station.nonPublic || !station.reqLevel) && this.filters['nonPublic']) return false; - - if (station.online && station.occupiedTo == 'KOŃCZY' && this.filters['ending']) return false; - - if (station.online && this.filters['occupied']) return false; - if (!station.online && this.filters['free']) return false; - - if (station.default && this.filters['default']) return false; - if (!station.default && this.filters['notDefault']) return false; - - if (parseInt(station.reqLevel) < this.filters['minLevel']) return false; - - if (this.filters['no-1track'] && (station.routes.oneWay.catenary != 0 || station.routes.oneWay.noCatenary != 0)) return false; - if (this.filters['no-2track'] && (station.routes.twoWay.catenary != 0 || station.routes.twoWay.noCatenary != 0)) return false; - - if (station.routes.oneWay.catenary < this.filters['minOneWayCatenary']) return false; - if (station.routes.oneWay.noCatenary < this.filters['minOneWay']) return false; - - if (station.routes.twoWay.catenary < this.filters['minTwoWayCatenary']) return false; - if (station.routes.twoWay.noCatenary < this.filters['minTwoWay']) return false; - - if (this.filters[station.controlType]) return false; - if (this.filters[station.signalType]) return false; - - if (this.filters['SPK'] && (station.controlType === 'SPK' || station.controlType.includes('+SPK'))) return false; - if (this.filters['SCS'] && (station.controlType === 'SCS' || station.controlType.includes('+SCS'))) return false; - - if (this.filters['SCS'] && this.filters['SPK'] && (station.controlType.includes('SPK') || station.controlType.includes('SCS'))) return false; - - if (this.filters['mechaniczne'] && station.controlType.includes('mechaniczne')) return false; - - if (this.filters['ręczne'] && station.controlType.includes('ręczne')) return false; - - return true; - }) - .sort((a, b) => { - switch (this.sorter.index) { - case 1: - if (parseInt(a.reqLevel) > parseInt(b.reqLevel)) return this.sorter.dir; - if (parseInt(a.reqLevel) < parseInt(b.reqLevel)) return -this.sorter.dir; - break; - - case 2: - if (a.statusTimestamp > b.statusTimestamp) return this.sorter.dir; - if (a.statusTimestamp < b.statusTimestamp) return -this.sorter.dir; - break; - - case 3: - if (a.dispatcherName.toLowerCase() > b.dispatcherName.toLowerCase()) return this.sorter.dir; - if (a.dispatcherName.toLowerCase() < b.dispatcherName.toLowerCase()) return -this.sorter.dir; - break; - - case 4: - if (a.dispatcherExp > b.dispatcherExp) return this.sorter.dir; - if (a.dispatcherExp < b.dispatcherExp) return -this.sorter.dir; - break; - - case 7: - if (a.currentUsers > b.currentUsers) return this.sorter.dir; - if (a.currentUsers < b.currentUsers) return -this.sorter.dir; - if (a.maxUsers > b.maxUsers) return this.sorter.dir; - if (a.maxUsers < b.maxUsers) return -this.sorter.dir; - break; - - case 8: - if (a.spawns > b.spawns) return this.sorter.dir; - if (a.spawns < b.spawns) return -this.sorter.dir; - - break; - - case 9: - if (a.scheduledTrains.length > b.scheduledTrains.length) return this.sorter.dir; - if (a.scheduledTrains.length < b.scheduledTrains.length) return -this.sorter.dir; - - default: - break; - } - - if (a.stationName.toLowerCase() >= b.stationName.toLowerCase()) return this.sorter.dir; - return -this.sorter.dir; - }); - } - - changeFilterValue(filter: { name: string; value: number }) { - this.filters[filter.name] = filter.value; - } - - resetFilters() { - this.filters = { ...this.filterInitStates }; - } - - changeSorter(index: number) { - if (index > 4 && index < 7) return; - - if (index == this.sorter.index) this.sorter.dir = -1 * this.sorter.dir; - else this.sorter.dir = 1; - - this.sorter.index = index; - } - - getSorter() { - return this.sorter; - } -} +import Station from '@/scripts/interfaces/Station'; + +export default class StationFilterManager { + private filterInitStates = { + default: false, + notDefault: false, + nonPublic: false, + SPK: false, + SCS: false, + ręczne: false, + mechaniczne: false, + współczesna: false, + kształtowa: false, + historyczna: false, + mieszana: false, + minLevel: 0, + minOneWayCatenary: 0, + minOneWay: 0, + minTwoWayCatenary: 0, + minTwoWay: 0, + 'no-1track': false, + 'no-2track': false, + free: true, + occupied: false, + ending: false, + }; + + private filters = { ...this.filterInitStates }; + + private sorter: { index: number; dir: number } = { index: 0, dir: 1 }; + + filteredStationList(stationList: Station[]): Station[] { + return stationList + .filter(station => { + if ((station.nonPublic || !station.reqLevel) && this.filters['nonPublic']) return false; + + if (station.online && station.occupiedTo == 'KOŃCZY' && this.filters['ending']) return false; + + if (station.online && this.filters['occupied']) return false; + if (!station.online && this.filters['free']) return false; + + if (station.default && this.filters['default']) return false; + if (!station.default && this.filters['notDefault']) return false; + + if (parseInt(station.reqLevel) < this.filters['minLevel']) return false; + + if (this.filters['no-1track'] && (station.routes.oneWay.catenary != 0 || station.routes.oneWay.noCatenary != 0)) return false; + if (this.filters['no-2track'] && (station.routes.twoWay.catenary != 0 || station.routes.twoWay.noCatenary != 0)) return false; + + if (station.routes.oneWay.catenary < this.filters['minOneWayCatenary']) return false; + if (station.routes.oneWay.noCatenary < this.filters['minOneWay']) return false; + + if (station.routes.twoWay.catenary < this.filters['minTwoWayCatenary']) return false; + if (station.routes.twoWay.noCatenary < this.filters['minTwoWay']) return false; + + if (this.filters[station.controlType]) return false; + if (this.filters[station.signalType]) return false; + + if (this.filters['SPK'] && (station.controlType === 'SPK' || station.controlType.includes('+SPK'))) return false; + if (this.filters['SCS'] && (station.controlType === 'SCS' || station.controlType.includes('+SCS'))) return false; + + if (this.filters['SCS'] && this.filters['SPK'] && (station.controlType.includes('SPK') || station.controlType.includes('SCS'))) return false; + + if (this.filters['mechaniczne'] && station.controlType.includes('mechaniczne')) return false; + + if (this.filters['ręczne'] && station.controlType.includes('ręczne')) return false; + + return true; + }) + .sort((a, b) => { + switch (this.sorter.index) { + case 1: + if (parseInt(a.reqLevel) > parseInt(b.reqLevel)) return this.sorter.dir; + if (parseInt(a.reqLevel) < parseInt(b.reqLevel)) return -this.sorter.dir; + break; + + case 2: + if (a.statusTimestamp > b.statusTimestamp) return this.sorter.dir; + if (a.statusTimestamp < b.statusTimestamp) return -this.sorter.dir; + break; + + case 3: + if (a.dispatcherName.toLowerCase() > b.dispatcherName.toLowerCase()) return this.sorter.dir; + if (a.dispatcherName.toLowerCase() < b.dispatcherName.toLowerCase()) return -this.sorter.dir; + break; + + case 4: + if (a.dispatcherExp > b.dispatcherExp) return this.sorter.dir; + if (a.dispatcherExp < b.dispatcherExp) return -this.sorter.dir; + break; + + case 7: + if (a.currentUsers > b.currentUsers) return this.sorter.dir; + if (a.currentUsers < b.currentUsers) return -this.sorter.dir; + if (a.maxUsers > b.maxUsers) return this.sorter.dir; + if (a.maxUsers < b.maxUsers) return -this.sorter.dir; + break; + + case 8: + if (a.spawns > b.spawns) return this.sorter.dir; + if (a.spawns < b.spawns) return -this.sorter.dir; + + break; + + case 9: + if (a.scheduledTrains.length > b.scheduledTrains.length) return this.sorter.dir; + if (a.scheduledTrains.length < b.scheduledTrains.length) return -this.sorter.dir; + + default: + break; + } + + if (a.stationName.toLowerCase() >= b.stationName.toLowerCase()) return this.sorter.dir; + return -this.sorter.dir; + }); + } + + changeFilterValue(filter: { name: string; value: number }) { + this.filters[filter.name] = filter.value; + } + + resetFilters() { + this.filters = { ...this.filterInitStates }; + } + + changeSorter(index: number) { + if (index > 4 && index < 7) return; + + if (index == this.sorter.index) this.sorter.dir = -1 * this.sorter.dir; + else this.sorter.dir = 1; + + this.sorter.index = index; + } + + getSorter() { + return this.sorter; + } +} diff --git a/src/scripts/storageManager.ts b/src/scripts/storageManager.ts index 82883c1..b24ee2c 100644 --- a/src/scripts/storageManager.ts +++ b/src/scripts/storageManager.ts @@ -1,42 +1,42 @@ -export default class StorageManager { - static registerStorage(name: string) { - window.localStorage.setItem(name, '1'); - } - - static unregisterStorage(name: string) { - window.localStorage.removeItem(name); - } - - static isRegistered(name: string) { - return window.localStorage.getItem(name) ? true : false; - } - - static setBooleanValue(key: string, val: boolean) { - window.localStorage.setItem(key, val.toString()); - } - - static setNumericValue(key: string, val: number) { - window.localStorage.setItem(key, val.toString()); - } - - static setStringValue(key: string, val: string) { - window.localStorage.setItem(key, val); - } - - static removeValue(key: string) { - window.localStorage.removeItem(key); - } - - static getBooleanValue(key: string): boolean { - return window.localStorage.getItem(key) === 'true' ? true : false; - } - - static getStringValue(key: string): string { - return window.localStorage.getItem(key) || ''; - } - - static getNumericValue(key: string): number { - const itemValue = window.localStorage.getItem(key); - return itemValue ? parseInt(itemValue) : 0; - } -} +export default class StorageManager { + static registerStorage(name: string) { + window.localStorage.setItem(name, '1'); + } + + static unregisterStorage(name: string) { + window.localStorage.removeItem(name); + } + + static isRegistered(name: string) { + return window.localStorage.getItem(name) ? true : false; + } + + static setBooleanValue(key: string, val: boolean) { + window.localStorage.setItem(key, val.toString()); + } + + static setNumericValue(key: string, val: number) { + window.localStorage.setItem(key, val.toString()); + } + + static setStringValue(key: string, val: string) { + window.localStorage.setItem(key, val); + } + + static removeValue(key: string) { + window.localStorage.removeItem(key); + } + + static getBooleanValue(key: string): boolean { + return window.localStorage.getItem(key) === 'true' ? true : false; + } + + static getStringValue(key: string): string { + return window.localStorage.getItem(key) || ''; + } + + static getNumericValue(key: string): number { + const itemValue = window.localStorage.getItem(key); + return itemValue ? parseInt(itemValue) : 0; + } +} diff --git a/src/store/store.ts b/src/store/store.ts index a543b62..53ea121 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -1,625 +1,625 @@ -import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'; -import axios from 'axios'; - -import JSONStationData from '@/data/stationData.json'; - -import Station from '@/scripts/interfaces/Station'; -import Train from '@/scripts/interfaces/Train'; -import TrainStop from '@/scripts/interfaces/TrainStop'; - -enum Status { - Initialized = -1, - Loading = 0, - Error = 1, - Loaded = 2, -} - -interface TimetableData { - trainNo: number; - driverName: string; - driverId: number; - currentStationName: string; - currentStationHash: string; - timetableId: number; - category: string; - route: string; - TWR: boolean; - SKR: boolean; - routeDistance: number; - followingStops: TrainStop[]; - followingSceneries: string[]; -} - -// const devEnv = true; - -const URLs = { - stations: 'https://api.td2.info.pl:9640/?method=getStationsOnline', - trains: 'https://api.td2.info.pl:9640/?method=getTrainsOnline', - dispatchers: 'https://api.td2.info.pl:9640/?method=readFromSWDR&value=getDispatcherStatusList%3B1', -}; - -const timetableURL = (trainNo: number) => `https://api.td2.info.pl:9640/?method=readFromSWDR&value=getTimetable%3B${trainNo}%3Beu`; -const getLocoURL = (locoType: string) => `https://rj.td2.info.pl/dist/img/thumbnails/${locoType.includes('EN') ? locoType + 'rb' : locoType}.png`; - -const getStatusLabel = (stationStatus: any) => { - if (!stationStatus) return 'NIEZALOGOWANY'; - - const statusCode = stationStatus[2]; - const statusTimestamp = stationStatus[3]; - - switch (statusCode) { - case 0: - if (statusTimestamp - Date.now() > 21000000) return 'BEZ LIMITU'; - - return `DO ${new Date(statusTimestamp).toLocaleTimeString('en-US', { - hour12: false, - hour: '2-digit', - minute: '2-digit', - })}`; - - case 1: - return 'Z/W'; - - case 2: - if (statusTimestamp == 0) return 'KOŃCZY'; - break; - - case 3: - return 'BRAK MIEJSCA'; - - default: - break; - } - - return 'NIEDOSTĘPNY'; -}; - -const getStatusTimestamp = (stationStatus: any) => { - if (!stationStatus) return -2; - - const statusCode = stationStatus[2]; - const statusTimestamp = stationStatus[3]; - - switch (statusCode) { - case 0: - case 1: - case 3: - return statusTimestamp; - - case 2: - if (statusTimestamp == 0) return 0; - break; - - default: - break; - } - - return -1; -}; - -const parseSpawns = (spawnString: string) => { - if (!spawnString) return []; - if (spawnString === 'NO_SPAWN') return []; - - return spawnString.split(';').map(spawn => { - const spawnArray = spawn.split(','); - const spawnName = spawnArray[6] ? spawnArray[6] : spawnArray[0]; - const spawnLength = parseInt(spawnArray[2]); - - return { spawnName, spawnLength }; - }); -}; - -const getTimestamp = (date: string) => (date ? new Date(date).getTime() : 0); -const timestampToTime = (timestamp: number) => - new Date(timestamp).toLocaleTimeString('pl-PL', { - hour: '2-digit', - minute: '2-digit', - }); - -@Module -export default class Store extends VuexModule { - private trainCount: number = 0; - private stationCount: number = 0; - - private dataConnectionStatus: Status = Status.Loading; - private timetableLoaded: Status = Status.Loading; - - private stationList: Station[] = []; - private trainList: Train[] = []; - - //GETTERS - get getAllData() { - return { - stationList: this.stationList, - trainList: this.trainList, - trainCount: this.trainCount, - stationCount: this.stationCount, - dataConnectionStatus: this.dataConnectionStatus, - timetableDataStatus: this.timetableLoaded, - }; - } - - get getStationList() { - return this.stationList; - } - - get getTrainList() { - return this.trainList; - } - - get getTimetableDataStatus() { - return this.timetableLoaded; - } - - get getDataStatus() { - return this.dataConnectionStatus; - } - - //ACTIONS - @Action - async synchronizeData() { - this.context.commit('setJSONData'); - - this.context.dispatch('fetchOnlineData'); - setInterval(() => this.context.dispatch('fetchOnlineData'), 20000); - } - - @Action({ commit: 'updateTimetableData' }) - async fetchTimetableData() { - return this.trainList.reduce(async (acc: Promise, train) => { - const timetable = await (await axios.get(timetableURL(train.trainNo))).data.message; - const trainInfo = timetable.trainInfo; - - if (!timetable || !trainInfo) return acc; - - const followingStops: TrainStop[] = timetable.stopPoints.reduce((stopsAcc: TrainStop[], point) => { - const arrivalTimestamp = getTimestamp(point.arrivalTime); - const arrivalRealTimestamp = getTimestamp(point.arrivalRealTime); - - const departureTimestamp = getTimestamp(point.departureTime); - const departureRealTimestamp = getTimestamp(point.departureRealTime); - - stopsAcc.push({ - stopName: point.pointName, - stopNameRAW: point.pointNameRAW, - stopType: point.pointStopType, - mainStop: point.pointName.includes('strong'), - - arrivalLine: point.arrivalLine, - arrivalTimeString: timestampToTime(point.arrivalTime), - arrivalTimestamp: arrivalTimestamp, - arrivalRealTimeString: timestampToTime(point.arrivalRealTime), - arrivalRealTimestamp: arrivalRealTimestamp, - arrivalDelay: point.arrivalDelay, - - departureLine: point.departureLine, - departureTimeString: timestampToTime(point.departureTime), - departureTimestamp: departureTimestamp, - departureRealTimeString: timestampToTime(point.departureRealTime), - departureRealTimestamp: departureRealTimestamp, - departureDelay: point.departureDelay, - - beginsHere: arrivalTimestamp == 0, - terminatesHere: departureTimestamp == 0, - - confirmed: point.confirmed, - stopped: point.isStopped, - stopTime: point.pointStopTime, - }); - - return stopsAcc; - }, []); - - (await acc).push({ - trainNo: train.trainNo, - driverName: train.driverName, - driverId: train.driverId, - currentStationName: train.currentStationName, - currentStationHash: train.currentStationHash, - timetableId: trainInfo.timetableId, - category: trainInfo.trainCategoryCode, - route: trainInfo.route, - TWR: trainInfo.twr, - SKR: trainInfo.skr, - routeDistance: timetable.stopPoints[timetable.stopPoints.length - 1].pointDistance, - followingStops, - followingSceneries: trainInfo.sceneries, - }); - - return acc; - }, Promise.resolve([])); - } - - @Action - async fetchOnlineData() { - Promise.all([axios.get(URLs.stations), axios.get(URLs.trains), axios.get(URLs.dispatchers)]) - .then(async response => { - const onlineStationsData = response[0].data.message; - const onlineTrainsData = await response[1].data.message; - const onlineDispatchersData = await response[2].data.message; - - let updatedStationList = onlineStationsData.reduce((acc, station) => { - if (station.region !== 'eu' || !station.isOnline) return acc; - - const stationStatus = onlineDispatchersData.find(status => status[0] == station.stationHash && status[1] == 'eu'); - - const statusLabel = getStatusLabel(stationStatus); - const statusTimestamp = getStatusTimestamp(stationStatus); - - const stationTrains = onlineTrainsData.filter(train => train.region === 'eu' && train.isOnline && train.station.stationName === station.stationName); - - acc.push({ - stationName: station.stationName, - stationHash: station.stationHash, - maxUsers: station.maxUsers, - currentUsers: station.currentUsers, - spawns: parseSpawns(station.spawnString), - dispatcherName: station.dispatcherName, - dispatcherRate: station.dispatcherRate, - dispatcherId: station.dispatcherId, - dispatcherExp: station.dispatcherExp, - dispatcherIsSupporter: station.dispatcherIsSupporter, - occupiedTo: statusLabel, - stationTrains, - statusTimestamp, - }); - - return acc; - }, []); - - let updatedTrainList = await Promise.all( - onlineTrainsData - .filter(train => train.region === 'eu') - .map(async train => { - const locoType = train.dataCon.split(';') ? train.dataCon.split(';')[0] : train.dataCon; - - return { - trainNo: train.trainNo, - mass: train.dataMass, - length: train.dataLength, - speed: train.dataSpeed, - distance: train.dataDistance, - signal: train.dataSignal, - online: train.isOnline, - driverId: train.driverId, - driverName: train.driverName, - currentStationName: train.station.stationName, - currentStationHash: train.station.stationHash, - connectedTrack: train.dataSceneryConnection, - locoType, - locoURL: getLocoURL(locoType), - }; - }) - ); - - this.context.commit('updateOnlineStations', updatedStationList); - this.context.commit('updateOnlineTrains', updatedTrainList); - - this.context.dispatch('fetchTimetableData'); - }) - .catch(err => { - this.context.commit('setDataConnectionStatus', Status.Error); - }); - } - - //MUTATIONS - @Mutation - private setDataConnectionStatus(status: Status) { - this.dataConnectionStatus = status; - } - - @Mutation setJSONData() { - /* - 0: stationName, - 1: stationURL, - 2: stationlines, - 3: stationProject?, - 4: reqLevel, - 5: supportersOnly, - 6: signalType, - 7: controlType, - 8: SBL, - 9: two-way block, - 10: routes, one-way, catenary, - 11: routes, one-way, no catenary, - 12: routes, two-way, catenary, - 13: routes, two-way, no catenary, - 14: subStations?, - 15: stops?, - 16: default, - 17: nonPublic, - 18: unavailable - */ - - this.stationList = JSONStationData.map(station => ({ - stationName: station[0] as string, - stationURL: station[1] as string, - stationLines: station[2] as string, - stationProject: station[3] as string, - reqLevel: station[4] as string, - supportersOnly: station[5] as string, - signalType: station[6] as string, - controlType: station[7] as string, - SBL: station[8] as string, - TWB: station[9] as string, - routes: { - oneWay: { - catenary: station[10] as number, - noCatenary: station[11] as number, - }, - twoWay: { - catenary: station[12] as number, - noCatenary: station[13] as number, - }, - }, - checkpoints: station[14] ? (station[14] as string[]).map(sub => ({ checkpointName: sub, scheduledTrains: [] })) : null, - stops: station[15] as string[], - - default: station[16] as boolean, - nonPublic: station[17] as boolean, - unavailable: station[18] as boolean, - - stationHash: '', - maxUsers: 0, - currentUsers: 0, - dispatcherName: '', - dispatcherRate: 0, - dispatcherExp: -1, - dispatcherId: 0, - dispatcherIsSupporter: false, - online: false, - occupiedTo: 'WOLNA', - statusTimestamp: -3, - stationTrains: [], - scheduledTrains: [], - spawns: [], - })); - } - - @Mutation - private updateOnlineStations(updatedStationList: any[]) { - this.stationList = this.stationList.reduce((acc, station) => { - const onlineStationData = updatedStationList.find(updatedStation => updatedStation.stationName === station.stationName); - const registeredStation = JSONStationData.find(data => data[0] === station.stationName); - - if (onlineStationData) - acc.push({ - ...station, - ...onlineStationData, - online: true, - }); - else if (registeredStation) - acc.push({ - ...station, - stationProject: '', - stationHash: '', - maxUsers: 0, - currentUsers: 0, - dispatcherName: '', - dispatcherRate: 0, - dispatcherExp: -1, - dispatcherId: 0, - dispatcherIsSupporter: false, - online: false, - occupiedTo: 'WOLNA', - statusTimestamp: -3, - stationTrains: [], - scheduledTrains: [], - checkpoints: null, - }); - - return acc; - }, [] as Station[]); - - // Dodawanie do listy online potencjalnych scenerii niewpisanych do bazy - updatedStationList.forEach(updatedStation => { - const alreadyInList: any = this.stationList.some(station => station.stationName === updatedStation.stationName); - - if (!alreadyInList) { - this.stationList.push({ - ...updatedStation, - scheduledTrains: [], - stationTrains: [], - subStations: [], - online: true, - reqLevel: '-1', - nonPublic: true, - }); - } - }); - - this.stationCount = this.stationList.filter(station => station.online).length; - this.dataConnectionStatus = Status.Loaded; - } - - @Mutation - private updateOnlineTrains(updatedTrainList) { - this.trainList = updatedTrainList.reduce((acc, updatedTrain) => { - const trainData = this.trainList.find(train => train.trainNo === updatedTrain.trainNo); - - if (trainData) acc.push({ ...trainData, ...updatedTrain }); - else acc.push({ ...updatedTrain }); - - return acc; - }, [] as Train[]); - - this.trainCount = this.trainList.filter(train => train.online).length; - this.dataConnectionStatus = Status.Loaded; - } - - @Mutation - private updateTimetableData(timetableList: TimetableData[]) { - this.stationList = this.stationList.map(station => { - const stationName = station.stationName.toLowerCase(); - const scheduledTrains: Station['scheduledTrains'] = timetableList.reduce((acc: Station['scheduledTrains'], timetableData: TimetableData, index) => { - if (!timetableData.followingSceneries.includes(station.stationHash)) return acc; - - const stopInfoIndex = timetableData.followingStops.findIndex(stop => { - const stopName = stop.stopNameRAW.toLowerCase(); - - if (stationName === stopName) return true; - if (stopName.includes(stationName) && !stop.stopName.includes('po.') && !stop.stopName.includes('podg.')) return true; - if (stationName.includes(stopName) && !stop.stopName.includes('po.') && !stop.stopName.includes('podg.')) return true; - if (stopName.includes('podg.') && stopName.split(', podg.')[0] && stationName === stopName.split(', podg.')[0]) return true; - - if (station.stops && station.stops.includes(stop.stopNameRAW)) return true; - - return false; - }); - - if (stopInfoIndex == -1) return acc; - - const stopInfo = timetableData.followingStops[stopInfoIndex]; - - let stopStatus = ''; - let stopLabel = ''; - let stopStatusID = 0; - let nearestStop = ''; - - if (stopInfo.terminatesHere && stopInfo.confirmed) { - stopStatus = 'terminated'; - stopLabel = 'Skończył bieg'; - stopStatusID = 5; - } else if (!stopInfo.terminatesHere && stopInfo.confirmed && timetableData.currentStationName == station.stationName) { - stopStatus = 'departed'; - stopLabel = 'Odprawiony'; - stopStatusID = 2; - } else if (!stopInfo.terminatesHere && stopInfo.confirmed && timetableData.currentStationName != station.stationName) { - stopStatus = 'departed-away'; - stopLabel = 'Odjechał'; - stopStatusID = 4; - } else if (timetableData.currentStationName == station.stationName && !stopInfo.stopped) { - stopStatus = 'online'; - stopLabel = 'Na stacji'; - stopStatusID = 0; - } else if (timetableData.currentStationName == station.stationName && stopInfo.stopped) { - stopStatus = 'stopped'; - stopLabel = 'Postój'; - stopStatusID = 1; - } else if (timetableData.currentStationName != station.stationName) { - stopStatus = 'arriving'; - stopLabel = 'W drodze'; - stopStatusID = 3; - } - - if (stopInfoIndex < timetableData.followingStops.length - 2) { - for (let i = stopInfoIndex + 1; i < timetableData.followingStops.length - 1; i++) { - const stop = timetableData.followingStops[i]; - - if (stop.mainStop && stop.stopType.includes('ph')) { - nearestStop = stop.stopNameRAW; - break; - } - } - } - - acc.push({ - trainNo: timetableData.trainNo, - driverName: timetableData.driverName, - driverId: timetableData.driverId, - currentStationName: timetableData.currentStationName, - currentStationHash: timetableData.currentStationHash, - category: timetableData.category, - beginsAt: timetableData.followingStops[0].stopNameRAW, - terminatesAt: timetableData.followingStops[timetableData.followingStops.length - 1].stopNameRAW, - nearestStop, - stopInfo, - stopLabel, - stopStatus, - stopStatusID, - }); - - return acc; - }, []); - - if (station.checkpoints) { - station.checkpoints.forEach(cp => (cp.scheduledTrains.length = 0)); - - for (let checkpoint of station.checkpoints) { - timetableList.reduce((acc, data) => { - data.followingStops - .filter(stop => stop.stopNameRAW === checkpoint.checkpointName) - .forEach(stopInfo => { - // const stopInfo = data.followingStops[stopInfoIndex]; - - let stopStatus = ''; - let stopLabel = ''; - let nearestStop = ''; - let stopStatusID = 0; - - if (stopInfo.terminatesHere && stopInfo.confirmed) { - stopStatus = 'terminated'; - stopLabel = 'Skończył bieg'; - stopStatusID = 5; - } else if (!stopInfo.terminatesHere && stopInfo.confirmed && data.currentStationName == station.stationName) { - stopStatus = 'departed'; - stopLabel = 'Odprawiony'; - stopStatusID = 2; - } else if (!stopInfo.terminatesHere && stopInfo.confirmed && data.currentStationName != station.stationName) { - stopStatus = 'departed-away'; - stopLabel = 'Odjechał'; - stopStatusID = 4; - } else if (data.currentStationName == station.stationName && !stopInfo.stopped) { - stopStatus = 'online'; - stopLabel = 'Na stacji'; - stopStatusID = 0; - } else if (data.currentStationName == station.stationName && stopInfo.stopped) { - stopStatus = 'stopped'; - stopLabel = 'Postój'; - stopStatusID = 1; - } else if (data.currentStationName != station.stationName) { - stopStatus = 'arriving'; - stopLabel = 'W drodze'; - stopStatusID = 3; - } - - // for (let i = stopInfoIndex; i < data.followingStops.length - 1; i++){ - // const stop = data.followingStops[i]; - - // if (stop.mainStop && stop.stopType.includes("ph")) { - // nearestStop = stop.stopNameRAW; - // break; - // } - // } - - checkpoint.scheduledTrains.push({ - trainNo: data.trainNo, - driverName: data.driverName, - driverId: data.driverId, - currentStationName: data.currentStationName, - currentStationHash: data.currentStationHash, - category: data.category, - beginsAt: data.followingStops[0].stopNameRAW, - terminatesAt: data.followingStops[data.followingStops.length - 1].stopNameRAW, - stopInfo, - stopLabel, - stopStatus, - nearestStop, - stopStatusID, - }); - }); - - return acc; - }, []); - } - } - - return { ...station, scheduledTrains }; - }); - - this.trainList = this.trainList.reduce((acc, train) => { - const timetableData = timetableList.find(data => data && data.trainNo === train.trainNo); - - if (timetableData) { - const trainData = this.stationList.find(station => station.stationName === train.currentStationName)?.scheduledTrains.find(stationTrain => stationTrain.trainNo === train.trainNo); - - acc.push({ ...train, timetableData, stopStatus: trainData?.stopStatus || '', stopLabel: trainData?.stopLabel || '' }); - } - - return acc; - }, [] as Train[]); - - this.timetableLoaded = Status.Loaded; - } -} +import { Module, VuexModule, Mutation, Action } from 'vuex-module-decorators'; +import axios from 'axios'; + +import JSONStationData from '@/data/stationData.json'; + +import Station from '@/scripts/interfaces/Station'; +import Train from '@/scripts/interfaces/Train'; +import TrainStop from '@/scripts/interfaces/TrainStop'; + +enum Status { + Initialized = -1, + Loading = 0, + Error = 1, + Loaded = 2, +} + +interface TimetableData { + trainNo: number; + driverName: string; + driverId: number; + currentStationName: string; + currentStationHash: string; + timetableId: number; + category: string; + route: string; + TWR: boolean; + SKR: boolean; + routeDistance: number; + followingStops: TrainStop[]; + followingSceneries: string[]; +} + +// const devEnv = true; + +const URLs = { + stations: 'https://api.td2.info.pl:9640/?method=getStationsOnline', + trains: 'https://api.td2.info.pl:9640/?method=getTrainsOnline', + dispatchers: 'https://api.td2.info.pl:9640/?method=readFromSWDR&value=getDispatcherStatusList%3B1', +}; + +const timetableURL = (trainNo: number) => `https://api.td2.info.pl:9640/?method=readFromSWDR&value=getTimetable%3B${trainNo}%3Beu`; +const getLocoURL = (locoType: string) => `https://rj.td2.info.pl/dist/img/thumbnails/${locoType.includes('EN') ? locoType + 'rb' : locoType}.png`; + +const getStatusLabel = (stationStatus: any) => { + if (!stationStatus) return 'NIEZALOGOWANY'; + + const statusCode = stationStatus[2]; + const statusTimestamp = stationStatus[3]; + + switch (statusCode) { + case 0: + if (statusTimestamp - Date.now() > 21000000) return 'BEZ LIMITU'; + + return `DO ${new Date(statusTimestamp).toLocaleTimeString('en-US', { + hour12: false, + hour: '2-digit', + minute: '2-digit', + })}`; + + case 1: + return 'Z/W'; + + case 2: + if (statusTimestamp == 0) return 'KOŃCZY'; + break; + + case 3: + return 'BRAK MIEJSCA'; + + default: + break; + } + + return 'NIEDOSTĘPNY'; +}; + +const getStatusTimestamp = (stationStatus: any) => { + if (!stationStatus) return -2; + + const statusCode = stationStatus[2]; + const statusTimestamp = stationStatus[3]; + + switch (statusCode) { + case 0: + case 1: + case 3: + return statusTimestamp; + + case 2: + if (statusTimestamp == 0) return 0; + break; + + default: + break; + } + + return -1; +}; + +const parseSpawns = (spawnString: string) => { + if (!spawnString) return []; + if (spawnString === 'NO_SPAWN') return []; + + return spawnString.split(';').map(spawn => { + const spawnArray = spawn.split(','); + const spawnName = spawnArray[6] ? spawnArray[6] : spawnArray[0]; + const spawnLength = parseInt(spawnArray[2]); + + return { spawnName, spawnLength }; + }); +}; + +const getTimestamp = (date: string) => (date ? new Date(date).getTime() : 0); +const timestampToTime = (timestamp: number) => + new Date(timestamp).toLocaleTimeString('pl-PL', { + hour: '2-digit', + minute: '2-digit', + }); + +@Module +export default class Store extends VuexModule { + private trainCount: number = 0; + private stationCount: number = 0; + + private dataConnectionStatus: Status = Status.Loading; + private timetableLoaded: Status = Status.Loading; + + private stationList: Station[] = []; + private trainList: Train[] = []; + + //GETTERS + get getAllData() { + return { + stationList: this.stationList, + trainList: this.trainList, + trainCount: this.trainCount, + stationCount: this.stationCount, + dataConnectionStatus: this.dataConnectionStatus, + timetableDataStatus: this.timetableLoaded, + }; + } + + get getStationList() { + return this.stationList; + } + + get getTrainList() { + return this.trainList; + } + + get getTimetableDataStatus() { + return this.timetableLoaded; + } + + get getDataStatus() { + return this.dataConnectionStatus; + } + + //ACTIONS + @Action + async synchronizeData() { + this.context.commit('setJSONData'); + + this.context.dispatch('fetchOnlineData'); + setInterval(() => this.context.dispatch('fetchOnlineData'), 20000); + } + + @Action({ commit: 'updateTimetableData' }) + async fetchTimetableData() { + return this.trainList.reduce(async (acc: Promise, train) => { + const timetable = await (await axios.get(timetableURL(train.trainNo))).data.message; + const trainInfo = timetable.trainInfo; + + if (!timetable || !trainInfo) return acc; + + const followingStops: TrainStop[] = timetable.stopPoints.reduce((stopsAcc: TrainStop[], point) => { + const arrivalTimestamp = getTimestamp(point.arrivalTime); + const arrivalRealTimestamp = getTimestamp(point.arrivalRealTime); + + const departureTimestamp = getTimestamp(point.departureTime); + const departureRealTimestamp = getTimestamp(point.departureRealTime); + + stopsAcc.push({ + stopName: point.pointName, + stopNameRAW: point.pointNameRAW, + stopType: point.pointStopType, + mainStop: point.pointName.includes('strong'), + + arrivalLine: point.arrivalLine, + arrivalTimeString: timestampToTime(point.arrivalTime), + arrivalTimestamp: arrivalTimestamp, + arrivalRealTimeString: timestampToTime(point.arrivalRealTime), + arrivalRealTimestamp: arrivalRealTimestamp, + arrivalDelay: point.arrivalDelay, + + departureLine: point.departureLine, + departureTimeString: timestampToTime(point.departureTime), + departureTimestamp: departureTimestamp, + departureRealTimeString: timestampToTime(point.departureRealTime), + departureRealTimestamp: departureRealTimestamp, + departureDelay: point.departureDelay, + + beginsHere: arrivalTimestamp == 0, + terminatesHere: departureTimestamp == 0, + + confirmed: point.confirmed, + stopped: point.isStopped, + stopTime: point.pointStopTime, + }); + + return stopsAcc; + }, []); + + (await acc).push({ + trainNo: train.trainNo, + driverName: train.driverName, + driverId: train.driverId, + currentStationName: train.currentStationName, + currentStationHash: train.currentStationHash, + timetableId: trainInfo.timetableId, + category: trainInfo.trainCategoryCode, + route: trainInfo.route, + TWR: trainInfo.twr, + SKR: trainInfo.skr, + routeDistance: timetable.stopPoints[timetable.stopPoints.length - 1].pointDistance, + followingStops, + followingSceneries: trainInfo.sceneries, + }); + + return acc; + }, Promise.resolve([])); + } + + @Action + async fetchOnlineData() { + Promise.all([axios.get(URLs.stations), axios.get(URLs.trains), axios.get(URLs.dispatchers)]) + .then(async response => { + const onlineStationsData = response[0].data.message; + const onlineTrainsData = await response[1].data.message; + const onlineDispatchersData = await response[2].data.message; + + let updatedStationList = onlineStationsData.reduce((acc, station) => { + if (station.region !== 'eu' || !station.isOnline) return acc; + + const stationStatus = onlineDispatchersData.find(status => status[0] == station.stationHash && status[1] == 'eu'); + + const statusLabel = getStatusLabel(stationStatus); + const statusTimestamp = getStatusTimestamp(stationStatus); + + const stationTrains = onlineTrainsData.filter(train => train.region === 'eu' && train.isOnline && train.station.stationName === station.stationName); + + acc.push({ + stationName: station.stationName, + stationHash: station.stationHash, + maxUsers: station.maxUsers, + currentUsers: station.currentUsers, + spawns: parseSpawns(station.spawnString), + dispatcherName: station.dispatcherName, + dispatcherRate: station.dispatcherRate, + dispatcherId: station.dispatcherId, + dispatcherExp: station.dispatcherExp, + dispatcherIsSupporter: station.dispatcherIsSupporter, + occupiedTo: statusLabel, + stationTrains, + statusTimestamp, + }); + + return acc; + }, []); + + let updatedTrainList = await Promise.all( + onlineTrainsData + .filter(train => train.region === 'eu') + .map(async train => { + const locoType = train.dataCon.split(';') ? train.dataCon.split(';')[0] : train.dataCon; + + return { + trainNo: train.trainNo, + mass: train.dataMass, + length: train.dataLength, + speed: train.dataSpeed, + distance: train.dataDistance, + signal: train.dataSignal, + online: train.isOnline, + driverId: train.driverId, + driverName: train.driverName, + currentStationName: train.station.stationName, + currentStationHash: train.station.stationHash, + connectedTrack: train.dataSceneryConnection, + locoType, + locoURL: getLocoURL(locoType), + }; + }) + ); + + this.context.commit('updateOnlineStations', updatedStationList); + this.context.commit('updateOnlineTrains', updatedTrainList); + + this.context.dispatch('fetchTimetableData'); + }) + .catch(err => { + this.context.commit('setDataConnectionStatus', Status.Error); + }); + } + + //MUTATIONS + @Mutation + private setDataConnectionStatus(status: Status) { + this.dataConnectionStatus = status; + } + + @Mutation setJSONData() { + /* + 0: stationName, + 1: stationURL, + 2: stationlines, + 3: stationProject?, + 4: reqLevel, + 5: supportersOnly, + 6: signalType, + 7: controlType, + 8: SBL, + 9: two-way block, + 10: routes, one-way, catenary, + 11: routes, one-way, no catenary, + 12: routes, two-way, catenary, + 13: routes, two-way, no catenary, + 14: subStations?, + 15: stops?, + 16: default, + 17: nonPublic, + 18: unavailable + */ + + this.stationList = JSONStationData.map(station => ({ + stationName: station[0] as string, + stationURL: station[1] as string, + stationLines: station[2] as string, + stationProject: station[3] as string, + reqLevel: station[4] as string, + supportersOnly: station[5] as string, + signalType: station[6] as string, + controlType: station[7] as string, + SBL: station[8] as string, + TWB: station[9] as string, + routes: { + oneWay: { + catenary: station[10] as number, + noCatenary: station[11] as number, + }, + twoWay: { + catenary: station[12] as number, + noCatenary: station[13] as number, + }, + }, + checkpoints: station[14] ? (station[14] as string[]).map(sub => ({ checkpointName: sub, scheduledTrains: [] })) : null, + stops: station[15] as string[], + + default: station[16] as boolean, + nonPublic: station[17] as boolean, + unavailable: station[18] as boolean, + + stationHash: '', + maxUsers: 0, + currentUsers: 0, + dispatcherName: '', + dispatcherRate: 0, + dispatcherExp: -1, + dispatcherId: 0, + dispatcherIsSupporter: false, + online: false, + occupiedTo: 'WOLNA', + statusTimestamp: -3, + stationTrains: [], + scheduledTrains: [], + spawns: [], + })); + } + + @Mutation + private updateOnlineStations(updatedStationList: any[]) { + this.stationList = this.stationList.reduce((acc, station) => { + const onlineStationData = updatedStationList.find(updatedStation => updatedStation.stationName === station.stationName); + const registeredStation = JSONStationData.find(data => data[0] === station.stationName); + + if (onlineStationData) + acc.push({ + ...station, + ...onlineStationData, + online: true, + }); + else if (registeredStation) + acc.push({ + ...station, + stationProject: '', + stationHash: '', + maxUsers: 0, + currentUsers: 0, + dispatcherName: '', + dispatcherRate: 0, + dispatcherExp: -1, + dispatcherId: 0, + dispatcherIsSupporter: false, + online: false, + occupiedTo: 'WOLNA', + statusTimestamp: -3, + stationTrains: [], + scheduledTrains: [], + checkpoints: null, + }); + + return acc; + }, [] as Station[]); + + // Dodawanie do listy online potencjalnych scenerii niewpisanych do bazy + updatedStationList.forEach(updatedStation => { + const alreadyInList: any = this.stationList.some(station => station.stationName === updatedStation.stationName); + + if (!alreadyInList) { + this.stationList.push({ + ...updatedStation, + scheduledTrains: [], + stationTrains: [], + subStations: [], + online: true, + reqLevel: '-1', + nonPublic: true, + }); + } + }); + + this.stationCount = this.stationList.filter(station => station.online).length; + this.dataConnectionStatus = Status.Loaded; + } + + @Mutation + private updateOnlineTrains(updatedTrainList) { + this.trainList = updatedTrainList.reduce((acc, updatedTrain) => { + const trainData = this.trainList.find(train => train.trainNo === updatedTrain.trainNo); + + if (trainData) acc.push({ ...trainData, ...updatedTrain }); + else acc.push({ ...updatedTrain }); + + return acc; + }, [] as Train[]); + + this.trainCount = this.trainList.filter(train => train.online).length; + this.dataConnectionStatus = Status.Loaded; + } + + @Mutation + private updateTimetableData(timetableList: TimetableData[]) { + this.stationList = this.stationList.map(station => { + const stationName = station.stationName.toLowerCase(); + const scheduledTrains: Station['scheduledTrains'] = timetableList.reduce((acc: Station['scheduledTrains'], timetableData: TimetableData, index) => { + if (!timetableData.followingSceneries.includes(station.stationHash)) return acc; + + const stopInfoIndex = timetableData.followingStops.findIndex(stop => { + const stopName = stop.stopNameRAW.toLowerCase(); + + if (stationName === stopName) return true; + if (stopName.includes(stationName) && !stop.stopName.includes('po.') && !stop.stopName.includes('podg.')) return true; + if (stationName.includes(stopName) && !stop.stopName.includes('po.') && !stop.stopName.includes('podg.')) return true; + if (stopName.includes('podg.') && stopName.split(', podg.')[0] && stationName === stopName.split(', podg.')[0]) return true; + + if (station.stops && station.stops.includes(stop.stopNameRAW)) return true; + + return false; + }); + + if (stopInfoIndex == -1) return acc; + + const stopInfo = timetableData.followingStops[stopInfoIndex]; + + let stopStatus = ''; + let stopLabel = ''; + let stopStatusID = 0; + let nearestStop = ''; + + if (stopInfo.terminatesHere && stopInfo.confirmed) { + stopStatus = 'terminated'; + stopLabel = 'Skończył bieg'; + stopStatusID = 5; + } else if (!stopInfo.terminatesHere && stopInfo.confirmed && timetableData.currentStationName == station.stationName) { + stopStatus = 'departed'; + stopLabel = 'Odprawiony'; + stopStatusID = 2; + } else if (!stopInfo.terminatesHere && stopInfo.confirmed && timetableData.currentStationName != station.stationName) { + stopStatus = 'departed-away'; + stopLabel = 'Odjechał'; + stopStatusID = 4; + } else if (timetableData.currentStationName == station.stationName && !stopInfo.stopped) { + stopStatus = 'online'; + stopLabel = 'Na stacji'; + stopStatusID = 0; + } else if (timetableData.currentStationName == station.stationName && stopInfo.stopped) { + stopStatus = 'stopped'; + stopLabel = 'Postój'; + stopStatusID = 1; + } else if (timetableData.currentStationName != station.stationName) { + stopStatus = 'arriving'; + stopLabel = 'W drodze'; + stopStatusID = 3; + } + + if (stopInfoIndex < timetableData.followingStops.length - 2) { + for (let i = stopInfoIndex + 1; i < timetableData.followingStops.length - 1; i++) { + const stop = timetableData.followingStops[i]; + + if (stop.mainStop && stop.stopType.includes('ph')) { + nearestStop = stop.stopNameRAW; + break; + } + } + } + + acc.push({ + trainNo: timetableData.trainNo, + driverName: timetableData.driverName, + driverId: timetableData.driverId, + currentStationName: timetableData.currentStationName, + currentStationHash: timetableData.currentStationHash, + category: timetableData.category, + beginsAt: timetableData.followingStops[0].stopNameRAW, + terminatesAt: timetableData.followingStops[timetableData.followingStops.length - 1].stopNameRAW, + nearestStop, + stopInfo, + stopLabel, + stopStatus, + stopStatusID, + }); + + return acc; + }, []); + + if (station.checkpoints) { + station.checkpoints.forEach(cp => (cp.scheduledTrains.length = 0)); + + for (let checkpoint of station.checkpoints) { + timetableList.reduce((acc, data) => { + data.followingStops + .filter(stop => stop.stopNameRAW === checkpoint.checkpointName) + .forEach(stopInfo => { + // const stopInfo = data.followingStops[stopInfoIndex]; + + let stopStatus = ''; + let stopLabel = ''; + let nearestStop = ''; + let stopStatusID = 0; + + if (stopInfo.terminatesHere && stopInfo.confirmed) { + stopStatus = 'terminated'; + stopLabel = 'Skończył bieg'; + stopStatusID = 5; + } else if (!stopInfo.terminatesHere && stopInfo.confirmed && data.currentStationName == station.stationName) { + stopStatus = 'departed'; + stopLabel = 'Odprawiony'; + stopStatusID = 2; + } else if (!stopInfo.terminatesHere && stopInfo.confirmed && data.currentStationName != station.stationName) { + stopStatus = 'departed-away'; + stopLabel = 'Odjechał'; + stopStatusID = 4; + } else if (data.currentStationName == station.stationName && !stopInfo.stopped) { + stopStatus = 'online'; + stopLabel = 'Na stacji'; + stopStatusID = 0; + } else if (data.currentStationName == station.stationName && stopInfo.stopped) { + stopStatus = 'stopped'; + stopLabel = 'Postój'; + stopStatusID = 1; + } else if (data.currentStationName != station.stationName) { + stopStatus = 'arriving'; + stopLabel = 'W drodze'; + stopStatusID = 3; + } + + // for (let i = stopInfoIndex; i < data.followingStops.length - 1; i++){ + // const stop = data.followingStops[i]; + + // if (stop.mainStop && stop.stopType.includes("ph")) { + // nearestStop = stop.stopNameRAW; + // break; + // } + // } + + checkpoint.scheduledTrains.push({ + trainNo: data.trainNo, + driverName: data.driverName, + driverId: data.driverId, + currentStationName: data.currentStationName, + currentStationHash: data.currentStationHash, + category: data.category, + beginsAt: data.followingStops[0].stopNameRAW, + terminatesAt: data.followingStops[data.followingStops.length - 1].stopNameRAW, + stopInfo, + stopLabel, + stopStatus, + nearestStop, + stopStatusID, + }); + }); + + return acc; + }, []); + } + } + + return { ...station, scheduledTrains }; + }); + + this.trainList = this.trainList.reduce((acc, train) => { + const timetableData = timetableList.find(data => data && data.trainNo === train.trainNo); + + if (timetableData) { + const trainData = this.stationList.find(station => station.stationName === train.currentStationName)?.scheduledTrains.find(stationTrain => stationTrain.trainNo === train.trainNo); + + acc.push({ ...train, timetableData, stopStatus: trainData?.stopStatus || '', stopLabel: trainData?.stopLabel || '' }); + } + + return acc; + }, [] as Train[]); + + this.timetableLoaded = Status.Loaded; + } +} diff --git a/src/styles/global.scss b/src/styles/global.scss index c68a957..14f6328 100644 --- a/src/styles/global.scss +++ b/src/styles/global.scss @@ -1,233 +1,233 @@ -:root { - font-size: 16px; -} - -::-webkit-scrollbar { - width: 0.5rem; - height: 0.5rem; - - &-track { - background: #222; - } - - &-thumb { - border-radius: 1rem; - background: #777; - } -} - - -.tooltip { - position: relative; - - & > &-text { - display: inline-block; - width: 150px; - - padding: .5rem .35rem; - background-color: #830000; - border-radius: .5rem; - - display: inline-block; - max-width: 150px; - - font-size: 1em; - text-align: center; - color: #fff; - - position: absolute; - z-index: 1; - visibility: hidden; - opacity: 0; - - left: 50%; - transform: translate(-50%, calc(-100% - 1rem)); - - transition: opacity 0.3s; - - &::after { - content: ""; - position: absolute; - top: 100%; - left: 50%; - margin-left: -5px; - border-width: 5px; - border-style: solid; - border-color: #830000 transparent transparent transparent; - } - } - - &:hover > &-text { - @include smallScreen() { - display: none; - } - - visibility: visible; - opacity: 1; - } -} - -html { - scroll-behavior: smooth; -} - -body { - width: 100%; - margin: 0; - // font-family: "Open Sans", sans-serif; - font-family: "Quicksand", sans-serif; - - overflow-x: hidden; -} - -button, -input, -select { - // font-family: "Open Sans", sans-serif; - font-family: "Quicksand", sans-serif; -} - -input { - border: 1px solid white; - background: none; - color: white; - font-size: 1em; - - padding: 0.15em; - margin: 0.2em; - - max-width: 55px; - outline: none; - - &::placeholder { - color: #bebebe; - } -} - -*, -*::before, -*::after { - box-sizing: border-box; - padding: 0; - margin: 0; - - -webkit-tap-highlight-color: transparent; -} - -.default-station { - font-weight: bold; - color: $accentCol; -} - -.card { - display: flex; - flex-direction: column; - - position: fixed; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - z-index: 4; - - overflow: auto; - background: #262a2e; - - box-shadow: 0 0 15px 5px #474747; - - width: 75%; - max-width: 750px; - max-height: 95%; - - // font-size: calc(0.6rem + 0.5vw); - font-size: calc(0.45rem + 0.35vw); - - @include smallScreen { - width: 95%; - } - - @include bigScreen { - font-size: 1.4rem; - } - - &-exit { - position: absolute; - top: 0; - right: 0; - margin: 0.3em 0em; - - img { - width: 1.6em; - } - - cursor: pointer; - } -} - -.title { - color: $accentCol; - font-weight: 600; - - padding: .35em 0; - -} - -.button { - display: flex; - align-items: center; - - background: #333; - border: none; - - color: #e0e0e0; - font-size: 0.9em; - - outline: none; - padding: 0.35em; - cursor: pointer; - - transition: all 0.3s; - - &.open { - color: $accentCol; - border: none; - } - - &:hover { - background: rgba(#e0e0e0, 0.4); - } -} - -a { - color: white; - text-decoration: none; - - transition: color 0.3s; - - &:hover, - &:focus { - color: $accentCol; - border: none; - outline: none; - } -} - -ul { - padding: 0; - list-style: none; -} - -.flex { - display: flex; - align-items: center; - justify-content: center; - - width: 100%; - - &-spaced { - justify-content: space-between; - } - - &-column { - flex-direction: column; - } +:root { + font-size: 16px; +} + +::-webkit-scrollbar { + width: 0.5rem; + height: 0.5rem; + + &-track { + background: #222; + } + + &-thumb { + border-radius: 1rem; + background: #777; + } +} + + +.tooltip { + position: relative; + + & > &-text { + display: inline-block; + width: 150px; + + padding: .5rem .35rem; + background-color: #830000; + border-radius: .5rem; + + display: inline-block; + max-width: 150px; + + font-size: 1em; + text-align: center; + color: #fff; + + position: absolute; + z-index: 1; + visibility: hidden; + opacity: 0; + + left: 50%; + transform: translate(-50%, calc(-100% - 1rem)); + + transition: opacity 0.3s; + + &::after { + content: ""; + position: absolute; + top: 100%; + left: 50%; + margin-left: -5px; + border-width: 5px; + border-style: solid; + border-color: #830000 transparent transparent transparent; + } + } + + &:hover > &-text { + @include smallScreen() { + display: none; + } + + visibility: visible; + opacity: 1; + } +} + +html { + scroll-behavior: smooth; +} + +body { + width: 100%; + margin: 0; + // font-family: "Open Sans", sans-serif; + font-family: "Quicksand", sans-serif; + + overflow-x: hidden; +} + +button, +input, +select { + // font-family: "Open Sans", sans-serif; + font-family: "Quicksand", sans-serif; +} + +input { + border: 1px solid white; + background: none; + color: white; + font-size: 1em; + + padding: 0.15em; + margin: 0.2em; + + max-width: 55px; + outline: none; + + &::placeholder { + color: #bebebe; + } +} + +*, +*::before, +*::after { + box-sizing: border-box; + padding: 0; + margin: 0; + + -webkit-tap-highlight-color: transparent; +} + +.default-station { + font-weight: bold; + color: $accentCol; +} + +.card { + display: flex; + flex-direction: column; + + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + z-index: 4; + + overflow: auto; + background: #262a2e; + + box-shadow: 0 0 15px 5px #474747; + + width: 75%; + max-width: 750px; + max-height: 95%; + + // font-size: calc(0.6rem + 0.5vw); + font-size: calc(0.45rem + 0.35vw); + + @include smallScreen { + width: 95%; + } + + @include bigScreen { + font-size: 1.4rem; + } + + &-exit { + position: absolute; + top: 0; + right: 0; + margin: 0.3em 0em; + + img { + width: 1.6em; + } + + cursor: pointer; + } +} + +.title { + color: $accentCol; + font-weight: 600; + + padding: .35em 0; + +} + +.button { + display: flex; + align-items: center; + + background: #333; + border: none; + + color: #e0e0e0; + font-size: 0.9em; + + outline: none; + padding: 0.35em; + cursor: pointer; + + transition: all 0.3s; + + &.open { + color: $accentCol; + border: none; + } + + &:hover { + background: rgba(#e0e0e0, 0.4); + } +} + +a { + color: white; + text-decoration: none; + + transition: color 0.3s; + + &:hover, + &:focus { + color: $accentCol; + border: none; + outline: none; + } +} + +ul { + padding: 0; + list-style: none; +} + +.flex { + display: flex; + align-items: center; + justify-content: center; + + width: 100%; + + &-spaced { + justify-content: space-between; + } + + &-column { + flex-direction: column; + } } \ No newline at end of file diff --git a/src/styles/scenery_status.scss b/src/styles/scenery_status.scss index a990bf3..6ec29eb 100644 --- a/src/styles/scenery_status.scss +++ b/src/styles/scenery_status.scss @@ -1,51 +1,51 @@ -$free: #8a8a8a; -$ending: #e6c300; -$no-limit: #0077ae; -$unav: #ff3d5d; -$brb: #e6a100; -$no-space: #222; -$taken: #09a116; - -.status { - border-radius: 1rem; - font-weight: 500; - - font-size: 0.9em; - padding: 0.2em 0.45em; - - background-color: $taken; - - &.free { - background-color: $free; - font-size: 0.95em; - } - - &.ending { - background-color: $ending; - color: black; - font-size: 0.9em; - } - - &.no-limit { - background-color: $no-limit; - font-size: 0.85em; - } - - &.not-signed, - &.unavailable { - background-color: $unav; - font-size: 0.8em; - } - - &.brb { - background-color: $brb; - color: black; - font-size: 0.95em; - } - - &.no-space { - background-color: $no-space; - color: white; - font-size: 0.85em; - } +$free: #8a8a8a; +$ending: #e6c300; +$no-limit: #0077ae; +$unav: #ff3d5d; +$brb: #e6a100; +$no-space: #222; +$taken: #09a116; + +.status { + border-radius: 1rem; + font-weight: 500; + + font-size: 0.9em; + padding: 0.2em 0.45em; + + background-color: $taken; + + &.free { + background-color: $free; + font-size: 0.95em; + } + + &.ending { + background-color: $ending; + color: black; + font-size: 0.9em; + } + + &.no-limit { + background-color: $no-limit; + font-size: 0.85em; + } + + &.not-signed, + &.unavailable { + background-color: $unav; + font-size: 0.8em; + } + + &.brb { + background-color: $brb; + color: black; + font-size: 0.95em; + } + + &.no-space { + background-color: $no-space; + color: white; + font-size: 0.85em; + } } \ No newline at end of file diff --git a/src/styles/user_badge.scss b/src/styles/user_badge.scss index e0395a4..4bfa106 100644 --- a/src/styles/user_badge.scss +++ b/src/styles/user_badge.scss @@ -1,54 +1,54 @@ -$no-timetable: #aaa; -$departed: springgreen; -$stopped: #ffa600; -$online: gold; -$terminated: red; -$disconnected: slategray; - - -.user-badge { - border: 2px solid white; - z-index: 4; - - margin-top: 0.5rem; - margin-right: 0.5rem; - - border-radius: 0.7em; - padding: 0.3em 0.5em; - font-size: 0.95em; - - &.borderless { - border: none; - margin: 0; - padding: 0; - } - - &.no-timetable { - border: 2px solid $no-timetable; - - a { - color: $no-timetable; - pointer-events: none; - } - } - - &.departed { - border: 2px solid $departed; - } - - &.stopped { - border: 2px solid $stopped; - } - - &.online { - border: 2px solid $online; - } - - &.terminated { - border: 2px solid $terminated; - } - - &.disconnected { - border: 1px solid $disconnected; - } +$no-timetable: #aaa; +$departed: springgreen; +$stopped: #ffa600; +$online: gold; +$terminated: red; +$disconnected: slategray; + + +.user-badge { + border: 2px solid white; + z-index: 4; + + margin-top: 0.5rem; + margin-right: 0.5rem; + + border-radius: 0.7em; + padding: 0.3em 0.5em; + font-size: 0.95em; + + &.borderless { + border: none; + margin: 0; + padding: 0; + } + + &.no-timetable { + border: 2px solid $no-timetable; + + a { + color: $no-timetable; + pointer-events: none; + } + } + + &.departed { + border: 2px solid $departed; + } + + &.stopped { + border: 2px solid $stopped; + } + + &.online { + border: 2px solid $online; + } + + &.terminated { + border: 2px solid $terminated; + } + + &.disconnected { + border: 1px solid $disconnected; + } } \ No newline at end of file diff --git a/src/views/SceneryView.vue b/src/views/SceneryView.vue index e535693..b6f4287 100644 --- a/src/views/SceneryView.vue +++ b/src/views/SceneryView.vue @@ -1,148 +1,148 @@ - - - - - \ No newline at end of file diff --git a/src/views/StationsView.vue b/src/views/StationsView.vue index 34aab7f..8ed1560 100644 --- a/src/views/StationsView.vue +++ b/src/views/StationsView.vue @@ -1,373 +1,373 @@ - - - - - + + + + + diff --git a/src/views/TimetableView.vue b/src/views/TimetableView.vue index 61f9487..4469712 100644 --- a/src/views/TimetableView.vue +++ b/src/views/TimetableView.vue @@ -1,770 +1,770 @@ - - - - - \ No newline at end of file diff --git a/src/views/TrainsView.vue b/src/views/TrainsView.vue index 9a4379f..189bfc6 100644 --- a/src/views/TrainsView.vue +++ b/src/views/TrainsView.vue @@ -1,166 +1,166 @@ - - - - - + + + + + diff --git a/vue.config.js b/vue.config.js index cd2b477..0702cd8 100644 --- a/vue.config.js +++ b/vue.config.js @@ -1,3 +1,3 @@ -// module.exports = { -// publicPath: process.env.NODE_ENV === "production" ? "/dist" : "/", -// }; +// module.exports = { +// publicPath: process.env.NODE_ENV === "production" ? "/dist" : "/", +// };