From 918ceb8e77e6c1f74c929e4bc7a94297265e988b Mon Sep 17 00:00:00 2001 From: Laura Hausmann Date: Wed, 26 Feb 2020 18:32:35 +0100 Subject: [PATCH] Initial commit --- .gitignore | 249 +++++ ZTravel.API/DBF/DbfAjaxObject.cs | 25 + ZTravel.API/DBF/DbfAjaxParser.cs | 84 ++ ZTravel.API/DBF/DbfApi.cs | 15 + ZTravel.API/DBF/DbfResponse.cs | 83 ++ ZTravel.API/DBF/DbfTypeMapping.cs | 37 + ZTravel.API/HAFAS/HafasApi.cs | 9 + .../HAFAS/Details/MarudorHafasDetailsApi.cs | 15 + .../Details/MarudorHafasDetailsResponse.cs | 152 +++ .../Marudor/Wagenreihung/WagenreihungApi.cs | 5 + .../Wagenreihung/WagenreihungResponse.cs | 156 +++ ZTravel.API/VRRF/VrrfApi.cs | 14 + ZTravel.API/VRRF/VrrfResponse.cs | 86 ++ ZTravel.API/ZTravel.API.csproj | 16 + ZTravel.CLI/Program.cs | 45 + ZTravel.CLI/TestMain.cs | 13 + ZTravel.CLI/ZTravel.CLI.csproj | 12 + ZTravel.Web/Pages/Cebotari.cshtml | 53 + ZTravel.Web/Pages/CebotariLCD.cshtml | 64 ++ ZTravel.Web/Pages/Error.cshtml | 26 + ZTravel.Web/Pages/Error.cshtml.cs | 27 + ZTravel.Web/Pages/Index.cshtml | 40 + ZTravel.Web/Pages/IndexTest.cshtml | 40 + ZTravel.Web/Pages/KaHbf.cshtml | 13 + ZTravel.Web/Pages/Mobile.cshtml | 33 + ZTravel.Web/Pages/MucHbf.cshtml | 13 + ZTravel.Web/Pages/ParschBhf.cshtml | 13 + ZTravel.Web/Pages/SbgHbf.cshtml | 13 + ZTravel.Web/Pages/SbgMuc.cshtml | 13 + ZTravel.Web/Pages/Shared/_Layout.cshtml | 1 + ZTravel.Web/Pages/Shared/_LayoutFern.cshtml | 159 +++ .../Shared/_ValidationScriptsPartial.cshtml | 2 + ZTravel.Web/Pages/Space.cshtml | 59 ++ ZTravel.Web/Pages/Weingarten.cshtml | 38 + ZTravel.Web/Pages/WeingartenBhf.cshtml | 13 + ZTravel.Web/Pages/_ViewImports.cshtml | 3 + ZTravel.Web/Pages/_ViewStart.cshtml | 3 + ZTravel.Web/Program.cs | 23 + ZTravel.Web/Properties/launchSettings.json | 27 + ZTravel.Web/Startup.cs | 46 + ZTravel.Web/ZTravel.Web.csproj | 48 + ZTravel.Web/appsettings.Development.json | 9 + ZTravel.Web/appsettings.json | 10 + ZTravel.Web/wwwroot/.DS_Store | Bin 0 -> 6148 bytes ZTravel.Web/wwwroot/css/fernv.css | 859 ++++++++++++++++ ZTravel.Web/wwwroot/css/sbahn.css | 854 ++++++++++++++++ ZTravel.Web/wwwroot/css/site.css | 936 +++++++++++++++++ ZTravel.Web/wwwroot/css/space.css | 957 ++++++++++++++++++ ZTravel.Web/wwwroot/favicon.ico | Bin 0 -> 32038 bytes ZTravel.Web/wwwroot/fonts/VRRR.ttf | Bin 0 -> 139372 bytes ZTravel.Web/wwwroot/js/site.js | 4 + ZTravel.sln | 28 + 52 files changed, 5443 insertions(+) create mode 100644 .gitignore create mode 100644 ZTravel.API/DBF/DbfAjaxObject.cs create mode 100644 ZTravel.API/DBF/DbfAjaxParser.cs create mode 100644 ZTravel.API/DBF/DbfApi.cs create mode 100644 ZTravel.API/DBF/DbfResponse.cs create mode 100644 ZTravel.API/DBF/DbfTypeMapping.cs create mode 100644 ZTravel.API/HAFAS/HafasApi.cs create mode 100644 ZTravel.API/Marudor/HAFAS/Details/MarudorHafasDetailsApi.cs create mode 100644 ZTravel.API/Marudor/HAFAS/Details/MarudorHafasDetailsResponse.cs create mode 100644 ZTravel.API/Marudor/Wagenreihung/WagenreihungApi.cs create mode 100644 ZTravel.API/Marudor/Wagenreihung/WagenreihungResponse.cs create mode 100644 ZTravel.API/VRRF/VrrfApi.cs create mode 100644 ZTravel.API/VRRF/VrrfResponse.cs create mode 100644 ZTravel.API/ZTravel.API.csproj create mode 100644 ZTravel.CLI/Program.cs create mode 100644 ZTravel.CLI/TestMain.cs create mode 100644 ZTravel.CLI/ZTravel.CLI.csproj create mode 100644 ZTravel.Web/Pages/Cebotari.cshtml create mode 100644 ZTravel.Web/Pages/CebotariLCD.cshtml create mode 100644 ZTravel.Web/Pages/Error.cshtml create mode 100644 ZTravel.Web/Pages/Error.cshtml.cs create mode 100644 ZTravel.Web/Pages/Index.cshtml create mode 100644 ZTravel.Web/Pages/IndexTest.cshtml create mode 100644 ZTravel.Web/Pages/KaHbf.cshtml create mode 100644 ZTravel.Web/Pages/Mobile.cshtml create mode 100644 ZTravel.Web/Pages/MucHbf.cshtml create mode 100644 ZTravel.Web/Pages/ParschBhf.cshtml create mode 100644 ZTravel.Web/Pages/SbgHbf.cshtml create mode 100644 ZTravel.Web/Pages/SbgMuc.cshtml create mode 100644 ZTravel.Web/Pages/Shared/_Layout.cshtml create mode 100644 ZTravel.Web/Pages/Shared/_LayoutFern.cshtml create mode 100644 ZTravel.Web/Pages/Shared/_ValidationScriptsPartial.cshtml create mode 100644 ZTravel.Web/Pages/Space.cshtml create mode 100644 ZTravel.Web/Pages/Weingarten.cshtml create mode 100644 ZTravel.Web/Pages/WeingartenBhf.cshtml create mode 100644 ZTravel.Web/Pages/_ViewImports.cshtml create mode 100644 ZTravel.Web/Pages/_ViewStart.cshtml create mode 100644 ZTravel.Web/Program.cs create mode 100644 ZTravel.Web/Properties/launchSettings.json create mode 100644 ZTravel.Web/Startup.cs create mode 100644 ZTravel.Web/ZTravel.Web.csproj create mode 100644 ZTravel.Web/appsettings.Development.json create mode 100644 ZTravel.Web/appsettings.json create mode 100644 ZTravel.Web/wwwroot/.DS_Store create mode 100644 ZTravel.Web/wwwroot/css/fernv.css create mode 100644 ZTravel.Web/wwwroot/css/sbahn.css create mode 100644 ZTravel.Web/wwwroot/css/site.css create mode 100644 ZTravel.Web/wwwroot/css/space.css create mode 100644 ZTravel.Web/wwwroot/favicon.ico create mode 100644 ZTravel.Web/wwwroot/fonts/VRRR.ttf create mode 100644 ZTravel.Web/wwwroot/js/site.js create mode 100644 ZTravel.sln diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1788af --- /dev/null +++ b/.gitignore @@ -0,0 +1,249 @@ + +# Created by https://www.gitignore.io/api/rider,jetbrains,dotnetcore,jetbrains+all,jetbrains+iml +# Edit at https://www.gitignore.io/?templates=rider,jetbrains,dotnetcore,jetbrains+all,jetbrains+iml + +### DotnetCore ### +# .NET Core build folders +bin +obj + +# Common node modules locations +node_modules +wwwroot/node_modules + + +### JetBrains ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf + +# Generated files +.idea/**/contentModel.xml + +# Sensitive or high-churn files +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml + +# Gradle +.idea/**/gradle.xml +.idea/**/libraries + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake +cmake-build-*/ + +# Mongo Explorer plugin +.idea/**/mongoSettings.xml + +# File-based project format +*.iws + +# IntelliJ +out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Cursive Clojure plugin +.idea/replstate.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +# Editor-based Rest Client +.idea/httpRequests + +# Android studio 3.1+ serialized cache file +.idea/caches/build_file_checksums.ser + +### JetBrains Patch ### +# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 + +# *.iml +# modules.xml +# .idea/misc.xml +# *.ipr + +# Sonarlint plugin +.idea/**/sonarlint/ + +# SonarQube Plugin +.idea/**/sonarIssues.xml + +# Markdown Navigator plugin +.idea/**/markdown-navigator.xml +.idea/**/markdown-navigator/ + +### JetBrains+all ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +### JetBrains+all Patch ### +# Ignores the whole .idea folder and all .iml files +# See https://github.com/joeblau/gitignore.io/issues/186 and https://github.com/joeblau/gitignore.io/issues/360 + +.idea/ + +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + +*.iml +modules.xml +.idea/misc.xml +*.ipr + +# Sonarlint plugin +.idea/sonarlint + +### JetBrains+iml ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +### JetBrains+iml Patch ### +# Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-249601023 + + +### Rider ### +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm +# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 + +# User-specific stuff + +# Generated files + +# Sensitive or high-churn files + +# Gradle + +# Gradle and Maven with auto-import +# When using Gradle or Maven with auto-import, you should exclude module files, +# since they will be recreated, and may cause churn. Uncomment if using +# auto-import. +# .idea/modules.xml +# .idea/*.iml +# .idea/modules +# *.iml +# *.ipr + +# CMake + +# Mongo Explorer plugin + +# File-based project format + +# IntelliJ + +# mpeltonen/sbt-idea plugin + +# JIRA plugin + +# Cursive Clojure plugin + +# Crashlytics plugin (for Android Studio and IntelliJ) + +# Editor-based Rest Client + +# Android studio 3.1+ serialized cache file + +# End of https://www.gitignore.io/api/rider,jetbrains,dotnetcore,jetbrains+all,jetbrains+iml \ No newline at end of file diff --git a/ZTravel.API/DBF/DbfAjaxObject.cs b/ZTravel.API/DBF/DbfAjaxObject.cs new file mode 100644 index 0000000..254e08d --- /dev/null +++ b/ZTravel.API/DBF/DbfAjaxObject.cs @@ -0,0 +1,25 @@ +using System; + +namespace ZTravel.API.DBF { + public class DbfAjaxObject { + public bool HasDepartureTime; + public bool HasArrivalTime; + public DateTime DepartureTime; + public DateTime ArrivalTime; + public string TrainName; + public string TrainClass; + public string TrainSubtype; + public string TrainNumber; + public string Line; + public string LineType; + public string Origin; + public string Destination; + public string Route; + public bool PlatformChanged = false; + public string Platform; + public int Delay; + public string Info; + public bool Cancelled; + public bool Replacement; + } +} \ No newline at end of file diff --git a/ZTravel.API/DBF/DbfAjaxParser.cs b/ZTravel.API/DBF/DbfAjaxParser.cs new file mode 100644 index 0000000..a8ee8f6 --- /dev/null +++ b/ZTravel.API/DBF/DbfAjaxParser.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Net; +using System.Web; +using System.Xml.Linq; +// ReSharper disable PossibleNullReferenceException + +namespace ZTravel.API.DBF { + public class DbfAjaxParser { + public static List GetDepartures(string station, string via = "") { + var url = $"https://dbf.finalrewind.org/{HttpUtility.UrlEncode(station)}?via={via}&show_realtime=1&ajax=1"; + var result = new List(); + var raw = new WebClient().DownloadString(url); + var xel = XElement.Parse($"{raw}", LoadOptions.PreserveWhitespace); + foreach (var el in xel.Elements()) { + var connection = new DbfAjaxObject(); + if (!string.IsNullOrWhiteSpace(el.Attribute("data-line")?.Value)) + connection.Line = el.Attribute("data-line")?.Value.Trim(); + if (!string.IsNullOrWhiteSpace(el.Attribute("data-train")?.Value)) + connection.TrainName = el.Attribute("data-train")?.Value.Trim(); + if (!string.IsNullOrWhiteSpace(el.Attribute("data-from")?.Value)) + connection.Origin = el.Attribute("data-from")?.Value.Trim(); + if (!string.IsNullOrWhiteSpace(el.Attribute("data-to")?.Value)) + connection.Destination = el.Attribute("data-to")?.Value.Trim(); + if (!string.IsNullOrWhiteSpace(el.Attribute("data-platform")?.Value)) + connection.Platform = el.Attribute("data-platform")?.Value.Trim(); + if (!string.IsNullOrWhiteSpace(el.Attribute("data-no")?.Value)) + connection.TrainNumber = el.Attribute("data-no")?.Value.Trim(); + if (!string.IsNullOrWhiteSpace(el.Attribute("data-linetype")?.Value)) + connection.LineType = el.Attribute("data-linetype")?.Value.Trim(); + + if (!string.IsNullOrWhiteSpace(el.Attribute("data-arrival")?.Value)) { + connection.HasArrivalTime = true; + connection.ArrivalTime = DateTime.ParseExact(el.Attribute("data-arrival")?.Value.Trim(), "HH:mm", CultureInfo.InvariantCulture); + } + + if (!string.IsNullOrWhiteSpace(el.Attribute("data-departure")?.Value)) { + connection.HasDepartureTime = true; + connection.DepartureTime = DateTime.ParseExact(el.Attribute("data-departure")?.Value.Trim(), "HH:mm", CultureInfo.InvariantCulture); + } + + var route = el.Descendants("span").FirstOrDefault(div => div.Attribute("class").Value.StartsWith("route"))?.Value; + if (!string.IsNullOrWhiteSpace(route)) + connection.Route = route.Trim(); + + var trainClass = el.Descendants("div").FirstOrDefault(div => div.Attribute("class").Value.StartsWith("line"))?.Value; + if (!string.IsNullOrWhiteSpace(trainClass)) + connection.TrainClass = trainClass.Trim().Split("\n")[0].Trim(); + + var trainSubtype = el.Descendants("div") + .FirstOrDefault(div => div.Descendants("span").Any(span => span.Attribute("class").Value.StartsWith("trainsubtype"))) + ?.Descendants("span") + .FirstOrDefault(span => span.Attribute("class").Value.StartsWith("trainsubtype")) + ?.Value; + if (!string.IsNullOrWhiteSpace(trainSubtype)) + connection.TrainSubtype = trainSubtype.Trim(); + + var trainNumber = el.Descendants("div") + .FirstOrDefault(div => div.Descendants("span").Any(span => span.Attribute("class").Value.StartsWith("trainno"))) + ?.Descendants("span") + .FirstOrDefault(span => span.Attribute("class").Value.StartsWith("trainno")) + ?.Value; + if (!string.IsNullOrWhiteSpace(trainNumber)) + connection.TrainNumber = trainNumber.Trim(); + + var platform = el.Descendants("span").FirstOrDefault(div => div.Attribute("class").Value.StartsWith("platform")); + if (platform.Attribute("class")?.Value == "platform changed-platform") { + connection.Platform = platform.Value.Trim(); + connection.PlatformChanged = true; + } + + var dest = el.Descendants("span").FirstOrDefault(div => div.Attribute("class").Value.StartsWith("dest")); + if (dest.Attribute("class")?.Value == "dest cancelled") + connection.Cancelled = true; + + result.Add(connection); + } + + return result; + } + } +} \ No newline at end of file diff --git a/ZTravel.API/DBF/DbfApi.cs b/ZTravel.API/DBF/DbfApi.cs new file mode 100644 index 0000000..fcff16d --- /dev/null +++ b/ZTravel.API/DBF/DbfApi.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Net; +using ZTravel.API.VRRF; + +namespace ZTravel.API.DBF { + public class DbfApi { + public static List GetDepartures(string api, string station, string via = "") { + var url = + $"https://{api}/{WebUtility.UrlEncode(station)}?show_realtime=1&via={WebUtility.UrlEncode(via)}&mode=json&version=3"; + var raw = new WebClient().DownloadString(url); + var json = DbfResponse.FromJson(raw); + return json.Departures; + } + } +} \ No newline at end of file diff --git a/ZTravel.API/DBF/DbfResponse.cs b/ZTravel.API/DBF/DbfResponse.cs new file mode 100644 index 0000000..ae0c678 --- /dev/null +++ b/ZTravel.API/DBF/DbfResponse.cs @@ -0,0 +1,83 @@ +// +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using ZTravel.API.DBF; +// +// var dbfResponse = DbfResponse.FromJson(jsonString); + +namespace ZTravel.API.DBF +{ + using System; + using System.Collections.Generic; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using J = Newtonsoft.Json.JsonPropertyAttribute; + using R = Newtonsoft.Json.Required; + using N = Newtonsoft.Json.NullValueHandling; + + public partial class DbfResponse + { + [J("departures")] public List Departures { get; set; } + } + + public partial class Departure + { + [J("delayArrival")] public int? DelayArrival { get; set; } + [J("delayDeparture")] public int? DelayDeparture { get; set; } + [J("destination")] public string Destination { get; set; } + [J("isCancelled")] public long IsCancelled { get; set; } + [J("messages")] public Messages Messages { get; set; } + [J("platform")] public string Platform { get; set; } + [J("route")] public List Route { get; set; } + [J("scheduledArrival")] public string ScheduledArrival { get; set; } + [J("scheduledDeparture")] public string ScheduledDeparture { get; set; } + [J("scheduledPlatform")] public string ScheduledPlatform { get; set; } + [J("train")] public string Train { get; set; } + [J("trainClasses")] public List TrainClasses { get; set; } + [J("trainNumber")] public string TrainNumber { get; set; } + [J("via")] public List Via { get; set; } + } + + public partial class Messages + { + [J("delay")] public List Delay { get; set; } + [J("qos")] public List Qos { get; set; } + } + + public partial class Delay + { + [J("text")] public string Text { get; set; } + [J("timestamp")] public string Timestamp { get; set; } + } + + public partial class Route + { + [J("name")] public string Name { get; set; } + } + + public partial class DbfResponse + { + public static DbfResponse FromJson(string json) => JsonConvert.DeserializeObject(json, ZTravel.API.DBF.Converter.Settings); + } + + public static partial class Serialize + { + public static string ToJson(this DbfResponse self) => JsonConvert.SerializeObject(self, ZTravel.API.DBF.Converter.Settings); + } + + internal static partial class Converter + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } +} diff --git a/ZTravel.API/DBF/DbfTypeMapping.cs b/ZTravel.API/DBF/DbfTypeMapping.cs new file mode 100644 index 0000000..9495b1b --- /dev/null +++ b/ZTravel.API/DBF/DbfTypeMapping.cs @@ -0,0 +1,37 @@ +// +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using ZTravel.API.DBF; +// +// var dbfTypeMapping = DbfTypeMapping.FromJson(jsonString); + +namespace ZTravel.API.DBF +{ + using System; + using System.Collections.Generic; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using J = Newtonsoft.Json.JsonPropertyAttribute; + using R = Newtonsoft.Json.Required; + using N = Newtonsoft.Json.NullValueHandling; + + public partial class DbfTypeMapping + { + [J("raw")] public string Raw { get; set; } + [J("short", NullValueHandling = N.Ignore)] public string Short { get; set; } + [J("type")] public string Type { get; set; } + } + + public partial class DbfTypeMapping + { + public static Dictionary FromJson(string json) => JsonConvert.DeserializeObject>(json, ZTravel.API.DBF.Converter.Settings); + } + + public static partial class Serialize + { + public static string ToJson(this Dictionary self) => JsonConvert.SerializeObject(self, ZTravel.API.DBF.Converter.Settings); + } +} diff --git a/ZTravel.API/HAFAS/HafasApi.cs b/ZTravel.API/HAFAS/HafasApi.cs new file mode 100644 index 0000000..d653ef2 --- /dev/null +++ b/ZTravel.API/HAFAS/HafasApi.cs @@ -0,0 +1,9 @@ +using dirkj.hafas.net; + +namespace ZTravel.API.HAFAS { + public class HafasApi { + public void test() { + var provider = new HafasProvider(HafasEndpoints.DSB); + } + } +} \ No newline at end of file diff --git a/ZTravel.API/Marudor/HAFAS/Details/MarudorHafasDetailsApi.cs b/ZTravel.API/Marudor/HAFAS/Details/MarudorHafasDetailsApi.cs new file mode 100644 index 0000000..3644154 --- /dev/null +++ b/ZTravel.API/Marudor/HAFAS/Details/MarudorHafasDetailsApi.cs @@ -0,0 +1,15 @@ +using System; +using System.Net; +using System.Web; + +namespace ZTravel.API.Marudor.HAFAS.Details { + public class MarudorHafasDetailsApi { + public static MarudorHafasDetailsResponse GetDetails(string train, long epoch = 0) { + var url = $"https://marudor.de/api/hafas/v1/details/{train}"; + Console.WriteLine(url); + var raw = new WebClient().DownloadString(url); + var json = MarudorHafasDetailsResponse.FromJson(raw); + return json; + } + } +} \ No newline at end of file diff --git a/ZTravel.API/Marudor/HAFAS/Details/MarudorHafasDetailsResponse.cs b/ZTravel.API/Marudor/HAFAS/Details/MarudorHafasDetailsResponse.cs new file mode 100644 index 0000000..361ce8f --- /dev/null +++ b/ZTravel.API/Marudor/HAFAS/Details/MarudorHafasDetailsResponse.cs @@ -0,0 +1,152 @@ +// +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using ZTravel.API.Marudor.HAFAS.Details; +// +// var marudorHafasDetailsResponse = MarudorHafasDetailsResponse.FromJson(jsonString); + +namespace ZTravel.API.Marudor.HAFAS.Details +{ + using System; + using System.Collections.Generic; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using J = Newtonsoft.Json.JsonPropertyAttribute; + using R = Newtonsoft.Json.Required; + using N = Newtonsoft.Json.NullValueHandling; + + public partial class MarudorHafasDetailsResponse + { + [J("arrival")] public Arrival Arrival { get; set; } + [J("departure")] public Arrival Departure { get; set; } + [J("duration")] public long Duration { get; set; } + [J("plannedSequence")] public PlannedSequence PlannedSequence { get; set; } + [J("train")] public Train Train { get; set; } + [J("segmentStart")] public Segment SegmentStart { get; set; } + [J("segmentDestination")] public Segment SegmentDestination { get; set; } + [J("stops")] public List Stops { get; set; } + [J("finalDestination")] public string FinalDestination { get; set; } + [J("jid")] public string Jid { get; set; } + [J("auslastung")] public Auslastung Auslastung { get; set; } + [J("messages")] public List Messages { get; set; } + [J("type")] public string Type { get; set; } + } + + public partial class Arrival + { + [J("platform")] public string Platform { get; set; } + [J("scheduledTime")] public long ScheduledTime { get; set; } + [J("time")] public long Time { get; set; } + [J("reihung")] public bool Reihung { get; set; } + } + + public partial class Auslastung + { + [J("first")] public long First { get; set; } + [J("second")] public long Second { get; set; } + } + + public partial class Message + { + [J("type")] public string Type { get; set; } + [J("code")] public string Code { get; set; } + [J("prio")] public long Prio { get; set; } + [J("icoX")] public long IcoX { get; set; } + [J("txtN")] public string TxtN { get; set; } + } + + public partial class PlannedSequence + { + [J("raw")] public string Raw { get; set; } + [J("short")] public string Short { get; set; } + [J("type")] public string Type { get; set; } + [J("wagons")] public Wagons Wagons { get; set; } + } + + public partial class Wagons + { + [J("Apmzf")] public bool Apmzf { get; set; } + [J("Avmz")] public bool Avmz { get; set; } + [J("BRmz")] public bool BRmz { get; set; } + [J("Bpmbz")] public bool Bpmbz { get; set; } + [J("Bpmz")] public bool Bpmz { get; set; } + [J("Bpmzf")] public bool Bpmzf { get; set; } + [J("Bvmz")] public bool Bvmz { get; set; } + [J("WRmz")] public bool WRmz { get; set; } + } + + public partial class Segment + { + [J("title")] public string Title { get; set; } + [J("id")] public string Id { get; set; } + } + + public partial class Stop + { + [J("station")] public Station Station { get; set; } + [J("departure", NullValueHandling = N.Ignore)] public Arrival Departure { get; set; } + [J("auslastung", NullValueHandling = N.Ignore)] public Auslastung Auslastung { get; set; } + [J("arrival", NullValueHandling = N.Ignore)] public Arrival Arrival { get; set; } + [J("irisMessages", NullValueHandling = N.Ignore)] public List IrisMessages { get; set; } + } + + public partial class IrisMessage + { + [J("text")] public string Text { get; set; } + [J("timestamp")] public long Timestamp { get; set; } + } + + public partial class Station + { + [J("id")] public string Id { get; set; } + [J("title")] public string Title { get; set; } + [J("coordinates")] public Coordinates Coordinates { get; set; } + } + + public partial class Coordinates + { + [J("lng")] public double Lng { get; set; } + [J("lat")] public double Lat { get; set; } + } + + public partial class Train + { + [J("name")] public string Name { get; set; } + [J("admin")] public string Admin { get; set; } + [J("number")] public string Number { get; set; } + [J("type")] public string Type { get; set; } + [J("operator")] public Operator Operator { get; set; } + } + + public partial class Operator + { + [J("name")] public string Name { get; set; } + [J("icoX")] public long IcoX { get; set; } + } + + public partial class MarudorHafasDetailsResponse + { + public static MarudorHafasDetailsResponse FromJson(string json) => JsonConvert.DeserializeObject(json, ZTravel.API.Marudor.HAFAS.Details.Converter.Settings); + } + + public static class Serialize + { + public static string ToJson(this MarudorHafasDetailsResponse self) => JsonConvert.SerializeObject(self, ZTravel.API.Marudor.HAFAS.Details.Converter.Settings); + } + + internal static class Converter + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } +} diff --git a/ZTravel.API/Marudor/Wagenreihung/WagenreihungApi.cs b/ZTravel.API/Marudor/Wagenreihung/WagenreihungApi.cs new file mode 100644 index 0000000..31082c2 --- /dev/null +++ b/ZTravel.API/Marudor/Wagenreihung/WagenreihungApi.cs @@ -0,0 +1,5 @@ +namespace ZTravel.API.Marudor.Wagenreihung { + public class WagenreihungApi { + + } +} \ No newline at end of file diff --git a/ZTravel.API/Marudor/Wagenreihung/WagenreihungResponse.cs b/ZTravel.API/Marudor/Wagenreihung/WagenreihungResponse.cs new file mode 100644 index 0000000..274500e --- /dev/null +++ b/ZTravel.API/Marudor/Wagenreihung/WagenreihungResponse.cs @@ -0,0 +1,156 @@ +// +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using ZTravel.API.Marudor.Wagenreihung; +// +// var wagenreihungResponse = WagenreihungResponse.FromJson(jsonString); + +namespace ZTravel.API.Marudor.Wagenreihung +{ + using System; + using System.Collections.Generic; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using J = Newtonsoft.Json.JsonPropertyAttribute; + using R = Newtonsoft.Json.Required; + using N = Newtonsoft.Json.NullValueHandling; + + public partial class WagenreihungResponse + { + [J("fahrtrichtung")] public string Fahrtrichtung { get; set; } + [J("allFahrzeuggruppe")] public List AllFahrzeuggruppe { get; set; } + [J("halt")] public Halt Halt { get; set; } + [J("liniebezeichnung")] public string Liniebezeichnung { get; set; } + [J("zuggattung")] public string Zuggattung { get; set; } + [J("zugnummer")] public string Zugnummer { get; set; } + [J("serviceid")] public string Serviceid { get; set; } + [J("planstarttag")] public string Planstarttag { get; set; } + [J("fahrtid")] public string Fahrtid { get; set; } + [J("istplaninformation")] public bool Istplaninformation { get; set; } + [J("differentDestination")] public bool DifferentDestination { get; set; } + [J("differentZugnummer")] public bool DifferentZugnummer { get; set; } + [J("realFahrtrichtung")] public bool RealFahrtrichtung { get; set; } + [J("scale")] public double Scale { get; set; } + [J("startPercentage")] public long StartPercentage { get; set; } + [J("endPercentage")] public long EndPercentage { get; set; } + [J("isRealtime")] public bool IsRealtime { get; set; } + } + + public partial class AllFahrzeuggruppe + { + [J("allFahrzeug")] public List AllFahrzeug { get; set; } + [J("fahrzeuggruppebezeichnung")] public string Fahrzeuggruppebezeichnung { get; set; } + [J("zielbetriebsstellename")] public string Zielbetriebsstellename { get; set; } + [J("startbetriebsstellename")] public string Startbetriebsstellename { get; set; } + [J("verkehrlichezugnummer")] public string Verkehrlichezugnummer { get; set; } + [J("br")] public Br Br { get; set; } + [J("goesToFrance")] public bool GoesToFrance { get; set; } + [J("tzn")] public string Tzn { get; set; } + [J("name")] public string Name { get; set; } + [J("startPercentage")] public long StartPercentage { get; set; } + [J("endPercentage")] public long EndPercentage { get; set; } + } + + public partial class AllFahrzeug + { + [J("allFahrzeugausstattung")] public List AllFahrzeugausstattung { get; set; } + [J("kategorie")] public string Kategorie { get; set; } + [J("fahrzeugnummer")] public string Fahrzeugnummer { get; set; } + [J("orientierung")] public string Orientierung { get; set; } + [J("positioningruppe")] public string Positioningruppe { get; set; } + [J("fahrzeugsektor")] public string Fahrzeugsektor { get; set; } + [J("fahrzeugtyp")] public string Fahrzeugtyp { get; set; } + [J("wagenordnungsnummer")] public string Wagenordnungsnummer { get; set; } + [J("positionamhalt")] public Positionam Positionamhalt { get; set; } + [J("status")] public string Status { get; set; } + [J("additionalInfo")] public AdditionalInfo AdditionalInfo { get; set; } + } + + public partial class AdditionalInfo + { + [J("klasse")] public long Klasse { get; set; } + [J("icons")] public Icons Icons { get; set; } + [J("comfort", NullValueHandling = N.Ignore)] public bool? Comfort { get; set; } + [J("comfortSeats", NullValueHandling = N.Ignore)] public string ComfortSeats { get; set; } + [J("disabledSeats", NullValueHandling = N.Ignore)] public string DisabledSeats { get; set; } + } + + public partial class Icons + { + [J("quiet", NullValueHandling = N.Ignore)] public bool? Quiet { get; set; } + [J("family", NullValueHandling = N.Ignore)] public bool? Family { get; set; } + [J("disabled", NullValueHandling = N.Ignore)] public bool? Disabled { get; set; } + [J("dining", NullValueHandling = N.Ignore)] public bool? Dining { get; set; } + [J("info", NullValueHandling = N.Ignore)] public bool? Info { get; set; } + [J("toddler", NullValueHandling = N.Ignore)] public bool? Toddler { get; set; } + [J("wheelchair", NullValueHandling = N.Ignore)] public bool? Wheelchair { get; set; } + } + + public partial class AllFahrzeugausstattung + { + [J("anzahl")] public string Anzahl { get; set; } + [J("ausstattungsart")] public string Ausstattungsart { get; set; } + [J("bezeichnung")] public string Bezeichnung { get; set; } + [J("status")] public string Status { get; set; } + } + + public partial class Positionam + { + [J("endemeter")] public string Endemeter { get; set; } + [J("endeprozent")] public string Endeprozent { get; set; } + [J("startmeter")] public string Startmeter { get; set; } + [J("startprozent")] public string Startprozent { get; set; } + } + + public partial class Br + { + [J("name")] public string Name { get; set; } + [J("BR")] public string BrBr { get; set; } + [J("country")] public string Country { get; set; } + [J("showBRInfo")] public bool ShowBrInfo { get; set; } + } + + public partial class Halt + { + [J("abfahrtszeit")] public string Abfahrtszeit { get; set; } + [J("ankunftszeit")] public string Ankunftszeit { get; set; } + [J("bahnhofsname")] public string Bahnhofsname { get; set; } + [J("evanummer")] public string Evanummer { get; set; } + [J("gleisbezeichnung")] public string Gleisbezeichnung { get; set; } + [J("haltid")] public string Haltid { get; set; } + [J("rl100")] public string Rl100 { get; set; } + [J("allSektor")] public List AllSektor { get; set; } + } + + public partial class AllSektor + { + [J("positionamgleis")] public Positionam Positionamgleis { get; set; } + [J("sektorbezeichnung")] public string Sektorbezeichnung { get; set; } + } + + public partial class WagenreihungResponse + { + public static WagenreihungResponse FromJson(string json) => JsonConvert.DeserializeObject(json, ZTravel.API.Marudor.Wagenreihung.Converter.Settings); + } + + public static class Serialize + { + public static string ToJson(this WagenreihungResponse self) => JsonConvert.SerializeObject(self, ZTravel.API.Marudor.Wagenreihung.Converter.Settings); + } + + internal static class Converter + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } +} diff --git a/ZTravel.API/VRRF/VrrfApi.cs b/ZTravel.API/VRRF/VrrfApi.cs new file mode 100644 index 0000000..520ac9e --- /dev/null +++ b/ZTravel.API/VRRF/VrrfApi.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using System.Net; + +namespace ZTravel.API.VRRF { + public class VrrfApi { + public static VrrfResponse GetDepartures(string api, string backend, string city, string station, int offset = 0, string line = "", string platform = "") { + var url = + $"https://{api}/{city}/{WebUtility.UrlEncode(station)}.json?backend={backend}&offset={offset}&line={line}&platform={platform}"; + var raw = new WebClient().DownloadString(url); + var json = VrrfResponse.FromJson(raw); + return json; + } + } +} \ No newline at end of file diff --git a/ZTravel.API/VRRF/VrrfResponse.cs b/ZTravel.API/VRRF/VrrfResponse.cs new file mode 100644 index 0000000..68ce660 --- /dev/null +++ b/ZTravel.API/VRRF/VrrfResponse.cs @@ -0,0 +1,86 @@ +// +// +// To parse this JSON data, add NuGet 'Newtonsoft.Json' then do: +// +// using ZTravel.API.VRRF; +// +// var vrrfResponse = VrrfResponse.FromJson(jsonString); + +namespace ZTravel.API.VRRF +{ + using System; + using System.Collections.Generic; + + using System.Globalization; + using Newtonsoft.Json; + using Newtonsoft.Json.Converters; + using J = Newtonsoft.Json.JsonPropertyAttribute; + using R = Newtonsoft.Json.Required; + using N = Newtonsoft.Json.NullValueHandling; + + public partial class VrrfResponse + { + [J("error")] public object Error { get; set; } + [J("preformatted")] public List> Preformatted { get; set; } + [J("raw")] public List Raw { get; set; } + [J("version")] public string Version { get; set; } + } + + public partial class Raw + { + [J("countdown")] public string Countdown { get; set; } + [J("date")] public string Date { get; set; } + [J("delay")] public string Delay { get; set; } + [J("destination")] public string Destination { get; set; } + [J("info")] public string Info { get; set; } + [J("is_cancelled")] public long IsCancelled { get; set; } + [J("key")] public string Key { get; set; } + [J("line")] public string Line { get; set; } + [J("lineref")] public Lineref Lineref { get; set; } + [J("mot")] public string Mot { get; set; } + [J("next_route")] public List NextRoute { get; set; } + [J("platform")] public string Platform { get; set; } + [J("platform_db")] public long PlatformDb { get; set; } + [J("platform_name")] public string PlatformName { get; set; } + [J("prev_route")] public List PrevRoute { get; set; } + [J("sched_date")] public string SchedDate { get; set; } + [J("sched_time")] public string SchedTime { get; set; } + [J("time")] public string Time { get; set; } + [J("type")] public string Type { get; set; } + } + + public partial class Lineref + { + [J("direction")] public string Direction { get; set; } + [J("identifier")] public string Identifier { get; set; } + [J("mot")] public string Mot { get; set; } + [J("name")] public string Name { get; set; } + [J("operator")] public string Operator { get; set; } + [J("route")] public string Route { get; set; } + [J("type")] public string Type { get; set; } + [J("valid")] public string Valid { get; set; } + } + + public partial class VrrfResponse + { + public static VrrfResponse FromJson(string json) => JsonConvert.DeserializeObject(json, ZTravel.API.VRRF.Converter.Settings); + } + + public static class Serialize + { + public static string ToJson(this VrrfResponse self) => JsonConvert.SerializeObject(self, ZTravel.API.VRRF.Converter.Settings); + } + + internal static class Converter + { + public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings + { + MetadataPropertyHandling = MetadataPropertyHandling.Ignore, + DateParseHandling = DateParseHandling.None, + Converters = + { + new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal } + }, + }; + } +} diff --git a/ZTravel.API/ZTravel.API.csproj b/ZTravel.API/ZTravel.API.csproj new file mode 100644 index 0000000..54de39c --- /dev/null +++ b/ZTravel.API/ZTravel.API.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp3.1 + + + + + + + + + + + + diff --git a/ZTravel.CLI/Program.cs b/ZTravel.CLI/Program.cs new file mode 100644 index 0000000..0eacb03 --- /dev/null +++ b/ZTravel.CLI/Program.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using ZTravel.API.VRRF; +using ZTravel.API.DBF; + +namespace ZTravel.CLI { + internal static class Departures { + private static void Mainold(string[] args) { + if (args[0] == "vrrf") { + var deps = args.Length switch { + 6 => VrrfApi.GetDepartures(args[1], args[2], args[3], args[4], platform: args[5]).Raw, + 5 => VrrfApi.GetDepartures(args[1], args[2], args[3], args[4]).Raw, + _ => new List() + }; + + foreach (var dep in deps) { + var rawtime = DateTime.ParseExact($"{dep.SchedDate} {dep.Time}", "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture); + var countdownRaw = rawtime - DateTime.Now; + var countdown = Math.Round(countdownRaw.TotalMinutes); + var time = countdown <= 60 ? $"{countdown,2} min" : $"{dep.Time,6}"; + if (countdown <= 0) + time = " now"; + if (countdown <= -1) + continue; + + Console.WriteLine($"{dep.Line,-3} -> {dep.Destination.Replace($"{args[3]} ", ""),-30} {time}"); + } + } + + if (args[0] == "dbf") { + var deps = args.Length switch { + 3 => DbfApi.GetDepartures(args[1], args[2]), + 4 => DbfApi.GetDepartures(args[1], args[2], args[3]), + _ => new List() + }; + + foreach (var dep in deps.Where(p => p.ScheduledDeparture != null)) { + Console.WriteLine($"{dep.Train,-10} -> {dep.Destination,-30} {dep.ScheduledDeparture}"); + } + } + } + } +} \ No newline at end of file diff --git a/ZTravel.CLI/TestMain.cs b/ZTravel.CLI/TestMain.cs new file mode 100644 index 0000000..5e59357 --- /dev/null +++ b/ZTravel.CLI/TestMain.cs @@ -0,0 +1,13 @@ +using System; +using ZTravel.API.DBF; + +namespace ZTravel.CLI { + public class TestMain { + private static void Main(string[] args) { + var deps = DbfAjaxParser.GetDepartures("München Hbf"); + foreach (var dep in deps) { + Console.WriteLine(dep.Line); + } + } + } +} \ No newline at end of file diff --git a/ZTravel.CLI/ZTravel.CLI.csproj b/ZTravel.CLI/ZTravel.CLI.csproj new file mode 100644 index 0000000..da2d464 --- /dev/null +++ b/ZTravel.CLI/ZTravel.CLI.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp3.1 + + + + + + + diff --git a/ZTravel.Web/Pages/Cebotari.cshtml b/ZTravel.Web/Pages/Cebotari.cshtml new file mode 100644 index 0000000..d5070a2 --- /dev/null +++ b/ZTravel.Web/Pages/Cebotari.cshtml @@ -0,0 +1,53 @@ +@page +@using System.Globalization +@using ZTravel.API.VRRF + + + + + + Departures - ZTravel + + + + + +
+
    + @foreach (var dep in VrrfApi.GetDepartures("vrrf.finalrewind.org", "efa.SVV", "salzburg", "cebotari", platform: "2").Raw) { + var rawtime = DateTime.ParseExact($"{dep.SchedDate} {dep.Time}", "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture); + var countdownRaw = rawtime - DateTime.Now; + var countdown = Math.Round(countdownRaw.TotalMinutes); + var time = countdown <= 60 ? $"{countdown} min" : dep.Time; + if (countdown <= 0) { + time = "now"; + } + if (countdown <= -1) { + continue; + } + +
  • + @if (int.Parse(dep.Line) < 14) { +
    @dep.Line
    + } + else { +
    @dep.Line
    + } +
    @dep.Destination
    + @dep.Lineref.Route + + @time + + @dep.Time +
  • + } +
+
+ + \ No newline at end of file diff --git a/ZTravel.Web/Pages/CebotariLCD.cshtml b/ZTravel.Web/Pages/CebotariLCD.cshtml new file mode 100644 index 0000000..5ce8253 --- /dev/null +++ b/ZTravel.Web/Pages/CebotariLCD.cshtml @@ -0,0 +1,64 @@ +@page +@using System.Globalization +@using ZTravel.API.VRRF + + + + + + Departures - ZTravel + + + + + + +
+
    + @{ + var counter = 0; + } + @foreach (var dep in VrrfApi.GetDepartures("vrrf.finalrewind.org", "efa.SVV", "salzburg", "maria-cebotari-straße", platform: "2").Raw) { + if (int.Parse(dep.Line) >= 20) { + continue; + } + counter++; + var rawtime = DateTime.ParseExact($"{dep.Date} {dep.Time}", "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture); + var countdownRaw = rawtime - DateTime.Now; + var countdown = Math.Round(countdownRaw.TotalMinutes); + var time = countdown <= 60 ? $"{countdown} min" : dep.Time; + if (countdown <= 0) { + time = "now"; + } + if (countdown <= 5) { + continue; + } +
  • + @if (int.Parse(dep.Line) < 14) { +
    @dep.Line
    + } + else { +
    @dep.Line
    + } +
    @dep.Destination
    + + @time + +
  • + } +
+
+ + \ No newline at end of file diff --git a/ZTravel.Web/Pages/Error.cshtml b/ZTravel.Web/Pages/Error.cshtml new file mode 100644 index 0000000..6f92b95 --- /dev/null +++ b/ZTravel.Web/Pages/Error.cshtml @@ -0,0 +1,26 @@ +@page +@model ErrorModel +@{ + ViewData["Title"] = "Error"; +} + +

Error.

+

An error occurred while processing your request.

+ +@if (Model.ShowRequestId) +{ +

+ Request ID: @Model.RequestId +

+} + +

Development Mode

+

+ Swapping to the Development environment displays detailed information about the error that occurred. +

+

+ The Development environment shouldn't be enabled for deployed applications. + It can result in displaying sensitive information from exceptions to end users. + For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development + and restarting the app. +

diff --git a/ZTravel.Web/Pages/Error.cshtml.cs b/ZTravel.Web/Pages/Error.cshtml.cs new file mode 100644 index 0000000..b3a2fee --- /dev/null +++ b/ZTravel.Web/Pages/Error.cshtml.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.Logging; + +namespace ZTravel.Pages { + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public class ErrorModel : PageModel { + public string RequestId { get; set; } + + public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); + + private readonly ILogger _logger; + + public ErrorModel(ILogger logger) { + _logger = logger; + } + + public void OnGet() { + RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; + } + } +} \ No newline at end of file diff --git a/ZTravel.Web/Pages/Index.cshtml b/ZTravel.Web/Pages/Index.cshtml new file mode 100644 index 0000000..7ecc3af --- /dev/null +++ b/ZTravel.Web/Pages/Index.cshtml @@ -0,0 +1,40 @@ +@page + + + + + Departures - ZTravel + + + + + +
+ + + + + +
+ + + \ No newline at end of file diff --git a/ZTravel.Web/Pages/IndexTest.cshtml b/ZTravel.Web/Pages/IndexTest.cshtml new file mode 100644 index 0000000..7ecc3af --- /dev/null +++ b/ZTravel.Web/Pages/IndexTest.cshtml @@ -0,0 +1,40 @@ +@page + + + + + Departures - ZTravel + + + + + +
+ + + + + +
+ + + \ No newline at end of file diff --git a/ZTravel.Web/Pages/KaHbf.cshtml b/ZTravel.Web/Pages/KaHbf.cshtml new file mode 100644 index 0000000..6599f8b --- /dev/null +++ b/ZTravel.Web/Pages/KaHbf.cshtml @@ -0,0 +1,13 @@ +@page +@{ + Layout = "_LayoutFern"; + ViewData["title"] = "Karlsruhe Hbf (+30, excl → Weingarten)"; + ViewData["station"] = "Karlsruhe Hbf"; + ViewData["stationId"] = "8079041"; + ViewData["via"] = ""; + ViewData["excludingVia"] = "Weingarten(Baden)"; + ViewData["offset"] = 30; + ViewData["andShowDestination"] = ""; + ViewData["fernverkehrOnly"] = false; + ViewData["onlyDepartures"] = true; +} \ No newline at end of file diff --git a/ZTravel.Web/Pages/Mobile.cshtml b/ZTravel.Web/Pages/Mobile.cshtml new file mode 100644 index 0000000..70edda7 --- /dev/null +++ b/ZTravel.Web/Pages/Mobile.cshtml @@ -0,0 +1,33 @@ +@page + + + + + Departures - ZTravel + + + + + +
+ + + + + +
+ + + \ No newline at end of file diff --git a/ZTravel.Web/Pages/MucHbf.cshtml b/ZTravel.Web/Pages/MucHbf.cshtml new file mode 100644 index 0000000..9fa43a2 --- /dev/null +++ b/ZTravel.Web/Pages/MucHbf.cshtml @@ -0,0 +1,13 @@ +@page +@{ + Layout = "_LayoutFern"; + ViewData["title"] = "München Hbf"; + ViewData["station"] = "München Hbf"; + ViewData["stationId"] = "8000261"; + ViewData["via"] = ""; + ViewData["excludingVia"] = ""; + ViewData["offset"] = 0; + ViewData["andShowDestination"] = "Salzburg Hbf"; + ViewData["fernverkehrOnly"] = true; + ViewData["onlyDepartures"] = false; +} \ No newline at end of file diff --git a/ZTravel.Web/Pages/ParschBhf.cshtml b/ZTravel.Web/Pages/ParschBhf.cshtml new file mode 100644 index 0000000..b37b010 --- /dev/null +++ b/ZTravel.Web/Pages/ParschBhf.cshtml @@ -0,0 +1,13 @@ +@page +@{ + Layout = "_LayoutFern"; + ViewData["title"] = "Salzburg Parsch"; + ViewData["station"] = "Salzburg Parsch"; + ViewData["stationId"] = "8101481"; + ViewData["via"] = ""; + ViewData["excludingVia"] = ""; + ViewData["offset"] = 0; + ViewData["andShowDestination"] = ""; + ViewData["fernverkehrOnly"] = false; + ViewData["onlyDepartures"] = false; +} \ No newline at end of file diff --git a/ZTravel.Web/Pages/SbgHbf.cshtml b/ZTravel.Web/Pages/SbgHbf.cshtml new file mode 100644 index 0000000..ddec590 --- /dev/null +++ b/ZTravel.Web/Pages/SbgHbf.cshtml @@ -0,0 +1,13 @@ +@page +@{ + Layout = "_LayoutFern"; + ViewData["title"] = "Salzburg Hbf (+20, excl → Parsch)"; + ViewData["station"] = "Salzburg Hbf"; + ViewData["stationId"] = "8100002"; + ViewData["via"] = ""; + ViewData["excludingVia"] = "Salzburg Parsch"; + ViewData["offset"] = 20; + ViewData["andShowDestination"] = ""; + ViewData["fernverkehrOnly"] = false; + ViewData["onlyDepartures"] = true; +} \ No newline at end of file diff --git a/ZTravel.Web/Pages/SbgMuc.cshtml b/ZTravel.Web/Pages/SbgMuc.cshtml new file mode 100644 index 0000000..6804ad4 --- /dev/null +++ b/ZTravel.Web/Pages/SbgMuc.cshtml @@ -0,0 +1,13 @@ +@page +@{ + Layout = "_LayoutFern"; + ViewData["title"] = "Salzburg Hbf (+20, → München Hbf)"; + ViewData["station"] = "Salzburg Hbf"; + ViewData["stationId"] = "8100002"; + ViewData["via"] = "München Hbf"; + ViewData["excludingVia"] = ""; + ViewData["offset"] = 20; + ViewData["andShowDestination"] = ""; + ViewData["fernverkehrOnly"] = false; + ViewData["onlyDepartures"] = true; +} \ No newline at end of file diff --git a/ZTravel.Web/Pages/Shared/_Layout.cshtml b/ZTravel.Web/Pages/Shared/_Layout.cshtml new file mode 100644 index 0000000..d2f231d --- /dev/null +++ b/ZTravel.Web/Pages/Shared/_Layout.cshtml @@ -0,0 +1 @@ +@RenderBody() \ No newline at end of file diff --git a/ZTravel.Web/Pages/Shared/_LayoutFern.cshtml b/ZTravel.Web/Pages/Shared/_LayoutFern.cshtml new file mode 100644 index 0000000..09487f6 --- /dev/null +++ b/ZTravel.Web/Pages/Shared/_LayoutFern.cshtml @@ -0,0 +1,159 @@ +@{ + // ReSharper disable ConditionIsAlwaysTrueOrFalse + var title = (string) ViewData["title"]; + var station = (string) ViewData["station"]; + var stationId = (string) ViewData["stationId"]; + var via = (string) ViewData["via"]; + var andShowDestination = (string) ViewData["andShowDestination"]; + var fernverkehrOnly = (bool) ViewData["fernverkehrOnly"]; + var onlyDepartures = (bool) ViewData["onlyDepartures"]; + var excludingVia = (string) ViewData["excludingVia"]; + var offset = (int) ViewData["offset"]; + IgnoreBody(); +} + +@using System.Globalization +@using System.Linq +@using ZTravel.API.DBF +@using ZTravel.Web + + + + + + Departures - ZTravel + + + + + +
+
    + @foreach (var dep in DbfApi.GetDepartures("dbf.finalrewind.org", station, via).Where(dep => !fernverkehrOnly || dep.TrainClasses.Contains("F") || dep.Destination == andShowDestination).Where(dep => !onlyDepartures || !string.IsNullOrWhiteSpace(dep.ScheduledDeparture))) { + if (dep.Route.Select(r => r.Name).Contains(excludingVia)) { + continue; + } + var typeclass = "bahn"; + if (dep.TrainClasses.Any()) { + typeclass = dep.TrainClasses.First() switch { + "S" => "sbahn", + "F" => "fern", + _ => "bahn"}; + } + + var trainclass = dep.Train.Split(" ")[0]; + + DateTime rawtime; + var delayed = false; + var undelayed = false; + var cancelled = dep.IsCancelled == 1; + var stringtime = ""; + var stringdelay = ""; + if (!string.IsNullOrWhiteSpace(dep.ScheduledDeparture)) { + rawtime = DateTime.ParseExact(dep.ScheduledDeparture, "HH:mm", CultureInfo.InvariantCulture); + if (dep.DelayDeparture != null) { + rawtime += new TimeSpan(0, (int) dep.DelayDeparture, 0); + if (dep.DelayDeparture > 0) { + delayed = true; + stringdelay = $"(+{dep.DelayDeparture})"; + } + else if (dep.DelayDeparture < 0) { + undelayed = true; + stringdelay = $"({dep.DelayDeparture})"; + } + } + stringtime = $"{rawtime:HH:mm}"; + } + else { + rawtime = DateTime.ParseExact(dep.ScheduledArrival, "HH:mm", CultureInfo.InvariantCulture); + if (dep.DelayArrival != null) { + rawtime += new TimeSpan(0, (int) dep.DelayArrival, 0); + if (dep.DelayArrival > 0) { + delayed = true; + stringdelay = $"(+{dep.DelayArrival})"; + } + else if (dep.DelayArrival < 0) { + undelayed = true; + stringdelay = $"({dep.DelayArrival})"; + } + } + stringtime = $"(arr) {rawtime:HH:mm}"; + dep.Destination += $" (from {dep.Route.First().Name})"; + } + + if ((rawtime - DateTime.Now).TotalMinutes < 0) { + rawtime += new TimeSpan(1, 0, 0, 0); + } + if ((rawtime - DateTime.Now).TotalMinutes < offset) { + continue; + } + +
  • +
    + @if (trainclass == "S") { + @dep.Train + } + else { + @trainclass + } + + @if (trainclass == "IC" || trainclass == "ICE") { + if (Program.TypeMapping.ContainsKey(dep.TrainNumber)) { + if (!string.IsNullOrWhiteSpace(Program.TypeMapping[dep.TrainNumber].Short)) { + @Program.TypeMapping[dep.TrainNumber].Short + } + } + } + @dep.TrainNumber +
    + @if (dep.Messages.Delay.Any()) { + if (dep.Messages.Qos.Any()) { + @(cancelled ? "Fahrt fällt aus: " : "")@dep.Messages.Delay.Select(p => p.Text).Aggregate((s, s1) => $"{s}, {s1}") +++ @dep.Messages.Qos.Select(p => p.Text).Aggregate((s, s1) => $"{s} +++ {s1}") + } + else { + @(cancelled ? "Fahrt fällt aus: " : "")@dep.Messages.Delay.Select(p => p.Text).Aggregate((s, s1) => $"{s}, {s1}") + } + } + else if (dep.Messages.Qos.Any()) { + @(cancelled ? "Fahrt fällt aus: " : "")@dep.Messages.Qos.Select(p => p.Text).Aggregate((s, s1) => $"{s} +++ {s1}") + } + else { + @(dep.Via.Any() ? dep.Via.Aggregate((s, s1) => $"{s} - {s1}") : "") + } + @dep.Destination + + @if (delayed) { + @stringdelay + } + else if (undelayed) { + @stringdelay + } + @dep.Platform + + @if (delayed) { + @stringtime + } + else if (undelayed) { + @stringtime + } + else { + @stringtime + } +
  • + } +
+
+ + + \ No newline at end of file diff --git a/ZTravel.Web/Pages/Shared/_ValidationScriptsPartial.cshtml b/ZTravel.Web/Pages/Shared/_ValidationScriptsPartial.cshtml new file mode 100644 index 0000000..5a16d80 --- /dev/null +++ b/ZTravel.Web/Pages/Shared/_ValidationScriptsPartial.cshtml @@ -0,0 +1,2 @@ + + diff --git a/ZTravel.Web/Pages/Space.cshtml b/ZTravel.Web/Pages/Space.cshtml new file mode 100644 index 0000000..ff6db4d --- /dev/null +++ b/ZTravel.Web/Pages/Space.cshtml @@ -0,0 +1,59 @@ +@page +@using System.Globalization +@using ZTravel.API.VRRF + + + + + + Departures - ZTravel + + + + + +
+
    + @{ + var counter = 0; + } + @foreach (var dep in VrrfApi.GetDepartures("vrrf.finalrewind.org", "efa.SVV", "salzburg", "justizgebäude").Raw) { + if (int.Parse(dep.Line) >= 20) { + continue; + } + counter++; + var rawtime = DateTime.ParseExact($"{dep.Date} {dep.Time}", "dd.MM.yyyy HH:mm", CultureInfo.InvariantCulture); + var countdownRaw = rawtime - DateTime.Now; + var countdown = Math.Round(countdownRaw.TotalMinutes); + var time = countdown <= 60 ? $"{countdown} min" : dep.Time; + if (countdown <= 0) { + time = "now"; + } + if (countdown <= 5) { + continue; + } +
  • + @if (int.Parse(dep.Line) < 14) { +
    @dep.Line
    + } + else { +
    @dep.Line
    + } +
    @dep.Destination
    + + @time + +
  • + } +
+
+ + \ No newline at end of file diff --git a/ZTravel.Web/Pages/Weingarten.cshtml b/ZTravel.Web/Pages/Weingarten.cshtml new file mode 100644 index 0000000..7d44f35 --- /dev/null +++ b/ZTravel.Web/Pages/Weingarten.cshtml @@ -0,0 +1,38 @@ +@page + + + + + Departures - ZTravel + + + + + +
+ + + +
+ + + \ No newline at end of file diff --git a/ZTravel.Web/Pages/WeingartenBhf.cshtml b/ZTravel.Web/Pages/WeingartenBhf.cshtml new file mode 100644 index 0000000..901c87f --- /dev/null +++ b/ZTravel.Web/Pages/WeingartenBhf.cshtml @@ -0,0 +1,13 @@ +@page +@{ + Layout = "_LayoutFern"; + ViewData["title"] = "Weingarten(Baden)"; + ViewData["station"] = "Weingarten(Baden)"; + ViewData["stationId"] = "8006287"; + ViewData["via"] = ""; + ViewData["excludingVia"] = ""; + ViewData["offset"] = 0; + ViewData["andShowDestination"] = ""; + ViewData["fernverkehrOnly"] = false; + ViewData["onlyDepartures"] = false; +} \ No newline at end of file diff --git a/ZTravel.Web/Pages/_ViewImports.cshtml b/ZTravel.Web/Pages/_ViewImports.cshtml new file mode 100644 index 0000000..4ee1692 --- /dev/null +++ b/ZTravel.Web/Pages/_ViewImports.cshtml @@ -0,0 +1,3 @@ +@using ZTravel +@namespace ZTravel.Pages +@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers diff --git a/ZTravel.Web/Pages/_ViewStart.cshtml b/ZTravel.Web/Pages/_ViewStart.cshtml new file mode 100644 index 0000000..a5f1004 --- /dev/null +++ b/ZTravel.Web/Pages/_ViewStart.cshtml @@ -0,0 +1,3 @@ +@{ + Layout = "_Layout"; +} diff --git a/ZTravel.Web/Program.cs b/ZTravel.Web/Program.cs new file mode 100644 index 0000000..610d7d9 --- /dev/null +++ b/ZTravel.Web/Program.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Hosting; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using ZTravel.API.DBF; + +namespace ZTravel.Web { + public class Program { + public static Dictionary TypeMapping = + DbfTypeMapping.FromJson(new WebClient().DownloadString("https://raw.githubusercontent.com/derf/db-fakedisplay/master/share/ice_type.json")); + public static void Main(string[] args) { + CreateHostBuilder(args).Build().Run(); + } + + public static IHostBuilder CreateHostBuilder(string[] args) => + Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup(); }); + } +} \ No newline at end of file diff --git a/ZTravel.Web/Properties/launchSettings.json b/ZTravel.Web/Properties/launchSettings.json new file mode 100644 index 0000000..3702881 --- /dev/null +++ b/ZTravel.Web/Properties/launchSettings.json @@ -0,0 +1,27 @@ +{ + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:34118", + "sslPort": 44353 + } + }, + "profiles": { + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "ZTravel.Web": { + "commandName": "Project", + "launchBrowser": true, + "applicationUrl": "https://localhost:5001;http://localhost:5000", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/ZTravel.Web/Startup.cs b/ZTravel.Web/Startup.cs new file mode 100644 index 0000000..e1971e1 --- /dev/null +++ b/ZTravel.Web/Startup.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.HttpsPolicy; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; + +namespace ZTravel.Web { + public class Startup { + public Startup(IConfiguration configuration) { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) { + services.AddRazorPages(); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { + if (env.IsDevelopment()) { + app.UseDeveloperExceptionPage(); + } + else { + app.UseExceptionHandler("/Error"); + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseStaticFiles(); + + app.UseRouting(); + + app.UseAuthorization(); + + app.UseEndpoints(endpoints => { endpoints.MapRazorPages(); }); + } + } +} \ No newline at end of file diff --git a/ZTravel.Web/ZTravel.Web.csproj b/ZTravel.Web/ZTravel.Web.csproj new file mode 100644 index 0000000..9284b10 --- /dev/null +++ b/ZTravel.Web/ZTravel.Web.csproj @@ -0,0 +1,48 @@ + + + + netcoreapp3.1 + + + + + + + + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.css" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.css.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.min.css" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-grid.min.css.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.css" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.css.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.min.css" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap-reboot.min.css.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.css" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.css.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.min.css" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\css\bootstrap.min.css.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.js.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.min.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.bundle.min.js.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.js.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.min.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\dist\js\bootstrap.min.js.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\bootstrap\LICENSE" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation-unobtrusive\jquery.validate.unobtrusive.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation-unobtrusive\jquery.validate.unobtrusive.min.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation-unobtrusive\LICENSE.txt" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\additional-methods.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\additional-methods.min.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\jquery.validate.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\dist\jquery.validate.min.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery-validation\LICENSE.md" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery\dist\jquery.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery\dist\jquery.min.js" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery\dist\jquery.min.map" /> + <_ContentIncludedByDefault Remove="wwwroot\lib\jquery\LICENSE.txt" /> + + + + diff --git a/ZTravel.Web/appsettings.Development.json b/ZTravel.Web/appsettings.Development.json new file mode 100644 index 0000000..8983e0f --- /dev/null +++ b/ZTravel.Web/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + } +} diff --git a/ZTravel.Web/appsettings.json b/ZTravel.Web/appsettings.json new file mode 100644 index 0000000..d9d9a9b --- /dev/null +++ b/ZTravel.Web/appsettings.json @@ -0,0 +1,10 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft": "Warning", + "Microsoft.Hosting.Lifetime": "Information" + } + }, + "AllowedHosts": "*" +} diff --git a/ZTravel.Web/wwwroot/.DS_Store b/ZTravel.Web/wwwroot/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..6fd6cb19ffc8a8a063335aa50307d1cdeb66500a GIT binary patch literal 6148 zcmeHK%}N6?5T2-yoLt3Hkz3i+bpqLiL`f=)3gl#nR=!k2nIeFkns7D7XO#y)Nj8=gzxrD?d$Lv@QVS%uP0xgt1#b66Z ze{#R ul { + position:relative; + width:100%; + + list-style-type:none; + margin:0; + padding:0; +} + +div.app > ul > li { + min-height:7em; + display:block; + width:100%; + position:relative; +} + +div.appdark > ul > li { + border-bottom: 1px solid #999999; + background-color: #000000; +} + +div.applight > ul > li { + border-bottom: 1px solid #999999; + background-color: #ffffff; +} + +div.app li .line { + font-size: 2.7em; + position:absolute; + bottom:5px; + left:2px; + max-width: 6em; + max-height: 3ex; + overflow: hidden; +} + +div.app li .line .trainsubtype { + font-weight: normal; + font-size: 70%; + position: relative; + vertical-align: baseline; + top: -0.6ex; + left: -0.5ex; +} + +div.app li .line .trainno { + font-weight: normal; +} + +div.app li .line .trainno_sub { + font-weight: normal; + font-size: 0.6em; + text-align: center; + margin-top: -0.2em; +} + +div.app li .sbahn .trainno_sub { + font-weight: normal; + font-size: 0.5em; + text-align: center; + margin-top: -0.25em; +} + +div.app li .lineinfo { + color:#000000; + font-size: 2em; + position:absolute; + top:0px; + left:2px; +} + +div.app .replacement { + color: #006600; +} + +div.app .replaced { + color: #660000; +} + +div.app .sbahn { + font-weight:bold; + border-radius: 30px; + padding:3px 6px 2px 6px; +} + +div.applight .sbahn { + background-color:#95d79f; +} + +div.appdark .sbahn { + background-color:#115511; +} + +div.app .bahn, +div.app .fern, +div.app .ext { + font-weight:bold; + border-radius: 5px; + padding:3px 5px 2px 5px; +} + +div.applight .bahn { + background-color: #eeeeee; +} + +div.appdark .bahn { + background-color: #333333; +} + +div.applight .fern { + background-color: #ffdddd; +} + +div.appdark .fern { + background-color: #551111; +} + +div.applight .ext { + background-color: #ffdddd; + border: 2px solid #ff6666; +} + +div.appdark .ext { + background-color: #551111; + border: 2px solid #993333; +} + +div.app li .route { + background-color: transparent; + font-size:2.1em; + position:absolute; + top:1px; + left:8.2em; + height: 1.2em; + width: 70%; + overflow: hidden; +} + +div.applight li .route { + color:#444444; +} + +div.appdark li .route { + color:#bbbbbb; +} + +div.app li .info { + color:#ff0000; + background-color: transparent; + font-size:2.1em; + position:absolute; + top:1px; + left:8.2em; + height: 1.2em; + width: 70%; + overflow: hidden; +} + +div.app .moreinfo { + font-size:2.1em; + position:fixed; + left:0; + right:0; + bottom:0em; + z-index: 5; + overflow: auto; + cursor: default; +} + +div.app .moreinfo .mheader, +div.app .moreinfo .mfooter { + max-width: 50em; + margin-left: auto; + margin-right: auto; +} + +div.applight .moreinfo { + background-color: #ffffff; +} + +div.appdark .moreinfo { + background-color: #000000; +} + +div.app .collapsed-moreinfo { + display: none; +} + +div.app .expanded-moreinfo { + display: block; +} + +div.app .moreinfo .mheader { + text-align: center; + font-size: 120%; + padding-top: 0.5em; + padding-bottom: 0.5em; + padding-left: 1em; + padding-right: 1em; + border-bottom: 0.1em dashed #cccccc; +} + +div.app .moreinfo .mfooter { + padding-top: 1em; + padding-left: 1em; + padding-right: 1em; +} + +div.app .moreinfo .loading { + text-align: center; + width: 100%; + color: #888888; +} + +div.app .moreinfo .reason, +div.app .moreinfo .minfo { + color: #ff0000; +} + +div.app .moreinfo .verbose { + margin-bottom: 0.6em; +} + +div.app .moreinfo .timeinfo { + margin-bottom: 0.6em; +} + +div.applight .moreinfo .mroute .important-stop { + color: #000000; +} + +div.appdark .moreinfo .mroute .important-stop { + color: #ffffff; +} + +div.applight .moreinfo .mroute .generic-stop { + color: #555555; +} + +div.appdark .moreinfo .mroute .generic-stop { + color: #999999; +} + +div.applight .moreinfo .mroute .additional-stop { + color: #009900; +} + +div.appdark .moreinfo .mroute .additional-stop { + color: #009900; +} + +div.applight .moreinfo .mroute .cancelled-stop { + color: #cc0000; +} + +div.appdark .moreinfo .mroute .cancelled-stop { + color: #cc0000; +} + +div.app li .dest { + background-color: transparent; + font-size:4em; + position:absolute; + top:0.62em; + left:4.25em; + bottom:0px; + width: 70%; + overflow: hidden; +} + +div.applight li .dest { + color:#000000; +} + +div.appdark li .dest { + color:#ffffff; +} + +div.applight li.cancelled { + background-color: #ffe7d0; +} + +div.appdark li.cancelled { + background-color: #512f00; +} + +div.app li .countdown { + background-color: transparent; + font-size: 3em; + position: absolute; + right: 5px; + bottom: 2px; + padding-left: 0.2em; +} + +div.applight li .countdown { + color: #000000; +} + +div.appdark li .countdown { + color: #ffffff; +} + +div.app li .header { + color:#000000; + font-size:2em; + font-weight:bold; + padding-top:8px; + border-width-top:0; + display:block; + text-align:center; +} + +div.app li .head { + border-bottom-width:0; +} + +div.app li .countdown .delay { + font-size:1em; + color:#FF0000; + background-color: transparent; + padding-right:7px; +} + +div.app li .countdown .undelay { + font-size:1em; + color:#006600; + padding-right:7px; +} + +div.app li .countdown .delaynorm { + font-size:0.9em; + color:#BB3333; + padding-right:7px; +} + +div.app li .countdown .undelaynorm { + font-size:0.9em; + color:#338833; + padding-right:7px; +} + +div.app li .countdown .platform { + font-weight: bold; +} + +div.app li .countdown .changed-platform { + color:#ff0000; +} + +div.app li .time { + background-color: transparent; + font-size:2.3em; + position:absolute; + right:5px; + top:4px; + padding-left: 0.2em; +} + +div.applight li .time { + color:#000000; +} + +div.appdark li .time { + color:#ffffff; +} + +div.app span.delayed { + color: #ff0000; + background-color: transparent; +} + +div.app span.undelayed { + color:#006600; + background-color: transparent; +} + +ul.ui-autocomplete { + max-height: 20em; + overflow-x: hidden; + overflow-y: auto; +} + +div.geolocation { + text-align: center; +} + +div.candidatestatus { + text-align: center; + color: #999999; +} + +div.candidatelist a { + display: block; + text-decoration: none; + font-size: 1.4em; + padding-top: 0.3em; + text-align: center; + border-bottom: 1px solid #999999; +} + +div.candidatelist a .distance:after { + content: " km"; +} + +div.candidatelist a .distance { + font-size: 0.6em; + color: #999999; + padding-top: 0.2em; + padding-bottom: 0.3em; +} + +div.about { + margin-top: 2em; + font-family: Sans-Serif; + color: #666666; +} + +div.about a { + color: #000066; + text-decoration: none; +} + +.notice { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #bce8f1; + border-radius: 4px; + color: #31708f; + background-color: #d9edf7; + margin-left: auto; + margin-right: auto; +} + +.warning { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #faebcc; + border-radius: 4px; + color: #8a6d3b; + background-color: #fcf8e3; + margin-left: auto; + margin-right: auto; +} + +.error { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #ebccd1; + border-radius: 4px; + color: #a94442; + background-color: #f2dede; + margin-left: auto; + margin-right: auto; +} + +.error .errcode { + font-family: Monospace; + margin-top: 2em; + font-size: 100%; + color: #aaaaaa; +} + +.container { + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +pre { + margin-bottom: 2em; +} + +span.optional, +span.notes { + color: #666666; +} + +.moresettings-header { +} + +.moresettings-header-collapsed:before { + content: "â–¹ " +} + +.moresettings-header-expanded:before { + content: "â–¿ " +} + +.moresettings-collapsed { + display: none; +} + +.moresettings-expanded { + display: block; +} + +.developers-header { +} + +.developers-header-collapsed:before { + content: "â–¹ " +} + +.developers-header-expanded:before { + content: "â–¿ " +} + +.developers-collapsed { + display: none; +} + +.developers-expanded { + display: block; +} + +div.break { + height: 1em; +} + +div.field { + margin-top: 0.3em; + margin-bottom: 0.6em; +} + +input, select, .button { + display: inline-block; + width: 60em; + max-width: 100%; + min-height: 1.8em; + border-radius: 4px; + color: #000; + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075); + font-size: 90%; + text-align: center; + vertical-align: middle; +} + +input[type="text"] { + width: 59em; + padding-left: 0.5em; + padding-right: 0.5em; + text-align: left; + box-sizing: border-box; +} + +select { + min-height: 2em; +} + +input[type="checkbox"] { + width: 1.5em; + box-shadow: none; +} + +input[type="submit"], .button { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + box-shadow: none; + padding-top: 0.9ex; + padding-bottom: 0.9ex; +} + +.button { + padding-top: 1.1ex; + padding-bottom: 0; +} + +input[type="submit"]:active, +input[type="submit"]:focus, +input[type="submit"]:hover, +.button:active, +.button:focus, +.button:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} + +input[type="submit"]:active, +.button.active { + box-shadow: inset 0 3px 5px rgba(0,0,0,.125); +} + +.button-light { + color: #333; + background-color: #fff; + border-color: #ccc; +} + +.button-light:active, +.button-light:focus, +.button-light:hover +{ + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} + +div.notes { + margin-top: 2em; +} + +div.notes ul { + margin-top: 1em; +} +div.app { + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +.navbar-fixed { + position: relative; + z-index: 997; +} + +.navbar-fixed nav { + position: fixed; +} + +nav { + width: 100%; + overflow: hidden; +} + +nav .nav-wrapper { + position: relative; + height: 100%; +} + +nav i, nav i.material-icons { + display: block; + font-size: 24px; +} + +nav .brand-logo { + position: absolute; + display: inline-block; + padding-left: 0.5rem; + z-index: -1; +} + +nav ul { + margin: 0; + padding-left: 0; + list-style-type: none; +} + +nav ul li { + transition: background-color .3s; + float: left; + padding: 0; + list-style-type: none; + background-color: #00838f; +} + +nav ul a { + transition: background-color .3s; + font-size: 1rem; + color: #fff; + display: block; + padding: 0 15px; +} + +@media only screen and (max-width: 600px) { + div.app > ul > li { + font-size: 40%; + } + div.navbar-fixed { + height: 40px; + } + nav { + height: 40px; + line-height: 40px; + } + nav .brand-logo { + font-size: 1.5rem; + } + nav .nav-wrapper i { + height: 40px; + line-height: 40px; + } +} + +@media only screen and (min-width: 600px) { + div.app > ul > li { + font-size: 40%; + } + div.navbar-fixed { + height: 40px; + } + nav { + height: 40px; + line-height: 40px; + } + nav .brand-logo { + font-size: 1.5rem; + } + nav .nav-wrapper i { + height: 40px; + line-height: 40px; + } +} + +div.app .moreinfo { + font-size: 100%; +} + +.content { +} \ No newline at end of file diff --git a/ZTravel.Web/wwwroot/css/sbahn.css b/ZTravel.Web/wwwroot/css/sbahn.css new file mode 100644 index 0000000..919a6fb --- /dev/null +++ b/ZTravel.Web/wwwroot/css/sbahn.css @@ -0,0 +1,854 @@ +body { + margin: 0; +} + +html { + font-family: Sans-Serif; +} + +a { + color: #000099; + text-decoration: none; +} + +p, +div.about, +div.input-field, +div.notes { + max-width: 94%; + margin-left: auto; + margin-right: auto; +} + +p { + text-align: justify; +} + +div.content { + width: 100%; + margin: 0; +} + +.wagonorder { + position: relative; + width: 100%; + height: 100ex; +} + +.wagonorder .section { + position: absolute; + left: 1em; + width: 2em; + text-align: center; +} + +.wagonorder .wagon { + position: absolute; + left: 3em; + min-width: 6em; + border: 1px solid #999999; + padding-left: 0.2em; + padding-right: 0.2em; +} + +.wagonorder .wagon ~ .wagon { + border-top: none; +} + +.wagonorder .wagon .material-icons { + color: #666666; +} + +.wagonorder .wagon .direction { + position: absolute; + left: 0.2em; + bottom: 0; + right: 0; + text-align: center; + color: #666666; +} + +.wagonorder .nondestwagon { + border-style: dashed; +} + +.wagonorder .details { + position: absolute; + padding-top: 0.5ex; + left: 10em; + right: 0em; +} + +.wagonorder .details .type { + display: inline-block; + width: 5em; + color: #666666; +} + +.wagonorder .details .uicunknown { + color: #999999; +} + +.wagonorder .details .uicexchange { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uiccountry { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uic5 { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uic56 { + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uic78 { + margin-right: 0.2em; + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uic78::before { + content: "-"; +} + +.wagonorder .details .uictype { + margin-right: 0.2em; + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uicno { + color: #666666; +} + +.wagonorder .details .uiccheck { + color: #999999; +} + +.wagonorder .details .uiccheck::before { + content: "-"; +} + +div.app { + border-width:1px 2px; + width:100%; + margin-bottom: 5em; +} + +div.app > ul { + position:relative; + width:100%; + + list-style-type:none; + margin:0; + padding:0; +} + +div.app > ul > li { + min-height:7em; + display:block; + width:100%; + position:relative; +} + +div.appdark > ul > li { + border-bottom: 1px solid #999999; + background-color: #000000; +} + +div.applight > ul > li { + border-bottom: 1px solid #999999; + background-color: #ffffff; +} + +div.app li .line { + font-size: 2.7em; + position:absolute; + bottom:5px; + left:2px; + max-width: 6em; + max-height: 3ex; + overflow: hidden; +} + +div.app li .line .trainsubtype { + font-weight: normal; + font-size: 70%; + position: relative; + vertical-align: baseline; + top: -0.6ex; + left: -0.5ex; +} + +div.app li .line .trainno { + font-weight: normal; +} + +div.app li .line .trainno_sub { + font-weight: normal; + font-size: 0.6em; + text-align: center; + margin-top: -0.2em; +} + +div.app li .sbahn .trainno_sub { + font-weight: normal; + font-size: 0.5em; + text-align: center; + margin-top: -0.25em; +} + +div.app li .lineinfo { + color:#000000; + font-size: 2em; + position:absolute; + top:0px; + left:2px; +} + +div.app .replacement { + color: #006600; +} + +div.app .replaced { + color: #660000; +} + +div.app .sbahn { + font-weight:bold; + border-radius: 30px; + padding:3px 6px 2px 6px; +} + +div.applight .sbahn { + background-color:#95d79f; +} + +div.appdark .sbahn { + background-color:#115511; +} + +div.app .bahn, +div.app .fern, +div.app .ext { + font-weight:bold; + border-radius: 5px; + padding:3px 5px 2px 5px; +} + +div.applight .bahn { + background-color: #eeeeee; +} + +div.appdark .bahn { + background-color: #333333; +} + +div.applight .fern { + background-color: #ffdddd; +} + +div.appdark .fern { + background-color: #551111; +} + +div.applight .ext { + background-color: #ffdddd; + border: 2px solid #ff6666; +} + +div.appdark .ext { + background-color: #551111; + border: 2px solid #993333; +} + +div.app li .route { + background-color: transparent; + font-size:2.1em; + position:absolute; + top:1px; + left:4.25em; + height: 1.2em; + width: 70%; + overflow: hidden; +} + +div.applight li .route { + color:#444444; +} + +div.appdark li .route { + color:#bbbbbb; +} + +div.app li .info { + color:#ff0000; + background-color: transparent; + font-size:2.1em; + position:absolute; + top:1px; + left:8.2em; + height: 1.2em; + width: 70%; + overflow: hidden; +} + +div.app .moreinfo { + font-size:2.1em; + position:fixed; + left:0; + right:0; + bottom:0em; + z-index: 5; + overflow: auto; + cursor: default; +} + +div.app .moreinfo .mheader, +div.app .moreinfo .mfooter { + max-width: 50em; + margin-left: auto; + margin-right: auto; +} + +div.applight .moreinfo { + background-color: #ffffff; +} + +div.appdark .moreinfo { + background-color: #000000; +} + +div.app .collapsed-moreinfo { + display: none; +} + +div.app .expanded-moreinfo { + display: block; +} + +div.app .moreinfo .mheader { + text-align: center; + font-size: 120%; + padding-top: 0.5em; + padding-bottom: 0.5em; + padding-left: 1em; + padding-right: 1em; + border-bottom: 0.1em dashed #cccccc; +} + +div.app .moreinfo .mfooter { + padding-top: 1em; + padding-left: 1em; + padding-right: 1em; +} + +div.app .moreinfo .loading { + text-align: center; + width: 100%; + color: #888888; +} + +div.app .moreinfo .reason, +div.app .moreinfo .minfo { + color: #ff0000; +} + +div.app .moreinfo .verbose { + margin-bottom: 0.6em; +} + +div.app .moreinfo .timeinfo { + margin-bottom: 0.6em; +} + +div.applight .moreinfo .mroute .important-stop { + color: #000000; +} + +div.appdark .moreinfo .mroute .important-stop { + color: #ffffff; +} + +div.applight .moreinfo .mroute .generic-stop { + color: #555555; +} + +div.appdark .moreinfo .mroute .generic-stop { + color: #999999; +} + +div.applight .moreinfo .mroute .additional-stop { + color: #009900; +} + +div.appdark .moreinfo .mroute .additional-stop { + color: #009900; +} + +div.applight .moreinfo .mroute .cancelled-stop { + color: #cc0000; +} + +div.appdark .moreinfo .mroute .cancelled-stop { + color: #cc0000; +} + +div.app li .dest { + background-color: transparent; + font-size:4em; + position:absolute; + top:0.62em; + left:2.25em; + bottom:0px; + width: 70%; + overflow: hidden; +} + +div.applight li .dest { + color:#000000; +} + +div.appdark li .dest { + color:#ffffff; +} + +div.applight li.cancelled { + background-color: #ffe7d0; +} + +div.appdark li.cancelled { + background-color: #512f00; +} + +div.app li .countdown { + background-color: transparent; + font-size: 3em; + position: absolute; + right: 5px; + bottom: 2px; + padding-left: 0.2em; +} + +div.applight li .countdown { + color: #000000; +} + +div.appdark li .countdown { + color: #ffffff; +} + +div.app li .header { + color:#000000; + font-size:2em; + font-weight:bold; + padding-top:8px; + border-width-top:0; + display:block; + text-align:center; +} + +div.app li .head { + border-bottom-width:0; +} + +div.app li .countdown .delay { + font-size:1em; + color:#FF0000; + background-color: transparent; + padding-right:7px; +} + +div.app li .countdown .undelay { + font-size:1em; + color:#006600; + padding-right:7px; +} + +div.app li .countdown .delaynorm { + font-size:0.9em; + color:#BB3333; + padding-right:7px; +} + +div.app li .countdown .undelaynorm { + font-size:0.9em; + color:#338833; + padding-right:7px; +} + +div.app li .countdown .platform { + font-weight: bold; +} + +div.app li .countdown .changed-platform { + color:#ff0000; +} + +div.app li .time { + background-color: transparent; + font-size:2.3em; + position:absolute; + right:5px; + top:4px; + padding-left: 0.2em; +} + +div.applight li .time { + color:#000000; +} + +div.appdark li .time { + color:#ffffff; +} + +div.app span.delayed { + color: #ff0000; + background-color: transparent; +} + +ul.ui-autocomplete { + max-height: 20em; + overflow-x: hidden; + overflow-y: auto; +} + +div.geolocation { + text-align: center; +} + +div.candidatestatus { + text-align: center; + color: #999999; +} + +div.candidatelist a { + display: block; + text-decoration: none; + font-size: 1.4em; + padding-top: 0.3em; + text-align: center; + border-bottom: 1px solid #999999; +} + +div.candidatelist a .distance:after { + content: " km"; +} + +div.candidatelist a .distance { + font-size: 0.6em; + color: #999999; + padding-top: 0.2em; + padding-bottom: 0.3em; +} + +div.about { + margin-top: 2em; + font-family: Sans-Serif; + color: #666666; +} + +div.about a { + color: #000066; + text-decoration: none; +} + +.notice { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #bce8f1; + border-radius: 4px; + color: #31708f; + background-color: #d9edf7; + margin-left: auto; + margin-right: auto; +} + +.warning { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #faebcc; + border-radius: 4px; + color: #8a6d3b; + background-color: #fcf8e3; + margin-left: auto; + margin-right: auto; +} + +.error { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #ebccd1; + border-radius: 4px; + color: #a94442; + background-color: #f2dede; + margin-left: auto; + margin-right: auto; +} + +.error .errcode { + font-family: Monospace; + margin-top: 2em; + font-size: 100%; + color: #aaaaaa; +} + +.container { + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +pre { + margin-bottom: 2em; +} + +span.optional, +span.notes { + color: #666666; +} + +.moresettings-header { +} + +.moresettings-header-collapsed:before { + content: "â–¹ " +} + +.moresettings-header-expanded:before { + content: "â–¿ " +} + +.moresettings-collapsed { + display: none; +} + +.moresettings-expanded { + display: block; +} + +.developers-header { +} + +.developers-header-collapsed:before { + content: "â–¹ " +} + +.developers-header-expanded:before { + content: "â–¿ " +} + +.developers-collapsed { + display: none; +} + +.developers-expanded { + display: block; +} + +div.break { + height: 1em; +} + +div.field { + margin-top: 0.3em; + margin-bottom: 0.6em; +} + +input, select, .button { + display: inline-block; + width: 60em; + max-width: 100%; + min-height: 1.8em; + border-radius: 4px; + color: #000; + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075); + font-size: 90%; + text-align: center; + vertical-align: middle; +} + +input[type="text"] { + width: 59em; + padding-left: 0.5em; + padding-right: 0.5em; + text-align: left; + box-sizing: border-box; +} + +select { + min-height: 2em; +} + +input[type="checkbox"] { + width: 1.5em; + box-shadow: none; +} + +input[type="submit"], .button { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + box-shadow: none; + padding-top: 0.9ex; + padding-bottom: 0.9ex; +} + +.button { + padding-top: 1.1ex; + padding-bottom: 0; +} + +input[type="submit"]:active, +input[type="submit"]:focus, +input[type="submit"]:hover, +.button:active, +.button:focus, +.button:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} + +input[type="submit"]:active, +.button.active { + box-shadow: inset 0 3px 5px rgba(0,0,0,.125); +} + +.button-light { + color: #333; + background-color: #fff; + border-color: #ccc; +} + +.button-light:active, +.button-light:focus, +.button-light:hover +{ + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} + +div.notes { + margin-top: 2em; +} + +div.notes ul { + margin-top: 1em; +} +div.app { + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +.navbar-fixed { + position: relative; + z-index: 997; +} + +.navbar-fixed nav { + position: fixed; +} + +nav { + width: 100%; + overflow: hidden; +} + +nav .nav-wrapper { + position: relative; + height: 100%; +} + +nav i, nav i.material-icons { + display: block; + font-size: 24px; +} + +nav .brand-logo { + position: absolute; + display: inline-block; + padding-left: 0.5rem; + z-index: -1; +} + +nav ul { + margin: 0; + padding-left: 0; + list-style-type: none; +} + +nav ul li { + transition: background-color .3s; + float: left; + padding: 0; + list-style-type: none; + background-color: #00838f; +} + +nav ul a { + transition: background-color .3s; + font-size: 1rem; + color: #fff; + display: block; + padding: 0 15px; +} + +@media only screen and (max-width: 600px) { + div.app > ul > li { + font-size: 40%; + } + div.navbar-fixed { + height: 40px; + } + nav { + height: 40px; + line-height: 40px; + } + nav .brand-logo { + font-size: 1.5rem; + } + nav .nav-wrapper i { + height: 40px; + line-height: 40px; + } +} + +@media only screen and (min-width: 600px) { + div.app > ul > li { + font-size: 40%; + } + div.navbar-fixed { + height: 40px; + } + nav { + height: 40px; + line-height: 40px; + } + nav .brand-logo { + font-size: 1.5rem; + } + nav .nav-wrapper i { + height: 40px; + line-height: 40px; + } +} + +div.app .moreinfo { + font-size: 100%; +} + +.content { +} \ No newline at end of file diff --git a/ZTravel.Web/wwwroot/css/site.css b/ZTravel.Web/wwwroot/css/site.css new file mode 100644 index 0000000..fcbd421 --- /dev/null +++ b/ZTravel.Web/wwwroot/css/site.css @@ -0,0 +1,936 @@ +body { + margin: 0; +} + +html { + font-family: Sans-Serif; +} + +a { + color: #000099; + text-decoration: none; +} + +p, +div.about, +div.input-field, +div.notes { + max-width: 94%; + margin-left: auto; + margin-right: auto; +} + +p { + text-align: justify; +} + +div.content { + width: 100%; + margin: 0; +} + +.wagonorder { + position: relative; + width: 100%; + height: 100ex; +} + +.wagonorder .section { + position: absolute; + left: 1em; + width: 2em; + text-align: center; +} + +.wagonorder .wagon { + position: absolute; + left: 3em; + min-width: 6em; + border: 1px solid #999999; + padding-left: 0.2em; + padding-right: 0.2em; +} + +.wagonorder .wagon ~ .wagon { + border-top: none; +} + +.wagonorder .wagon .material-icons { + color: #666666; +} + +.wagonorder .wagon .direction { + position: absolute; + left: 0.2em; + bottom: 0; + right: 0; + text-align: center; + color: #666666; +} + +.wagonorder .nondestwagon { + border-style: dashed; +} + +.wagonorder .details { + position: absolute; + padding-top: 0.5ex; + left: 10em; + right: 0em; +} + +.wagonorder .details .type { + display: inline-block; + width: 5em; + color: #666666; +} + +.wagonorder .details .uicunknown { + color: #999999; +} + +.wagonorder .details .uicexchange { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uiccountry { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uic5 { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uic56 { + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uic78 { + margin-right: 0.2em; + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uic78::before { + content: "-"; +} + +.wagonorder .details .uictype { + margin-right: 0.2em; + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uicno { + color: #666666; +} + +.wagonorder .details .uiccheck { + color: #999999; +} + +.wagonorder .details .uiccheck::before { + content: "-"; +} + +div.app { + border-width:1px 2px; + width:100%; + margin-bottom: 5em; +} + +div.app > ul { + position:relative; + width:100%; + + list-style-type:none; + margin:0; + padding:0; +} + +div.app > ul > li { + min-height:7em; + display:block; + width:100%; + position:relative; +} + +div.appdark > ul > li { + border-bottom: 1px solid #999999; + background-color: #000000; +} + +div.applight > ul > li { + border-bottom: 1px solid #999999; + background-color: #ffffff; +} + +div.app li .line { + font-size: 2.7em; + position:absolute; + top:5px; + bottom:5px; + left:2px; + overflow: hidden; +} + +div.app li .line .trainsubtype { + font-weight: normal; + font-size: 70%; + position: relative; + vertical-align: baseline; + top: -0.6ex; + left: -0.5ex; +} + +div.app li .line .trainno { + font-weight: normal; +} + +div.app li .line .trainno_sub { + font-weight: normal; + font-size: 0.6em; + text-align: center; + margin-top: -0.2em; +} + +div.app li .sbahn .trainno_sub { + font-weight: normal; + font-size: 0.5em; + text-align: center; + margin-top: -0.25em; +} + +div.app li .lineinfo { + color:#000000; + font-size: 2em; + position:absolute; + top:0px; + left:2px; +} + +div.app .replacement { + color: #006600; +} + +div.app .replaced { + color: #660000; +} + +div.app .sbahn { + font-weight:bold; + border-radius: 30px; + height: 45% !important; + padding:3px 6px 2px 6px; +} + +div.applight .sbahn { + background-color:#95d79f; +} + +div.appdark .sbahn { + background-color:#115511; +} + +div.app .bahn, +div.app .fern, +div.app .ext { + font-weight:bold; + border-radius: 5px; + padding:3px 5px 2px 5px; +} + +div.app .bus { + font-weight:bold; + border-radius: 100%; + font-size: 14pt !important; + color: white; + background-color: rgb(125,44,140); + height: 35px !important; + width: 35px !important; + text-align: center; + line-height: 36px; +} + +div.app .obus { + font-weight:bold; + border-radius: 0; + height: 35px !important; + width: 35px !important; + text-align: center; + font-size: 18pt !important; + line-height: 35px; +} + +div.app .obus-line-1 { + background-color: rgb(238,33,42); + color: white; +} + +div.app .obus-line-2 { + background-color: rgb(46,116,183); + color: white; +} + +div.app .obus-line-3 { + background-color: rgb(140,101,38); + color: white; +} + +div.app .obus-line-4 { + background-color: rgb(248,205,14); + color: black; +} + +div.app .obus-line-5 { + background-color: rgb(77,192,235); + color: white; +} + +div.app .obus-line-6 { + background-color: rgb(132,191,63); + color: white; +} + +div.app .obus-line-7 { + background-color: rgb(64,167,163); + color: white; +} + +div.app .obus-line-8 { + background-color: rgb(244,150,30); + color: white; +} + +div.app .obus-line-9 { + background-color: rgb(119,42,145); + color: white; +} + +div.app .obus-line-10 { + background-color: rgb(247,181,152); + color: black; +} + +div.app .obus-line-12 { + background-color: rgb(173,221,215); + color: black; +} + +div.app .obus-line-14 { + background-color: rgb(197,222,155); + color: black; +} + +div.applight .bahn { + background-color: #eeeeee; +} + +div.appdark .bahn { + background-color: #333333; +} + +div.applight .fern { + background-color: #ffdddd; +} + +div.appdark .fern { + background-color: #551111; +} + +div.applight .ext { + background-color: #ffdddd; + border: 2px solid #ff6666; +} + +div.appdark .ext { + background-color: #551111; + border: 2px solid #993333; +} + +div.app li .route { + background-color: transparent; + font-size:2.1em; + position:absolute; + top:1px; + left:4.25em; + height: 1.2em; + width: 70%; + overflow: hidden; +} + +div.applight li .route { + color:#444444; +} + +div.appdark li .route { + color:#bbbbbb; +} + +div.app li .info { + color:#ff0000; + background-color: transparent; + font-size:2.1em; + position:absolute; + top:1px; + left:7.7em; + height: 1.2em; + width: 70%; + overflow: hidden; +} + +div.app .moreinfo { + font-size:2.1em; + position:fixed; + left:0; + right:0; + bottom:0em; + z-index: 5; + overflow: auto; + cursor: default; +} + +div.app .moreinfo .mheader, +div.app .moreinfo .mfooter { + max-width: 50em; + margin-left: auto; + margin-right: auto; +} + +div.applight .moreinfo { + background-color: #ffffff; +} + +div.appdark .moreinfo { + background-color: #000000; +} + +div.app .collapsed-moreinfo { + display: none; +} + +div.app .expanded-moreinfo { + display: block; +} + +div.app .moreinfo .mheader { + text-align: center; + font-size: 120%; + padding-top: 0.5em; + padding-bottom: 0.5em; + padding-left: 1em; + padding-right: 1em; + border-bottom: 0.1em dashed #cccccc; +} + +div.app .moreinfo .mfooter { + padding-top: 1em; + padding-left: 1em; + padding-right: 1em; +} + +div.app .moreinfo .loading { + text-align: center; + width: 100%; + color: #888888; +} + +div.app .moreinfo .reason, +div.app .moreinfo .minfo { + color: #ff0000; +} + +div.app .moreinfo .verbose { + margin-bottom: 0.6em; +} + +div.app .moreinfo .timeinfo { + margin-bottom: 0.6em; +} + +div.applight .moreinfo .mroute .important-stop { + color: #000000; +} + +div.appdark .moreinfo .mroute .important-stop { + color: #ffffff; +} + +div.applight .moreinfo .mroute .generic-stop { + color: #555555; +} + +div.appdark .moreinfo .mroute .generic-stop { + color: #999999; +} + +div.applight .moreinfo .mroute .additional-stop { + color: #009900; +} + +div.appdark .moreinfo .mroute .additional-stop { + color: #009900; +} + +div.applight .moreinfo .mroute .cancelled-stop { + color: #cc0000; +} + +div.appdark .moreinfo .mroute .cancelled-stop { + color: #cc0000; +} + +div.app li .dest { + background-color: transparent; + font-size:3.9em; + position:absolute; + top:0.62em; + left:2.25em; + bottom:0; + width: 70%; + overflow: hidden; +} + +div.applight li .dest { + color:#000000; +} + +div.appdark li .dest { + color:#ffffff; +} + +div.applight li.cancelled { + background-color: #ffe7d0; +} + +div.appdark li.cancelled { + background-color: #512f00; +} + +div.app li .countdown { + background-color: transparent; + font-size: 3em; + position: absolute; + right: 5px; + bottom: 2px; + padding-left: 0.2em; +} + +div.applight li .countdown { + color: #000000; +} + +div.appdark li .countdown { + color: #ffffff; +} + +div.app li .header { + color:#000000; + font-size:2em; + font-weight:bold; + padding-top:8px; + border-width-top:0; + display:block; + text-align:center; +} + +div.app li .head { + border-bottom-width:0; +} + +div.app li .countdown .delay { + font-size:1em; + color:#FF0000; + background-color: transparent; + padding-right:7px; +} + +div.app li .countdown .undelay { + font-size:1em; + color:#006600; + padding-right:7px; +} + +div.app li .countdown .delaynorm { + font-size:0.9em; + color:#BB3333; + padding-right:7px; +} + +div.app li .countdown .undelaynorm { + font-size:0.9em; + color:#338833; + padding-right:7px; +} + +div.app li .countdown .platform { + font-weight: bold; +} + +div.app li .countdown .changed-platform { + color:#ff0000; +} + +div.app li .time { + background-color: transparent; + font-size:2.3em; + position:absolute; + right:5px; + top:4px; + padding-left: 0.2em; +} + +div.applight li .time { + color:#000000; +} + +div.appdark li .time { + color:#ffffff; +} + +div.app span.delayed { + color: #ff0000; + background-color: transparent; +} + +ul.ui-autocomplete { + max-height: 20em; + overflow-x: hidden; + overflow-y: auto; +} + +div.geolocation { + text-align: center; +} + +div.candidatestatus { + text-align: center; + color: #999999; +} + +div.candidatelist a { + display: block; + text-decoration: none; + font-size: 1.4em; + padding-top: 0.3em; + text-align: center; + border-bottom: 1px solid #999999; +} + +div.candidatelist a .distance:after { + content: " km"; +} + +div.candidatelist a .distance { + font-size: 0.6em; + color: #999999; + padding-top: 0.2em; + padding-bottom: 0.3em; +} + +div.about { + margin-top: 2em; + font-family: Sans-Serif; + color: #666666; +} + +div.about a { + color: #000066; + text-decoration: none; +} + +.notice { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #bce8f1; + border-radius: 4px; + color: #31708f; + background-color: #d9edf7; + margin-left: auto; + margin-right: auto; +} + +.warning { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #faebcc; + border-radius: 4px; + color: #8a6d3b; + background-color: #fcf8e3; + margin-left: auto; + margin-right: auto; +} + +.error { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #ebccd1; + border-radius: 4px; + color: #a94442; + background-color: #f2dede; + margin-left: auto; + margin-right: auto; +} + +.error .errcode { + font-family: Monospace; + margin-top: 2em; + font-size: 100%; + color: #aaaaaa; +} + +.container { + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +pre { + margin-bottom: 2em; +} + +span.optional, +span.notes { + color: #666666; +} + +.moresettings-header { +} + +.moresettings-header-collapsed:before { + content: "â–¹ " +} + +.moresettings-header-expanded:before { + content: "â–¿ " +} + +.moresettings-collapsed { + display: none; +} + +.moresettings-expanded { + display: block; +} + +.developers-header { +} + +.developers-header-collapsed:before { + content: "â–¹ " +} + +.developers-header-expanded:before { + content: "â–¿ " +} + +.developers-collapsed { + display: none; +} + +.developers-expanded { + display: block; +} + +div.break { + height: 1em; +} + +div.field { + margin-top: 0.3em; + margin-bottom: 0.6em; +} + +input, select, .button { + display: inline-block; + width: 60em; + max-width: 100%; + min-height: 1.8em; + border-radius: 4px; + color: #000; + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075); + font-size: 90%; + text-align: center; + vertical-align: middle; +} + +input[type="text"] { + width: 59em; + padding-left: 0.5em; + padding-right: 0.5em; + text-align: left; + box-sizing: border-box; +} + +select { + min-height: 2em; +} + +input[type="checkbox"] { + width: 1.5em; + box-shadow: none; +} + +input[type="submit"], .button { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + box-shadow: none; + padding-top: 0.9ex; + padding-bottom: 0.9ex; +} + +.button { + padding-top: 1.1ex; + padding-bottom: 0; +} + +input[type="submit"]:active, +input[type="submit"]:focus, +input[type="submit"]:hover, +.button:active, +.button:focus, +.button:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} + +input[type="submit"]:active, +.button.active { + box-shadow: inset 0 3px 5px rgba(0,0,0,.125); +} + +.button-light { + color: #333; + background-color: #fff; + border-color: #ccc; +} + +.button-light:active, +.button-light:focus, +.button-light:hover +{ + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} + +div.notes { + margin-top: 2em; +} + +div.notes ul { + margin-top: 1em; +} +div.app { + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +.navbar-fixed { + position: relative; + z-index: 997; +} + +.navbar-fixed nav { + position: fixed; +} + +nav { + width: 100%; + overflow: hidden; +} + +nav .nav-wrapper { + position: relative; + height: 100%; +} + +nav i, nav i.material-icons { + display: block; + font-size: 12px; +} + +nav .brand-logo { + position: absolute; + display: inline-block; + padding-left: 0.5rem; + z-index: -1; +} + +nav ul { + margin: 0; + padding-left: 0; + list-style-type: none; +} + +nav ul li { + transition: background-color .3s; + float: left; + padding: 0; + list-style-type: none; + background-color: #00838f; +} + +nav ul a { + transition: background-color .3s; + font-size: 1rem; + color: #fff; + display: block; + padding: 0 15px; +} + +@media only screen and (max-width: 600px) { + div.app > ul > li { + font-size: 40%; + } + div.navbar-fixed { + height: 40px; + } + nav { + height: 40px; + line-height: 40px; + } + nav .brand-logo { + font-size: 1.5rem; + } + nav .nav-wrapper i { + height: 40px; + line-height: 40px; + } +} + +@media only screen and (min-width: 600px) { + div.app > ul > li { + font-size: 40%; + } + div.navbar-fixed { + height: 40px; + } + nav { + height: 40px; + line-height: 40px; + } + nav .brand-logo { + font-size: 1.5rem; + } + nav .nav-wrapper i { + height: 40px; + line-height: 40px; + } +} + +div.app .moreinfo { + font-size: 100%; +} + +.content { +} \ No newline at end of file diff --git a/ZTravel.Web/wwwroot/css/space.css b/ZTravel.Web/wwwroot/css/space.css new file mode 100644 index 0000000..5f9650f --- /dev/null +++ b/ZTravel.Web/wwwroot/css/space.css @@ -0,0 +1,957 @@ +@font-face { + font-family: VRRR; + src: url('/fonts/VRRR.ttf'); +} + +body { + margin: 0; + background-color: #000000; + zoom: 190%; +} + +html { + font-family: Sans-Serif; + overflow: hidden; +} + +a { + color: #000099; + text-decoration: none; +} + +p, +div.about, +div.input-field, +div.notes { + max-width: 94%; + margin-left: auto; + margin-right: auto; +} + +p { + text-align: justify; +} + +div.content { + width: 100%; + margin: 0; +} + +.wagonorder { + position: relative; + width: 100%; + height: 100ex; +} + +.wagonorder .section { + position: absolute; + left: 1em; + width: 2em; + text-align: center; +} + +.wagonorder .wagon { + position: absolute; + left: 3em; + min-width: 6em; + border: 1px solid #999999; + padding-left: 0.2em; + padding-right: 0.2em; +} + +.wagonorder .wagon ~ .wagon { + border-top: none; +} + +.wagonorder .wagon .material-icons { + color: #666666; +} + +.wagonorder .wagon .direction { + position: absolute; + left: 0.2em; + bottom: 0; + right: 0; + text-align: center; + color: #666666; +} + +.wagonorder .nondestwagon { + border-style: dashed; +} + +.wagonorder .details { + position: absolute; + padding-top: 0.5ex; + left: 10em; + right: 0em; +} + +.wagonorder .details .type { + display: inline-block; + width: 5em; + color: #666666; +} + +.wagonorder .details .uicunknown { + color: #999999; +} + +.wagonorder .details .uicexchange { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uiccountry { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uic5 { + margin-right: 0.2em; + color: #999999; +} + +.wagonorder .details .uic56 { + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uic78 { + margin-right: 0.2em; + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uic78::before { + content: "-"; +} + +.wagonorder .details .uictype { + margin-right: 0.2em; + color: #666666; + font-weight: bold; +} + +.wagonorder .details .uicno { + color: #666666; +} + +.wagonorder .details .uiccheck { + color: #999999; +} + +.wagonorder .details .uiccheck::before { + content: "-"; +} + +div.app { + border-width:1px 2px; + width:100%; + margin-bottom: 5em; +} + +div.app > ul { + position:relative; + width:100%; + + list-style-type:none; + margin:0; + padding:0; +} + +div.app > ul > li { + min-height:7em; + display:block; + width:100%; + position:relative; +} + +div.appdark > ul > li { + border-bottom: 1px solid #434343; + background-color: #000000; +} + +div.applight > ul > li { + border-bottom: 1px solid #999999; + background-color: #ffffff; +} + +div.app li .line { + font-size: 2.7em; + position:absolute; + top:5px; + bottom:5px; + left:2px; + overflow: hidden; + opacity: 85%; +} + +div.app li .line .trainsubtype { + font-weight: normal; + font-size: 70%; + position: relative; + vertical-align: baseline; + top: -0.6ex; + left: -0.5ex; +} + +div.app li .line .trainno { + font-weight: normal; +} + +div.app li .line .trainno_sub { + font-weight: normal; + font-size: 0.6em; + text-align: center; + margin-top: -0.2em; +} + +div.app li .sbahn .trainno_sub { + font-weight: normal; + font-size: 0.5em; + text-align: center; + margin-top: -0.25em; +} + +div.app li .lineinfo { + color:#000000; + font-size: 2em; + position:absolute; + top:0px; + left:2px; +} + +div.app .replacement { + color: #006600; +} + +div.app .replaced { + color: #660000; +} + +div.app .sbahn { + font-weight:bold; + border-radius: 15px; + height: 50% !important; + padding:3px 6px 2px 6px; + top:13px !important; +} + +div.applight .sbahn { + background-color:#95d79f; +} + +div.appdark .sbahn { + background-color:#115511; +} + +div.app .bahn, +div.app .fern, +div.app .ext { + font-weight:bold; + border-radius: 5px; + padding:3px 5px 2px 5px; +} + +div.app .bus { + font-weight:bold; + border-radius: 100%; + font-size: 14pt !important; + color: white; + background-color: rgb(125,44,140); + height: 35px !important; + width: 35px !important; + text-align: center; + line-height: 36px; +} + +div.app .obus { + opacity: 100% !important; + border-radius: 0; + height: 30px !important; + width: 30px !important; + margin-top: 3px; + margin-left: 5px; + text-align: right; + line-height: 30px; + font-size: 8.5em !important; + font-family: VRRR, sans-serif; + color: #f8d102; +} + +div.app .obus-line-1 { + background-color: rgb(238,33,42); + color: white; +} + +div.app .obus-line-2 { + background-color: rgb(46,116,183); + color: white; +} + +div.app .obus-line-3 { + background-color: rgb(140,101,38); + color: white; +} + +div.app .obus-line-4 { + background-color: rgb(248,205,14); + color: black; +} + +div.app .obus-line-5 { + background-color: rgb(77,192,235); + color: white; +} + +div.app .obus-line-6 { + background-color: rgb(132,191,63); + color: white; +} + +div.app .obus-line-7 { + background-color: rgb(64,167,163); + color: white; +} + +div.app .obus-line-8 { + background-color: rgb(225, 131, 29); + color: white; +} + +div.app .obus-line-9 { + background-color: rgb(119,42,145); + color: white; +} + +div.app .obus-line-10 { + background-color: rgb(247,181,152); + color: black; +} + +div.app .obus-line-12 { + background-color: rgb(173,221,215); + color: black; +} + +div.app .obus-line-14 { + background-color: rgb(197,222,155); + color: black; +} + +div.applight .bahn { + background-color: #eeeeee; +} + +div.appdark .bahn { + background-color: #333333; +} + +div.applight .fern { + background-color: #ffdddd; +} + +div.appdark .fern { + background-color: #551111; +} + +div.applight .ext { + background-color: #ffdddd; + border: 2px solid #ff6666; +} + +div.appdark .ext { + background-color: #551111; + border: 2px solid #993333; +} + +div.app li .route { + background-color: transparent; + font-size:2.1em; + position:absolute; + top:1px; + left:3.85em; + height: 1.2em; + width: 70%; + overflow: hidden; +} + +div.applight li .route { + color:#444444; +} + +div.appdark li .route { + color:#bbbbbb; +} + +div.app li .info { + color:#ff0000; + background-color: transparent; + font-size:2.1em; + position:absolute; + top:1px; + left:7.7em; + height: 1.2em; + width: 70%; + overflow: hidden; +} + +div.app .moreinfo { + font-size:2.1em; + position:fixed; + left:0; + right:0; + bottom:0em; + z-index: 5; + overflow: auto; + cursor: default; +} + +div.app .moreinfo .mheader, +div.app .moreinfo .mfooter { + max-width: 50em; + margin-left: auto; + margin-right: auto; +} + +div.applight .moreinfo { + background-color: #ffffff; +} + +div.appdark .moreinfo { + background-color: #000000; +} + +div.app .collapsed-moreinfo { + display: none; +} + +div.app .expanded-moreinfo { + display: block; +} + +div.app .moreinfo .mheader { + text-align: center; + font-size: 120%; + padding-top: 0.5em; + padding-bottom: 0.5em; + padding-left: 1em; + padding-right: 1em; + border-bottom: 0.1em dashed #cccccc; +} + +div.app .moreinfo .mfooter { + padding-top: 1em; + padding-left: 1em; + padding-right: 1em; +} + +div.app .moreinfo .loading { + text-align: center; + width: 100%; + color: #888888; +} + +div.app .moreinfo .reason, +div.app .moreinfo .minfo { + color: #ff0000; +} + +div.app .moreinfo .verbose { + margin-bottom: 0.6em; +} + +div.app .moreinfo .timeinfo { + margin-bottom: 0.6em; +} + +div.applight .moreinfo .mroute .important-stop { + color: #000000; +} + +div.appdark .moreinfo .mroute .important-stop { + color: #ffffff; +} + +div.applight .moreinfo .mroute .generic-stop { + color: #555555; +} + +div.appdark .moreinfo .mroute .generic-stop { + color: #999999; +} + +div.applight .moreinfo .mroute .additional-stop { + color: #009900; +} + +div.appdark .moreinfo .mroute .additional-stop { + color: #009900; +} + +div.applight .moreinfo .mroute .cancelled-stop { + color: #cc0000; +} + +div.appdark .moreinfo .mroute .cancelled-stop { + color: #cc0000; +} + +div.app li .dest { + background-color: transparent; + font-size:8.5em; + position:absolute; + left: 1em; + bottom: 3px; + width: 70%; + overflow: hidden; + font-family: VRRR, sans-serif !important; + color: #f8d102 !important; +} + +div.applight li .dest { + color:#000000; +} + +div.appdark li .dest { + color:#ffffff; +} + +div.applight li.cancelled { + background-color: #ffe7d0; +} + +div.appdark li.cancelled { + background-color: #512f00; +} + +div.app li .countdown { + background-color: transparent; + font-size: 8.5em; + position: absolute; + right: 5px; + bottom: 3px; + padding-left: 0.2em; + font-family: VRRR, sans-serif !important; +} + +div.applight li .countdown { + color: #000000; +} + +div.appdark li .countdown { + color: #ffffff; +} + +div.app li .header { + color:#000000; + font-size:2em; + font-weight:bold; + padding-top:8px; + border-width-top:0; + display:block; + text-align:center; +} + +div.app li .head { + border-bottom-width:0; +} + +div.app li .countdown .delay { + font-size:1em; + color:#FF0000; + background-color: transparent; + padding-right:7px; +} + +div.app li .countdown .undelay { + font-size:1em; + color:#006600; + padding-right:7px; +} + +div.app li .countdown .delaynorm { + font-size:0.9em; + color:#BB3333; + padding-right:7px; +} + +div.app li .countdown .undelaynorm { + font-size:0.9em; + color:#338833; + padding-right:7px; +} + +div.app li .countdown .platform { + font-weight: normal; + color: #f8d102; +} + +div.app li .countdown .changed-platform { + color:#ff0000; +} + +div.app li .time { + background-color: transparent; + font-size:2.3em; + position:absolute; + right:5px; + top:4px; + padding-left: 0.2em; +} + +div.applight li .time { + color:#000000; +} + +div.appdark li .time { + color:#ffffff; +} + +div.app span.delayed { + color: #ff0000; + background-color: transparent; +} + +ul.ui-autocomplete { + max-height: 20em; + overflow-x: hidden; + overflow-y: auto; +} + +div.geolocation { + text-align: center; +} + +div.candidatestatus { + text-align: center; + color: #999999; +} + +div.candidatelist a { + display: block; + text-decoration: none; + font-size: 1.4em; + padding-top: 0.3em; + text-align: center; + border-bottom: 1px solid #999999; +} + +div.candidatelist a .distance:after { + content: " km"; +} + +div.candidatelist a .distance { + font-size: 0.6em; + color: #999999; + padding-top: 0.2em; + padding-bottom: 0.3em; +} + +div.about { + margin-top: 2em; + font-family: Sans-Serif; + color: #666666; +} + +div.about a { + color: #000066; + text-decoration: none; +} + +.notice { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #bce8f1; + border-radius: 4px; + color: #31708f; + background-color: #d9edf7; + margin-left: auto; + margin-right: auto; +} + +.warning { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #faebcc; + border-radius: 4px; + color: #8a6d3b; + background-color: #fcf8e3; + margin-left: auto; + margin-right: auto; +} + +.error { + padding: 15px; + margin-bottom: 20px; + border: 1px solid #ebccd1; + border-radius: 4px; + color: #a94442; + background-color: #f2dede; + margin-left: auto; + margin-right: auto; +} + +.error .errcode { + font-family: Monospace; + margin-top: 2em; + font-size: 100%; + color: #aaaaaa; +} + +.container { + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +pre { + margin-bottom: 2em; +} + +span.optional, +span.notes { + color: #666666; +} + +.moresettings-header { +} + +.moresettings-header-collapsed:before { + content: "â–¹ " +} + +.moresettings-header-expanded:before { + content: "â–¿ " +} + +.moresettings-collapsed { + display: none; +} + +.moresettings-expanded { + display: block; +} + +.developers-header { +} + +.developers-header-collapsed:before { + content: "â–¹ " +} + +.developers-header-expanded:before { + content: "â–¿ " +} + +.developers-collapsed { + display: none; +} + +.developers-expanded { + display: block; +} + +div.break { + height: 1em; +} + +div.field { + margin-top: 0.3em; + margin-bottom: 0.6em; +} + +input, select, .button { + display: inline-block; + width: 60em; + max-width: 100%; + min-height: 1.8em; + border-radius: 4px; + color: #000; + background-color: #fff; + border: 1px solid #ccc; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075); + font-size: 90%; + text-align: center; + vertical-align: middle; +} + +input[type="text"] { + width: 59em; + padding-left: 0.5em; + padding-right: 0.5em; + text-align: left; + box-sizing: border-box; +} + +select { + min-height: 2em; +} + +input[type="checkbox"] { + width: 1.5em; + box-shadow: none; +} + +input[type="submit"], .button { + color: #fff; + background-color: #337ab7; + border-color: #2e6da4; + box-shadow: none; + padding-top: 0.9ex; + padding-bottom: 0.9ex; +} + +.button { + padding-top: 1.1ex; + padding-bottom: 0; +} + +input[type="submit"]:active, +input[type="submit"]:focus, +input[type="submit"]:hover, +.button:active, +.button:focus, +.button:hover { + color: #fff; + background-color: #286090; + border-color: #204d74; +} + +input[type="submit"]:active, +.button.active { + box-shadow: inset 0 3px 5px rgba(0,0,0,.125); +} + +.button-light { + color: #333; + background-color: #fff; + border-color: #ccc; +} + +.button-light:active, +.button-light:focus, +.button-light:hover +{ + color: #333; + background-color: #e6e6e6; + border-color: #adadad; +} + +div.notes { + margin-top: 2em; +} + +div.notes ul { + margin-top: 1em; +} +div.app { + max-width: 60em; + margin-left: auto; + margin-right: auto; +} + +.navbar-fixed { + position: relative; + z-index: 997; +} + +.navbar-fixed nav { + position: fixed; +} + +nav { + font-family: VRRR, sans-serif !important; +} + +nav { + width: 100%; + overflow: hidden; +} + +nav .nav-wrapper { + position: relative; + height: 100%; +} + +nav i, nav i.material-icons { + display: block; + font-size: 12px; +} + +nav .brand-logo { + position: absolute; + display: inline-block; + padding-left: 0.5rem; + z-index: -1; +} + +nav ul { + margin: 0; + padding-left: 0; + list-style-type: none; +} + +nav ul li { + transition: background-color .3s; + float: left; + padding: 0; + list-style-type: none; + background-color: #00838f; +} + +nav ul a { + transition: background-color .3s; + font-size: 1rem; + color: #fff; + display: block; + padding: 0 15px; +} + +@media only screen and (max-width: 600px) { + div.app > ul > li { + font-size: 40%; + } + div.navbar-fixed { + height: 35px; + } + nav { + height: 35px; + line-height: 35px; + } + nav .brand-logo { + font-size: 2.5rem; + } + nav .nav-wrapper i { + height: 35px; + line-height: 35px; + } +} + +@media only screen and (min-width: 600px) { + div.app > ul > li { + font-size: 40%; + } + div.navbar-fixed { + height: 35px; + } + nav { + height: 35px; + line-height: 35px; + } + nav .brand-logo { + font-size: 2.5rem; + } + nav .nav-wrapper i { + height: 35px; + line-height: 35px; + } +} + +div.app .moreinfo { + font-size: 100%; +} + +.content { +} \ No newline at end of file diff --git a/ZTravel.Web/wwwroot/favicon.ico b/ZTravel.Web/wwwroot/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..a3a799985c43bc7309d701b2cad129023377dc71 GIT binary patch literal 32038 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 literal 0 HcmV?d00001 diff --git a/ZTravel.Web/wwwroot/js/site.js b/ZTravel.Web/wwwroot/js/site.js new file mode 100644 index 0000000..3c76e6d --- /dev/null +++ b/ZTravel.Web/wwwroot/js/site.js @@ -0,0 +1,4 @@ +// Please see documentation at https://docs.microsoft.com/aspnet/core/client-side/bundling-and-minification +// for details on configuring this project to bundle and minify static web assets. + +// Write your Javascript code. diff --git a/ZTravel.sln b/ZTravel.sln new file mode 100644 index 0000000..39b6785 --- /dev/null +++ b/ZTravel.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZTravel.CLI", "ZTravel.CLI\ZTravel.CLI.csproj", "{80CE6E0D-EC94-43C8-BEED-FE122D101BF0}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZTravel.Web", "ZTravel.Web\ZTravel.Web.csproj", "{46DC5B3C-8A8B-489A-AF2F-F2915DC94E98}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZTravel.API", "ZTravel.API\ZTravel.API.csproj", "{A2C75A67-69D0-4942-9FC8-2F240002C8AC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {80CE6E0D-EC94-43C8-BEED-FE122D101BF0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {80CE6E0D-EC94-43C8-BEED-FE122D101BF0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {80CE6E0D-EC94-43C8-BEED-FE122D101BF0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {80CE6E0D-EC94-43C8-BEED-FE122D101BF0}.Release|Any CPU.Build.0 = Release|Any CPU + {46DC5B3C-8A8B-489A-AF2F-F2915DC94E98}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {46DC5B3C-8A8B-489A-AF2F-F2915DC94E98}.Debug|Any CPU.Build.0 = Debug|Any CPU + {46DC5B3C-8A8B-489A-AF2F-F2915DC94E98}.Release|Any CPU.ActiveCfg = Release|Any CPU + {46DC5B3C-8A8B-489A-AF2F-F2915DC94E98}.Release|Any CPU.Build.0 = Release|Any CPU + {A2C75A67-69D0-4942-9FC8-2F240002C8AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A2C75A67-69D0-4942-9FC8-2F240002C8AC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A2C75A67-69D0-4942-9FC8-2F240002C8AC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A2C75A67-69D0-4942-9FC8-2F240002C8AC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection +EndGlobal