From 759f802281f4d1a16aa11b99bb320b35bc2fe983 Mon Sep 17 00:00:00 2001 From: Tobias Sebring Date: Fri, 29 Dec 2017 23:09:24 +0100 Subject: [PATCH 01/15] Initial --- ArkBot.Tests/ArkBot.Tests.csproj | 1 + ArkBot/ArkBot.csproj | 47 ++- ArkBot/Commands/Admin/AdminCommand.cs | 102 +++--- ArkBot/Commands/Experimental/DebugCommand.cs | 4 +- ArkBot/Commands/ServersCommand.cs | 13 +- ArkBot/Commands/UnlinkSteamCommand.cs | 2 +- ArkBot/Commands/WebAppCommand.cs | 37 +++ ArkBot/Config.cs | 223 +++++++++---- ArkBot/Configuration/DirectoryPathEditor.cs | 59 ++++ .../Configuration/MyCustomTypeDescriptor.cs | 313 ++++++++++++++++++ .../Validation/DirectoryExistsAttribute.cs | 37 +++ .../Validation/ValidUrlAttribute.cs | 32 ++ .../Validation/ValidationTemplate.cs | 81 +++++ ArkBot/Controls/Configuration.xaml | 95 ++++++ ArkBot/Controls/Configuration.xaml.cs | 29 ++ ArkBot/Discord/ArkDiscordBot.cs | 12 +- .../RoleRestrictedPreconditionAttribute.cs | 15 +- ArkBot/Discord/DiscordManager.cs | 2 +- ArkBot/FodyWeavers.xml | 3 +- ArkBot/IConfig.cs | 14 +- ArkBot/Layout/PaneStyleSelector.cs | 3 + ArkBot/Layout/PaneTemplateSelector.cs | 3 + ArkBot/MainWindow.xaml | 18 + ArkBot/Properties/AssemblyInfo.cs | 4 +- .../ScheduledTasks/ScheduledTasksManager.cs | 16 +- ArkBot/Services/ArkServerService.cs | 2 +- ArkBot/Steam/SteamManager.cs | 16 +- ArkBot/ViewModel/ConfigurationViewModel.cs | 28 ++ ArkBot/ViewModel/Workspace.cs | 120 ++++--- ArkBot/Voting/VotingManager.cs | 8 +- .../WebApi/Controllers/BaseApiController.cs | 5 +- .../WebApi/Controllers/ServersController.cs | 2 +- ArkBot/WebApi/Model/AccessControlViewModel.cs | 2 +- ArkBot/defaultconfig.json | 32 +- ArkBot/packages.config | 3 +- 35 files changed, 1112 insertions(+), 271 deletions(-) create mode 100644 ArkBot/Commands/WebAppCommand.cs create mode 100644 ArkBot/Configuration/DirectoryPathEditor.cs create mode 100644 ArkBot/Configuration/MyCustomTypeDescriptor.cs create mode 100644 ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs create mode 100644 ArkBot/Configuration/Validation/ValidUrlAttribute.cs create mode 100644 ArkBot/Configuration/Validation/ValidationTemplate.cs create mode 100644 ArkBot/Controls/Configuration.xaml create mode 100644 ArkBot/Controls/Configuration.xaml.cs create mode 100644 ArkBot/ViewModel/ConfigurationViewModel.cs diff --git a/ArkBot.Tests/ArkBot.Tests.csproj b/ArkBot.Tests/ArkBot.Tests.csproj index b2ca838..a387ccd 100644 --- a/ArkBot.Tests/ArkBot.Tests.csproj +++ b/ArkBot.Tests/ArkBot.Tests.csproj @@ -25,6 +25,7 @@ DEBUG;TRACE prompt 4 + x64 pdbonly diff --git a/ArkBot/ArkBot.csproj b/ArkBot/ArkBot.csproj index 4599f18..2817a38 100644 --- a/ArkBot/ArkBot.csproj +++ b/ArkBot/ArkBot.csproj @@ -466,6 +466,9 @@ ..\packages\System.Xml.ReaderWriter.4.3.0\lib\net46\System.Xml.ReaderWriter.dll True + + ..\packages\Validar.Fody.1.6.0.0\lib\net452\Validar.dll + ..\packages\VDS.Common.1.6.0\lib\net40-client\VDS.Common.dll True @@ -475,29 +478,23 @@ True - - ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.AvalonDock.dll - True + + ..\packages\Extended.Wpf.Toolkit.3.2.0\lib\net40\Xceed.Wpf.AvalonDock.dll - - ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll - True + + ..\packages\Extended.Wpf.Toolkit.3.2.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.Aero.dll - - ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll - True + + ..\packages\Extended.Wpf.Toolkit.3.2.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.Metro.dll - - ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll - True + + ..\packages\Extended.Wpf.Toolkit.3.2.0\lib\net40\Xceed.Wpf.AvalonDock.Themes.VS2010.dll - - ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.DataGrid.dll - True + + ..\packages\Extended.Wpf.Toolkit.3.2.0\lib\net40\Xceed.Wpf.DataGrid.dll - - ..\packages\Extended.Wpf.Toolkit.2.9\lib\net40\Xceed.Wpf.Toolkit.dll - True + + ..\packages\Extended.Wpf.Toolkit.3.2.0\lib\net40\Xceed.Wpf.Toolkit.dll ..\packages\Zlib.Portable.Signed.1.11.0\lib\portable-net4+sl5+wp8+win8+wpa81+MonoTouch+MonoAndroid\Zlib.Portable.dll @@ -530,9 +527,18 @@ + + + + + + + + Configuration.xaml + @@ -666,6 +672,7 @@ + @@ -801,6 +808,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + MSBuild:Compile Designer diff --git a/ArkBot/Commands/Admin/AdminCommand.cs b/ArkBot/Commands/Admin/AdminCommand.cs index be4d417..e65d7ba 100644 --- a/ArkBot/Commands/Admin/AdminCommand.cs +++ b/ArkBot/Commands/Admin/AdminCommand.cs @@ -65,8 +65,8 @@ public AdminCommand( "** BanPlayer **: Ban a player", "** UnbanPlayer **: Unban a player", "** KillPlayer **: Kill a player", - "** SetVotingAllowed true/false**: Set voting allowed/disallowed for a player", - "** EnableVoting true/false**: Enable voting system", + //"** SetVotingAllowed true/false**: Set voting allowed/disallowed for a player", + //"** EnableVoting true/false**: Enable voting system", "** DoExit**: Shutdown server", "** Broadcast **: Broadcast a message to all players on the server", "** ListPlayers**: List all connected players and their SteamIDs", @@ -121,8 +121,8 @@ public async Task Admin([Remainder] string arguments = null) SteamId = 0L, SaveWorld = false, DestroyWildDinos = false, - EnableVoting = false, - SetVotingAllowed = 0L, //steam id + //EnableVoting = false, + //SetVotingAllowed = 0L, //steam id KickPlayer = 0L, //steam id BanPlayer = 0L, //steam id UnbanPlayer = 0L, //steam id @@ -160,7 +160,7 @@ public async Task Admin([Remainder] string arguments = null) .For(y => y.Backups, flag: true) .For(y => y.SaveWorld, flag: true) .For(y => y.DestroyWildDinos, flag: true) - .For(y => y.EnableVoting, flag: true) + //.For(y => y.EnableVoting, flag: true) .For(y => y.DoExit, flag: true) .For(y => y.ListPlayers, flag: true) .For(y => y.Broadcast, untilNextToken: true) @@ -396,54 +396,54 @@ public async Task Admin([Remainder] string arguments = null) if (result == null) sb.AppendLine($"**Failed to kick player with steamid {args.KickPlayer}... :(**"); else sb.AppendLine($"**Kicked player with steamid {args.KickPlayer}!**"); } - else if (args.EnableVoting) - { - if (!(args.True || args.False)) - { - sb.AppendLine($"**This command requires additional arguments!**"); - } - else - { - using (var context = _databaseContextFactory.Create()) - { - _savedstate.VotingDisabled = !args.True; - _savedstate.Save(); - sb.AppendLine($"**Voting system is now {(_savedstate.VotingDisabled ? "disabled" : "enabled")}!**"); - } - } + //else if (args.EnableVoting) + //{ + // if (!(args.True || args.False)) + // { + // sb.AppendLine($"**This command requires additional arguments!**"); + // } + // else + // { + // using (var context = _databaseContextFactory.Create()) + // { + // _savedstate.VotingDisabled = !args.True; + // _savedstate.Save(); + // sb.AppendLine($"**Voting system is now {(_savedstate.VotingDisabled ? "disabled" : "enabled")}!**"); + // } + // } - //var result = await CommandHelper.SendRconCommand(_config, $"kickplayer {args.KickPlayer}"); - //if (result == null) sb.AppendLine($"**Failed to kick player with steamid {args.KickPlayer}... :(**"); - //else sb.AppendLine($"**Kicked player with steamid {args.KickPlayer}!**"); - } - else if (args.SetVotingAllowed > 0) - { - if (!(args.True || args.False)) - { - sb.AppendLine($"**This command requires additional arguments!**"); - } - else - { - using (var context = _databaseContextFactory.Create()) - { - var user = context.Users.FirstOrDefault(x => x != null && x.DiscordId == (long)Context.User.Id); - if (user != null) - { - user.DisallowVoting = !args.True; - context.SaveChanges(); - sb.AppendLine($"**The user is now {(user.DisallowVoting ? "unable" : "allowed")} to vote!**"); - } - else - { - sb.AppendLine($"**The user is not linked!**"); - } - } - } + // //var result = await CommandHelper.SendRconCommand(_config, $"kickplayer {args.KickPlayer}"); + // //if (result == null) sb.AppendLine($"**Failed to kick player with steamid {args.KickPlayer}... :(**"); + // //else sb.AppendLine($"**Kicked player with steamid {args.KickPlayer}!**"); + //} + //else if (args.SetVotingAllowed > 0) + //{ + // if (!(args.True || args.False)) + // { + // sb.AppendLine($"**This command requires additional arguments!**"); + // } + // else + // { + // using (var context = _databaseContextFactory.Create()) + // { + // var user = context.Users.FirstOrDefault(x => x != null && x.DiscordId == (long)Context.User.Id); + // if (user != null) + // { + // user.DisallowVoting = !args.True; + // context.SaveChanges(); + // sb.AppendLine($"**The user is now {(user.DisallowVoting ? "unable" : "allowed")} to vote!**"); + // } + // else + // { + // sb.AppendLine($"**The user is not linked!**"); + // } + // } + // } - //var result = await CommandHelper.SendRconCommand(_config, $"kickplayer {args.KickPlayer}"); - //if (result == null) sb.AppendLine($"**Failed to kick player with steamid {args.KickPlayer}... :(**"); - //else sb.AppendLine($"**Kicked player with steamid {args.KickPlayer}!**"); - } + // //var result = await CommandHelper.SendRconCommand(_config, $"kickplayer {args.KickPlayer}"); + // //if (result == null) sb.AppendLine($"**Failed to kick player with steamid {args.KickPlayer}... :(**"); + // //else sb.AppendLine($"**Kicked player with steamid {args.KickPlayer}!**"); + //} else if (args.BanPlayer > 0) { var result = await serverContext.Steam.SendRconCommand($"ban {args.BanPlayer}"); diff --git a/ArkBot/Commands/Experimental/DebugCommand.cs b/ArkBot/Commands/Experimental/DebugCommand.cs index 3d6920e..8630148 100644 --- a/ArkBot/Commands/Experimental/DebugCommand.cs +++ b/ArkBot/Commands/Experimental/DebugCommand.cs @@ -104,7 +104,7 @@ public async Task Debug([Remainder] string arguments = null) } else if (args.json) { - if (_config.DisableDeveloperFetchSaveData) + if (_config.Discord.DisableDeveloperFetchSaveData) { await Context.Channel.SendMessageAsync("The administrator have disabled this featurContext."); return; @@ -197,7 +197,7 @@ public async Task Debug([Remainder] string arguments = null) } else if (args.save) { - if (_config.DisableDeveloperFetchSaveData) + if (_config.Discord.DisableDeveloperFetchSaveData) { await Context.Channel.SendMessageAsync("The administrator have disabled this featurContext."); return; diff --git a/ArkBot/Commands/ServersCommand.cs b/ArkBot/Commands/ServersCommand.cs index 557e008..3314018 100644 --- a/ArkBot/Commands/ServersCommand.cs +++ b/ArkBot/Commands/ServersCommand.cs @@ -36,8 +36,8 @@ public async Task Servers([Remainder] string arguments = null) if (_config.Servers != null) { - var sb = new StringBuilder(); - sb.AppendLine("**Server List**"); + var embed = new EmbedBuilder(); + embed.WithTitle("Server List"); foreach (var server in _config.Servers) { @@ -51,15 +51,14 @@ public async Task Servers([Remainder] string arguments = null) name = m.Success ? m.Groups["name"].Value : info.Name; } - var address = $"{server.Ip}:{server.Port}"; + var address = server.DisplayAddress ?? $"{server.Ip}:{server.QueryPort}"; - var cluster = args.cluster || args.clusters ? $" (cluster **{server.Cluster}**)" : ""; + var cluster = args.cluster || args.clusters ? $" (cluster **`{server.Cluster}`**)" : ""; - sb.AppendLine( - $"● **{name ?? address}**{(name != null ? $" ({address})" : "")} (key: **{server.Key}**){cluster}"); + embed.AddInlineField($"{ name ?? address}", $"steam://connect/{address} (key: `{server.Key}`){cluster}"); } - await CommandHelper.SendPartitioned(Context.Channel, sb.ToString()); + await Context.Channel.SendMessageAsync("", false, embed.Build()); } else { diff --git a/ArkBot/Commands/UnlinkSteamCommand.cs b/ArkBot/Commands/UnlinkSteamCommand.cs index 931013b..3546f3a 100644 --- a/ArkBot/Commands/UnlinkSteamCommand.cs +++ b/ArkBot/Commands/UnlinkSteamCommand.cs @@ -46,7 +46,7 @@ public async Task UnlinkSteam() try { var duser = server.GetUser(Context.User.Id); - var role = server.Roles.FirstOrDefault(x => x.Name.Equals(_config.MemberRoleName)); + var role = server.Roles.FirstOrDefault(x => x.Name.Equals(_config.Discord.MemberRoleName)); if (duser != null && role == null) continue; if (duser?.Roles.Any(x => x.Id == role.Id) == true) await duser.RemoveRoleAsync(role); diff --git a/ArkBot/Commands/WebAppCommand.cs b/ArkBot/Commands/WebAppCommand.cs new file mode 100644 index 0000000..ef73ec4 --- /dev/null +++ b/ArkBot/Commands/WebAppCommand.cs @@ -0,0 +1,37 @@ +using System; +using System.Text; +using System.Threading.Tasks; +using Discord.Commands; +using ArkBot.Helpers; +using System.Reflection; +using ArkBot.Discord.Command; + +namespace ArkBot.Commands +{ + public class WebAppCommand : ModuleBase + { + private IConfig _config; + + public WebAppCommand(IConfig config) + { + _config = config; + } + + [Command("webapp")] + [Alias("app", "companionapp")] + [Summary("Get a link to the Companion App (Web App)")] + [RoleRestrictedPrecondition("webapp")] + public async Task WebApp() + { + var sb = new StringBuilder(); + if (string.IsNullOrWhiteSpace(_config.AppUrl)) + sb.AppendLine("**The setting `appUrl` is missing from the configuration...**"); + else + { + sb.AppendLine("**Companion App (Web App)**"); + sb.AppendLine($"{_config.AppUrl}"); + } + await CommandHelper.SendPartitioned(Context.Channel, sb.ToString()); + } + } +} diff --git a/ArkBot/Config.cs b/ArkBot/Config.cs index 7b42fad..e81537c 100644 --- a/ArkBot/Config.cs +++ b/ArkBot/Config.cs @@ -1,13 +1,36 @@ using Newtonsoft.Json; using System; +using System.Collections; using System.Collections.Generic; using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; namespace ArkBot { + internal static class ConfigurationCategory + { + /// + /// Settings that must be changed + /// + internal const string UserSettings = "User Settings"; + /// + /// Settings that are either optional or may be left at default + /// + internal const string Optional = "Optional"; + } + + [AddINotifyPropertyChangedInterface] + [InjectValidation] public class Config : IConfig { public Config() @@ -18,104 +41,85 @@ public Config() ArkMultipliers = new ArkMultipliersConfigSection(); Servers = new ServerConfigSection[] { }; Clusters = new ClusterConfigSection[] { }; - DiscordBotEnabled = true; WebAppRedirectListenPrefix = new string[] { }; - AccessControl = new Dictionary>(); + AccessControl = new AccessControlConfigSection(); Discord = new DiscordConfigSection(); } - [JsonProperty(PropertyName = "botId")] - [Description("Simple non-whitespace or special character ID to identify the bot (A-Za-z0-9)")] - public string BotId { get; set; } + // Optional [JsonProperty(PropertyName = "botName")] + [DisplayName("Bot Name")] [Description("Short name to identify the bot")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(0)] + [MinLength(1, ErrorMessage = "{0} is not set")] public string BotName { get; set; } - [JsonProperty(PropertyName = "botNamespace")] - [Description("Unique namespace url given to the bot (may be same as botUrl)")] - public string BotNamespace { get; set; } - [JsonProperty(PropertyName = "botUrl")] - [Description("Website url associated with the bot or ARK server (optional).")] + [DisplayName("Bot URL")] + [Description("Website url associated with the bot or ARK server (optional)")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(1)] + [ValidUrl(Optional = true, ErrorMessage = "{0} is not a valid URL")] public string BotUrl { get; set; } [JsonProperty(PropertyName = "appUrl")] - [Description("External url pointing to the Web App (optional).")] + [DisplayName("Web App URL")] + [Description("External url pointing to the Web App (optional)")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(2)] + [ValidUrl(Optional = true, ErrorMessage = "{0} is not a valid URL")] public string AppUrl { get; set; } - [JsonProperty(PropertyName = "tempFileOutputDirPath")] - [Description("An existing directory path where temporary binary files can be stored (map-images etc.)")] - public string TempFileOutputDirPath { get; set; } - - [JsonProperty(PropertyName = "botToken")] - [Description("Bot authentication token from https://discordapp.com/developers")] - public string BotToken { get; set; } - - [JsonProperty(PropertyName = "steamOpenIdRelyingServiceListenPrefix")] - [Description("Http listen prefix for Steam OpenID Relying Party webservice (requires a port that is open to external connections)")] - public string SteamOpenIdRelyingServiceListenPrefix { get; set; } - - [JsonProperty(PropertyName = "steamOpenIdRedirectUri")] - [Description("Publicly accessible url for incoming Steam OpenID Relying Party webservice connections (requires a port that is open to external connections)")] - public string SteamOpenIdRedirectUri { get; set; } - - [JsonProperty(PropertyName = "googleApiKey")] - [Description("Google API key used for url-shortening services.")] - public string GoogleApiKey { get; set; } - - [JsonProperty(PropertyName = "steamApiKey")] - [Description("Steam API key used for fetching user information.")] - public string SteamApiKey { get; set; } - [JsonProperty(PropertyName = "arkMultipliers")] - [Description("Server specific multipliers.")] + [DisplayName("ARK Multipliers")] + [Description("Server specific multipliers")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(3)] + [Required(ErrorMessage = "{0} is not set")] public ArkMultipliersConfigSection ArkMultipliers { get; set; } - [JsonProperty(PropertyName = "disableDeveloperFetchSaveData")] - [Description("Diable users in \"developer\"-role fetching json or save file data.")] - public bool DisableDeveloperFetchSaveData { get; set; } - - [JsonProperty(PropertyName = "memberRoleName")] - [Description("The name of the member role in Discord.")] - public string MemberRoleName { get; set; } - [JsonProperty(PropertyName = "discord")] - [Description("Discord bot settings.")] + [DisplayName("Discord")] + [Description("Discord bot settings")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(4)] + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] public DiscordConfigSection Discord { get; set; } [JsonProperty(PropertyName = "userRoles")] - [Description("Explicit steam user role assignment.")] + [DisplayName("User Roles")] + [Description("Explicit steam user role assignment")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(5)] + [Required(ErrorMessage = "{0} is not set")] public Dictionary UserRoles { get; set; } [JsonProperty(PropertyName = "accessControl")] - [Description("Per-feature role based access control configuration.")] - public Dictionary> AccessControl { get; set; } - - [JsonProperty(PropertyName = "enabledChannels")] - [Description("A list of channels where the bot will listen to and answer commands.")] - public string[] EnabledChannels { get; set; } - - [JsonProperty(PropertyName = "infoTopicChannel")] - [Description("Channel where topic is set to display information about last update, next update and how to use bot commands.")] - public string InfoTopicChannel { get; set; } - - [JsonProperty(PropertyName = "announcementChannel")] - [Description("Channel where announcements are made (votes etc.)")] - public string AnnouncementChannel { get; set; } + [DisplayName("Access Control")] + [Description("Per-feature role based access control configuration")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(6)] + [Required(ErrorMessage = "{0} is not set")] + public AccessControlConfigSection AccessControl { get; set; } [JsonProperty(PropertyName = "backupsEnabled")] - [Description("Option to enable savegame backups.")] + [DisplayName("Backups Enabled")] + [Description("Option to enable savegame backups")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(7)] public bool BackupsEnabled { get; set; } [JsonProperty(PropertyName = "backupsDirectoryPath")] - [Description("Directory path where savegame backups are stored.")] + [DisplayName("Backups Directory Path")] + [Description("Directory path where savegame backups are stored")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(8)] + [DirectoryExists(IfMethod = nameof(IsBackupsEnabled), ErrorMessage = "{0} directory path does not exist")] public string BackupsDirectoryPath { get; set; } - [JsonProperty(PropertyName = "discordBotEnabled")] - [Description("Option to enable/disable the discord bot component.")] - public bool DiscordBotEnabled { get; set; } - [JsonProperty(PropertyName = "webApiListenPrefix")] [Description("Http listen prefix for WebAPI service (requires a port that is open to external connections) [The prebuilt web-app included in this release is by default configured to call the web api on 127.0.0.1:60001. If you want to use another port for the web api you will need to reflect this change in environment.prod.ts and rebuild the web-app dist manually.]")] public string WebApiListenPrefix { get; set; } @@ -138,6 +142,7 @@ public Config() [JsonProperty(PropertyName = "ssl")] [Description("Configure Web App and WebAPI to use SSL with a free certificate from Lets Encrypt")] + [ExpandableObject] public SslConfigSection Ssl { get; set; } [JsonProperty(PropertyName = "savegameExtractionMaxDegreeOfParallelism")] @@ -155,20 +160,97 @@ public Config() [JsonProperty(PropertyName = "clusters")] [Description("Cluster instance configurations.")] public ClusterConfigSection[] Clusters { get; set; } + + + // Required + + [JsonProperty(PropertyName = "tempFileOutputDirPath")] + [DisplayName("Temporary file output directory path")] + [Description("An existing directory path where temporary binary files can be stored (map-images etc.)")] + [Category(ConfigurationCategory.UserSettings)] + [PropertyOrder(0)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryExists(ErrorMessage = "{0} is not set or the directory path does not exist")] + public string TempFileOutputDirPath { get; set; } + + [JsonProperty(PropertyName = "googleApiKey")] + [DisplayName("Google API Key")] + [Description("Google API Key used for url-shortening services")] + [Category(ConfigurationCategory.UserSettings)] + [PropertyOrder(1)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate google api key with google + public string GoogleApiKey { get; set; } + + [JsonProperty(PropertyName = "steamApiKey")] + [DisplayName("Steam API Key")] + [Description("Steam API Key used for fetching user information")] + [Category(ConfigurationCategory.UserSettings)] + [PropertyOrder(2)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate steam api key with steam + public string SteamApiKey { get; set; } + + + // Validation methods + + private bool IsBackupsEnabled() + { + return BackupsEnabled; + } } + [AddINotifyPropertyChangedInterface] public class DiscordConfigSection { public DiscordConfigSection() { + DiscordBotEnabled = true; AccessControl = new Dictionary>(); } + [JsonProperty(PropertyName = "discordBotEnabled")] + [Description("Option to enable/disable the discord bot component.")] + public bool DiscordBotEnabled { get; set; } + + [JsonProperty(PropertyName = "botToken")] + [Description("Bot authentication token from https://discordapp.com/developers")] + public string BotToken { get; set; } + + [JsonProperty(PropertyName = "enabledChannels")] + [Description("A list of channels where the bot will listen to and answer commands.")] + public string[] EnabledChannels { get; set; } + + [JsonProperty(PropertyName = "infoTopicChannel")] + [Description("Channel where topic is set to display information about last update, next update and how to use bot commands.")] + public string InfoTopicChannel { get; set; } + + [JsonProperty(PropertyName = "announcementChannel")] + [Description("Channel where announcements are made (votes etc.)")] + public string AnnouncementChannel { get; set; } + + [JsonProperty(PropertyName = "memberRoleName")] + [Description("The name of the member role in Discord.")] + public string MemberRoleName { get; set; } + + [JsonProperty(PropertyName = "disableDeveloperFetchSaveData")] + [Description("Diable users in \"developer\"-role fetching json or save file data.")] + public bool DisableDeveloperFetchSaveData { get; set; } + [JsonProperty(PropertyName = "accessControl")] [Description("Per-feature role based access control configuration.")] public Dictionary> AccessControl { get; set; } + + [JsonProperty(PropertyName = "steamOpenIdRelyingServiceListenPrefix")] + [Description("Http listen prefix for Steam OpenID Relying Party webservice (requires a port that is open to external connections)")] + public string SteamOpenIdRelyingServiceListenPrefix { get; set; } + + [JsonProperty(PropertyName = "steamOpenIdRedirectUri")] + [Description("Publicly accessible url for incoming Steam OpenID Relying Party webservice connections (requires a port that is open to external connections)")] + public string SteamOpenIdRedirectUri { get; set; } } + [AddINotifyPropertyChangedInterface] public class SslConfigSection { public SslConfigSection() @@ -209,6 +291,7 @@ public SslConfigSection() public bool UseCompatibilityNonSNIBindings { get; set; } } + [AddINotifyPropertyChangedInterface] public class ArkMultipliersConfigSection { public ArkMultipliersConfigSection() @@ -231,6 +314,7 @@ public ArkMultipliersConfigSection() public double CuddleIntervalMultiplier { get; set; } } + [AddINotifyPropertyChangedInterface] public class ServerConfigSection { public ServerConfigSection() @@ -257,9 +341,9 @@ public ServerConfigSection() [Description("The IP address used to connect to this server instance.")] public string Ip { get; set; } - [JsonProperty(PropertyName = "port")] - [Description("The port used to connect to this server instance.")] - public int Port { get; set; } + [JsonProperty(PropertyName = "queryPort")] + [Description("The port used to query to this server instance.")] + public int QueryPort { get; set; } [JsonProperty(PropertyName = "rconPort")] [Description("The port used to connect to this server instance over rcon.")] @@ -303,6 +387,7 @@ public ServerConfigSection() } + [AddINotifyPropertyChangedInterface] public class ClusterConfigSection { public ClusterConfigSection() diff --git a/ArkBot/Configuration/DirectoryPathEditor.cs b/ArkBot/Configuration/DirectoryPathEditor.cs new file mode 100644 index 0000000..c4434fa --- /dev/null +++ b/ArkBot/Configuration/DirectoryPathEditor.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using Xceed.Wpf.Toolkit.PropertyGrid; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration +{ + public class DirectoryPathEditor : ITypeEditor + { + public FrameworkElement ResolveEditor(PropertyItem propertyItem) + { + Grid panel = new Grid(); + panel.ColumnDefinitions.Add(new ColumnDefinition()); + panel.ColumnDefinitions.Add(new ColumnDefinition() + { + Width = GridLength.Auto + }); + + TextBox textBox = new TextBox(); + textBox.HorizontalAlignment = HorizontalAlignment.Stretch; + Binding binding = new Binding("Value"); //bind to the Value property of the PropertyItem + binding.Source = propertyItem; + binding.Mode = BindingMode.TwoWay; + BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding); + + Button button = new Button(); + button.Content = "..."; + button.Tag = propertyItem; + button.Click += button_Click; + Grid.SetColumn(button, 1); + + panel.Children.Add(textBox); + panel.Children.Add(button); + + return panel; + } + + private void button_Click(object sender, RoutedEventArgs e) + { + PropertyItem item = ((Button)sender).Tag as PropertyItem; + if (null == item) + { + return; + } + + using (var dialog = new System.Windows.Forms.FolderBrowserDialog()) + { + System.Windows.Forms.DialogResult result = dialog.ShowDialog(); + item.Value = dialog.SelectedPath; + } + } + } +} diff --git a/ArkBot/Configuration/MyCustomTypeDescriptor.cs b/ArkBot/Configuration/MyCustomTypeDescriptor.cs new file mode 100644 index 0000000..24f9a65 --- /dev/null +++ b/ArkBot/Configuration/MyCustomTypeDescriptor.cs @@ -0,0 +1,313 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using System.ComponentModel; +using System.Reflection; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Media; +using Xceed.Wpf.Toolkit; +using Xceed.Wpf.Toolkit.PropertyGrid; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration +{ + [ReadOnly(true)] + [TypeConverter(typeof(MyCustomTypeDescriptor))] + [ExpandableObject] + public class AccessControlConfigSection : Dictionary + { + + } + + [TypeConverter(typeof(MyCustomTypeDescriptor2>))] + [ExpandableObject] + public class AccessControlFeatureGroup : Dictionary> + { + + } + + public class StringArrayEditorWithPreview : PrimitiveTypeCollectionEditor2 + { + protected override void SetControlProperties(PropertyItem propertyItem) + { + base.SetControlProperties(propertyItem); + Editor.Content = null; + } + + public override FrameworkElement ResolveEditor(PropertyItem propertyItem) + { + var editor = base.ResolveEditor(propertyItem); + return editor; + } + } + + public class PrimitiveTypeCollectionEditor2 : TypeEditor + { + protected override void SetControlProperties(PropertyItem propertyItem) + { + Editor.BorderThickness = new System.Windows.Thickness(0); + } + + protected override void SetValueDependencyProperty() + { + ValueProperty = PrimitiveTypeCollectionControl2.ItemsSourceProperty; + } + + protected override void ResolveValueBinding(PropertyItem propertyItem) + { + var type = propertyItem.PropertyType; + Editor.ItemsSourceType = type; + + if (type.BaseType == typeof(System.Array)) + { + Editor.ItemType = type.GetElementType(); + } + else + { + var typeArguments = type.GetGenericArguments(); + if (typeArguments.Length > 0) + { + Editor.ItemType = typeArguments[0]; + } + } + + base.ResolveValueBinding(propertyItem); + } + } + + public class PrimitiveTypeCollectionControl2 : PrimitiveTypeCollectionControl + { + protected override void OnTextChanged(string oldValue, string newValue) + { + base.OnTextChanged(oldValue, newValue); + Content = newValue?.Replace("\r\n", "; "); + } + } + + public class MyCustomTypeDescriptor : ExpandableObjectConverter + { + public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) + { + if (value is IDictionary) + { + IDictionary list = value as IDictionary; + PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null); + + var num = 0; + foreach (var kv in list) + { + propDescriptions.Add(new ListItemPropertyDescriptor(list, kv.Key, num++)); + } + //IEnumerator enumerator = list.GetEnumerator(); + //int counter = -1; + //while (enumerator.MoveNext()) + //{ + // counter++; + + + //} + return propDescriptions; + } + else + { + return base.GetProperties(context, value, attributes); + } + } + } + + public class ListItemPropertyDescriptor : PropertyDescriptor + { + private readonly IDictionary owner; + private readonly T index; + private readonly int order; + + public ListItemPropertyDescriptor(IDictionary owner, T index, int order) : base("[" + index + "]", null) + { + this.owner = owner; + this.index = index; + this.order = order; + } + + public override AttributeCollection Attributes + { + get + { + var attributes = TypeDescriptor.GetAttributes(GetValue(null), false); + //If the Xceed expandable object attribute is not applied then apply it + //if (!attributes.OfType().Any()) + //{ + // attributes = AddAttribute(new ExpandableObjectAttribute(), attributes); + //} + + //set the xceed order attribute + attributes = AddAttribute(new DisplayNameAttribute(index.ToString()), attributes); + attributes = AddAttribute(new PropertyOrderAttribute(order), attributes); + + return attributes; + } + } + private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes) + { + Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1]; + oldAttributes.CopyTo(newAttributes, 1); + newAttributes[0] = newAttribute; + + return new AttributeCollection(newAttributes); + } + + public override bool CanResetValue(object component) + { + return false; + } + + public override object GetValue(object component) + { + return Value; + } + + private T2 Value + => owner[index]; + + public override void ResetValue(object component) + { + throw new NotImplementedException(); + } + + public override void SetValue(object component, object value) + { + owner[index] = (T2)value; + } + + public override bool ShouldSerializeValue(object component) + { + return false; + } + + public override Type ComponentType + => owner.GetType(); + + public override bool IsReadOnly + => true; + + public override Type PropertyType + => Value?.GetType(); + + } + + public class MyCustomTypeDescriptor2 : ExpandableObjectConverter + { + public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) + { + if (value is IDictionary) + { + IDictionary list = value as IDictionary; + PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null); + + var num = 0; + foreach (var kv in list) + { + propDescriptions.Add(new ListItemPropertyDescriptor2(list, kv.Key, num++)); + } + //IEnumerator enumerator = list.GetEnumerator(); + //int counter = -1; + //while (enumerator.MoveNext()) + //{ + // counter++; + + + //} + return propDescriptions; + } + else + { + return base.GetProperties(context, value, attributes); + } + } + } + + public class ListItemPropertyDescriptor2 : PropertyDescriptor + { + private readonly IDictionary owner; + private readonly T index; + private readonly int order; + + public ListItemPropertyDescriptor2(IDictionary owner, T index, int order) : base("[" + index + "]", null) + { + this.owner = owner; + this.index = index; + this.order = order; + } + + public override AttributeCollection Attributes + { + get + { + var attributes = TypeDescriptor.GetAttributes(GetValue(null), false); + //If the Xceed expandable object attribute is not applied then apply it + //if (!attributes.OfType().Any()) + //{ + // attributes = AddAttribute(new ExpandableObjectAttribute(), attributes); + //} + + //set the xceed order attribute + attributes = AddAttribute(new DisplayNameAttribute(index.ToString()), attributes); + attributes = AddAttribute(new PropertyOrderAttribute(order), attributes); + attributes = AddAttribute(new EditorAttribute(typeof(StringArrayEditorWithPreview), typeof(StringArrayEditorWithPreview)), attributes); + + return attributes; + } + } + private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes) + { + Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1]; + oldAttributes.CopyTo(newAttributes, 1); + newAttributes[0] = newAttribute; + + return new AttributeCollection(newAttributes); + } + + public override bool CanResetValue(object component) + { + return false; + } + + public override object GetValue(object component) + { + return Value; + } + + private T2 Value + => owner[index]; + + public override void ResetValue(object component) + { + throw new NotImplementedException(); + } + + public override void SetValue(object component, object value) + { + owner[index] = (T2)value; + } + + public override bool ShouldSerializeValue(object component) + { + return false; + } + + public override Type ComponentType + => owner.GetType(); + + public override bool IsReadOnly + => false; + + public override Type PropertyType + => Value?.GetType(); + + } +} diff --git a/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs b/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs new file mode 100644 index 0000000..e3b99fd --- /dev/null +++ b/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class DirectoryExistsAttribute : ValidationAttribute + { + public string IfMethod { get; set; } + + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + if (IfMethod != null) + { + var ifMethodInfo = validationContext.ObjectType.GetMethod(IfMethod, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + if (ifMethodInfo == null) + return new ValidationResult( + $"IfMethod '{validationContext.ObjectType.Name}.{IfMethod}' could not be found!", new[] { validationContext.MemberName }); + + if (!(bool) ifMethodInfo.Invoke(validationContext.ObjectInstance, null)) + return ValidationResult.Success; + } + + return !string.IsNullOrWhiteSpace(value as string) && Directory.Exists((string) value) + ? ValidationResult.Success + : new ValidationResult(String.Format(CultureInfo.CurrentCulture, ErrorMessageString, + validationContext.MemberName), new [] { validationContext.MemberName }); + } + } +} diff --git a/ArkBot/Configuration/Validation/ValidUrlAttribute.cs b/ArkBot/Configuration/Validation/ValidUrlAttribute.cs new file mode 100644 index 0000000..ccf09b2 --- /dev/null +++ b/ArkBot/Configuration/Validation/ValidUrlAttribute.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RazorEngine.Compilation.ImpromptuInterface.InvokeExt; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class ValidUrlAttribute : ValidationAttribute + { + public bool Optional { get; set; } + + public override bool IsValid(object value) + { + if (!(value is string)) return false; + if (Optional && string.IsNullOrEmpty((string) value)) return true; + + return Uri.TryCreate((string) value, UriKind.Absolute, out var uriResult) && + (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps); + } + + public override string FormatErrorMessage(string name) + { + return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name); + } + } +} diff --git a/ArkBot/Configuration/Validation/ValidationTemplate.cs b/ArkBot/Configuration/Validation/ValidationTemplate.cs new file mode 100644 index 0000000..a40dc61 --- /dev/null +++ b/ArkBot/Configuration/Validation/ValidationTemplate.cs @@ -0,0 +1,81 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ArkBot.Configuration.Validation +{ + public class ValidationTemplate : /*IDataErrorInfo,*/ INotifyDataErrorInfo + { + private readonly INotifyPropertyChanged _target; + readonly ValidationContext _validationContext; + readonly List _validationResults; + + public ValidationTemplate(INotifyPropertyChanged target) + { + this._target = target; + _validationContext = new ValidationContext(target, null, null); + _validationResults = new List(); + Validator.TryValidateObject(target, _validationContext, _validationResults, true); + target.PropertyChanged += Validate; + } + + void Validate(object sender, PropertyChangedEventArgs e) + { + var oldErrors = new HashSet(_validationResults.SelectMany(x => x.MemberNames)); + _validationResults.Clear(); + Validator.TryValidateObject(_target, _validationContext, _validationResults, true); + var hashSet = new HashSet(_validationResults.SelectMany(x => x.MemberNames)); + foreach (var error in hashSet) + { + RaiseErrorsChanged(error); + } + foreach (var noerror in oldErrors.Except(hashSet)) + { + RaiseErrorsChanged(noerror); + } + } + + public IEnumerable GetErrors(string propertyName) + { + return _validationResults.Where(x => x.MemberNames.Contains(propertyName)) + .Select(x => x.ErrorMessage); + } + + public bool HasErrors => _validationResults.Count > 0; + + public string Error + { + get + { + var strings = _validationResults.Select(x => x.ErrorMessage) + .ToArray(); + return string.Join(Environment.NewLine, strings); + } + } + + public string this[string propertyName] + { + get + { + var strings = _validationResults.Where(x => x.MemberNames.Contains(propertyName)) + .Select(x => x.ErrorMessage) + .ToArray(); + return string.Join(Environment.NewLine, strings); + } + } + + public event EventHandler ErrorsChanged; + + void RaiseErrorsChanged(string propertyName) + { + Debug.WriteLine($"Errors changed raised for '{propertyName}'"); + ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName)); + } + } +} diff --git a/ArkBot/Controls/Configuration.xaml b/ArkBot/Controls/Configuration.xaml new file mode 100644 index 0000000..85328d0 --- /dev/null +++ b/ArkBot/Controls/Configuration.xaml @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ArkBot/Controls/Configuration.xaml.cs b/ArkBot/Controls/Configuration.xaml.cs new file mode 100644 index 0000000..cd0de13 --- /dev/null +++ b/ArkBot/Controls/Configuration.xaml.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace ArkBot.Controls +{ + /// + /// Interaction logic for Configuration.xaml + /// + public partial class Configuration : UserControl + { + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register("Model", typeof(Config), typeof(Configuration), new FrameworkPropertyMetadata()); + + public Config Model + { + get { return GetValue(ModelProperty) as Config; } + set { SetValue(ModelProperty, value); } + } + + public Configuration() + { + InitializeComponent(); + } + } +} diff --git a/ArkBot/Discord/ArkDiscordBot.cs b/ArkBot/Discord/ArkDiscordBot.cs index 2971d8e..ea11f87 100644 --- a/ArkBot/Discord/ArkDiscordBot.cs +++ b/ArkBot/Discord/ArkDiscordBot.cs @@ -86,12 +86,12 @@ public ArkDiscordBot( private async Task DiscordOnGuildAvailable(SocketGuild socketGuild) { - if (_wasRestarted && socketGuild != null && !string.IsNullOrWhiteSpace(_config.AnnouncementChannel) && !_wasRestartedServersNotified.Contains(socketGuild.Id)) + if (_wasRestarted && socketGuild != null && !string.IsNullOrWhiteSpace(_config.Discord.AnnouncementChannel) && !_wasRestartedServersNotified.Contains(socketGuild.Id)) { try { _wasRestartedServersNotified.Add(socketGuild.Id); - var channel = socketGuild.TextChannels.FirstOrDefault(y => _config.AnnouncementChannel.Equals(y.Name, StringComparison.OrdinalIgnoreCase)); + var channel = socketGuild.TextChannels.FirstOrDefault(y => _config.Discord.AnnouncementChannel.Equals(y.Name, StringComparison.OrdinalIgnoreCase)); if (channel != null) await channel.SendMessageAsync("**I have automatically restarted due to previous unexpected shutdown!**"); } catch (Exception ex) { /*ignore exceptions */ } @@ -132,8 +132,8 @@ private async Task HandleCommandAsync(SocketMessage messageParam) //check if command is allowed in this channel if(!(context.Channel is ISocketPrivateChannel) - && _config.EnabledChannels?.Length > 0 - && !_config.EnabledChannels.Contains(context.Channel.Name, StringComparer.OrdinalIgnoreCase)) + && _config.Discord.EnabledChannels?.Length > 0 + && !_config.Discord.EnabledChannels.Contains(context.Channel.Name, StringComparer.OrdinalIgnoreCase)) { return; } @@ -141,6 +141,8 @@ private async Task HandleCommandAsync(SocketMessage messageParam) var preconditions = await cm.CheckPreconditionsAsync(context, _serviceProvider); if (!preconditions.IsSuccess) { + if (preconditions.ErrorReason?.Equals(RoleRestrictedPreconditionAttribute.CommandDisabledErrorString) == true) return; + Logging.Log( $"Command precondition(s) failed [command name: {iCommand.Name}, preconditions error: {preconditions.ErrorReason}]", GetType(), LogLevel.DEBUG); @@ -395,7 +397,7 @@ public async Task Initialize(CancellationToken token, bool skipExtract = false) public async Task Start(ArkSpeciesAliases aliases = null) { - await _discord.LoginAsync(TokenType.Bot, _config.BotToken); + await _discord.LoginAsync(TokenType.Bot, _config.Discord.BotToken); await _discord.StartAsync(); //await _discord.Connect(_config.BotToken, TokenType.Bot); diff --git a/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs b/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs index 8eea0f2..be1eacb 100644 --- a/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs +++ b/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs @@ -10,6 +10,8 @@ namespace ArkBot.Discord.Command { public class RoleRestrictedPreconditionAttribute : PreconditionAttribute { + internal const string CommandDisabledErrorString = "Command disabled"; + public string AccessControlName { get; set; } public RoleRestrictedPreconditionAttribute(string accessControlName) @@ -42,12 +44,12 @@ public override async Task CheckPermissions(ICommandContext roles = roles.Distinct().ToList(); - var hasFeatureAccess = - HasFeatureAccess(config, "commands", AccessControlName, roles.ToArray()); - if (!hasFeatureAccess) + var froles = GetFeatureRoles(config, "commands", AccessControlName); + if (!(froles?.Length > 0)) return PreconditionResult.FromError(CommandDisabledErrorString); + if (!HasFeatureAccess(froles, roles.ToArray())) return PreconditionResult.FromError("The user does not have access to this command!"); - var croles = GetFeatureRoles(config, "commands", AccessControlName)?.Intersect(roles).ToArray() ?? + var croles = froles?.Intersect(roles).ToArray() ?? new string[] { }; var proles = GetFeatureRoles(config, "channels", @@ -65,10 +67,9 @@ public override async Task CheckPermissions(ICommandContext } } - private bool HasFeatureAccess(IConfig config, string featureGroup, string featureName, string[] roles) + private bool HasFeatureAccess(string[] featureRoles, string[] userRoles) { - var rf = GetFeatureRoles(config, featureGroup, featureName); - return rf != null && rf.Intersect(roles, StringComparer.OrdinalIgnoreCase).Any(); + return featureRoles != null && featureRoles.Intersect(userRoles, StringComparer.OrdinalIgnoreCase).Any(); } private string[] GetFeatureRoles(IConfig config, string featureGroup, string featureName) diff --git a/ArkBot/Discord/DiscordManager.cs b/ArkBot/Discord/DiscordManager.cs index b225f5c..ec8d796 100644 --- a/ArkBot/Discord/DiscordManager.cs +++ b/ArkBot/Discord/DiscordManager.cs @@ -36,7 +36,7 @@ public async Task SendTextMessageToChannelNameOnAllServers(string channelName, s public async Task EditChannelByNameOnAllServers(string infoTopicChannel, string name = null, string topic = null, int? position = null) { - var channels = _discord.Guilds.Select(x => x.TextChannels.FirstOrDefault(y => _config.InfoTopicChannel.Equals(y.Name, StringComparison.OrdinalIgnoreCase))).Where(x => x != null); + var channels = _discord.Guilds.Select(x => x.TextChannels.FirstOrDefault(y => _config.Discord.InfoTopicChannel.Equals(y.Name, StringComparison.OrdinalIgnoreCase))).Where(x => x != null); foreach (var channel in channels) { await channel.ModifyAsync(g => diff --git a/ArkBot/FodyWeavers.xml b/ArkBot/FodyWeavers.xml index 0227a5d..f33a4e2 100644 --- a/ArkBot/FodyWeavers.xml +++ b/ArkBot/FodyWeavers.xml @@ -1,4 +1,5 @@ - + + \ No newline at end of file diff --git a/ArkBot/IConfig.cs b/ArkBot/IConfig.cs index b1374b9..c5b02c9 100644 --- a/ArkBot/IConfig.cs +++ b/ArkBot/IConfig.cs @@ -1,32 +1,22 @@ using System.Collections.Generic; +using ArkBot.Configuration; namespace ArkBot { public interface IConfig { ArkMultipliersConfigSection ArkMultipliers { get; set; } - string BotId { get; set; } string BotName { get; set; } - string BotNamespace { get; set; } - string BotToken { get; set; } string BotUrl { get; set; } string AppUrl { get; set; } string GoogleApiKey { get; set; } string SteamApiKey { get; set; } - string SteamOpenIdRedirectUri { get; set; } - string SteamOpenIdRelyingServiceListenPrefix { get; set; } string TempFileOutputDirPath { get; set; } - bool DisableDeveloperFetchSaveData { get; set; } - string MemberRoleName { get; set; } DiscordConfigSection Discord { get; set; } Dictionary UserRoles { get; set; } - Dictionary> AccessControl { get; set; } - string[] EnabledChannels { get; set; } - string InfoTopicChannel { get; set; } - string AnnouncementChannel { get; set; } + AccessControlConfigSection AccessControl { get; set; } bool BackupsEnabled { get; set; } string BackupsDirectoryPath { get; set; } - bool DiscordBotEnabled { get; set; } string WebApiListenPrefix { get; set; } string WebAppListenPrefix { get; set; } string[] WebAppRedirectListenPrefix { get; set; } diff --git a/ArkBot/Layout/PaneStyleSelector.cs b/ArkBot/Layout/PaneStyleSelector.cs index 8605572..46358be 100644 --- a/ArkBot/Layout/PaneStyleSelector.cs +++ b/ArkBot/Layout/PaneStyleSelector.cs @@ -12,11 +12,14 @@ namespace ArkBot.Layout public class PaneStyleSelector : StyleSelector { public Style ConsoleStyle { get; set; } + public Style ConfigurationStyle { get; set; } public override Style SelectStyle(object item, DependencyObject container) { if (item is ConsoleViewModel) return ConsoleStyle; + if (item is ConfigurationViewModel) + return ConfigurationStyle; return base.SelectStyle(item, container); } diff --git a/ArkBot/Layout/PaneTemplateSelector.cs b/ArkBot/Layout/PaneTemplateSelector.cs index 4854d61..046e4aa 100644 --- a/ArkBot/Layout/PaneTemplateSelector.cs +++ b/ArkBot/Layout/PaneTemplateSelector.cs @@ -13,6 +13,7 @@ namespace ArkBot.Layout public class PaneTemplateSelector : DataTemplateSelector { public DataTemplate ConsoleTemplate { get; set; } + public DataTemplate ConfigurationTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { @@ -20,6 +21,8 @@ public override DataTemplate SelectTemplate(object item, DependencyObject contai if (item is ConsoleViewModel) return ConsoleTemplate; + if (item is ConfigurationViewModel) + return ConfigurationTemplate; return base.SelectTemplate(item, container); } diff --git a/ArkBot/MainWindow.xaml b/ArkBot/MainWindow.xaml index 841ad74..d48ec04 100644 --- a/ArkBot/MainWindow.xaml +++ b/ArkBot/MainWindow.xaml @@ -83,6 +83,11 @@ + + + + + @@ -100,6 +105,19 @@ + + + diff --git a/ArkBot/Properties/AssemblyInfo.cs b/ArkBot/Properties/AssemblyInfo.cs index 0757272..73a358a 100644 --- a/ArkBot/Properties/AssemblyInfo.cs +++ b/ArkBot/Properties/AssemblyInfo.cs @@ -44,5 +44,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.82.*")] -[assembly: AssemblyFileVersion("1.82.0.0")] \ No newline at end of file +[assembly: AssemblyVersion("1.83.*")] +[assembly: AssemblyFileVersion("1.83.0.0")] \ No newline at end of file diff --git a/ArkBot/ScheduledTasks/ScheduledTasksManager.cs b/ArkBot/ScheduledTasks/ScheduledTasksManager.cs index d2e6294..0385bc6 100644 --- a/ArkBot/ScheduledTasks/ScheduledTasksManager.cs +++ b/ArkBot/ScheduledTasks/ScheduledTasksManager.cs @@ -67,9 +67,9 @@ public async Task StartCountdown(ArkServerContext serverContext, string reason, var serverContexts = serverContext == null ? _contextManager.Servers.Where(x => !x.Config.DisableChatNotificationOnGlobalCountdown).ToArray() : new ArkServerContext[] { serverContext }; foreach (var sc in serverContexts) await sc.Steam.SendRconCommand($"serverchat Countdown started: {reason} in {delayInMinutes} minute{(delayInMinutes > 1 ? "s" : "")}..."); - if (!string.IsNullOrWhiteSpace(_config.AnnouncementChannel)) + if (!string.IsNullOrWhiteSpace(_config.Discord.AnnouncementChannel)) { - await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.AnnouncementChannel, $"**Countdown{(serverContext == null ? "" : $" on server {serverContext.Config.Key}")} started: {reason} in {delayInMinutes} minute{(delayInMinutes > 1 ? "s" : "")}...**"); + await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.Discord.AnnouncementChannel, $"**Countdown{(serverContext == null ? "" : $" on server {serverContext.Config.Key}")} started: {reason} in {delayInMinutes} minute{(delayInMinutes > 1 ? "s" : "")}...**"); } foreach (var min in Enumerable.Range(1, delayInMinutes)) @@ -81,9 +81,9 @@ public async Task StartCountdown(ArkServerContext serverContext, string reason, { var countdown = delayInMinutes - min; foreach (var sc in serverContexts) await sc.Steam.SendRconCommand(countdown > 0 ? $"serverchat {reason} in {countdown} minute{(countdown > 1 ? "s" : "")}..." : $"serverchat {reason}..."); - if (!string.IsNullOrWhiteSpace(_config.AnnouncementChannel)) + if (!string.IsNullOrWhiteSpace(_config.Discord.AnnouncementChannel)) { - await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.AnnouncementChannel, countdown > 0 ? $"**{(serverContext == null ? "" : $"{serverContext.Config.Key}: ")}{reason} in {countdown} minute{(countdown > 1 ? "s" : "")}...**" : $"**{(serverContext == null ? "" : $"{serverContext.Config.Key}: ")}{reason}...**"); + await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.Discord.AnnouncementChannel, countdown > 0 ? $"**{(serverContext == null ? "" : $"{serverContext.Config.Key}: ")}{reason} in {countdown} minute{(countdown > 1 ? "s" : "")}...**" : $"**{(serverContext == null ? "" : $"{serverContext.Config.Key}: ")}{reason}...**"); } if (countdown <= 0 && react != null) await react(); }) @@ -114,7 +114,7 @@ private async void _timer_Callback(object state) var fireAndForget = Task.Run(task.Callback); //fire and forget } - if (_config.InfoTopicChannel != null) + if (_config.Discord.InfoTopicChannel != null) { if (DateTime.Now - _prevTopicUpdate > TimeSpan.FromSeconds(60)) { @@ -139,7 +139,11 @@ private async void _timer_Callback(object state) try { - await _discordManager.EditChannelByNameOnAllServers(_config.InfoTopicChannel, topic: sb.ToString()); + await _discordManager.EditChannelByNameOnAllServers(_config.Discord.InfoTopicChannel, topic: sb.ToString()); + } + catch (System.Net.Http.HttpRequestException ex) when (ex.Message.IndexOf("Error while copying content to a stream", StringComparison.Ordinal) != -1) + { + Logging.Log("Error when attempting to change bot info channel topic", GetType()); } catch (Exception ex) { diff --git a/ArkBot/Services/ArkServerService.cs b/ArkBot/Services/ArkServerService.cs index 31a62b7..e154a7b 100644 --- a/ArkBot/Services/ArkServerService.cs +++ b/ArkBot/Services/ArkServerService.cs @@ -216,7 +216,7 @@ public async Task StartServer(string serverKey, Func Ping() public ServerInfo GetServerInfoCached() { var cache = MemoryCache.Default; - var cacheKey = $"{nameof(GetServerInfo)}_{_config.Ip}_{_config.Port}"; + var cacheKey = $"{nameof(GetServerInfo)}_{_config.Ip}_{_config.QueryPort}"; return cache[cacheKey] as ServerInfo; } public QueryMaster.QueryMasterCollection GetServerRulesCached() { var cache = MemoryCache.Default; - var cacheKey = $"{nameof(GetServerRules)}_{_config.Ip}_{_config.Port}"; + var cacheKey = $"{nameof(GetServerRules)}_{_config.Ip}_{_config.QueryPort}"; return cache[cacheKey] as QueryMaster.QueryMasterCollection; } public QueryMaster.QueryMasterCollection GetServerPlayersCached() { var cache = MemoryCache.Default; - var cacheKey = $"{nameof(GetServerPlayers)}_{_config.Ip}_{_config.Port}"; + var cacheKey = $"{nameof(GetServerPlayers)}_{_config.Ip}_{_config.QueryPort}"; return cache[cacheKey] as QueryMaster.QueryMasterCollection; } @@ -188,7 +188,7 @@ public QueryMaster.QueryMasterCollection GetServerPlayersCached() public async Task GetServerInfo() { var cache = MemoryCache.Default; - var cacheKey = $"{nameof(GetServerInfo)}_{_config.Ip}_{_config.Port}"; + var cacheKey = $"{nameof(GetServerInfo)}_{_config.Ip}_{_config.QueryPort}"; var info = cache[cacheKey] as ServerInfo; if ((DateTime.Now - _lastServerInfo) > TimeSpan.FromMinutes(1)) @@ -234,7 +234,7 @@ await Task.Run(async () => public async Task> GetServerRules() { var cache = MemoryCache.Default; - var cacheKey = $"{nameof(GetServerRules)}_{_config.Ip}_{_config.Port}"; + var cacheKey = $"{nameof(GetServerRules)}_{_config.Ip}_{_config.QueryPort}"; var rules = cache[cacheKey] as QueryMaster.QueryMasterCollection; if ((DateTime.Now - _lastServerRules) > TimeSpan.FromMinutes(1)) @@ -280,7 +280,7 @@ await Task.Run(async () => public async Task> GetServerPlayers() { var cache = MemoryCache.Default; - var cacheKey = $"{nameof(GetServerPlayers)}_{_config.Ip}_{_config.Port}"; + var cacheKey = $"{nameof(GetServerPlayers)}_{_config.Ip}_{_config.QueryPort}"; var players = cache[cacheKey] as QueryMaster.QueryMasterCollection; if ((DateTime.Now - _lastServerPlayers) > TimeSpan.FromMinutes(1)) diff --git a/ArkBot/ViewModel/ConfigurationViewModel.cs b/ArkBot/ViewModel/ConfigurationViewModel.cs new file mode 100644 index 0000000..c188286 --- /dev/null +++ b/ArkBot/ViewModel/ConfigurationViewModel.cs @@ -0,0 +1,28 @@ +using ArkBot.Commands; +using ArkBot.Helpers; +using Newtonsoft.Json; +using Prism.Commands; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace ArkBot.ViewModel +{ + public class ConfigurationViewModel : TabViewModel + { + public Config Config { get; set; } + + public ConfigurationViewModel() : base("Configuration", "Configuration") + { + } + } +} diff --git a/ArkBot/ViewModel/Workspace.cs b/ArkBot/ViewModel/Workspace.cs index 7fc5b28..38276b4 100644 --- a/ArkBot/ViewModel/Workspace.cs +++ b/ArkBot/ViewModel/Workspace.cs @@ -63,11 +63,14 @@ public struct Constants public static Workspace Instance => _instance ?? (_instance = new Workspace()); private static Workspace _instance; - public IEnumerable Panes => _panes ?? (_panes = new PaneViewModel[] { Console }); + public IEnumerable Panes => _panes ?? (_panes = new PaneViewModel[] { Console, Configuration }); private PaneViewModel[] _panes; public ConsoleViewModel Console => _console ?? (_console = new ConsoleViewModel()); private ConsoleViewModel _console; + + public ConfigurationViewModel Configuration => _configuration ?? (_configuration = new ConfigurationViewModel()); + private ConfigurationViewModel _configuration; public DelegateCommand ClosingCommand { get; private set; } @@ -222,6 +225,7 @@ internal async Task Init() try { _config = JsonConvert.DeserializeObject(File.ReadAllText(Constants.ConfigFilePath)); + if (_config.Discord == null) _config.Discord = new DiscordConfigSection(); } catch (Exception ex) { @@ -236,48 +240,18 @@ internal async Task Init() } var sb = new StringBuilder(); - if (string.IsNullOrWhiteSpace(_config.BotId) || !new Regex(@"^[a-z0-9]+$", RegexOptions.IgnoreCase | RegexOptions.Singleline).IsMatch(_config.BotId)) - { - sb.AppendLine($@"Error: {nameof(_config.BotId)} is not a valid id."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BotId))}"); - sb.AppendLine(); - } if (string.IsNullOrWhiteSpace(_config.BotName)) { sb.AppendLine($@"Error: {nameof(_config.BotName)} is not set."); sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BotName))}"); sb.AppendLine(); } - if (string.IsNullOrWhiteSpace(_config.BotNamespace) || !Uri.IsWellFormedUriString(_config.BotNamespace, UriKind.Absolute)) - { - sb.AppendLine($@"Error: {nameof(_config.BotNamespace)} is not set or not a valid url."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BotNamespace))}"); - sb.AppendLine(); - } if (string.IsNullOrWhiteSpace(_config.TempFileOutputDirPath) || !Directory.Exists(_config.TempFileOutputDirPath)) { sb.AppendLine($@"Error: {nameof(_config.TempFileOutputDirPath)} is not a valid directory path."); sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.TempFileOutputDirPath))}"); sb.AppendLine(); } - if (string.IsNullOrWhiteSpace(_config.BotToken)) - { - sb.AppendLine($@"Error: {nameof(_config.BotToken)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BotToken))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.SteamOpenIdRedirectUri)) - { - sb.AppendLine($@"Error: {nameof(_config.SteamOpenIdRedirectUri)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.SteamOpenIdRedirectUri))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.SteamOpenIdRelyingServiceListenPrefix)) - { - sb.AppendLine($@"Error: {nameof(_config.SteamOpenIdRelyingServiceListenPrefix)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.SteamOpenIdRelyingServiceListenPrefix))}"); - sb.AppendLine(); - } if (string.IsNullOrWhiteSpace(_config.GoogleApiKey)) { sb.AppendLine($@"Error: {nameof(_config.GoogleApiKey)} is not set."); @@ -341,6 +315,37 @@ internal async Task Init() sb.AppendLine(); } } + if (_config.Discord.DiscordBotEnabled) + { + if (string.IsNullOrWhiteSpace(_config.Discord.BotToken)) + { + sb.AppendLine($@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.BotToken)} is not set."); + sb.AppendLine($@"Expected value: { + ValidationHelper.GetDescriptionForMember(_config.Discord, nameof(_config.Discord.BotToken)) + }"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Discord.SteamOpenIdRedirectUri)) + { + sb.AppendLine($@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.SteamOpenIdRedirectUri)} is not set."); + sb.AppendLine($@"Expected value: { + ValidationHelper.GetDescriptionForMember(_config.Discord, + nameof(_config.Discord.SteamOpenIdRedirectUri)) + }"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)) + { + sb.AppendLine( + $@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)} is not set."); + sb.AppendLine($@"Expected value: { + ValidationHelper.GetDescriptionForMember(_config.Discord, + nameof(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)) + }"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Discord.MemberRoleName)) _config.Discord.MemberRoleName = "ark"; + } var clusterkeys = _config.Clusters?.Select(x => x.Key).ToArray(); var serverkeys = _config.Servers?.Select(x => x.Key).ToArray(); @@ -378,10 +383,10 @@ internal async Task Init() sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.Ip))}"); sb.AppendLine(); } - if (server.Port <= 0) + if (server.QueryPort <= 0) { - sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.Port)} is not valid for server instance ""{server.Key}""."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.Port))}"); + sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.QueryPort)} is not valid for server instance ""{server.Key}""."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.QueryPort))}"); sb.AppendLine(); } //if (server.RconPort <= 0) @@ -405,6 +410,10 @@ internal async Task Init() } } + Configuration.Config = _config as Config; + + return; + //todo: for now this section is not really needed unless !imprintcheck is used //if (config.ArkMultipliers == null) //{ @@ -418,8 +427,6 @@ internal async Task Init() System.Console.WriteLine("Anonymizing all data in the WebAPI (anonymizeWebApiData=true)" + Environment.NewLine); } - if (string.IsNullOrWhiteSpace(_config.MemberRoleName)) _config.MemberRoleName = "ark"; - //load aliases and check integrity var aliases = ArkSpeciesAliases.Instance; if (aliases == null || !aliases.CheckIntegrity) @@ -477,26 +484,31 @@ internal async Task Init() //var playedTimeWatcher = new PlayedTimeWatcher(_config); - var options = new SteamOpenIdOptions + BarebonesSteamOpenId openId = null; + if (_config.Discord.DiscordBotEnabled) { - ListenPrefixes = new[] { _config.SteamOpenIdRelyingServiceListenPrefix }, - RedirectUri = _config.SteamOpenIdRedirectUri, - }; - var openId = new BarebonesSteamOpenId(options, - new Func>(async (success, steamId, discordId) => + var options = new SteamOpenIdOptions { - var razorConfig = new TemplateServiceConfiguration + ListenPrefixes = new[] {_config.Discord.SteamOpenIdRelyingServiceListenPrefix}, + RedirectUri = _config.Discord.SteamOpenIdRedirectUri, + }; + openId = new BarebonesSteamOpenId(options, + new Func>(async (success, steamId, discordId) => { - DisableTempFileLocking = true, - CachingProvider = new DefaultCachingProvider(t => { }) - }; + var razorConfig = new TemplateServiceConfiguration + { + DisableTempFileLocking = true, + CachingProvider = new DefaultCachingProvider(t => { }) + }; - using (var service = RazorEngineService.Create(razorConfig)) - { - var html = await FileHelper.ReadAllTextTaskAsync(constants.OpenidresponsetemplatePath); - return service.RunCompile(html, constants.OpenidresponsetemplatePath, null, new { Success = success, botName = _config.BotName, botUrl = _config.BotUrl }); - } - })); + using (var service = RazorEngineService.Create(razorConfig)) + { + var html = await FileHelper.ReadAllTextTaskAsync(constants.OpenidresponsetemplatePath); + return service.RunCompile(html, constants.OpenidresponsetemplatePath, null, + new {Success = success, botName = _config.BotName, botUrl = _config.BotUrl}); + } + })); + } var discord = new DiscordSocketClient(new DiscordSocketConfig { @@ -532,7 +544,7 @@ internal async Task Init() builder.RegisterInstance(_savedstate).As(); builder.RegisterInstance(_config as Config).As(); //builder.RegisterInstance(playedTimeWatcher).As(); - builder.RegisterInstance(openId).As(); + if (openId != null) builder.RegisterInstance(openId).As(); builder.RegisterType().AsSelf().As() .WithParameter(new TypedParameter(typeof(string), constants.DatabaseConnectionString)); builder.RegisterType(); @@ -645,7 +657,7 @@ internal async Task Init() } //run the discord bot - if (_config.DiscordBotEnabled) + if (_config.Discord.DiscordBotEnabled) { _runDiscordBotCts = new CancellationTokenSource(); _runDiscordBotTask = await Task.Factory.StartNew(async () => await RunDiscordBot(), _runDiscordBotCts.Token, TaskCreationOptions.LongRunning, TaskScheduler.Default); diff --git a/ArkBot/Voting/VotingManager.cs b/ArkBot/Voting/VotingManager.cs index b090282..47c191e 100644 --- a/ArkBot/Voting/VotingManager.cs +++ b/ArkBot/Voting/VotingManager.cs @@ -157,9 +157,9 @@ private void _contextManager_VoteInitiated(ArkServerContext serverContext, VoteI if (result == null) return; if (result.MessageRcon != null) await serverContext.Steam.SendRconCommand($"serverchat {result.MessageRcon.ReplaceRconSpecialChars()}"); - if (result.MessageAnnouncement != null && !string.IsNullOrWhiteSpace(_config.AnnouncementChannel)) + if (result.MessageAnnouncement != null && !string.IsNullOrWhiteSpace(_config.Discord.AnnouncementChannel)) { - await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.AnnouncementChannel, result.MessageAnnouncement); + await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.Discord.AnnouncementChannel, result.MessageAnnouncement); } }) }); @@ -204,9 +204,9 @@ private async Task VoteFinished(ArkServerContext serverContext, IEfDatabaseConte if (!noAnnouncement && result != null) { if (result.MessageRcon != null) await serverContext.Steam.SendRconCommand($"serverchat {result.MessageRcon.ReplaceRconSpecialChars()}"); - if (result.MessageAnnouncement != null && !string.IsNullOrWhiteSpace(_config.AnnouncementChannel)) + if (result.MessageAnnouncement != null && !string.IsNullOrWhiteSpace(_config.Discord.AnnouncementChannel)) { - await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.AnnouncementChannel, result.MessageAnnouncement); + await _discordManager.SendTextMessageToChannelNameOnAllServers(_config.Discord.AnnouncementChannel, result.MessageAnnouncement); } } } diff --git a/ArkBot/WebApi/Controllers/BaseApiController.cs b/ArkBot/WebApi/Controllers/BaseApiController.cs index 6bd9288..fb6d10c 100644 --- a/ArkBot/WebApi/Controllers/BaseApiController.cs +++ b/ArkBot/WebApi/Controllers/BaseApiController.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using System.Web.Http; +using ArkBot.Configuration; namespace ArkBot.WebApi.Controllers { @@ -40,9 +41,9 @@ public bool HasFeatureAccess(string featureGroup, string featureName, string for var accessControl = _config.AccessControl; if (accessControl == null) return false; - var fg = (Dictionary)null; + var fg = (AccessControlFeatureGroup)null; if (!accessControl.TryGetValue(featureGroup, out fg)) return false; - var rf = (string[])null; + var rf = (List)null; if (!fg.TryGetValue(featureName, out rf)) return false; var user = WebApiHelper.GetUser(Request, _config); diff --git a/ArkBot/WebApi/Controllers/ServersController.cs b/ArkBot/WebApi/Controllers/ServersController.cs index 7d3855d..ff03b46 100644 --- a/ArkBot/WebApi/Controllers/ServersController.cs +++ b/ArkBot/WebApi/Controllers/ServersController.cs @@ -220,7 +220,7 @@ private static AccessControlViewModel BuildViewModelForAccessControl(IConfig con { foreach (var fg in config.AccessControl) { - var acfg = new Dictionary(); + var acfg = new Dictionary>(); ac[fg.Key] = acfg; if (fg.Value == null) continue; diff --git a/ArkBot/WebApi/Model/AccessControlViewModel.cs b/ArkBot/WebApi/Model/AccessControlViewModel.cs index 7060929..c2779bf 100644 --- a/ArkBot/WebApi/Model/AccessControlViewModel.cs +++ b/ArkBot/WebApi/Model/AccessControlViewModel.cs @@ -6,7 +6,7 @@ namespace ArkBot.WebApi.Model { - public class AccessControlViewModel : Dictionary> + public class AccessControlViewModel : Dictionary>> { public AccessControlViewModel() { diff --git a/ArkBot/defaultconfig.json b/ArkBot/defaultconfig.json index 5fc2686..fb2b9c8 100644 --- a/ArkBot/defaultconfig.json +++ b/ArkBot/defaultconfig.json @@ -1,20 +1,18 @@ { - "botId": "arkbot", "botName": "ARK Bot", - "botNamespace": "http://www.arkbot.com/", "botUrl": "", "appUrl": "", - "enabledChannels": [ "bot-commands" ], - "infoTopicChannel": "bot-commands", - "announcementChannel": "bot-notifications", "tempFileOutputDirPath": "C:\\ArkBot\\temp", - "botToken": "", - "steamOpenIdRelyingServiceListenPrefix": "http://+:60002/openid/", - "steamOpenIdRedirectUri": "http://:60002/openid/", "googleApiKey": "", "steamApiKey": "", - "memberRoleName": "ark", "discord": { + "discordBotEnabled": true, + "botToken": "", + "enabledChannels": [ "bot-commands" ], + "infoTopicChannel": "bot-commands", + "announcementChannel": "bot-notifications", + "memberRoleName": "ark", + "disableDeveloperFetchSaveData": false, "accessControl": { "channels": { "public": [ "@everyone", "admin", "developer" ], @@ -33,7 +31,9 @@ "whoami": [ "@everyone" ], "disabled": [ "@everyone" ] } - } + }, + "steamOpenIdRelyingServiceListenPrefix": "http://+:60002/openid/", + "steamOpenIdRedirectUri": "http://:60002/openid/" }, "userRoles": { "admin": [ ] @@ -80,10 +80,8 @@ "structures-rcon": [ "disabled" ] } }, - "disableDeveloperFetchSaveData" : false, "backupsEnabled": false, "backupsDirectoryPath": "C:\\ARK Servers\\Backups", - "discordBotEnabled": true, "webApiListenPrefix": "http://+:60001/", "webAppListenPrefix": "http://+:80/", "webAppRedirectListenPrefix": [ @@ -116,7 +114,7 @@ "saveFilePath": "C:\\ARK Servers\\server1\\ShooterGame\\Saved\\SavedArks\\TheIsland.ark", "displayAddress": "myarkserver.domain.com:27015", "ip": "127.0.0.1", - "port": 27015, + "queryPort": 27015, "rconPort": 27020, "rconPassword": "password", "serverExecutablePath": "C:\\ARK Servers\\server1\\ShooterGame\\Binaries\\Win64\\ShooterGameServer.exe", @@ -128,15 +126,15 @@ }, { "key": "server2", - "cluster" : "cluster1", + "cluster": "cluster1", "saveFilePath": "C:\\ARK Servers\\server2\\ShooterGame\\Saved\\SavedArks\\TheIsland.ark", "displayAddress": "myarkserver.domain.com:27016", "ip": "127.0.0.1", - "port": 27016, + "queryPort": 27016, "rconPort": 27021, - "rconPassword": "password", + "rconPassword": "password", "serverExecutablePath": "C:\\ARK Servers\\server2\\ShooterGame\\Binaries\\Win64\\ShooterGameServer.exe", - "serverExecutableArguments": "TheIsland?listen?Port=7779?QueryPort=27016?RCONPort=27021?RCONEnabled=True?SessionName=Server2?ServerPassword=?ServerAdminPassword=password?SpectatorPassword=password?MaxPlayers=5 -culture=en -nosteamclient -clusterid=cluster1 -ClusterDirOverride=\"C:\\ARK Servers\\cluster1\" -serverkey=server2", + "serverExecutableArguments": "TheIsland?listen?Port=7779?QueryPort=27016?RCONPort=27021?RCONEnabled=True?SessionName=Server2?ServerPassword=?ServerAdminPassword=password?SpectatorPassword=password?MaxPlayers=5 -culture=en -nosteamclient -clusterid=cluster1 -ClusterDirOverride=\"C:\\ARK Servers\\cluster1\" -serverkey=server2", "steamCmdExecutablePath": "C:\\SteamCmd\\steamcmd.exe", "serverInstallDirPath": "C:\\ARK Servers\\server2", "usePowershellOutputRedirect": false, diff --git a/ArkBot/packages.config b/ArkBot/packages.config index 300c792..2314334 100644 --- a/ArkBot/packages.config +++ b/ArkBot/packages.config @@ -23,7 +23,7 @@ - + @@ -126,6 +126,7 @@ + From 671571a3c4b95974b6c77bc7e5192d1eff6fe483 Mon Sep 17 00:00:00 2001 From: Tobias Sebring Date: Sat, 30 Dec 2017 12:12:15 +0100 Subject: [PATCH 02/15] Changes --- ArkBot/Ark/ArkServerContext.cs | 4 +- ArkBot/ArkBot.csproj | 4 + ArkBot/Config.cs | 330 ++++++++++++------ ArkBot/Configuration/DirectoryPathEditor.cs | 39 ++- ArkBot/Configuration/OpenFilePathEditor.cs | 87 +++++ .../Validation/DirectoryExistsAttribute.cs | 16 +- .../Validation/FileExistsAttribute.cs | 27 ++ .../Validation/IfValidationAttribute.cs | 34 ++ .../Validation/RangeOptionalAttribute.cs | 34 ++ .../Validation/ValidationTemplate.cs | 6 - ArkBot/Controls/Configuration.xaml | 58 +-- ArkBot/Controls/Configuration.xaml.cs | 52 +++ .../RoleRestrictedPreconditionAttribute.cs | 2 +- ArkBot/IConfig.cs | 5 +- ArkBot/Services/ArkServerService.cs | 2 +- ArkBot/Services/SavegameBackupService.cs | 8 +- ArkBot/ViewModel/Workspace.cs | 8 +- ArkBot/defaultconfig.json | 19 +- 18 files changed, 542 insertions(+), 193 deletions(-) create mode 100644 ArkBot/Configuration/OpenFilePathEditor.cs create mode 100644 ArkBot/Configuration/Validation/FileExistsAttribute.cs create mode 100644 ArkBot/Configuration/Validation/IfValidationAttribute.cs create mode 100644 ArkBot/Configuration/Validation/RangeOptionalAttribute.cs diff --git a/ArkBot/Ark/ArkServerContext.cs b/ArkBot/Ark/ArkServerContext.cs index 797a7cb..6838aff 100644 --- a/ArkBot/Ark/ArkServerContext.cs +++ b/ArkBot/Ark/ArkServerContext.cs @@ -166,7 +166,7 @@ public bool Update(bool manualUpdate, IConfig fullconfig, ISavegameBackupService SavegameBackupResult bresult = null; try { - if (fullconfig.BackupsEnabled) + if (fullconfig.Backups.BackupsEnabled) { bresult = savegameBackupService.CreateBackup(Config, _contextManager?.GetCluster(Config.Cluster)?.Config); if (bresult != null && bresult.ArchivePaths != null) progress.Report($@"Server ({Config.Key}): Backup successfull ({(string.Join(", ", bresult.ArchivePaths.Select(x => $@"""{x}""")))})!"); @@ -174,7 +174,7 @@ public bool Update(bool manualUpdate, IConfig fullconfig, ISavegameBackupService } } catch (Exception ex) { Logging.LogException($"Server ({Config.Key}): Backup failed", ex, typeof(ArkServerContext), LogLevel.ERROR, ExceptionLevel.Ignored); } - BackupCompleted?.Invoke(this, fullconfig.BackupsEnabled, bresult); + BackupCompleted?.Invoke(this, fullconfig.Backups.BackupsEnabled, bresult); } diff --git a/ArkBot/ArkBot.csproj b/ArkBot/ArkBot.csproj index 2817a38..75277c8 100644 --- a/ArkBot/ArkBot.csproj +++ b/ArkBot/ArkBot.csproj @@ -532,7 +532,11 @@ + + + + diff --git a/ArkBot/Config.cs b/ArkBot/Config.cs index e81537c..ead480c 100644 --- a/ArkBot/Config.cs +++ b/ArkBot/Config.cs @@ -14,23 +14,38 @@ using PropertyChanged; using Validar; using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; namespace ArkBot { internal static class ConfigurationCategory { /// - /// Settings that must be changed + /// Settings that must be changed (environment specific) /// - internal const string UserSettings = "User Settings"; + internal const string Required = "Required"; /// /// Settings that are either optional or may be left at default /// internal const string Optional = "Optional"; + + /// + /// Optional settings for advanced configurations + /// + internal const string Advanced = "Advanced"; + + /// + /// Optional setting for debugging, logging etc. + /// + internal const string Debug = "Debug"; } [AddINotifyPropertyChangedInterface] [InjectValidation] + [CategoryOrder(ConfigurationCategory.Required, 0)] + [CategoryOrder(ConfigurationCategory.Optional, 1)] + [CategoryOrder(ConfigurationCategory.Advanced, 2)] + [CategoryOrder(ConfigurationCategory.Debug, 3)] public class Config : IConfig { public Config() @@ -44,8 +59,55 @@ public Config() WebAppRedirectListenPrefix = new string[] { }; AccessControl = new AccessControlConfigSection(); Discord = new DiscordConfigSection(); + Backups = new BackupsConfigSection(); } + // Required + + [JsonProperty(PropertyName = "googleApiKey")] + [DisplayName("Google API Key")] + [Description("Google API Key used for url-shortening services")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(0)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate google api key with google + public string GoogleApiKey { get; set; } + + [JsonProperty(PropertyName = "steamApiKey")] + [DisplayName("Steam API Key")] + [Description("Steam API Key used for fetching user information")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(1)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate steam api key with steam + public string SteamApiKey { get; set; } + + [JsonProperty(PropertyName = "tempFileOutputDirPath")] + [DisplayName("Temporary Files Directory")] + [Description("An existing directory path where temporary binary files can be stored (zip-files etc.)")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(2)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryExists(ErrorMessage = "{0} is not set or the directory path does not exist")] + public string TempFileOutputDirPath { get; set; } + + [JsonProperty(PropertyName = "servers")] + [DisplayName("Servers")] + [Description("Server instance configurations")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(3)] + [Required(ErrorMessage = "{0} is not set")] + public ServerConfigSection[] Servers { get; set; } + + [JsonProperty(PropertyName = "clusters")] + [DisplayName("Clusters")] + [Description("Cluster instance configurations")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(4)] + [Required(ErrorMessage = "{0} is not set")] + public ClusterConfigSection[] Clusters { get; set; } + + // Optional [JsonProperty(PropertyName = "botName")] @@ -77,6 +139,7 @@ public Config() [Description("Server specific multipliers")] [Category(ConfigurationCategory.Optional)] [PropertyOrder(3)] + [ExpandableObject] [Required(ErrorMessage = "{0} is not set")] public ArkMultipliersConfigSection ArkMultipliers { get; set; } @@ -105,152 +168,185 @@ public Config() [Required(ErrorMessage = "{0} is not set")] public AccessControlConfigSection AccessControl { get; set; } - [JsonProperty(PropertyName = "backupsEnabled")] - [DisplayName("Backups Enabled")] - [Description("Option to enable savegame backups")] + [JsonProperty(PropertyName = "backups")] + [DisplayName("Backups")] + [Description("Savegame backups")] [Category(ConfigurationCategory.Optional)] [PropertyOrder(7)] - public bool BackupsEnabled { get; set; } + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] + public BackupsConfigSection Backups { get; set; } - [JsonProperty(PropertyName = "backupsDirectoryPath")] - [DisplayName("Backups Directory Path")] - [Description("Directory path where savegame backups are stored")] + [JsonProperty(PropertyName = "webAppRedirectListenPrefix")] + [DisplayName("Web App Redirect Listen Prefix(es)")] + [Description("Http listen prefix(es) that are redirected to BotUrl")] [Category(ConfigurationCategory.Optional)] [PropertyOrder(8)] - [DirectoryExists(IfMethod = nameof(IsBackupsEnabled), ErrorMessage = "{0} directory path does not exist")] - public string BackupsDirectoryPath { get; set; } - - [JsonProperty(PropertyName = "webApiListenPrefix")] - [Description("Http listen prefix for WebAPI service (requires a port that is open to external connections) [The prebuilt web-app included in this release is by default configured to call the web api on 127.0.0.1:60001. If you want to use another port for the web api you will need to reflect this change in environment.prod.ts and rebuild the web-app dist manually.]")] - public string WebApiListenPrefix { get; set; } - - [JsonProperty(PropertyName = "webAppListenPrefix")] - [Description("Http listen prefix for Web App (requires a port that is open to external connections)")] - public string WebAppListenPrefix { get; set; } - - [JsonProperty(PropertyName = "webAppRedirectListenPrefix")] - [Description("Http listen prefix(es) that are redirected to BotUrl.")] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate this listen prefix public string[] WebAppRedirectListenPrefix { get; set; } [JsonProperty(PropertyName = "powershellFilePath")] + [DisplayName("Powershell Executable Path")] [Description("Absolute file path of the powershell executable (only used with Server.UsePowershellOutputRedirect)")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(9)] + [Editor(typeof(OpenFilePathEditor), typeof(OpenFilePathEditor))] + [OpenFilePathEditor(Filter = "Executable files (*.exe)|*.exe|All files (*.*)|*.*")] + [FileExists(ErrorMessage = "{0} is not set or the file path does not exist")] public string PowershellFilePath { get; set; } - [JsonProperty(PropertyName = "useCompatibilityChangeWatcher")] - [Description("Use timer based .ark save file watcher rather than the default (based on FileSystemWatcher)")] - public bool UseCompatibilityChangeWatcher { get; set; } - [JsonProperty(PropertyName = "ssl")] + [DisplayName("SSL")] [Description("Configure Web App and WebAPI to use SSL with a free certificate from Lets Encrypt")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(10)] [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] public SslConfigSection Ssl { get; set; } - [JsonProperty(PropertyName = "savegameExtractionMaxDegreeOfParallelism")] - [Description("Max degree of parallelism to use for savegame extraction. Change only if experiencing out of memory exceptions.")] - public int? SavegameExtractionMaxDegreeOfParallelism { get; set; } - - [JsonProperty(PropertyName = "anonymizeWebApiData")] - [Description("Anonymize all data in the WebAPI. Used to create data dumps for demoing the web-app.")] - public bool AnonymizeWebApiData { get; set; } - - [JsonProperty(PropertyName = "servers")] - [Description("Server instance configurations.")] - public ServerConfigSection[] Servers { get; set; } + [JsonProperty(PropertyName = "webApiListenPrefix")] + [DisplayName("Web API Listen Prefix")] + [Description("Http listen prefix for WebAPI service (requires a port that is open to external connections) [The prebuilt web-app included in this release is by default configured to call the web api on 127.0.0.1:60001. If you want to use another port for the web api you will need to reflect this change in environment.prod.ts and rebuild the web-app dist manually.]")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(11)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate this listen prefix + public string WebApiListenPrefix { get; set; } - [JsonProperty(PropertyName = "clusters")] - [Description("Cluster instance configurations.")] - public ClusterConfigSection[] Clusters { get; set; } + [JsonProperty(PropertyName = "webAppListenPrefix")] + [DisplayName("Web App Listen Prefix")] + [Description("Http listen prefix for Web App (requires a port that is open to external connections)")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(12)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate this listen prefix + public string WebAppListenPrefix { get; set; } - // Required + // Optional Advanced - [JsonProperty(PropertyName = "tempFileOutputDirPath")] - [DisplayName("Temporary file output directory path")] - [Description("An existing directory path where temporary binary files can be stored (map-images etc.)")] - [Category(ConfigurationCategory.UserSettings)] + [JsonProperty(PropertyName = "savegameExtractionMaxDegreeOfParallelism")] + [DisplayName("Savegame Extraction Max Degree Of Parallelism")] + [Description("Max degree of parallelism to use for savegame extraction. Change only if experiencing out of memory exceptions")] + [Category(ConfigurationCategory.Advanced)] [PropertyOrder(0)] - [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] - [DirectoryExists(ErrorMessage = "{0} is not set or the directory path does not exist")] - public string TempFileOutputDirPath { get; set; } + [RangeOptional(1, 32, Optional = true)] + public int? SavegameExtractionMaxDegreeOfParallelism { get; set; } - [JsonProperty(PropertyName = "googleApiKey")] - [DisplayName("Google API Key")] - [Description("Google API Key used for url-shortening services")] - [Category(ConfigurationCategory.UserSettings)] + [JsonProperty(PropertyName = "useCompatibilityChangeWatcher")] + [DisplayName("Use Compatibility Change Watcher")] + [Description("Use timer based .ark save file watcher rather than the default (based on FileSystemWatcher)")] + [Category(ConfigurationCategory.Advanced)] [PropertyOrder(1)] - [MinLength(1, ErrorMessage = "{0} is not set")] - //todo: validate google api key with google - public string GoogleApiKey { get; set; } + public bool UseCompatibilityChangeWatcher { get; set; } - [JsonProperty(PropertyName = "steamApiKey")] - [DisplayName("Steam API Key")] - [Description("Steam API Key used for fetching user information")] - [Category(ConfigurationCategory.UserSettings)] - [PropertyOrder(2)] - [MinLength(1, ErrorMessage = "{0} is not set")] - //todo: validate steam api key with steam - public string SteamApiKey { get; set; } + // Debugging, Logging etc. - // Validation methods + [JsonProperty(PropertyName = "discordLogLevel")] + [DisplayName("Discord Log Level")] + [Description("Log level for Discord.NET")] + [Category(ConfigurationCategory.Debug)] + [PropertyOrder(0)] + public LogSeverity DiscordLogLevel { get; set; } - private bool IsBackupsEnabled() - { - return BackupsEnabled; - } + [JsonProperty(PropertyName = "anonymizeWebApiData")] + [DisplayName("Anonymize Web API Data")] + [Description("Anonymize all data in the WebAPI. Used to create data dumps for demoing the web-app")] + [Category(ConfigurationCategory.Debug)] + [PropertyOrder(1)] + public bool AnonymizeWebApiData { get; set; } } [AddINotifyPropertyChangedInterface] + [InjectValidation] public class DiscordConfigSection { public DiscordConfigSection() { DiscordBotEnabled = true; - AccessControl = new Dictionary>(); + AccessControl = new AccessControlConfigSection(); } [JsonProperty(PropertyName = "discordBotEnabled")] - [Description("Option to enable/disable the discord bot component.")] + [DisplayName("Discord Bot Enabled")] + [Description("Option to enable/disable the discord bot component")] public bool DiscordBotEnabled { get; set; } [JsonProperty(PropertyName = "botToken")] + [DisplayName("Bot Token")] [Description("Bot authentication token from https://discordapp.com/developers")] public string BotToken { get; set; } [JsonProperty(PropertyName = "enabledChannels")] - [Description("A list of channels where the bot will listen to and answer commands.")] + [DisplayName("Enabled Channels")] + [Description("A list of channels where the bot will listen to and answer commands")] public string[] EnabledChannels { get; set; } [JsonProperty(PropertyName = "infoTopicChannel")] - [Description("Channel where topic is set to display information about last update, next update and how to use bot commands.")] + [DisplayName("Info Topic Channel")] + [Description("Channel where topic is set to display information about last update, next update and how to use bot commands")] public string InfoTopicChannel { get; set; } [JsonProperty(PropertyName = "announcementChannel")] + [DisplayName("Announcement Channel")] [Description("Channel where announcements are made (votes etc.)")] public string AnnouncementChannel { get; set; } [JsonProperty(PropertyName = "memberRoleName")] - [Description("The name of the member role in Discord.")] + [DisplayName("Member Role Name")] + [Description("The name of the member role in Discord")] public string MemberRoleName { get; set; } [JsonProperty(PropertyName = "disableDeveloperFetchSaveData")] - [Description("Diable users in \"developer\"-role fetching json or save file data.")] + [DisplayName("Disable Developer Fetch Save Data")] + [Description("Diable users in \"developer\"-role fetching json or save file data")] public bool DisableDeveloperFetchSaveData { get; set; } [JsonProperty(PropertyName = "accessControl")] - [Description("Per-feature role based access control configuration.")] - public Dictionary> AccessControl { get; set; } + [DisplayName("Access Control")] + [Description("Per-feature role based access control configuration")] + public AccessControlConfigSection AccessControl { get; set; } [JsonProperty(PropertyName = "steamOpenIdRelyingServiceListenPrefix")] + [DisplayName("Steam Open ID Relying Server Listen Prefix")] [Description("Http listen prefix for Steam OpenID Relying Party webservice (requires a port that is open to external connections)")] public string SteamOpenIdRelyingServiceListenPrefix { get; set; } [JsonProperty(PropertyName = "steamOpenIdRedirectUri")] + [DisplayName("Steam Open ID Redirect URL")] [Description("Publicly accessible url for incoming Steam OpenID Relying Party webservice connections (requires a port that is open to external connections)")] public string SteamOpenIdRedirectUri { get; set; } } [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class BackupsConfigSection + { + [JsonProperty(PropertyName = "backupsEnabled")] + [DisplayName("Backups Enabled")] + [Description("Option to enable savegame backups")] + [PropertyOrder(0)] + public bool BackupsEnabled { get; set; } + + [JsonProperty(PropertyName = "backupsDirectoryPath")] + [DisplayName("Backups Directory Path")] + [Description("Directory path where savegame backups are stored")] + [PropertyOrder(1)] + [DirectoryExists(IfMethod = nameof(IsBackupsEnabled), ErrorMessage = "{0} directory path does not exist")] + public string BackupsDirectoryPath { get; set; } + + // Validation methods + + private bool IsBackupsEnabled() + { + return BackupsEnabled; + } + } + + [AddINotifyPropertyChangedInterface] + [InjectValidation] public class SslConfigSection { public SslConfigSection() @@ -259,39 +355,48 @@ public SslConfigSection() } [JsonProperty(PropertyName = "enabled")] + [DisplayName("Enabled")] [Description("Toggle ssl.")] public bool Enabled { get; set; } [JsonProperty(PropertyName = "challengeListenPrefix")] + [DisplayName("Challenge Listen Prefix")] [Description("Http listen prefix for ssl challenge request (external port must be 80)")] public string ChallengeListenPrefix { get; set; } [JsonProperty(PropertyName = "name")] - [Description("Friendly name of the certificate.")] + [DisplayName("Name")] + [Description("Friendly name of the certificate")] public string Name { get; set; } [JsonProperty(PropertyName = "password")] - [Description("Private password.")] + [DisplayName("Password")] + [Description("Private password")] public string Password { get; set; } [JsonProperty(PropertyName = "email")] - [Description("Registration contact email.")] + [DisplayName("Email")] + [Description("Registration contact email")] public string Email { get; set; } [JsonProperty(PropertyName = "domains")] - [Description("Domain name(s) to issue the certificate for.")] + [DisplayName("Domain name(s)")] + [Description("Domain name(s) to issue the certificate for")] public string[] Domains { get; set; } [JsonProperty(PropertyName = "ports")] - [Description("Ports to bind the ssl certificate to.")] + [DisplayName("Ports")] + [Description("Ports to bind the ssl certificate to")] public int[] Ports { get; set; } [JsonProperty(PropertyName = "useCompatibilityNonSNIBindings")] + [DisplayName("Use Compatibility non-SNI Bindings")] [Description("Use non SNI SSL bindings for previous Windows OS (before Windows 8/2012)")] public bool UseCompatibilityNonSNIBindings { get; set; } } [AddINotifyPropertyChangedInterface] + [InjectValidation] public class ArkMultipliersConfigSection { public ArkMultipliersConfigSection() @@ -302,19 +407,23 @@ public ArkMultipliersConfigSection() } [JsonProperty(PropertyName = "eggHatchSpeedMultiplier")] - [Description("Pregnancy/incubation time multiplier.")] + [DisplayName("Egg Hatch Speed Multiplier")] + [Description("Pregnancy/incubation time multiplier")] public double EggHatchSpeedMultiplier { get; set; } [JsonProperty(PropertyName = "babyMatureSpeedMultiplier")] - [Description("Baby mature time multiplier.")] + [DisplayName("Baby Mature Speed Multiplier")] + [Description("Baby mature time multiplier")] public double BabyMatureSpeedMultiplier { get; set; } [JsonProperty(PropertyName = "cuddleIntervalMultiplier")] - [Description("Multiplier for duration between cuddles.")] + [DisplayName("Cuddle Interval Multiplier")] + [Description("Multiplier for duration between cuddles")] public double CuddleIntervalMultiplier { get; set; } } [AddINotifyPropertyChangedInterface] + [InjectValidation] public class ServerConfigSection { public ServerConfigSection() @@ -322,72 +431,87 @@ public ServerConfigSection() } [JsonProperty(PropertyName = "key")] - [Description("Unique key/name for this server instance.")] + [DisplayName("Key")] + [Description("Unique key/name for this server instance")] public string Key { get; set; } [JsonProperty(PropertyName = "cluster")] - [Description("Optional key for the cluster instance this server is part of.")] + [DisplayName("Cluster")] + [Description("Optional key for the cluster instance this server is part of")] public string Cluster { get; set; } [JsonProperty(PropertyName = "saveFilePath")] - [Description("Absolute file path of the .ark save file to monitor/extract data from.")] + [DisplayName("Save File Path")] + [Description("Absolute file path of the .ark save file to monitor/extract data from")] public string SaveFilePath { get; set; } [JsonProperty(PropertyName = "displayAddress")] - [Description("Public server address visible to players.")] + [DisplayName("Display Address")] + [Description("Public server address visible to players")] public string DisplayAddress { get; set; } [JsonProperty(PropertyName = "ip")] - [Description("The IP address used to connect to this server instance.")] + [DisplayName("IP")] + [Description("The IP address used to connect to this server instance")] public string Ip { get; set; } [JsonProperty(PropertyName = "queryPort")] - [Description("The port used to query to this server instance.")] + [DisplayName("Query Port")] + [Description("The port used to query to this server instance")] public int QueryPort { get; set; } [JsonProperty(PropertyName = "rconPort")] - [Description("The port used to connect to this server instance over rcon.")] + [DisplayName("RCON Port")] + [Description("The port used to connect to this server instance over rcon")] public int RconPort { get; set; } [JsonProperty(PropertyName = "rconPassword")] - [Description("The password used to connect to this server instance via rcon.")] + [DisplayName("RCON Password")] + [Description("The password used to connect to this server instance via rcon")] public string RconPassword { get; set; } //[JsonProperty(PropertyName = "updateBatchFilePath")] - //[Description("Absolute file path of a batch file to run in order to update the server.")] + //[Description("Absolute file path of a batch file to run in order to update the server")] //public string UpdateBatchFilePath { get; set; } //[JsonProperty(PropertyName = "startBatchFilePath")] - //[Description("Absolute file path of a batch file to run in order to start the server.")] + //[Description("Absolute file path of a batch file to run in order to start the server")] //public string StartBatchFilePath { get; set; } [JsonProperty(PropertyName = "serverExecutablePath")] - [Description("Absolute file path of the server instance executable.")] + [DisplayName("Server Executable Path")] + [Description("Absolute file path of the server instance executable")] public string ServerExecutablePath { get; set; } [JsonProperty(PropertyName = "serverExecutableArguments")] - [Description("Command line arguments used when starting the server instance.")] + [DisplayName("Server Executable Arguments")] + [Description("Command line arguments used when starting the server instance")] public string ServerExecutableArguments { get; set; } [JsonProperty(PropertyName = "steamCmdExecutablePath")] - [Description("Absolute file path of the steamcmd executable.")] + [DisplayName("Steam Cmd Executable Path")] + [Description("Absolute file path of the steamcmd executable")] public string SteamCmdExecutablePath { get; set; } [JsonProperty(PropertyName = "serverInstallDirPath")] - [Description("The directory path to force steamcmd updates to.")] + [DisplayName("Server Install Directory Path")] + [Description("The directory path to force steamcmd updates to")] public string ServerInstallDirPath { get; set; } [JsonProperty(PropertyName = "usePowershellOutputRedirect")] - [Description("Use alternative powershell/file based output redirect for update progress notifications.")] + [DisplayName("Use Powershell Output Redirect")] + [Description("Use alternative powershell/file based output redirect for update progress notifications")] public bool UsePowershellOutputRedirect { get; set; } [JsonProperty(PropertyName = "disableChatNotificationOnGlobalCountdown")] - [Description("Disable chat notifications for this server instance when trigged by admin multiple server countdown (feature is used for compatibility with cross server chat).")] + [DisplayName("Disable Chat Notification On Global Countdown")] + [Description("Disable chat notifications for this server instance when trigged by admin multiple server countdown (feature is used for compatibility with cross server chat)")] public bool DisableChatNotificationOnGlobalCountdown { get; set; } } [AddINotifyPropertyChangedInterface] + [InjectValidation] public class ClusterConfigSection { public ClusterConfigSection() @@ -395,11 +519,13 @@ public ClusterConfigSection() } [JsonProperty(PropertyName = "key")] - [Description("Unique key/name for this cluster instance.")] + [DisplayName("Key")] + [Description("Unique key/name for this cluster instance")] public string Key { get; set; } [JsonProperty(PropertyName = "savePath")] - [Description("The directory path where cluster save data is stored.")] + [DisplayName("Save Path")] + [Description("The directory path where cluster save data is stored")] public string SavePath { get; set; } } } diff --git a/ArkBot/Configuration/DirectoryPathEditor.cs b/ArkBot/Configuration/DirectoryPathEditor.cs index c4434fa..cc22337 100644 --- a/ArkBot/Configuration/DirectoryPathEditor.cs +++ b/ArkBot/Configuration/DirectoryPathEditor.cs @@ -1,20 +1,38 @@ using System; using System.Collections.Generic; +using System.Globalization; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; +using System.Windows.Forms; using Xceed.Wpf.Toolkit.PropertyGrid; using Xceed.Wpf.Toolkit.PropertyGrid.Editors; +using Binding = System.Windows.Data.Binding; +using Button = System.Windows.Controls.Button; +using HorizontalAlignment = System.Windows.HorizontalAlignment; +using TextBox = System.Windows.Controls.TextBox; namespace ArkBot.Configuration { + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class DirectoryPathEditorAttribute : Attribute + { + public string Title { get; set; } + } + public class DirectoryPathEditor : ITypeEditor { + private DirectoryPathEditorAttribute _attr; + public FrameworkElement ResolveEditor(PropertyItem propertyItem) { + _attr = propertyItem.PropertyDescriptor.Attributes.OfType() + .FirstOrDefault(); + Grid panel = new Grid(); panel.ColumnDefinitions.Add(new ColumnDefinition()); panel.ColumnDefinitions.Add(new ColumnDefinition() @@ -44,15 +62,22 @@ public FrameworkElement ResolveEditor(PropertyItem propertyItem) private void button_Click(object sender, RoutedEventArgs e) { PropertyItem item = ((Button)sender).Tag as PropertyItem; - if (null == item) - { - return; - } + if (null == item) return; - using (var dialog = new System.Windows.Forms.FolderBrowserDialog()) + var path = item.Value as string; + var di = !string.IsNullOrEmpty(path) && Directory.Exists(path) ? new DirectoryInfo(path) : null; + + using (var dialog = new System.Windows.Forms.FolderBrowserDialog + { + SelectedPath = di?.FullName, + ShowNewFolderButton = true, + Description = String.Format(CultureInfo.CurrentCulture, _attr?.Title ?? "Select {0}", item.DisplayName) + }) { - System.Windows.Forms.DialogResult result = dialog.ShowDialog(); - item.Value = dialog.SelectedPath; + if (dialog.ShowDialog() == DialogResult.OK) + { + item.Value = dialog.SelectedPath; + } } } } diff --git a/ArkBot/Configuration/OpenFilePathEditor.cs b/ArkBot/Configuration/OpenFilePathEditor.cs new file mode 100644 index 0000000..0b49080 --- /dev/null +++ b/ArkBot/Configuration/OpenFilePathEditor.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Forms; +using Xceed.Wpf.Toolkit.PropertyGrid; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; +using Binding = System.Windows.Data.Binding; +using Button = System.Windows.Controls.Button; +using HorizontalAlignment = System.Windows.HorizontalAlignment; +using TextBox = System.Windows.Controls.TextBox; + +namespace ArkBot.Configuration +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class OpenFilePathEditorAttribute : Attribute + { + public string Filter { get; set; } + public string Title { get; set; } + } + + public class OpenFilePathEditor : ITypeEditor + { + private OpenFilePathEditorAttribute _attr; + + public FrameworkElement ResolveEditor(PropertyItem propertyItem) + { + _attr = propertyItem.PropertyDescriptor.Attributes.OfType() + .FirstOrDefault(); + + Grid panel = new Grid(); + panel.ColumnDefinitions.Add(new ColumnDefinition()); + panel.ColumnDefinitions.Add(new ColumnDefinition() + { + Width = GridLength.Auto + }); + + TextBox textBox = new TextBox(); + textBox.HorizontalAlignment = HorizontalAlignment.Stretch; + Binding binding = new Binding("Value"); //bind to the Value property of the PropertyItem + binding.Source = propertyItem; + binding.Mode = BindingMode.TwoWay; + BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding); + + Button button = new Button(); + button.Content = "..."; + button.Tag = propertyItem; + button.Click += button_Click; + Grid.SetColumn(button, 1); + + panel.Children.Add(textBox); + panel.Children.Add(button); + + return panel; + } + + private void button_Click(object sender, RoutedEventArgs e) + { + PropertyItem item = ((Button)sender).Tag as PropertyItem; + if (null == item) return; + + var path = item.Value as string; + var fi = !string.IsNullOrEmpty(path) && File.Exists(path) ? new FileInfo(path) : null; + + using (var dialog = new System.Windows.Forms.OpenFileDialog + { + FileName = fi?.Name, + InitialDirectory = fi?.DirectoryName, + CheckFileExists = true, + Filter = _attr?.Filter, + Title = String.Format(CultureInfo.CurrentCulture, _attr?.Title ?? "Select {0}", item.DisplayName) + }) + { + if (dialog.ShowDialog() == DialogResult.OK) + { + item.Value = dialog.FileName; + } + } + } + } +} diff --git a/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs b/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs index e3b99fd..7121157 100644 --- a/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs +++ b/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs @@ -11,22 +11,12 @@ namespace ArkBot.Configuration.Validation { [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] - public sealed class DirectoryExistsAttribute : ValidationAttribute + public sealed class DirectoryExistsAttribute : IfValidationAttribute { - public string IfMethod { get; set; } - protected override ValidationResult IsValid(object value, ValidationContext validationContext) { - if (IfMethod != null) - { - var ifMethodInfo = validationContext.ObjectType.GetMethod(IfMethod, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); - if (ifMethodInfo == null) - return new ValidationResult( - $"IfMethod '{validationContext.ObjectType.Name}.{IfMethod}' could not be found!", new[] { validationContext.MemberName }); - - if (!(bool) ifMethodInfo.Invoke(validationContext.ObjectInstance, null)) - return ValidationResult.Success; - } + var result = base.IfMethodValid(value, validationContext); + if (result != null) return result; return !string.IsNullOrWhiteSpace(value as string) && Directory.Exists((string) value) ? ValidationResult.Success diff --git a/ArkBot/Configuration/Validation/FileExistsAttribute.cs b/ArkBot/Configuration/Validation/FileExistsAttribute.cs new file mode 100644 index 0000000..9279773 --- /dev/null +++ b/ArkBot/Configuration/Validation/FileExistsAttribute.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class FileExistsAttribute : IfValidationAttribute + { + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + var result = base.IfMethodValid(value, validationContext); + if (result != null) return result; + + return !string.IsNullOrWhiteSpace(value as string) && File.Exists((string) value) + ? ValidationResult.Success + : new ValidationResult(String.Format(CultureInfo.CurrentCulture, ErrorMessageString, + validationContext.MemberName), new [] { validationContext.MemberName }); + } + } +} diff --git a/ArkBot/Configuration/Validation/IfValidationAttribute.cs b/ArkBot/Configuration/Validation/IfValidationAttribute.cs new file mode 100644 index 0000000..bbdeb53 --- /dev/null +++ b/ArkBot/Configuration/Validation/IfValidationAttribute.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public abstract class IfValidationAttribute : ValidationAttribute + { + public string IfMethod { get; set; } + + protected ValidationResult IfMethodValid(object value, ValidationContext validationContext) + { + if (IfMethod != null) + { + var ifMethodInfo = validationContext.ObjectType.GetMethod(IfMethod, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + if (ifMethodInfo == null) + return new ValidationResult( + $"IfMethod '{validationContext.ObjectType.Name}.{IfMethod}' could not be found!", new[] { validationContext.MemberName }); + + if (!(bool) ifMethodInfo.Invoke(validationContext.ObjectInstance, null)) + return ValidationResult.Success; + } + + return null; + } + } +} diff --git a/ArkBot/Configuration/Validation/RangeOptionalAttribute.cs b/ArkBot/Configuration/Validation/RangeOptionalAttribute.cs new file mode 100644 index 0000000..885e32f --- /dev/null +++ b/ArkBot/Configuration/Validation/RangeOptionalAttribute.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RazorEngine.Compilation.ImpromptuInterface.InvokeExt; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class RangeOptionalAttribute : RangeAttribute + { + public bool Optional { get; set; } + + public RangeOptionalAttribute(int minimum, int maximum) : base(minimum, maximum) + { + } + + public override bool IsValid(object value) + { + if (Optional && value == null) return true; + + return base.IsValid(value); + } + + public override string FormatErrorMessage(string name) + { + return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name); + } + } +} diff --git a/ArkBot/Configuration/Validation/ValidationTemplate.cs b/ArkBot/Configuration/Validation/ValidationTemplate.cs index a40dc61..3db0ce8 100644 --- a/ArkBot/Configuration/Validation/ValidationTemplate.cs +++ b/ArkBot/Configuration/Validation/ValidationTemplate.cs @@ -27,7 +27,6 @@ public ValidationTemplate(INotifyPropertyChanged target) void Validate(object sender, PropertyChangedEventArgs e) { - var oldErrors = new HashSet(_validationResults.SelectMany(x => x.MemberNames)); _validationResults.Clear(); Validator.TryValidateObject(_target, _validationContext, _validationResults, true); var hashSet = new HashSet(_validationResults.SelectMany(x => x.MemberNames)); @@ -35,10 +34,6 @@ void Validate(object sender, PropertyChangedEventArgs e) { RaiseErrorsChanged(error); } - foreach (var noerror in oldErrors.Except(hashSet)) - { - RaiseErrorsChanged(noerror); - } } public IEnumerable GetErrors(string propertyName) @@ -74,7 +69,6 @@ public string this[string propertyName] void RaiseErrorsChanged(string propertyName) { - Debug.WriteLine($"Errors changed raised for '{propertyName}'"); ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName)); } } diff --git a/ArkBot/Controls/Configuration.xaml b/ArkBot/Controls/Configuration.xaml index 85328d0..b23f986 100644 --- a/ArkBot/Controls/Configuration.xaml +++ b/ArkBot/Controls/Configuration.xaml @@ -16,23 +16,12 @@ + + - + - - - + + + + + diff --git a/ArkBot/Controls/Configuration.xaml.cs b/ArkBot/Controls/Configuration.xaml.cs index cd0de13..4246208 100644 --- a/ArkBot/Controls/Configuration.xaml.cs +++ b/ArkBot/Controls/Configuration.xaml.cs @@ -1,10 +1,14 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using Xceed.Wpf.Toolkit.PropertyGrid; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; namespace ArkBot.Controls { @@ -24,6 +28,54 @@ public Config Model public Configuration() { InitializeComponent(); + + ConfigurationPropertyGrid.PropertyValueChanged += ConfigurationPropertyGrid_PropertyValueChanged; + ConfigurationPropertyGrid.PreparePropertyItem += ConfigurationPropertyGrid_PreparePropertyItem; + } + + private void ConfigurationPropertyGrid_PreparePropertyItem(object sender, PropertyItemEventArgs e) + { + if (e.PropertyItem.Name.Equals("ServerExecutableArguments", StringComparison.Ordinal)) + { + e.PropertyItem.Editor.Height = 100; + } + } + + /// + /// PropertyGrid only updates validation for the PropertyItem that was changed by default. This is a way to force it to update all properties in order to support dependencies. PropertyGrid is built for .NET 4 and does not support the ValidatesOnNotifyDataErrors binding property. + /// + private void ConfigurationPropertyGrid_PropertyValueChanged(object sender, Xceed.Wpf.Toolkit.PropertyGrid.PropertyValueChangedEventArgs e) + { + var modifiedPropertyItem = e.OriginalSource as PropertyItem; + if (modifiedPropertyItem != null) + { + var mi = typeof(PropertyItem).GetMethod("SetRedInvalidBorder", + BindingFlags.Instance | BindingFlags.NonPublic); + if (mi == null) return; + + var grid = sender as PropertyGrid; + UpdateRecursive(mi, modifiedPropertyItem, grid.Properties.Cast()); + } + } + + private void UpdateRecursive(MethodInfo miSetRedInvalidBorder, PropertyItem modifiedPropertyItem, IEnumerable properties) + { + foreach (var prop in properties) + { + if (prop == modifiedPropertyItem) continue; + + var be = prop.GetBindingExpression(PropertyItem.ValueProperty); + if (be != null) + { + be.UpdateSource(); + miSetRedInvalidBorder.Invoke(prop, new[] { be }); + } + + if (prop.IsExpandable) + { + UpdateRecursive(miSetRedInvalidBorder, modifiedPropertyItem, prop.Properties.Cast()); + } + } } } } diff --git a/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs b/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs index be1eacb..5e259e0 100644 --- a/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs +++ b/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs @@ -81,7 +81,7 @@ private string[] GetFeatureRoles(IConfig config, string featureGroup, string fea if (accessControl == null) return null; if (!accessControl.TryGetValue(featureGroup, out var fg)) return null; - return !fg.TryGetValue(featureName, out var rf) ? null : rf; + return !fg.TryGetValue(featureName, out var rf) ? null : rf.ToArray(); } } } diff --git a/ArkBot/IConfig.cs b/ArkBot/IConfig.cs index c5b02c9..af8b9fe 100644 --- a/ArkBot/IConfig.cs +++ b/ArkBot/IConfig.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using ArkBot.Configuration; +using Discord; namespace ArkBot { @@ -15,8 +16,7 @@ public interface IConfig DiscordConfigSection Discord { get; set; } Dictionary UserRoles { get; set; } AccessControlConfigSection AccessControl { get; set; } - bool BackupsEnabled { get; set; } - string BackupsDirectoryPath { get; set; } + BackupsConfigSection Backups { get; set; } string WebApiListenPrefix { get; set; } string WebAppListenPrefix { get; set; } string[] WebAppRedirectListenPrefix { get; set; } @@ -25,6 +25,7 @@ public interface IConfig SslConfigSection Ssl { get; set; } int? SavegameExtractionMaxDegreeOfParallelism { get; set; } bool AnonymizeWebApiData { get; set; } + LogSeverity DiscordLogLevel { get; set; } ServerConfigSection[] Servers { get; set; } ClusterConfigSection[] Clusters { get; set; } diff --git a/ArkBot/Services/ArkServerService.cs b/ArkBot/Services/ArkServerService.cs index e154a7b..57a95c4 100644 --- a/ArkBot/Services/ArkServerService.cs +++ b/ArkBot/Services/ArkServerService.cs @@ -84,7 +84,7 @@ public async Task SaveWorld(string serverKey, Func= 1)) + if (_config.Backups.BackupsEnabled && !(state?.Item3?.ArchivePaths?.Length >= 1)) { if (sendMessageDirected != null) await sendMessageDirected($"savegame backup failed..."); return false; diff --git a/ArkBot/Services/SavegameBackupService.cs b/ArkBot/Services/SavegameBackupService.cs index aa9803e..00494f2 100644 --- a/ArkBot/Services/SavegameBackupService.cs +++ b/ArkBot/Services/SavegameBackupService.cs @@ -27,7 +27,7 @@ public List GetBackupsList(string[] keys = null, Func GetBackupsList(string[] keys = null, Func new { a = _a, b = _b }).SkipWhile(x => x.a.Equals(x.b, StringComparison.OrdinalIgnoreCase)).Select(x => x.a).ToArray()); var entry = new BackupListEntity @@ -145,7 +145,7 @@ public SavegameBackupResult CreateBackup(ServerConfigSection server, ClusterConf cluster != null ? new Tuple(cluster.SavePath, "cluster", clusters = Directory.GetFiles(cluster.SavePath, "*", SearchOption.AllDirectories)) : null }.Where(x => x != null && x.Item2 != null).ToArray(); - var backupDir = Path.Combine(_config.BackupsDirectoryPath, server.Key, DateTime.Now.ToString("yyyy-MM")); + var backupDir = Path.Combine(_config.Backups.BackupsDirectoryPath, server.Key, DateTime.Now.ToString("yyyy-MM")); if (!Directory.Exists(backupDir)) Directory.CreateDirectory(backupDir); @@ -181,7 +181,7 @@ public SavegameBackupResult CreateClusterBackupForSteamId(ClusterConfigSection c if (!(clusters?.Length > 0)) return null; - var backupDir = Path.Combine(_config.BackupsDirectoryPath, cluster.Key, DateTime.Now.ToString("yyyy-MM")); + var backupDir = Path.Combine(_config.Backups.BackupsDirectoryPath, cluster.Key, DateTime.Now.ToString("yyyy-MM")); if (!Directory.Exists(backupDir)) Directory.CreateDirectory(backupDir); diff --git a/ArkBot/ViewModel/Workspace.cs b/ArkBot/ViewModel/Workspace.cs index 38276b4..e01b0db 100644 --- a/ArkBot/ViewModel/Workspace.cs +++ b/ArkBot/ViewModel/Workspace.cs @@ -264,10 +264,10 @@ internal async Task Init() sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.SteamApiKey))}"); sb.AppendLine(); } - if (_config.BackupsEnabled && (string.IsNullOrWhiteSpace(_config.BackupsDirectoryPath) || !FileHelper.IsValidDirectoryPath(_config.BackupsDirectoryPath))) + if (_config.Backups.BackupsEnabled && (string.IsNullOrWhiteSpace(_config.Backups.BackupsDirectoryPath) || !FileHelper.IsValidDirectoryPath(_config.Backups.BackupsDirectoryPath))) { - sb.AppendLine($@"Error: {nameof(_config.BackupsDirectoryPath)} is not a valid directory path."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BackupsDirectoryPath))}"); + sb.AppendLine($@"Error: {nameof(_config.Backups.BackupsDirectoryPath)} is not a valid directory path."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.Backups.BackupsDirectoryPath))}"); sb.AppendLine(); } if (string.IsNullOrWhiteSpace(_config.WebApiListenPrefix)) @@ -513,7 +513,7 @@ internal async Task Init() var discord = new DiscordSocketClient(new DiscordSocketConfig { WebSocketProvider = WS4NetProvider.Instance, //required for Win 7 - LogLevel = LogSeverity.Warning + LogLevel = _config.DiscordLogLevel }); discord.Log += msg => { diff --git a/ArkBot/defaultconfig.json b/ArkBot/defaultconfig.json index fb2b9c8..b9b214e 100644 --- a/ArkBot/defaultconfig.json +++ b/ArkBot/defaultconfig.json @@ -36,7 +36,7 @@ "steamOpenIdRedirectUri": "http://:60002/openid/" }, "userRoles": { - "admin": [ ] + "admin": [] }, "accessControl": { "pages": { @@ -80,8 +80,10 @@ "structures-rcon": [ "disabled" ] } }, - "backupsEnabled": false, - "backupsDirectoryPath": "C:\\ARK Servers\\Backups", + "backups": { + "backupsEnabled": false, + "backupsDirectoryPath": "C:\\ARK Servers\\Backups" + }, "webApiListenPrefix": "http://+:60001/", "webAppListenPrefix": "http://+:80/", "webAppRedirectListenPrefix": [ @@ -89,7 +91,7 @@ "powershellFilePath": "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe", "useCompatibilityChangeWatcher": true, "ssl": { - "enabled": false, + "enabled": false, "challengeListenPrefix": "http://+:80/", "name": "ark-bot-ssl", "password": "secret123", @@ -98,7 +100,7 @@ "app.yourdomain.com" ], "ports": [ 443, 60001 ], - "useCompatibilityNonSNIBindings": true + "useCompatibilityNonSNIBindings": true }, "arkMultipliers": { "eggHatchSpeedMultiplier": 1.0, @@ -106,7 +108,8 @@ "cuddleIntervalMultiplier": 1.0 }, "savegameExtractionMaxDegreeOfParallelism": null, - "anonymizeWebApiData": false, + "anonymizeWebApiData": false, + "discordLogLevel": "Warning", "servers": [ { "key": "server1", @@ -116,9 +119,9 @@ "ip": "127.0.0.1", "queryPort": 27015, "rconPort": 27020, - "rconPassword": "password", + "rconPassword": "password", "serverExecutablePath": "C:\\ARK Servers\\server1\\ShooterGame\\Binaries\\Win64\\ShooterGameServer.exe", - "serverExecutableArguments": "TheIsland?listen?Port=7777?QueryPort=27015?RCONPort=27020?RCONEnabled=True?SessionName=Server1?ServerPassword=?ServerAdminPassword=password?SpectatorPassword=password?MaxPlayers=5 -culture=en -nosteamclient -clusterid=cluster1 -ClusterDirOverride=\"C:\\ARK Servers\\cluster1\" -serverkey=server1", + "serverExecutableArguments": "TheIsland?listen?Port=7777?QueryPort=27015?RCONPort=27020?RCONEnabled=True?SessionName=Server1?ServerPassword=?ServerAdminPassword=password?SpectatorPassword=password?MaxPlayers=5 -culture=en -nosteamclient -clusterid=cluster1 -ClusterDirOverride=\"C:\\ARK Servers\\cluster1\" -serverkey=server1", "steamCmdExecutablePath": "C:\\SteamCmd\\steamcmd.exe", "serverInstallDirPath": "C:\\ARK Servers\\server1", "usePowershellOutputRedirect": false, From fc5f50e691aeb84df679832d8aaf103a5a26da80 Mon Sep 17 00:00:00 2001 From: Tobias Sebring Date: Thu, 31 May 2018 09:25:37 +0200 Subject: [PATCH 03/15] Beta branch initial commit --- ArkBot.Tests/ArkBot.Tests.csproj | 18 + ArkBot.sln | 15 +- ArkBot/App.xaml | 7 +- ArkBot/App.xaml.cs | 11 + ArkBot/Ark/ArkClusterContext.cs | 3 +- ArkBot/Ark/ArkContextManager.cs | 7 +- ArkBot/Ark/ArkServerContext.cs | 5 +- ArkBot/Ark/IArkUpdateableContext.cs | 3 +- ArkBot/ArkBot.csproj | 115 +++- .../Browser/Behaviours/HoverLinkBehaviour.cs | 39 ++ .../Browser/EventArgs/BaseRequestEventArgs.cs | 20 + .../EventArgs/GetAuthCredentialsEventArgs.cs | 43 ++ .../GetResourceResponseFilterEventArgs.cs | 29 + .../EventArgs/OnBeforeBrowseEventArgs.cs | 30 + .../OnBeforeResourceLoadEventArgs.cs | 37 ++ .../EventArgs/OnCertificateErrorEventArgs.cs | 38 ++ .../EventArgs/OnOpenUrlFromTabEventArgs.cs | 32 + .../EventArgs/OnPluginCrashedEventArgs.cs | 18 + .../EventArgs/OnProtocolExecutionEventArgs.cs | 25 + .../EventArgs/OnQuotaRequestEventArgs.cs | 36 ++ .../OnRenderProcessTerminatedEventArgs.cs | 19 + .../EventArgs/OnRenderViewReadyEventArgs.cs | 15 + .../OnResourceLoadCompleteEventArgs.cs | 27 + .../EventArgs/OnResourceRedirectEventArgs.cs | 29 + .../EventArgs/OnResourceResponseEventArgs.cs | 32 + ArkBot/Browser/RequestEventHandler.cs | 178 ++++++ ArkBot/Commands/Admin/AdminCommand.cs | 1 + ArkBot/Commands/Admin/CloudCommand.cs | 1 + ArkBot/Commands/Admin/RconCommand.cs | 1 + ArkBot/Commands/CommandListCommand.cs | 1 + ArkBot/Commands/DisabledCommands.cs | 1 + ArkBot/Commands/Experimental/DebugCommand.cs | 3 +- ArkBot/Commands/ServersCommand.cs | 3 +- ArkBot/Commands/UnlinkSteamCommand.cs | 1 + ArkBot/Commands/WebAppCommand.cs | 1 + ArkBot/Config.cs | 531 ---------------- .../AccessControlConfigSectionConverter.cs | 21 + .../AccessControlFeatureGroupConverter.cs | 21 + ...ssControlFeatureGroupPropertyDescriptor.cs | 52 ++ .../AccessControlFeaturePropertyDescriptor.cs | 53 ++ .../ConfigurationHelpAttribute.cs | 22 + .../Configuration/CustomCollectionEditor.cs | 210 +++++++ ArkBot/Configuration/DirectoryPathEditor.cs | 6 +- .../Model/AccessControlConfigSection.cs | 30 + .../Model/AccessControlFeatureGroup.cs | 29 + .../Model/AccessControlFeatureRoles.cs | 26 + .../Model/ArkMultipliersConfigSection.cs | 46 ++ .../Model/BackupsConfigSection.cs | 46 ++ .../Model/ClusterConfigSection.cs | 53 ++ .../Model/ClustersConfigSection.cs | 27 + ArkBot/Configuration/Model/Config.cs | 308 ++++++++++ .../Model/ConfigurationCategories.cs | 30 + .../Model/DiscordConfigSection.cs | 71 +++ ArkBot/{ => Configuration/Model}/IConfig.cs | 10 +- .../Model/ServerConfigSection.cs | 134 +++++ .../Model/ServerManagementConfigSection.cs | 86 +++ .../Model/ServersConfigSection.cs | 27 + .../Configuration/Model/SslConfigSection.cs | 64 ++ .../Model/UserRolesConfigSection.cs | 16 + .../Configuration/Model/UsersInRoleConfig.cs | 42 ++ ArkBot/Configuration/Model/_temp_test.cs | 137 +++++ .../Configuration/MyCustomTypeDescriptor.cs | 313 ---------- ArkBot/Configuration/OpenFilePathEditor.cs | 6 +- ...imitiveTypeCollectionControlWithPreview.cs | 27 + .../StringArrayEditorWithPreview.cs | 56 ++ .../TypeToDisplayNameConverter.cs | 27 + .../Validation/DirectoryExistsAttribute.cs | 9 +- .../DirectoryPathIsValidAttribute.cs | 37 ++ .../Validation/FileExistsAttribute.cs | 6 +- .../Validation/IfValidationAttribute.cs | 14 +- .../Validation/MinLengthOptionalAttribute.cs | 38 ++ .../RegularExpressionCustomAttribute.cs | 36 ++ .../Validation/ValidateCollectionAttribute.cs | 44 ++ .../Validation/ValidateExpandableAttribute.cs | 40 ++ .../Validation/ValidationTemplate.cs | 10 +- ArkBot/Constants.cs | 2 + ArkBot/Controls/About.xaml | 33 + ArkBot/Controls/About.xaml.cs | 84 +++ ArkBot/Controls/Configuration.xaml | 75 ++- ArkBot/Controls/Configuration.xaml.cs | 411 ++++++++++++- ArkBot/Data/ArkSpeciesStats.cs | 3 +- ArkBot/Discord/ArkDiscordBot.cs | 1 + .../RoleRestrictedPreconditionAttribute.cs | 1 + ArkBot/Discord/DiscordManager.cs | 1 + .../Extensions/DependencyObjectExtensions.cs | 97 +++ ArkBot/Helpers/ArkDataHelper.cs | 3 +- ArkBot/Helpers/WebApiHelper.cs | 11 +- ArkBot/IConstants.cs | 2 + ArkBot/Layout/PaneStyleSelector.cs | 3 + ArkBot/Layout/PaneTemplateSelector.cs | 3 + ArkBot/MainWindow.xaml | 41 +- ArkBot/MainWindow.xaml.cs | 30 +- ArkBot/OpenID/SteamOpenIdOwin_temp.cs | 114 ++++ ArkBot/Resources/about.html | 72 +++ ArkBot/Resources/configurationHelp.html | 97 +++ .../ScheduledTasks/ScheduledTasksManager.cs | 3 +- ArkBot/Services/ArkServerService.cs | 23 +- ArkBot/Services/ISavegameBackupService.cs | 3 +- ArkBot/Services/SavegameBackupService.cs | 1 + ArkBot/Services/UrlShortenerService.cs | 3 +- ArkBot/Steam/SteamManager.cs | 3 +- ArkBot/Themes/CollectionControlDialog.xaml | 98 +++ ArkBot/ViewModel/AboutViewModel.cs | 97 +++ ArkBot/ViewModel/ConfigurationViewModel.cs | 107 +++- ArkBot/ViewModel/ConsoleViewModel.cs | 18 +- ArkBot/ViewModel/PaneViewModel.cs | 54 +- ArkBot/ViewModel/ToolViewModel.cs | 16 +- ArkBot/ViewModel/ViewModelBase.cs | 8 +- ArkBot/ViewModel/Workspace.cs | 568 ++++++++++-------- ArkBot/Voting/Handlers/BanVoteHandler.cs | 1 + .../Handlers/DestroyWildDinosVoteHandler.cs | 1 + ArkBot/Voting/Handlers/IVoteHandler.cs | 1 + .../Handlers/RestartServerVoteHandler.cs | 1 + .../Handlers/SetTimeOfDayVoteHandler.cs | 1 + ArkBot/Voting/Handlers/UnbanVoteHandler.cs | 1 + .../Handlers/UpdateServerVoteHandler.cs | 1 + ArkBot/Voting/VotingManager.cs | 1 + .../AccessControlAuthorizationFilter.cs | 3 +- .../Controllers/AdminServerController.cs | 1 + .../Controllers/AdministerController.cs | 1 + .../Controllers/AuthenticationController.cs | 9 +- .../WebApi/Controllers/BaseApiController.cs | 3 +- ArkBot/WebApi/Controllers/MapController.cs | 1 + ArkBot/WebApi/Controllers/PlayerController.cs | 15 +- ArkBot/WebApi/Controllers/ServerController.cs | 1 + .../WebApi/Controllers/ServersController.cs | 41 +- .../Controllers/StructuresController.cs | 1 + .../Controllers/WildCreaturesController.cs | 1 + ArkBot/WebApi/WebApiStartup.cs | 4 +- ArkBot/WebApp/WebAppStartup.cs | 35 +- ArkBot/WebApp/dist/index.html | 3 +- .../inline.8d8c7910f2f1b97eeb2d.bundle.js | 1 + .../inline.d542697940a0f4ff0711.bundle.js | 1 - .../dist/main.1a731cc2354a19787d11.bundle.js | 1 - .../dist/main.688b1c8230c8935f23ef.bundle.js | 1 + .../arkmap-structures.component.ts | 7 +- ArkBot/WebApp/src/app/arkmap.component.ts | 7 +- ArkBot/WebApp/src/app/http.service.ts | 7 +- ArkBot/WebApp/src/app/message.service.ts | 6 +- .../server-list/server-list.component.html | 2 +- .../src/environments/environment.prod.ts | 4 +- ArkBot/WebApp/src/index.html | 1 + ArkBot/aliases.json | 10 + ArkBot/defaultconfig.json | 75 ++- ArkBot/packages.config | 6 + 145 files changed, 4590 insertions(+), 1357 deletions(-) create mode 100644 ArkBot/Browser/Behaviours/HoverLinkBehaviour.cs create mode 100644 ArkBot/Browser/EventArgs/BaseRequestEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/GetAuthCredentialsEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/GetResourceResponseFilterEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnBeforeBrowseEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnBeforeResourceLoadEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnCertificateErrorEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnOpenUrlFromTabEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnPluginCrashedEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnProtocolExecutionEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnQuotaRequestEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnRenderProcessTerminatedEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnRenderViewReadyEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnResourceLoadCompleteEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnResourceRedirectEventArgs.cs create mode 100644 ArkBot/Browser/EventArgs/OnResourceResponseEventArgs.cs create mode 100644 ArkBot/Browser/RequestEventHandler.cs delete mode 100644 ArkBot/Config.cs create mode 100644 ArkBot/Configuration/AccessControlConfigSectionConverter.cs create mode 100644 ArkBot/Configuration/AccessControlFeatureGroupConverter.cs create mode 100644 ArkBot/Configuration/AccessControlFeatureGroupPropertyDescriptor.cs create mode 100644 ArkBot/Configuration/AccessControlFeaturePropertyDescriptor.cs create mode 100644 ArkBot/Configuration/ConfigurationHelpAttribute.cs create mode 100644 ArkBot/Configuration/CustomCollectionEditor.cs create mode 100644 ArkBot/Configuration/Model/AccessControlConfigSection.cs create mode 100644 ArkBot/Configuration/Model/AccessControlFeatureGroup.cs create mode 100644 ArkBot/Configuration/Model/AccessControlFeatureRoles.cs create mode 100644 ArkBot/Configuration/Model/ArkMultipliersConfigSection.cs create mode 100644 ArkBot/Configuration/Model/BackupsConfigSection.cs create mode 100644 ArkBot/Configuration/Model/ClusterConfigSection.cs create mode 100644 ArkBot/Configuration/Model/ClustersConfigSection.cs create mode 100644 ArkBot/Configuration/Model/Config.cs create mode 100644 ArkBot/Configuration/Model/ConfigurationCategories.cs create mode 100644 ArkBot/Configuration/Model/DiscordConfigSection.cs rename ArkBot/{ => Configuration/Model}/IConfig.cs (81%) create mode 100644 ArkBot/Configuration/Model/ServerConfigSection.cs create mode 100644 ArkBot/Configuration/Model/ServerManagementConfigSection.cs create mode 100644 ArkBot/Configuration/Model/ServersConfigSection.cs create mode 100644 ArkBot/Configuration/Model/SslConfigSection.cs create mode 100644 ArkBot/Configuration/Model/UserRolesConfigSection.cs create mode 100644 ArkBot/Configuration/Model/UsersInRoleConfig.cs create mode 100644 ArkBot/Configuration/Model/_temp_test.cs delete mode 100644 ArkBot/Configuration/MyCustomTypeDescriptor.cs create mode 100644 ArkBot/Configuration/PrimitiveTypeCollectionControlWithPreview.cs create mode 100644 ArkBot/Configuration/StringArrayEditorWithPreview.cs create mode 100644 ArkBot/Configuration/TypeToDisplayNameConverter.cs create mode 100644 ArkBot/Configuration/Validation/DirectoryPathIsValidAttribute.cs create mode 100644 ArkBot/Configuration/Validation/MinLengthOptionalAttribute.cs create mode 100644 ArkBot/Configuration/Validation/RegularExpressionCustomAttribute.cs create mode 100644 ArkBot/Configuration/Validation/ValidateCollectionAttribute.cs create mode 100644 ArkBot/Configuration/Validation/ValidateExpandableAttribute.cs create mode 100644 ArkBot/Controls/About.xaml create mode 100644 ArkBot/Controls/About.xaml.cs create mode 100644 ArkBot/Extensions/DependencyObjectExtensions.cs create mode 100644 ArkBot/OpenID/SteamOpenIdOwin_temp.cs create mode 100644 ArkBot/Resources/about.html create mode 100644 ArkBot/Resources/configurationHelp.html create mode 100644 ArkBot/Themes/CollectionControlDialog.xaml create mode 100644 ArkBot/ViewModel/AboutViewModel.cs create mode 100644 ArkBot/WebApp/dist/inline.8d8c7910f2f1b97eeb2d.bundle.js delete mode 100644 ArkBot/WebApp/dist/inline.d542697940a0f4ff0711.bundle.js delete mode 100644 ArkBot/WebApp/dist/main.1a731cc2354a19787d11.bundle.js create mode 100644 ArkBot/WebApp/dist/main.688b1c8230c8935f23ef.bundle.js diff --git a/ArkBot.Tests/ArkBot.Tests.csproj b/ArkBot.Tests/ArkBot.Tests.csproj index a387ccd..37c7223 100644 --- a/ArkBot.Tests/ArkBot.Tests.csproj +++ b/ArkBot.Tests/ArkBot.Tests.csproj @@ -35,6 +35,24 @@ prompt 4 + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + MinimumRecommendedRules.ruleset + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + prompt + MinimumRecommendedRules.ruleset + diff --git a/ArkBot.sln b/ArkBot.sln index 1093962..f8409cc 100644 --- a/ArkBot.sln +++ b/ArkBot.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 14 -VisualStudioVersion = 14.0.25420.1 +# Visual Studio 15 +VisualStudioVersion = 15.0.27130.2003 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ArkBot", "ArkBot\ArkBot.csproj", "{BB61C4D0-0060-401B-BF8F-4747CBD86D9D}" EndProject @@ -10,17 +10,28 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {BB61C4D0-0060-401B-BF8F-4747CBD86D9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BB61C4D0-0060-401B-BF8F-4747CBD86D9D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB61C4D0-0060-401B-BF8F-4747CBD86D9D}.Debug|x64.ActiveCfg = Debug|x64 + {BB61C4D0-0060-401B-BF8F-4747CBD86D9D}.Debug|x64.Build.0 = Debug|x64 {BB61C4D0-0060-401B-BF8F-4747CBD86D9D}.Release|Any CPU.ActiveCfg = Release|Any CPU {BB61C4D0-0060-401B-BF8F-4747CBD86D9D}.Release|Any CPU.Build.0 = Release|Any CPU + {BB61C4D0-0060-401B-BF8F-4747CBD86D9D}.Release|x64.ActiveCfg = Release|x64 + {BB61C4D0-0060-401B-BF8F-4747CBD86D9D}.Release|x64.Build.0 = Release|x64 {F302C35B-97B4-4E9A-B628-F17FE7DB8A45}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F302C35B-97B4-4E9A-B628-F17FE7DB8A45}.Debug|x64.ActiveCfg = Debug|x64 {F302C35B-97B4-4E9A-B628-F17FE7DB8A45}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F302C35B-97B4-4E9A-B628-F17FE7DB8A45}.Release|x64.ActiveCfg = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {CAF3F7A8-BCB0-4EEA-9730-DF724C1C6C2C} + EndGlobalSection EndGlobal diff --git a/ArkBot/App.xaml b/ArkBot/App.xaml index ef26420..7a49456 100644 --- a/ArkBot/App.xaml +++ b/ArkBot/App.xaml @@ -1,9 +1,14 @@  - + + + + + diff --git a/ArkBot/App.xaml.cs b/ArkBot/App.xaml.cs index 47b0b8d..5df8fba 100644 --- a/ArkBot/App.xaml.cs +++ b/ArkBot/App.xaml.cs @@ -6,9 +6,11 @@ using System.Data; using System.IO; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; using System.Windows; +using CefSharp; namespace ArkBot { @@ -23,6 +25,15 @@ public App() Console.SetOut(new WpfConsoleWriter()); Kernel32.RegisterApplicationRestart("/restart", (int)RestartRestrictions.None); + + var settings = new CefSettings() + { + //LogSeverity = LogSeverity.Verbose, + LogFile = "logs\\cefsharp.log", + BrowserSubprocessPath = "lib\\CefSharp.BrowserSubprocess.exe", + }; + + Cef.Initialize(settings, performDependencyCheck: true, browserProcessHandler: null); } private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) diff --git a/ArkBot/Ark/ArkClusterContext.cs b/ArkBot/Ark/ArkClusterContext.cs index 688cca4..62d1520 100644 --- a/ArkBot/Ark/ArkClusterContext.cs +++ b/ArkBot/Ark/ArkClusterContext.cs @@ -1,4 +1,5 @@ -using ArkBot.Services; +using ArkBot.Configuration.Model; +using ArkBot.Services; using ArkSavegameToolkitNet; using ArkSavegameToolkitNet.Domain; using System; diff --git a/ArkBot/Ark/ArkContextManager.cs b/ArkBot/Ark/ArkContextManager.cs index e5c6e79..7d5a73a 100644 --- a/ArkBot/Ark/ArkContextManager.cs +++ b/ArkBot/Ark/ArkContextManager.cs @@ -1,4 +1,5 @@ -using ArkBot.Services; +using ArkBot.Configuration.Model; +using ArkBot.Services; using ArkBot.Services.Data; using ArkBot.Threading; using ArkSavegameToolkitNet; @@ -89,7 +90,7 @@ private void _saveFileWatcher_Changed(ArkServerContext serverContext, ArkSaveFil { QueueServerUpdate(serverContext); - var clusterContext = GetCluster(serverContext.Config.Cluster); + var clusterContext = GetCluster(serverContext.Config.ClusterKey); if (clusterContext == null) return; QueueClusterUpdate(clusterContext); } @@ -225,7 +226,7 @@ public ArkServerContext[] GetServersInCluster(string key) { if (key == null) return null; - return Servers.Where(x => x.Config.Cluster.Equals(key, StringComparison.OrdinalIgnoreCase)).ToArray(); + return Servers.Where(x => x.Config.ClusterKey.Equals(key, StringComparison.OrdinalIgnoreCase)).ToArray(); } public ArkClusterContext GetCluster(string key) diff --git a/ArkBot/Ark/ArkServerContext.cs b/ArkBot/Ark/ArkServerContext.cs index 6838aff..4174b85 100644 --- a/ArkBot/Ark/ArkServerContext.cs +++ b/ArkBot/Ark/ArkServerContext.cs @@ -1,4 +1,5 @@ -using ArkBot.Database.Model; +using ArkBot.Configuration.Model; +using ArkBot.Database.Model; using ArkBot.Services; using ArkBot.Services.Data; using ArkBot.Steam; @@ -168,7 +169,7 @@ public bool Update(bool manualUpdate, IConfig fullconfig, ISavegameBackupService { if (fullconfig.Backups.BackupsEnabled) { - bresult = savegameBackupService.CreateBackup(Config, _contextManager?.GetCluster(Config.Cluster)?.Config); + bresult = savegameBackupService.CreateBackup(Config, _contextManager?.GetCluster(Config.ClusterKey)?.Config); if (bresult != null && bresult.ArchivePaths != null) progress.Report($@"Server ({Config.Key}): Backup successfull ({(string.Join(", ", bresult.ArchivePaths.Select(x => $@"""{x}""")))})!"); else progress.Report($"Server ({Config.Key}): Backup failed..."); } diff --git a/ArkBot/Ark/IArkUpdateableContext.cs b/ArkBot/Ark/IArkUpdateableContext.cs index ee5f5b6..3cd7aff 100644 --- a/ArkBot/Ark/IArkUpdateableContext.cs +++ b/ArkBot/Ark/IArkUpdateableContext.cs @@ -1,4 +1,5 @@ -using ArkBot.Services; +using ArkBot.Configuration.Model; +using ArkBot.Services; using System; using System.Collections.Generic; using System.Linq; diff --git a/ArkBot/ArkBot.csproj b/ArkBot/ArkBot.csproj index 75277c8..a6037b4 100644 --- a/ArkBot/ArkBot.csproj +++ b/ArkBot/ArkBot.csproj @@ -1,5 +1,7 @@  + + @@ -46,6 +48,27 @@ basket_empty.ico + + true + bin\x64\Debug\ + DEBUG;TRACE + full + x64 + prompt + MinimumRecommendedRules.ruleset + true + + + bin\x64\Release\ + TRACE + true + pdbonly + x64 + false + prompt + MinimumRecommendedRules.ruleset + true + ..\packages\Accord.3.5.0\lib\net46\Accord.dll @@ -184,6 +207,9 @@ ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll True + + ..\packages\Markdig.0.14.8\lib\net40\Markdig.dll + ..\packages\Microsoft.AspNet.SignalR.Core.2.2.2\lib\net45\Microsoft.AspNet.SignalR.Core.dll True @@ -264,6 +290,9 @@ ..\packages\Nancy.1.4.1\lib\net40\Nancy.dll True + + ..\packages\Nancy.Bootstrappers.Autofac.1.4.1\lib\net40\Nancy.Bootstrappers.Autofac.dll + ..\packages\Nancy.Owin.1.4.1\lib\net40\Nancy.Owin.dll True @@ -508,6 +537,23 @@ + + + + + + + + + + + + + + + + + @@ -531,15 +577,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + About.xaml + Configuration.xaml @@ -576,12 +654,14 @@ + + @@ -613,7 +693,7 @@ 201703262316086_Voting.cs - + @@ -647,7 +727,7 @@ - + @@ -676,6 +756,7 @@ + @@ -776,6 +857,12 @@ --> + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -812,6 +899,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + MSBuild:Compile Designer @@ -824,9 +915,16 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + + + $(TargetDir)\lib + @@ -842,6 +940,12 @@ + + + + + + @@ -855,6 +959,7 @@ + @@ -866,4 +971,8 @@ + + + + \ No newline at end of file diff --git a/ArkBot/Browser/Behaviours/HoverLinkBehaviour.cs b/ArkBot/Browser/Behaviours/HoverLinkBehaviour.cs new file mode 100644 index 0000000..57522e0 --- /dev/null +++ b/ArkBot/Browser/Behaviours/HoverLinkBehaviour.cs @@ -0,0 +1,39 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp.Wpf; +using System.Windows; +using System.Windows.Interactivity; +using System; + +namespace ArkBot.Browser.Behaviours +{ + public class HoverLinkBehaviour : Behavior + { + // Using a DependencyProperty as the backing store for HoverLink. This enables animation, styling, binding, etc... + public static readonly DependencyProperty HoverLinkProperty = DependencyProperty.Register("HoverLink", typeof(string), typeof(HoverLinkBehaviour), new PropertyMetadata(string.Empty)); + + public string HoverLink + { + get { return (string)GetValue(HoverLinkProperty); } + set { SetValue(HoverLinkProperty, value); } + } + + protected override void OnAttached() + { + AssociatedObject.StatusMessage += OnStatusMessageChanged; + } + + protected override void OnDetaching() + { + AssociatedObject.StatusMessage -= OnStatusMessageChanged; + } + + private void OnStatusMessageChanged(object sender, CefSharp.StatusMessageEventArgs e) + { + var chromiumWebBrowser = sender as ChromiumWebBrowser; + chromiumWebBrowser.Dispatcher.BeginInvoke((Action)(() => HoverLink = e.Value)); + } + } +} diff --git a/ArkBot/Browser/EventArgs/BaseRequestEventArgs.cs b/ArkBot/Browser/EventArgs/BaseRequestEventArgs.cs new file mode 100644 index 0000000..833bef4 --- /dev/null +++ b/ArkBot/Browser/EventArgs/BaseRequestEventArgs.cs @@ -0,0 +1,20 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public abstract class BaseRequestEventArgs : System.EventArgs + { + protected BaseRequestEventArgs(IWebBrowser browserControl, IBrowser browser) + { + BrowserControl = browserControl; + Browser = browser; + } + + public IWebBrowser BrowserControl { get; private set; } + public IBrowser Browser { get; private set; } + } +} diff --git a/ArkBot/Browser/EventArgs/GetAuthCredentialsEventArgs.cs b/ArkBot/Browser/EventArgs/GetAuthCredentialsEventArgs.cs new file mode 100644 index 0000000..fee239f --- /dev/null +++ b/ArkBot/Browser/EventArgs/GetAuthCredentialsEventArgs.cs @@ -0,0 +1,43 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class GetAuthCredentialsEventArgs : BaseRequestEventArgs + { + public GetAuthCredentialsEventArgs(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback) : base(browserControl, browser) + { + Frame = frame; + IsProxy = isProxy; + Host = host; + Port = port; + Realm = realm; + Scheme = scheme; + Callback = callback; + + ContinueAsync = false; // default + } + + public IFrame Frame { get; private set; } + public bool IsProxy { get; private set; } + public string Host { get; private set; } + public int Port { get; private set; } + public string Realm { get; private set; } + public string Scheme { get; private set; } + + /// + /// Callback interface used for asynchronous continuation of authentication requests. + /// + public IAuthCallback Callback { get; private set; } + + /// + /// Set to true to continue the request and call + /// when the authentication information + /// is available. Set to false to cancel the request. + /// + public bool ContinueAsync { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/GetResourceResponseFilterEventArgs.cs b/ArkBot/Browser/EventArgs/GetResourceResponseFilterEventArgs.cs new file mode 100644 index 0000000..717cdad --- /dev/null +++ b/ArkBot/Browser/EventArgs/GetResourceResponseFilterEventArgs.cs @@ -0,0 +1,29 @@ +// Copyright � 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class GetResourceResponseFilterEventArgs : BaseRequestEventArgs + { + public GetResourceResponseFilterEventArgs(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) : base(browserControl, browser) + { + Frame = frame; + Request = request; + Response = response; + + ResponseFilter = null; // default + } + + public IFrame Frame { get; private set; } + public IRequest Request { get; private set; } + public IResponse Response { get; private set; } + + /// + /// Set a ResponseFilter to intercept this response, leave it null otherwise. + /// + public IResponseFilter ResponseFilter { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnBeforeBrowseEventArgs.cs b/ArkBot/Browser/EventArgs/OnBeforeBrowseEventArgs.cs new file mode 100644 index 0000000..ce89a77 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnBeforeBrowseEventArgs.cs @@ -0,0 +1,30 @@ +// Copyright � 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnBeforeBrowseEventArgs : BaseRequestEventArgs + { + public OnBeforeBrowseEventArgs(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect) + : base(browserControl, browser) + { + Frame = frame; + Request = request; + IsRedirect = isRedirect; + + CancelNavigation = false; // default + } + + public IFrame Frame { get; private set; } + public IRequest Request { get; private set; } + public bool IsRedirect { get; private set; } + + /// + /// Set to true to cancel the navigation or false to allow the navigation to proceed. + /// + public bool CancelNavigation { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnBeforeResourceLoadEventArgs.cs b/ArkBot/Browser/EventArgs/OnBeforeResourceLoadEventArgs.cs new file mode 100644 index 0000000..1c6b50c --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnBeforeResourceLoadEventArgs.cs @@ -0,0 +1,37 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnBeforeResourceLoadEventArgs : BaseRequestEventArgs + { + public OnBeforeResourceLoadEventArgs(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) + : base(browserControl, browser) + { + Frame = frame; + Request = request; + Callback = callback; + + ContinuationHandling = CefReturnValue.Continue; // default + } + + public IFrame Frame { get; private set; } + public IRequest Request { get; private set; } + + /// + /// Callback interface used for asynchronous continuation of url requests. + /// + public IRequestCallback Callback { get; private set; } + + /// + /// To cancel loading of the resource return + /// or to allow the resource to load normally. For async + /// return and use + /// to handle continuation. + /// + public CefReturnValue ContinuationHandling { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnCertificateErrorEventArgs.cs b/ArkBot/Browser/EventArgs/OnCertificateErrorEventArgs.cs new file mode 100644 index 0000000..ef48489 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnCertificateErrorEventArgs.cs @@ -0,0 +1,38 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnCertificateErrorEventArgs : BaseRequestEventArgs + { + public OnCertificateErrorEventArgs(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback) + : base(browserControl, browser) + { + ErrorCode = errorCode; + RequestUrl = requestUrl; + SSLInfo = sslInfo; + Callback = callback; + + ContinueAsync = false; // default + } + + public CefErrorCode ErrorCode { get; private set; } + public string RequestUrl { get; private set; } + public ISslInfo SSLInfo { get; private set; } + + /// + /// Callback interface used for asynchronous continuation of url requests. + /// If empty the error cannot be recovered from and the request will be canceled automatically. + /// + public IRequestCallback Callback { get; private set; } + + /// + /// Set to false to cancel the request immediately. Set to true and use to + /// execute in an async fashion. + /// + public bool ContinueAsync { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnOpenUrlFromTabEventArgs.cs b/ArkBot/Browser/EventArgs/OnOpenUrlFromTabEventArgs.cs new file mode 100644 index 0000000..cac822e --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnOpenUrlFromTabEventArgs.cs @@ -0,0 +1,32 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnOpenUrlFromTabEventArgs : BaseRequestEventArgs + { + public OnOpenUrlFromTabEventArgs(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) + : base(browserControl, browser) + { + Frame = frame; + TargetUrl = targetUrl; + TargetDisposition = targetDisposition; + UserGesture = userGesture; + + CancelNavigation = false; // default + } + + public IFrame Frame { get; private set; } + public string TargetUrl { get; private set; } + public WindowOpenDisposition TargetDisposition { get; private set; } + public bool UserGesture { get; private set; } + + /// + /// Set to true to cancel the navigation or false to allow the navigation to proceed. + /// + public bool CancelNavigation { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnPluginCrashedEventArgs.cs b/ArkBot/Browser/EventArgs/OnPluginCrashedEventArgs.cs new file mode 100644 index 0000000..8ee0390 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnPluginCrashedEventArgs.cs @@ -0,0 +1,18 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnPluginCrashedEventArgs : BaseRequestEventArgs + { + public OnPluginCrashedEventArgs(IWebBrowser browserControl, IBrowser browser, string pluginPath) : base(browserControl, browser) + { + PluginPath = pluginPath; + } + + public string PluginPath { get; private set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnProtocolExecutionEventArgs.cs b/ArkBot/Browser/EventArgs/OnProtocolExecutionEventArgs.cs new file mode 100644 index 0000000..1493f4b --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnProtocolExecutionEventArgs.cs @@ -0,0 +1,25 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnProtocolExecutionEventArgs : BaseRequestEventArgs + { + public OnProtocolExecutionEventArgs(IWebBrowser browserControl, IBrowser browser, string url) : base(browserControl, browser) + { + Url = url; + + AttemptExecution = false; // default + } + + public string Url { get; private set; } + + /// + /// Set to true to attempt execution via the registered OS protocol handler, if any. Otherwise set to false. + /// + public bool AttemptExecution { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnQuotaRequestEventArgs.cs b/ArkBot/Browser/EventArgs/OnQuotaRequestEventArgs.cs new file mode 100644 index 0000000..3d12402 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnQuotaRequestEventArgs.cs @@ -0,0 +1,36 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnQuotaRequestEventArgs : BaseRequestEventArgs + { + public OnQuotaRequestEventArgs(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback) + : base(browserControl, browser) + { + OriginUrl = originUrl; + NewSize = newSize; + Callback = callback; + + ContinueAsync = false; // default + } + + public string OriginUrl { get; private set; } + public long NewSize { get; private set; } + + /// + /// Callback interface used for asynchronous continuation of url requests. + /// + public IRequestCallback Callback { get; private set; } + + /// + /// Set to false to cancel the request immediately. Set to true to continue the request + /// and call either in this method or at a later + /// time to grant or deny the request. + /// + public bool ContinueAsync { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnRenderProcessTerminatedEventArgs.cs b/ArkBot/Browser/EventArgs/OnRenderProcessTerminatedEventArgs.cs new file mode 100644 index 0000000..6156885 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnRenderProcessTerminatedEventArgs.cs @@ -0,0 +1,19 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnRenderProcessTerminatedEventArgs : BaseRequestEventArgs + { + public OnRenderProcessTerminatedEventArgs(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status) + : base(browserControl, browser) + { + Status = status; + } + + public CefTerminationStatus Status { get; private set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnRenderViewReadyEventArgs.cs b/ArkBot/Browser/EventArgs/OnRenderViewReadyEventArgs.cs new file mode 100644 index 0000000..65dd266 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnRenderViewReadyEventArgs.cs @@ -0,0 +1,15 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnRenderViewReadyEventArgs : BaseRequestEventArgs + { + public OnRenderViewReadyEventArgs(IWebBrowser browserControl, IBrowser browser) : base(browserControl, browser) + { + } + } +} diff --git a/ArkBot/Browser/EventArgs/OnResourceLoadCompleteEventArgs.cs b/ArkBot/Browser/EventArgs/OnResourceLoadCompleteEventArgs.cs new file mode 100644 index 0000000..4d9f552 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnResourceLoadCompleteEventArgs.cs @@ -0,0 +1,27 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnResourceLoadCompleteEventArgs : BaseRequestEventArgs + { + public OnResourceLoadCompleteEventArgs(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) + : base(browserControl, browser) + { + Frame = frame; + Request = request; + Response = response; + Status = status; + ReceivedContentLength = receivedContentLength; + } + + public IFrame Frame { get; private set; } + public IRequest Request { get; private set; } + public IResponse Response { get; private set; } + public UrlRequestStatus Status { get; private set; } + public long ReceivedContentLength { get; private set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnResourceRedirectEventArgs.cs b/ArkBot/Browser/EventArgs/OnResourceRedirectEventArgs.cs new file mode 100644 index 0000000..7671a67 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnResourceRedirectEventArgs.cs @@ -0,0 +1,29 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnResourceRedirectEventArgs : BaseRequestEventArgs + { + public OnResourceRedirectEventArgs(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, string newUrl) + : base(browserControl, browser) + { + Frame = frame; + Request = request; + Response = response; + NewUrl = newUrl; + } + + public IFrame Frame { get; private set; } + public IRequest Request { get; private set; } + public IResponse Response { get; private set; } + + /// + /// the new URL and can be changed if desired. + /// + public string NewUrl { get; set; } + } +} diff --git a/ArkBot/Browser/EventArgs/OnResourceResponseEventArgs.cs b/ArkBot/Browser/EventArgs/OnResourceResponseEventArgs.cs new file mode 100644 index 0000000..d4f7834 --- /dev/null +++ b/ArkBot/Browser/EventArgs/OnResourceResponseEventArgs.cs @@ -0,0 +1,32 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using CefSharp; + +namespace ArkBot.Browser.EventArgs +{ + public class OnResourceResponseEventArgs : BaseRequestEventArgs + { + public OnResourceResponseEventArgs(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) + : base(browserControl, browser) + { + Frame = frame; + Request = request; + Response = response; + + RedirectOrRetry = false; // default + } + + public IFrame Frame { get; private set; } + public IRequest Request { get; private set; } + public IResponse Response { get; private set; } + + /// + /// To allow the resource to load normally set to false. + /// To redirect or retry the resource, modify (url, headers or + /// post body) and set to true. + /// + public bool RedirectOrRetry { get; set; } + } +} diff --git a/ArkBot/Browser/RequestEventHandler.cs b/ArkBot/Browser/RequestEventHandler.cs new file mode 100644 index 0000000..1874fca --- /dev/null +++ b/ArkBot/Browser/RequestEventHandler.cs @@ -0,0 +1,178 @@ +// Copyright © 2010-2017 The CefSharp Authors. All rights reserved. +// +// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. + +using ArkBot.Browser.EventArgs; +using CefSharp; +using System; +using System.Security.Cryptography.X509Certificates; + +namespace ArkBot.Browser +{ + /// + /// To use this class, check for more information about the event parameters. + /// Often you will find MANDATORY information on how to work with the parameters or which thread the call comes from. + /// Simply check out the interface' method the event was named by. + /// (e.g corresponds to + /// ) + /// inspired by: + /// https://github.com/cefsharp/CefSharp/blob/fa41529853b2527eb0468a507ab6c5bd0768eb59/CefSharp.Example/RequestHandler.cs + /// + public class RequestEventHandler : IRequestHandler + { + public event EventHandler OnBeforeBrowseEvent; + public event EventHandler OnOpenUrlFromTabEvent; + public event EventHandler OnCertificateErrorEvent; + public event EventHandler OnPluginCrashedEvent; + public event EventHandler OnBeforeResourceLoadEvent; + public event EventHandler GetAuthCredentialsEvent; + public event EventHandler OnRenderProcessTerminatedEvent; + public event EventHandler OnQuotaRequestEvent; + public event EventHandler OnResourceRedirectEvent; + + /// + /// SECURITY WARNING: YOU SHOULD USE THIS EVENT TO ENFORCE RESTRICTIONS BASED ON SCHEME, HOST OR OTHER URL ANALYSIS + /// BEFORE ALLOWING OS EXECUTION. + /// + public event EventHandler OnProtocolExecutionEvent; + public event EventHandler OnRenderViewReadyEvent; + public event EventHandler OnResourceResponseEvent; + public event EventHandler GetResourceResponseFilterEvent; + public event EventHandler OnResourceLoadCompleteEvent; + + bool IRequestHandler.OnBeforeBrowse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, bool isRedirect) + { + var args = new OnBeforeBrowseEventArgs(browserControl, browser, frame, request, isRedirect); + ExecuteEventHandler(OnBeforeBrowseEvent, args); + return args.CancelNavigation; + } + + bool IRequestHandler.OnOpenUrlFromTab(IWebBrowser browserControl, IBrowser browser, IFrame frame, string targetUrl, WindowOpenDisposition targetDisposition, bool userGesture) + { + var args = new OnOpenUrlFromTabEventArgs(browserControl, browser, frame, targetUrl, targetDisposition, userGesture); + ExecuteEventHandler(OnOpenUrlFromTabEvent, args); + return args.CancelNavigation; + } + + bool IRequestHandler.OnCertificateError(IWebBrowser browserControl, IBrowser browser, CefErrorCode errorCode, string requestUrl, ISslInfo sslInfo, IRequestCallback callback) + { + var args = new OnCertificateErrorEventArgs(browserControl, browser, errorCode, requestUrl, sslInfo, callback); + ExecuteEventHandler(OnCertificateErrorEvent, args); + + EnsureCallbackDisposal(callback); + return args.ContinueAsync; + } + + void IRequestHandler.OnPluginCrashed(IWebBrowser browserControl, IBrowser browser, string pluginPath) + { + var args = new OnPluginCrashedEventArgs(browserControl, browser, pluginPath); + ExecuteEventHandler(OnPluginCrashedEvent, args); + } + + CefReturnValue IRequestHandler.OnBeforeResourceLoad(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IRequestCallback callback) + { + var args = new OnBeforeResourceLoadEventArgs(browserControl, browser, frame, request, callback); + ExecuteEventHandler(OnBeforeResourceLoadEvent, args); + + EnsureCallbackDisposal(callback); + return args.ContinuationHandling; + } + + bool IRequestHandler.GetAuthCredentials(IWebBrowser browserControl, IBrowser browser, IFrame frame, bool isProxy, string host, int port, string realm, string scheme, IAuthCallback callback) + { + var args = new GetAuthCredentialsEventArgs(browserControl, browser, frame, isProxy, host, port, realm, scheme, callback); + ExecuteEventHandler(GetAuthCredentialsEvent, args); + + EnsureCallbackDisposal(callback); + return args.ContinueAsync; + } + + void IRequestHandler.OnRenderProcessTerminated(IWebBrowser browserControl, IBrowser browser, CefTerminationStatus status) + { + var args = new OnRenderProcessTerminatedEventArgs(browserControl, browser, status); + ExecuteEventHandler(OnRenderProcessTerminatedEvent, args); + } + + bool IRequestHandler.OnQuotaRequest(IWebBrowser browserControl, IBrowser browser, string originUrl, long newSize, IRequestCallback callback) + { + var args = new OnQuotaRequestEventArgs(browserControl, browser, originUrl, newSize, callback); + ExecuteEventHandler(OnQuotaRequestEvent, args); + + EnsureCallbackDisposal(callback); + return args.ContinueAsync; + } + + void IRequestHandler.OnResourceRedirect(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, ref string newUrl) + { + var args = new OnResourceRedirectEventArgs(browserControl, browser, frame, request, response, newUrl); + ExecuteEventHandler(OnResourceRedirectEvent, args); + if (!Equals(newUrl, args.NewUrl)) + { + newUrl = args.NewUrl; + } + } + + bool IRequestHandler.OnProtocolExecution(IWebBrowser browserControl, IBrowser browser, string url) + { + var args = new OnProtocolExecutionEventArgs(browserControl, browser, url); + ExecuteEventHandler(OnProtocolExecutionEvent, args); + return args.AttemptExecution; + } + + void IRequestHandler.OnRenderViewReady(IWebBrowser browserControl, IBrowser browser) + { + var args = new OnRenderViewReadyEventArgs(browserControl, browser); + ExecuteEventHandler(OnRenderViewReadyEvent, args); + } + + bool IRequestHandler.OnResourceResponse(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) + { + var args = new OnResourceResponseEventArgs(browserControl, browser, frame, request, response); + ExecuteEventHandler(OnResourceResponseEvent, args); + return args.RedirectOrRetry; + } + + IResponseFilter IRequestHandler.GetResourceResponseFilter(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response) + { + var args = new GetResourceResponseFilterEventArgs(browserControl, browser, frame, request, response); + ExecuteEventHandler(GetResourceResponseFilterEvent, args); + return args.ResponseFilter; + } + + void IRequestHandler.OnResourceLoadComplete(IWebBrowser browserControl, IBrowser browser, IFrame frame, IRequest request, IResponse response, UrlRequestStatus status, long receivedContentLength) + { + var args = new OnResourceLoadCompleteEventArgs(browserControl, browser, frame, request, response, status, receivedContentLength); + ExecuteEventHandler(OnResourceLoadCompleteEvent, args); + } + + bool IRequestHandler.OnSelectClientCertificate(IWebBrowser browserControl, IBrowser browser, bool isProxy, string host, int port, X509Certificate2Collection certificates, ISelectClientCertificateCallback callback) + { + //TODO: Someone please contribute an implementation of this + throw new NotImplementedException(); + } + + private static void EnsureCallbackDisposal(IRequestCallback callbackToDispose) + { + if (callbackToDispose != null && !callbackToDispose.IsDisposed) + { + callbackToDispose.Dispose(); + } + } + + private static void EnsureCallbackDisposal(IAuthCallback callbackToDispose) + { + if (callbackToDispose != null && !callbackToDispose.IsDisposed) + { + callbackToDispose.Dispose(); + } + } + + private void ExecuteEventHandler(EventHandler handler, T args) + { + if (handler != null) + { + handler(this, args); + } + } + } +} diff --git a/ArkBot/Commands/Admin/AdminCommand.cs b/ArkBot/Commands/Admin/AdminCommand.cs index e65d7ba..3d8fc79 100644 --- a/ArkBot/Commands/Admin/AdminCommand.cs +++ b/ArkBot/Commands/Admin/AdminCommand.cs @@ -18,6 +18,7 @@ using ArkBot.ScheduledTasks; using Discord.Commands.Builders; using RestSharp; +using ArkBot.Configuration.Model; namespace ArkBot.Commands.Admin { diff --git a/ArkBot/Commands/Admin/CloudCommand.cs b/ArkBot/Commands/Admin/CloudCommand.cs index dcc2b2a..1771c8b 100644 --- a/ArkBot/Commands/Admin/CloudCommand.cs +++ b/ArkBot/Commands/Admin/CloudCommand.cs @@ -20,6 +20,7 @@ using ArkBot.Discord.Command; using Discord.Commands.Builders; using RestSharp; +using ArkBot.Configuration.Model; namespace ArkBot.Commands.Admin { diff --git a/ArkBot/Commands/Admin/RconCommand.cs b/ArkBot/Commands/Admin/RconCommand.cs index aa43345..0925b11 100644 --- a/ArkBot/Commands/Admin/RconCommand.cs +++ b/ArkBot/Commands/Admin/RconCommand.cs @@ -15,6 +15,7 @@ using ArkBot.ScheduledTasks; using Discord.Commands.Builders; using RestSharp; +using ArkBot.Configuration.Model; namespace ArkBot.Commands.Admin { diff --git a/ArkBot/Commands/CommandListCommand.cs b/ArkBot/Commands/CommandListCommand.cs index 98facbc..5b4d55d 100644 --- a/ArkBot/Commands/CommandListCommand.cs +++ b/ArkBot/Commands/CommandListCommand.cs @@ -11,6 +11,7 @@ using Discord.Commands.Builders; using Discord.WebSocket; using RestSharp; +using ArkBot.Configuration.Model; namespace ArkBot.Commands { diff --git a/ArkBot/Commands/DisabledCommands.cs b/ArkBot/Commands/DisabledCommands.cs index cbc543b..ebc8aa3 100644 --- a/ArkBot/Commands/DisabledCommands.cs +++ b/ArkBot/Commands/DisabledCommands.cs @@ -8,6 +8,7 @@ using Discord.Commands.Builders; using Discord.Net; using RestSharp; +using ArkBot.Configuration.Model; namespace ArkBot.Commands { diff --git a/ArkBot/Commands/Experimental/DebugCommand.cs b/ArkBot/Commands/Experimental/DebugCommand.cs index 8630148..afcba71 100644 --- a/ArkBot/Commands/Experimental/DebugCommand.cs +++ b/ArkBot/Commands/Experimental/DebugCommand.cs @@ -15,6 +15,7 @@ using Discord.Commands.Builders; using Discord.Net; using RestSharp; +using ArkBot.Configuration.Model; namespace ArkBot.Commands.Experimental { @@ -214,7 +215,7 @@ public async Task Debug([Remainder] string arguments = null) return; } saveFilePath = server.SaveFilePath; - var cluster = !string.IsNullOrEmpty(server.Cluster) ? _config.Clusters?.FirstOrDefault(x => x.Key.Equals(server.Cluster, StringComparison.OrdinalIgnoreCase)) : null; + var cluster = !string.IsNullOrEmpty(server.ClusterKey) ? _config.Clusters?.FirstOrDefault(x => x.Key.Equals(server.ClusterKey, StringComparison.OrdinalIgnoreCase)) : null; clusterSavePath = cluster?.SavePath; } else diff --git a/ArkBot/Commands/ServersCommand.cs b/ArkBot/Commands/ServersCommand.cs index 3314018..b56c140 100644 --- a/ArkBot/Commands/ServersCommand.cs +++ b/ArkBot/Commands/ServersCommand.cs @@ -9,6 +9,7 @@ using ArkBot.Discord.Command; using Discord.Commands.Builders; using Discord.Net; +using ArkBot.Configuration.Model; namespace ArkBot.Commands { @@ -53,7 +54,7 @@ public async Task Servers([Remainder] string arguments = null) var address = server.DisplayAddress ?? $"{server.Ip}:{server.QueryPort}"; - var cluster = args.cluster || args.clusters ? $" (cluster **`{server.Cluster}`**)" : ""; + var cluster = args.cluster || args.clusters ? $" (cluster **`{server.ClusterKey}`**)" : ""; embed.AddInlineField($"{ name ?? address}", $"steam://connect/{address} (key: `{server.Key}`){cluster}"); } diff --git a/ArkBot/Commands/UnlinkSteamCommand.cs b/ArkBot/Commands/UnlinkSteamCommand.cs index 3546f3a..5d8f542 100644 --- a/ArkBot/Commands/UnlinkSteamCommand.cs +++ b/ArkBot/Commands/UnlinkSteamCommand.cs @@ -5,6 +5,7 @@ using ArkBot.Discord.Command; using Discord; using Discord.Net; +using ArkBot.Configuration.Model; namespace ArkBot.Commands { diff --git a/ArkBot/Commands/WebAppCommand.cs b/ArkBot/Commands/WebAppCommand.cs index ef73ec4..2e6bbac 100644 --- a/ArkBot/Commands/WebAppCommand.cs +++ b/ArkBot/Commands/WebAppCommand.cs @@ -5,6 +5,7 @@ using ArkBot.Helpers; using System.Reflection; using ArkBot.Discord.Command; +using ArkBot.Configuration.Model; namespace ArkBot.Commands { diff --git a/ArkBot/Config.cs b/ArkBot/Config.cs deleted file mode 100644 index ead480c..0000000 --- a/ArkBot/Config.cs +++ /dev/null @@ -1,531 +0,0 @@ -using Newtonsoft.Json; -using System; -using System.Collections; -using System.Collections.Generic; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using ArkBot.Configuration; -using ArkBot.Configuration.Validation; -using Discord; -using Microsoft.IdentityModel; -using PropertyChanged; -using Validar; -using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; -using Xceed.Wpf.Toolkit.PropertyGrid.Editors; - -namespace ArkBot -{ - internal static class ConfigurationCategory - { - /// - /// Settings that must be changed (environment specific) - /// - internal const string Required = "Required"; - /// - /// Settings that are either optional or may be left at default - /// - internal const string Optional = "Optional"; - - /// - /// Optional settings for advanced configurations - /// - internal const string Advanced = "Advanced"; - - /// - /// Optional setting for debugging, logging etc. - /// - internal const string Debug = "Debug"; - } - - [AddINotifyPropertyChangedInterface] - [InjectValidation] - [CategoryOrder(ConfigurationCategory.Required, 0)] - [CategoryOrder(ConfigurationCategory.Optional, 1)] - [CategoryOrder(ConfigurationCategory.Advanced, 2)] - [CategoryOrder(ConfigurationCategory.Debug, 3)] - public class Config : IConfig - { - public Config() - { - // Default values - Ssl = new SslConfigSection(); - UserRoles = new Dictionary(); - ArkMultipliers = new ArkMultipliersConfigSection(); - Servers = new ServerConfigSection[] { }; - Clusters = new ClusterConfigSection[] { }; - WebAppRedirectListenPrefix = new string[] { }; - AccessControl = new AccessControlConfigSection(); - Discord = new DiscordConfigSection(); - Backups = new BackupsConfigSection(); - } - - // Required - - [JsonProperty(PropertyName = "googleApiKey")] - [DisplayName("Google API Key")] - [Description("Google API Key used for url-shortening services")] - [Category(ConfigurationCategory.Required)] - [PropertyOrder(0)] - [MinLength(1, ErrorMessage = "{0} is not set")] - //todo: validate google api key with google - public string GoogleApiKey { get; set; } - - [JsonProperty(PropertyName = "steamApiKey")] - [DisplayName("Steam API Key")] - [Description("Steam API Key used for fetching user information")] - [Category(ConfigurationCategory.Required)] - [PropertyOrder(1)] - [MinLength(1, ErrorMessage = "{0} is not set")] - //todo: validate steam api key with steam - public string SteamApiKey { get; set; } - - [JsonProperty(PropertyName = "tempFileOutputDirPath")] - [DisplayName("Temporary Files Directory")] - [Description("An existing directory path where temporary binary files can be stored (zip-files etc.)")] - [Category(ConfigurationCategory.Required)] - [PropertyOrder(2)] - [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] - [DirectoryExists(ErrorMessage = "{0} is not set or the directory path does not exist")] - public string TempFileOutputDirPath { get; set; } - - [JsonProperty(PropertyName = "servers")] - [DisplayName("Servers")] - [Description("Server instance configurations")] - [Category(ConfigurationCategory.Required)] - [PropertyOrder(3)] - [Required(ErrorMessage = "{0} is not set")] - public ServerConfigSection[] Servers { get; set; } - - [JsonProperty(PropertyName = "clusters")] - [DisplayName("Clusters")] - [Description("Cluster instance configurations")] - [Category(ConfigurationCategory.Required)] - [PropertyOrder(4)] - [Required(ErrorMessage = "{0} is not set")] - public ClusterConfigSection[] Clusters { get; set; } - - - // Optional - - [JsonProperty(PropertyName = "botName")] - [DisplayName("Bot Name")] - [Description("Short name to identify the bot")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(0)] - [MinLength(1, ErrorMessage = "{0} is not set")] - public string BotName { get; set; } - - [JsonProperty(PropertyName = "botUrl")] - [DisplayName("Bot URL")] - [Description("Website url associated with the bot or ARK server (optional)")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(1)] - [ValidUrl(Optional = true, ErrorMessage = "{0} is not a valid URL")] - public string BotUrl { get; set; } - - [JsonProperty(PropertyName = "appUrl")] - [DisplayName("Web App URL")] - [Description("External url pointing to the Web App (optional)")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(2)] - [ValidUrl(Optional = true, ErrorMessage = "{0} is not a valid URL")] - public string AppUrl { get; set; } - - [JsonProperty(PropertyName = "arkMultipliers")] - [DisplayName("ARK Multipliers")] - [Description("Server specific multipliers")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(3)] - [ExpandableObject] - [Required(ErrorMessage = "{0} is not set")] - public ArkMultipliersConfigSection ArkMultipliers { get; set; } - - [JsonProperty(PropertyName = "discord")] - [DisplayName("Discord")] - [Description("Discord bot settings")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(4)] - [ExpandableObject] - [Required(ErrorMessage = "{0} is not set")] - public DiscordConfigSection Discord { get; set; } - - [JsonProperty(PropertyName = "userRoles")] - [DisplayName("User Roles")] - [Description("Explicit steam user role assignment")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(5)] - [Required(ErrorMessage = "{0} is not set")] - public Dictionary UserRoles { get; set; } - - [JsonProperty(PropertyName = "accessControl")] - [DisplayName("Access Control")] - [Description("Per-feature role based access control configuration")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(6)] - [Required(ErrorMessage = "{0} is not set")] - public AccessControlConfigSection AccessControl { get; set; } - - [JsonProperty(PropertyName = "backups")] - [DisplayName("Backups")] - [Description("Savegame backups")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(7)] - [ExpandableObject] - [Required(ErrorMessage = "{0} is not set")] - public BackupsConfigSection Backups { get; set; } - - [JsonProperty(PropertyName = "webAppRedirectListenPrefix")] - [DisplayName("Web App Redirect Listen Prefix(es)")] - [Description("Http listen prefix(es) that are redirected to BotUrl")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(8)] - [MinLength(1, ErrorMessage = "{0} is not set")] - //todo: validate this listen prefix - public string[] WebAppRedirectListenPrefix { get; set; } - - [JsonProperty(PropertyName = "powershellFilePath")] - [DisplayName("Powershell Executable Path")] - [Description("Absolute file path of the powershell executable (only used with Server.UsePowershellOutputRedirect)")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(9)] - [Editor(typeof(OpenFilePathEditor), typeof(OpenFilePathEditor))] - [OpenFilePathEditor(Filter = "Executable files (*.exe)|*.exe|All files (*.*)|*.*")] - [FileExists(ErrorMessage = "{0} is not set or the file path does not exist")] - public string PowershellFilePath { get; set; } - - [JsonProperty(PropertyName = "ssl")] - [DisplayName("SSL")] - [Description("Configure Web App and WebAPI to use SSL with a free certificate from Lets Encrypt")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(10)] - [ExpandableObject] - [Required(ErrorMessage = "{0} is not set")] - public SslConfigSection Ssl { get; set; } - - [JsonProperty(PropertyName = "webApiListenPrefix")] - [DisplayName("Web API Listen Prefix")] - [Description("Http listen prefix for WebAPI service (requires a port that is open to external connections) [The prebuilt web-app included in this release is by default configured to call the web api on 127.0.0.1:60001. If you want to use another port for the web api you will need to reflect this change in environment.prod.ts and rebuild the web-app dist manually.]")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(11)] - [MinLength(1, ErrorMessage = "{0} is not set")] - //todo: validate this listen prefix - public string WebApiListenPrefix { get; set; } - - [JsonProperty(PropertyName = "webAppListenPrefix")] - [DisplayName("Web App Listen Prefix")] - [Description("Http listen prefix for Web App (requires a port that is open to external connections)")] - [Category(ConfigurationCategory.Optional)] - [PropertyOrder(12)] - [MinLength(1, ErrorMessage = "{0} is not set")] - //todo: validate this listen prefix - public string WebAppListenPrefix { get; set; } - - - // Optional Advanced - - [JsonProperty(PropertyName = "savegameExtractionMaxDegreeOfParallelism")] - [DisplayName("Savegame Extraction Max Degree Of Parallelism")] - [Description("Max degree of parallelism to use for savegame extraction. Change only if experiencing out of memory exceptions")] - [Category(ConfigurationCategory.Advanced)] - [PropertyOrder(0)] - [RangeOptional(1, 32, Optional = true)] - public int? SavegameExtractionMaxDegreeOfParallelism { get; set; } - - [JsonProperty(PropertyName = "useCompatibilityChangeWatcher")] - [DisplayName("Use Compatibility Change Watcher")] - [Description("Use timer based .ark save file watcher rather than the default (based on FileSystemWatcher)")] - [Category(ConfigurationCategory.Advanced)] - [PropertyOrder(1)] - public bool UseCompatibilityChangeWatcher { get; set; } - - - // Debugging, Logging etc. - - [JsonProperty(PropertyName = "discordLogLevel")] - [DisplayName("Discord Log Level")] - [Description("Log level for Discord.NET")] - [Category(ConfigurationCategory.Debug)] - [PropertyOrder(0)] - public LogSeverity DiscordLogLevel { get; set; } - - [JsonProperty(PropertyName = "anonymizeWebApiData")] - [DisplayName("Anonymize Web API Data")] - [Description("Anonymize all data in the WebAPI. Used to create data dumps for demoing the web-app")] - [Category(ConfigurationCategory.Debug)] - [PropertyOrder(1)] - public bool AnonymizeWebApiData { get; set; } - } - - [AddINotifyPropertyChangedInterface] - [InjectValidation] - public class DiscordConfigSection - { - public DiscordConfigSection() - { - DiscordBotEnabled = true; - AccessControl = new AccessControlConfigSection(); - } - - [JsonProperty(PropertyName = "discordBotEnabled")] - [DisplayName("Discord Bot Enabled")] - [Description("Option to enable/disable the discord bot component")] - public bool DiscordBotEnabled { get; set; } - - [JsonProperty(PropertyName = "botToken")] - [DisplayName("Bot Token")] - [Description("Bot authentication token from https://discordapp.com/developers")] - public string BotToken { get; set; } - - [JsonProperty(PropertyName = "enabledChannels")] - [DisplayName("Enabled Channels")] - [Description("A list of channels where the bot will listen to and answer commands")] - public string[] EnabledChannels { get; set; } - - [JsonProperty(PropertyName = "infoTopicChannel")] - [DisplayName("Info Topic Channel")] - [Description("Channel where topic is set to display information about last update, next update and how to use bot commands")] - public string InfoTopicChannel { get; set; } - - [JsonProperty(PropertyName = "announcementChannel")] - [DisplayName("Announcement Channel")] - [Description("Channel where announcements are made (votes etc.)")] - public string AnnouncementChannel { get; set; } - - [JsonProperty(PropertyName = "memberRoleName")] - [DisplayName("Member Role Name")] - [Description("The name of the member role in Discord")] - public string MemberRoleName { get; set; } - - [JsonProperty(PropertyName = "disableDeveloperFetchSaveData")] - [DisplayName("Disable Developer Fetch Save Data")] - [Description("Diable users in \"developer\"-role fetching json or save file data")] - public bool DisableDeveloperFetchSaveData { get; set; } - - [JsonProperty(PropertyName = "accessControl")] - [DisplayName("Access Control")] - [Description("Per-feature role based access control configuration")] - public AccessControlConfigSection AccessControl { get; set; } - - [JsonProperty(PropertyName = "steamOpenIdRelyingServiceListenPrefix")] - [DisplayName("Steam Open ID Relying Server Listen Prefix")] - [Description("Http listen prefix for Steam OpenID Relying Party webservice (requires a port that is open to external connections)")] - public string SteamOpenIdRelyingServiceListenPrefix { get; set; } - - [JsonProperty(PropertyName = "steamOpenIdRedirectUri")] - [DisplayName("Steam Open ID Redirect URL")] - [Description("Publicly accessible url for incoming Steam OpenID Relying Party webservice connections (requires a port that is open to external connections)")] - public string SteamOpenIdRedirectUri { get; set; } - } - - [AddINotifyPropertyChangedInterface] - [InjectValidation] - public class BackupsConfigSection - { - [JsonProperty(PropertyName = "backupsEnabled")] - [DisplayName("Backups Enabled")] - [Description("Option to enable savegame backups")] - [PropertyOrder(0)] - public bool BackupsEnabled { get; set; } - - [JsonProperty(PropertyName = "backupsDirectoryPath")] - [DisplayName("Backups Directory Path")] - [Description("Directory path where savegame backups are stored")] - [PropertyOrder(1)] - [DirectoryExists(IfMethod = nameof(IsBackupsEnabled), ErrorMessage = "{0} directory path does not exist")] - public string BackupsDirectoryPath { get; set; } - - // Validation methods - - private bool IsBackupsEnabled() - { - return BackupsEnabled; - } - } - - [AddINotifyPropertyChangedInterface] - [InjectValidation] - public class SslConfigSection - { - public SslConfigSection() - { - Domains = new string[] { }; - } - - [JsonProperty(PropertyName = "enabled")] - [DisplayName("Enabled")] - [Description("Toggle ssl.")] - public bool Enabled { get; set; } - - [JsonProperty(PropertyName = "challengeListenPrefix")] - [DisplayName("Challenge Listen Prefix")] - [Description("Http listen prefix for ssl challenge request (external port must be 80)")] - public string ChallengeListenPrefix { get; set; } - - [JsonProperty(PropertyName = "name")] - [DisplayName("Name")] - [Description("Friendly name of the certificate")] - public string Name { get; set; } - - [JsonProperty(PropertyName = "password")] - [DisplayName("Password")] - [Description("Private password")] - public string Password { get; set; } - - [JsonProperty(PropertyName = "email")] - [DisplayName("Email")] - [Description("Registration contact email")] - public string Email { get; set; } - - [JsonProperty(PropertyName = "domains")] - [DisplayName("Domain name(s)")] - [Description("Domain name(s) to issue the certificate for")] - public string[] Domains { get; set; } - - [JsonProperty(PropertyName = "ports")] - [DisplayName("Ports")] - [Description("Ports to bind the ssl certificate to")] - public int[] Ports { get; set; } - - [JsonProperty(PropertyName = "useCompatibilityNonSNIBindings")] - [DisplayName("Use Compatibility non-SNI Bindings")] - [Description("Use non SNI SSL bindings for previous Windows OS (before Windows 8/2012)")] - public bool UseCompatibilityNonSNIBindings { get; set; } - } - - [AddINotifyPropertyChangedInterface] - [InjectValidation] - public class ArkMultipliersConfigSection - { - public ArkMultipliersConfigSection() - { - EggHatchSpeedMultiplier = 1d; - BabyMatureSpeedMultiplier = 1d; - CuddleIntervalMultiplier = 1d; - } - - [JsonProperty(PropertyName = "eggHatchSpeedMultiplier")] - [DisplayName("Egg Hatch Speed Multiplier")] - [Description("Pregnancy/incubation time multiplier")] - public double EggHatchSpeedMultiplier { get; set; } - - [JsonProperty(PropertyName = "babyMatureSpeedMultiplier")] - [DisplayName("Baby Mature Speed Multiplier")] - [Description("Baby mature time multiplier")] - public double BabyMatureSpeedMultiplier { get; set; } - - [JsonProperty(PropertyName = "cuddleIntervalMultiplier")] - [DisplayName("Cuddle Interval Multiplier")] - [Description("Multiplier for duration between cuddles")] - public double CuddleIntervalMultiplier { get; set; } - } - - [AddINotifyPropertyChangedInterface] - [InjectValidation] - public class ServerConfigSection - { - public ServerConfigSection() - { - } - - [JsonProperty(PropertyName = "key")] - [DisplayName("Key")] - [Description("Unique key/name for this server instance")] - public string Key { get; set; } - - [JsonProperty(PropertyName = "cluster")] - [DisplayName("Cluster")] - [Description("Optional key for the cluster instance this server is part of")] - public string Cluster { get; set; } - - [JsonProperty(PropertyName = "saveFilePath")] - [DisplayName("Save File Path")] - [Description("Absolute file path of the .ark save file to monitor/extract data from")] - public string SaveFilePath { get; set; } - - [JsonProperty(PropertyName = "displayAddress")] - [DisplayName("Display Address")] - [Description("Public server address visible to players")] - public string DisplayAddress { get; set; } - - [JsonProperty(PropertyName = "ip")] - [DisplayName("IP")] - [Description("The IP address used to connect to this server instance")] - public string Ip { get; set; } - - [JsonProperty(PropertyName = "queryPort")] - [DisplayName("Query Port")] - [Description("The port used to query to this server instance")] - public int QueryPort { get; set; } - - [JsonProperty(PropertyName = "rconPort")] - [DisplayName("RCON Port")] - [Description("The port used to connect to this server instance over rcon")] - public int RconPort { get; set; } - - [JsonProperty(PropertyName = "rconPassword")] - [DisplayName("RCON Password")] - [Description("The password used to connect to this server instance via rcon")] - public string RconPassword { get; set; } - - //[JsonProperty(PropertyName = "updateBatchFilePath")] - //[Description("Absolute file path of a batch file to run in order to update the server")] - //public string UpdateBatchFilePath { get; set; } - - //[JsonProperty(PropertyName = "startBatchFilePath")] - //[Description("Absolute file path of a batch file to run in order to start the server")] - //public string StartBatchFilePath { get; set; } - - [JsonProperty(PropertyName = "serverExecutablePath")] - [DisplayName("Server Executable Path")] - [Description("Absolute file path of the server instance executable")] - public string ServerExecutablePath { get; set; } - - [JsonProperty(PropertyName = "serverExecutableArguments")] - [DisplayName("Server Executable Arguments")] - [Description("Command line arguments used when starting the server instance")] - public string ServerExecutableArguments { get; set; } - - [JsonProperty(PropertyName = "steamCmdExecutablePath")] - [DisplayName("Steam Cmd Executable Path")] - [Description("Absolute file path of the steamcmd executable")] - public string SteamCmdExecutablePath { get; set; } - - [JsonProperty(PropertyName = "serverInstallDirPath")] - [DisplayName("Server Install Directory Path")] - [Description("The directory path to force steamcmd updates to")] - public string ServerInstallDirPath { get; set; } - - [JsonProperty(PropertyName = "usePowershellOutputRedirect")] - [DisplayName("Use Powershell Output Redirect")] - [Description("Use alternative powershell/file based output redirect for update progress notifications")] - public bool UsePowershellOutputRedirect { get; set; } - - [JsonProperty(PropertyName = "disableChatNotificationOnGlobalCountdown")] - [DisplayName("Disable Chat Notification On Global Countdown")] - [Description("Disable chat notifications for this server instance when trigged by admin multiple server countdown (feature is used for compatibility with cross server chat)")] - public bool DisableChatNotificationOnGlobalCountdown { get; set; } - - } - - [AddINotifyPropertyChangedInterface] - [InjectValidation] - public class ClusterConfigSection - { - public ClusterConfigSection() - { - } - - [JsonProperty(PropertyName = "key")] - [DisplayName("Key")] - [Description("Unique key/name for this cluster instance")] - public string Key { get; set; } - - [JsonProperty(PropertyName = "savePath")] - [DisplayName("Save Path")] - [Description("The directory path where cluster save data is stored")] - public string SavePath { get; set; } - } -} diff --git a/ArkBot/Configuration/AccessControlConfigSectionConverter.cs b/ArkBot/Configuration/AccessControlConfigSectionConverter.cs new file mode 100644 index 0000000..2fe1d6e --- /dev/null +++ b/ArkBot/Configuration/AccessControlConfigSectionConverter.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace ArkBot.Configuration +{ + public class AccessControlConfigSectionConverter : ExpandableObjectConverter + { + public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) + { + if (!(value is IDictionary)) return base.GetProperties(context, value, attributes); + + var dict = value as IDictionary; + var propDescriptions = new PropertyDescriptorCollection(null); + + var num = 0; + foreach (var kv in dict) propDescriptions.Add(new AccessControlFeatureGroupPropertyDescriptor(dict, kv.Key, num++)); + return propDescriptions; + } + } +} diff --git a/ArkBot/Configuration/AccessControlFeatureGroupConverter.cs b/ArkBot/Configuration/AccessControlFeatureGroupConverter.cs new file mode 100644 index 0000000..8616cff --- /dev/null +++ b/ArkBot/Configuration/AccessControlFeatureGroupConverter.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; + +namespace ArkBot.Configuration +{ + public class AccessControlFeatureGroupConverter : ExpandableObjectConverter + { + public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) + { + if (!(value is IDictionary)) return base.GetProperties(context, value, attributes); + + var dict = value as IDictionary; + var propDescriptions = new PropertyDescriptorCollection(null); + + var num = 0; + foreach (var kv in dict) propDescriptions.Add(new AccessControlFeaturePropertyDescriptor(dict, kv.Key, num++)); + return propDescriptions; + } + } +} diff --git a/ArkBot/Configuration/AccessControlFeatureGroupPropertyDescriptor.cs b/ArkBot/Configuration/AccessControlFeatureGroupPropertyDescriptor.cs new file mode 100644 index 0000000..bdbc95d --- /dev/null +++ b/ArkBot/Configuration/AccessControlFeatureGroupPropertyDescriptor.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using System.ComponentModel; + +namespace ArkBot.Configuration +{ + public class AccessControlFeatureGroupPropertyDescriptor : PropertyDescriptor + { + private readonly IDictionary _owner; + private readonly T _index; + private readonly int _order; + + public AccessControlFeatureGroupPropertyDescriptor(IDictionary owner, T index, int order) : base("[" + index + "]", null) + { + _owner = owner; + _index = index; + _order = order; + } + + public override AttributeCollection Attributes + { + get + { + var attributes = TypeDescriptor.GetAttributes(GetValue(null), false); + attributes = AddAttribute(new DisplayNameAttribute(_index.ToString()), attributes); + attributes = AddAttribute(new PropertyOrderAttribute(_order), attributes); + + return attributes; + } + } + private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes) + { + var newAttributes = new Attribute[oldAttributes.Count + 1]; + oldAttributes.CopyTo(newAttributes, 1); + newAttributes[0] = newAttribute; + + return new AttributeCollection(newAttributes); + } + + public override bool CanResetValue(object component) => false; + public override object GetValue(object component) => Value; + private T2 Value => _owner[_index]; + public override void ResetValue(object component) => throw new NotImplementedException(); + public override void SetValue(object component, object value) => _owner[_index] = (T2)value; + public override bool ShouldSerializeValue(object component) => false; + public override Type ComponentType => _owner.GetType(); + public override bool IsReadOnly => true; + public override Type PropertyType => Value?.GetType(); + + } +} diff --git a/ArkBot/Configuration/AccessControlFeaturePropertyDescriptor.cs b/ArkBot/Configuration/AccessControlFeaturePropertyDescriptor.cs new file mode 100644 index 0000000..da80951 --- /dev/null +++ b/ArkBot/Configuration/AccessControlFeaturePropertyDescriptor.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using System.ComponentModel; + +namespace ArkBot.Configuration +{ + public class AccessControlFeaturePropertyDescriptor : PropertyDescriptor + { + private readonly IDictionary _owner; + private readonly T _index; + private readonly int _order; + + public AccessControlFeaturePropertyDescriptor(IDictionary owner, T index, int order) : base("[" + index + "]", null) + { + _owner = owner; + _index = index; + _order = order; + } + + public override AttributeCollection Attributes + { + get + { + var attributes = TypeDescriptor.GetAttributes(GetValue(null), false); + + attributes = AddAttribute(new DisplayNameAttribute(_index.ToString()), attributes); + attributes = AddAttribute(new PropertyOrderAttribute(_order), attributes); + attributes = AddAttribute(new EditorAttribute(typeof(StringArrayEditorWithPreview), typeof(StringArrayEditorWithPreview)), attributes); + + return attributes; + } + } + private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes) + { + var newAttributes = new Attribute[oldAttributes.Count + 1]; + oldAttributes.CopyTo(newAttributes, 1); + newAttributes[0] = newAttribute; + + return new AttributeCollection(newAttributes); + } + + public override bool CanResetValue(object component) => false; + public override object GetValue(object component) => Value; + private T2 Value => _owner[_index]; + public override void ResetValue(object component) => throw new NotImplementedException(); + public override void SetValue(object component, object value) => _owner[_index] = (T2)value; + public override bool ShouldSerializeValue(object component) => false; + public override Type ComponentType => _owner.GetType(); + public override bool IsReadOnly => false; + public override Type PropertyType => Value?.GetType(); + } +} diff --git a/ArkBot/Configuration/ConfigurationHelpAttribute.cs b/ArkBot/Configuration/ConfigurationHelpAttribute.cs new file mode 100644 index 0000000..17b13d9 --- /dev/null +++ b/ArkBot/Configuration/ConfigurationHelpAttribute.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ArkBot.Configuration +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class ConfigurationHelpAttribute : Attribute + { + public string Remarks { get; set; } + public string Instructions { get; set; } + public string Example { get; set; } + + public ConfigurationHelpAttribute(string[] remarks = null, string[] instructions = null) + { + if (remarks != null) Remarks = string.Join(Environment.NewLine, remarks); + if (instructions != null) Instructions = string.Join(Environment.NewLine, instructions); + } + } +} diff --git a/ArkBot/Configuration/CustomCollectionEditor.cs b/ArkBot/Configuration/CustomCollectionEditor.cs new file mode 100644 index 0000000..62cd7a2 --- /dev/null +++ b/ArkBot/Configuration/CustomCollectionEditor.cs @@ -0,0 +1,210 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Xceed.Wpf.Toolkit.PropertyGrid; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; +using Xceed.Wpf.Toolkit.Core.Utilities; +using System.Windows.Controls.Primitives; +using System.Reflection; +using System.Windows.Controls; +using Xceed.Wpf.Toolkit; +using ArkBot.Extensions; +using ArkBot.ViewModel; +using System.Windows.Data; +using System.Collections.Concurrent; +using System.Windows.Media; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel; +using System.Windows.Threading; +using Nito.AsyncEx; + +namespace ArkBot.Configuration +{ + public class CustomCollectionEditor : CollectionEditor + { + //public static readonly DependencyProperty ModelProperty = DependencyProperty.Register("Model", typeof(ConfigurationViewModel), typeof(CollectionControlButton), new FrameworkPropertyMetadata()); + + //public ConfigurationViewModel Model + //{ + // get { return Editor.GetValue(ModelProperty) as ConfigurationViewModel; } + // set { Editor.SetValue(ModelProperty, value); } + //} + + protected override void SetControlProperties(PropertyItem propertyItem) + { + RemoveRoutedEventHandlers(Editor, ButtonBase.ClickEvent); + + SetEditorContent(propertyItem); + propertyItem.PropertyChanged += (s, e) => SetEditorContent(propertyItem); + + Editor.Foreground = Brushes.Gray; + Editor.Padding = new Thickness(3); + Editor.Click += new RoutedEventHandler(async (s, e) => + { + var dlg = new CollectionControlDialog + { + Title = "Config Editor", + Width = 1000, + Height = 800, + MinWidth = 800, + MinHeight = 500, + ItemsSource = Editor.ItemsSource, + NewItemTypes = Editor.NewItemTypes, + ItemsSourceType = Editor.ItemsSourceType, + IsReadOnly = Editor.IsReadOnly + }; + + var cc = dlg.CollectionControl; + //var pg = cc.PropertyGrid; + //pg.Loaded += PropertyGrid_Loaded; + + using (var viewModel = await ConfigurationViewModel.CreateAsync(false)) + { + //foo.SelectedObject = cc.SelectedItem; + + //dlg.Loaded += Dlg_Loaded; + + dlg.DataContext = viewModel; + + if (dlg.ShowDialog() == true) + { + // trigger a full revalidation and update the grid + var conf = Editor.FindVisualParents().OfType().FirstOrDefault(); + if (conf != null) + { + AsyncContext.Run(async () => + { + await conf.UpdateValidation(trigger: true); + }); + } + } + } + }); + } + + private void SetEditorContent(PropertyItem propertyItem) + { + var value = propertyItem.Value; + var t = propertyItem.Value.GetType(); + var valueString = value.ToString(); + if (string.IsNullOrEmpty(valueString) || (valueString == t.UnderlyingSystemType.ToString())) + { + valueString = propertyItem.DisplayName; + } + + Editor.Content = valueString; + } + + //private DependencyPropertyListener _foo; + + //private void Dlg_Loaded(object sender, RoutedEventArgs e) + //{ + // var dlg = (sender as CollectionControlDialog); + // var cc = dlg.CollectionControl; + + // _foo = new DependencyPropertyListener(cc, CollectionControl.SelectedItemProperty, _e => + // { + // (dlg.DataContext as ConfigurationViewModel).SelectedObject = _e.NewValue; + // }); + //} + + private void PropertyGrid_Loaded(object sender, RoutedEventArgs e) + { + //modify styles dynamically during runtime because it is too complicated to override the templates/styles in xaml + var expandSites = (sender as PropertyGrid).FindVisualChildrenWithPath("Expander[expander]/Grid/Border[ExpandSite]"); + foreach (var exp in expandSites) + { + exp.Padding = new Thickness(exp.Padding.Left, exp.Padding.Top, 23, exp.Padding.Bottom); //add some padding on the right side to make room for validation adorners + } + } + + //from: https://stackoverflow.com/a/12618521 + public static void RemoveRoutedEventHandlers(UIElement elm, RoutedEvent re) + { + var pi = typeof(UIElement).GetProperty("EventHandlersStore", BindingFlags.Instance | BindingFlags.NonPublic); + var ehs = pi.GetValue(elm, null); + if (ehs == null) return; + + var mi = ehs.GetType().GetMethod("GetRoutedEventHandlers", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); + var reh = (RoutedEventHandlerInfo[])mi.Invoke(ehs, new object[] { re }); + + foreach (var ei in reh) elm.RemoveHandler(re, ei.Handler); + } + } + + //public sealed class DependencyPropertyListener : DependencyObject, IDisposable + //{ + // private static readonly ConcurrentDictionary Cache = new ConcurrentDictionary(); + + // private static readonly DependencyProperty ProxyProperty = DependencyProperty.Register( + // "Proxy", + // typeof(object), + // typeof(DependencyPropertyListener), + // new PropertyMetadata(null, OnSourceChanged)); + + // private readonly Action onChanged; + // private bool disposed; + + // public DependencyPropertyListener( + // DependencyObject source, + // DependencyProperty property, + // Action onChanged = null) + // : this(source, Cache.GetOrAdd(property, x => new PropertyPath(x)), onChanged) + // { + // } + + // public DependencyPropertyListener( + // DependencyObject source, + // PropertyPath property, + // Action onChanged) + // { + // this.Binding = new Binding + // { + // Source = source, + // Path = property, + // Mode = BindingMode.OneWay, + // }; + // this.BindingExpression = (BindingExpression)BindingOperations.SetBinding(this, ProxyProperty, this.Binding); + // this.onChanged = onChanged; + // } + + // public event EventHandler Changed; + + // public BindingExpression BindingExpression { get; } + + // public Binding Binding { get; } + + // public DependencyObject Source => (DependencyObject)this.Binding.Source; + + // public void Dispose() + // { + // if (this.disposed) + // { + // return; + // } + + // this.disposed = true; + // BindingOperations.ClearBinding(this, ProxyProperty); + // } + + // private static void OnSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + // { + // var listener = (DependencyPropertyListener)d; + // if (listener.disposed) + // { + // return; + // } + + // listener.onChanged?.Invoke(e); + // listener.OnChanged(e); + // } + + // private void OnChanged(DependencyPropertyChangedEventArgs e) + // { + // this.Changed?.Invoke(this, e); + // } + //} +} diff --git a/ArkBot/Configuration/DirectoryPathEditor.cs b/ArkBot/Configuration/DirectoryPathEditor.cs index cc22337..1be8934 100644 --- a/ArkBot/Configuration/DirectoryPathEditor.cs +++ b/ArkBot/Configuration/DirectoryPathEditor.cs @@ -40,14 +40,14 @@ public FrameworkElement ResolveEditor(PropertyItem propertyItem) Width = GridLength.Auto }); - TextBox textBox = new TextBox(); + TextBox textBox = new TextBox { BorderThickness = new Thickness(0), Padding = new Thickness(3) }; textBox.HorizontalAlignment = HorizontalAlignment.Stretch; Binding binding = new Binding("Value"); //bind to the Value property of the PropertyItem binding.Source = propertyItem; binding.Mode = BindingMode.TwoWay; BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding); - Button button = new Button(); + Button button = new Button { MinWidth = 19 }; button.Content = "..."; button.Tag = propertyItem; button.Click += button_Click; @@ -65,6 +65,8 @@ private void button_Click(object sender, RoutedEventArgs e) if (null == item) return; var path = item.Value as string; + if (path != null) path = Environment.ExpandEnvironmentVariables(path); + var di = !string.IsNullOrEmpty(path) && Directory.Exists(path) ? new DirectoryInfo(path) : null; using (var dialog = new System.Windows.Forms.FolderBrowserDialog diff --git a/ArkBot/Configuration/Model/AccessControlConfigSection.cs b/ArkBot/Configuration/Model/AccessControlConfigSection.cs new file mode 100644 index 0000000..efe27aa --- /dev/null +++ b/ArkBot/Configuration/Model/AccessControlConfigSection.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + [ReadOnly(true)] + [TypeConverter(typeof(AccessControlConfigSectionConverter))] + [ExpandableObject] + public class AccessControlConfigSection : Dictionary + { + public override string ToString() => "Access Control"; + } +} diff --git a/ArkBot/Configuration/Model/AccessControlFeatureGroup.cs b/ArkBot/Configuration/Model/AccessControlFeatureGroup.cs new file mode 100644 index 0000000..9a0328e --- /dev/null +++ b/ArkBot/Configuration/Model/AccessControlFeatureGroup.cs @@ -0,0 +1,29 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + [TypeConverter(typeof(AccessControlFeatureGroupConverter))] + [ExpandableObject] + public class AccessControlFeatureGroup : Dictionary + { + public override string ToString() => "Group"; + } +} diff --git a/ArkBot/Configuration/Model/AccessControlFeatureRoles.cs b/ArkBot/Configuration/Model/AccessControlFeatureRoles.cs new file mode 100644 index 0000000..2e0c0e5 --- /dev/null +++ b/ArkBot/Configuration/Model/AccessControlFeatureRoles.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class AccessControlFeatureRoles : List + { + } +} diff --git a/ArkBot/Configuration/Model/ArkMultipliersConfigSection.cs b/ArkBot/Configuration/Model/ArkMultipliersConfigSection.cs new file mode 100644 index 0000000..ff78206 --- /dev/null +++ b/ArkBot/Configuration/Model/ArkMultipliersConfigSection.cs @@ -0,0 +1,46 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class ArkMultipliersConfigSection + { + public ArkMultipliersConfigSection() + { + EggHatchSpeedMultiplier = 1d; + BabyMatureSpeedMultiplier = 1d; + CuddleIntervalMultiplier = 1d; + } + + public override string ToString() => "ARK Multipliers"; + + [JsonProperty(PropertyName = "eggHatchSpeedMultiplier")] + [Display(Name = "Egg Hatch Speed Multiplier", Description = "Pregnancy/incubation time multiplier")] + public double EggHatchSpeedMultiplier { get; set; } + + [JsonProperty(PropertyName = "babyMatureSpeedMultiplier")] + [Display(Name = "Baby Mature Speed Multiplier", Description = "Baby mature time multiplier")] + public double BabyMatureSpeedMultiplier { get; set; } + + [JsonProperty(PropertyName = "cuddleIntervalMultiplier")] + [Display(Name = "Cuddle Interval Multiplier", Description = "Multiplier for duration between cuddles")] + public double CuddleIntervalMultiplier { get; set; } + } +} diff --git a/ArkBot/Configuration/Model/BackupsConfigSection.cs b/ArkBot/Configuration/Model/BackupsConfigSection.cs new file mode 100644 index 0000000..e5336c4 --- /dev/null +++ b/ArkBot/Configuration/Model/BackupsConfigSection.cs @@ -0,0 +1,46 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class BackupsConfigSection + { + public override string ToString() => $"Backups ({(BackupsEnabled ? "Enabled" : "Disabled")})"; + + [JsonProperty(PropertyName = "backupsEnabled")] + [Display(Name = "Backups Enabled", Description = "Option to enable savegame backups")] + [PropertyOrder(0)] + public bool BackupsEnabled { get; set; } + + [JsonProperty(PropertyName = "backupsDirectoryPath")] + [Display(Name = "Backups Directory Path", Description = "Directory path where savegame backups are stored")] + [PropertyOrder(1)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryExists(IfMethod = nameof(IsBackupsEnabled), ErrorMessage = "{0} directory path does not exist")] + public string BackupsDirectoryPath { get; set; } + + // Validation methods + + private bool IsBackupsEnabled() + { + return BackupsEnabled; + } + } +} diff --git a/ArkBot/Configuration/Model/ClusterConfigSection.cs b/ArkBot/Configuration/Model/ClusterConfigSection.cs new file mode 100644 index 0000000..ebfedc9 --- /dev/null +++ b/ArkBot/Configuration/Model/ClusterConfigSection.cs @@ -0,0 +1,53 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + [DisplayName("Cluster Instance")] + [CategoryOrder(ConfigurationCategory.Required, 0)] + [CategoryOrder(ConfigurationCategory.Optional, 1)] + [CategoryOrder(ConfigurationCategory.Advanced, 2)] + [CategoryOrder(ConfigurationCategory.Debug, 3)] + public class ClusterConfigSection + { + public ClusterConfigSection() + { + } + + public override string ToString() => Key; + + + [JsonProperty(PropertyName = "key")] + [Display(Name = "Key", Description = "Unique key/name for this cluster instance")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(0)] + [MinLength(1, ErrorMessage = "{0} is not set")] + [RegularExpression(@"^[a-z0-9_\-]+$", ErrorMessage = "{0} must consist of letters (a-z), numbers (0-9), dashes (-) and underscores (_)")] + public string Key { get; set; } + + [JsonProperty(PropertyName = "savePath")] + [Display(Name = "Save Path", Description = "The directory path where cluster save data is stored")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(1)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryExists(ErrorMessage = "{0} directory path does not exist")] + public string SavePath { get; set; } + } +} diff --git a/ArkBot/Configuration/Model/ClustersConfigSection.cs b/ArkBot/Configuration/Model/ClustersConfigSection.cs new file mode 100644 index 0000000..e3cc0c4 --- /dev/null +++ b/ArkBot/Configuration/Model/ClustersConfigSection.cs @@ -0,0 +1,27 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class ClustersConfigSection : List + { + public override string ToString() => "Clusters" + (Count > 0 ? $" ({(string.Join(", ", this.Select(x => x.Key)))})" : ""); + } +} diff --git a/ArkBot/Configuration/Model/Config.cs b/ArkBot/Configuration/Model/Config.cs new file mode 100644 index 0000000..04b5c57 --- /dev/null +++ b/ArkBot/Configuration/Model/Config.cs @@ -0,0 +1,308 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + [CategoryOrder(ConfigurationCategory.Required, 0)] + [CategoryOrder(ConfigurationCategory.Optional, 1)] + [CategoryOrder(ConfigurationCategory.Advanced, 2)] + [CategoryOrder(ConfigurationCategory.Debug, 3)] + public class Config : IConfig + { + public Config() + { + // Default values + Ssl = new SslConfigSection(); + UserRoles = new UserRolesConfigSection(); + ArkMultipliers = new ArkMultipliersConfigSection(); + Servers = new ServersConfigSection(); + Clusters = new ClustersConfigSection(); + WebAppRedirectListenPrefix = new string[] { }; + AccessControl = new AccessControlConfigSection(); + Discord = new DiscordConfigSection(); + Backups = new BackupsConfigSection(); + + //Test = new Test1ConfigSection(); + } + + // Required + + [JsonProperty(PropertyName = "googleApiKey")] + [Display(Name = "Google API Key", Description = "API Key from Google used for url-shortening services")] + [ConfigurationHelp(instructions: new[] { + @"1. Go to [Googe APIs & Services](https://console.developers.google.com/apis/credentials) and create a credential of type ""API Key"".", + @"2. Go to [URL Shortener API](https://console.developers.google.com/apis/api/urlshortener.googleapis.com) and enable it." }, + Example = "`AIzaSyBukSL8pbCjkyR__f6kvL0XW_2OcP5Mrfo`")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(0)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate google api key with google + public string GoogleApiKey { get; set; } + + [JsonProperty(PropertyName = "steamApiKey")] + [Display(Name = "Steam API Key", Description = "API Key from Steam used for fetching server and user details from the Steam API")] + [ConfigurationHelp(instructions: new[] { + @"1. Go to [Register Steam Web API Key](https://steamcommunity.com/dev/apikey) and create a new Steam API Key."}, + Example = "`5E3512AD4C7EB822105E9C07910E2A01`")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(1)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate steam api key with steam + public string SteamApiKey { get; set; } + + [JsonProperty(PropertyName = "servers")] + [Display(Name = "Servers", Description = "Server instance configurations for your particular server setup")] + [ConfigurationHelp(remarks: new[] { + "In this section configure servers to match your ARK server environment. Add or remove additional server configurations if necessary.\r\n", + "Servers each have a unique key that is used to identify a particular server instance in Discord commands, Companion App etc.\r\n" + })] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(2)] + [Editor(typeof(CustomCollectionEditor), typeof(CustomCollectionEditor))] + [Required(ErrorMessage = "{0} is not set")] + [ValidateCollection(ErrorMessage = "{0} contains item(s) that are invalid")] + public ServersConfigSection Servers { get; set; } + + [JsonProperty(PropertyName = "clusters")] + [Display(Name = "Clusters", Description = "Cluster instance configurations for your particular server setup")] + [ConfigurationHelp(remarks: new[] { + "In this section configure clusters to match your ARK server environment. Add or remove additional cluster configurations if necessary.\r\n", + "Leave it empty if your server setup does not include a cluster.\r\n", + "Servers are connected to clusters through a unique key. Remember the key you assigned when configuring your servers.\r\n" + })] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(3)] + [Editor(typeof(CustomCollectionEditor), typeof(CustomCollectionEditor))] + [Required(ErrorMessage = "{0} is not set")] + [ValidateCollection(ErrorMessage = "{0} contains item(s) that are invalid")] + public ClustersConfigSection Clusters { get; set; } + + + // Optional + + [JsonProperty(PropertyName = "botName")] + [Display(Name = "Bot Name", Description = "Short name to identify the bot")] + [DefaultValue("ARK Bot")] + [ConfigurationHelp(remarks: new[] { "Is used as the title and application name when communicating with third party web services etc." }, Example = "ARK Bot")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(0)] + [MinLength(1, ErrorMessage = "{0} is not set")] + public string BotName { get; set; } + + [JsonProperty(PropertyName = "botUrl")] + [Display(Name = "Bot URL", Description = "Website url associated with the bot or ARK server")] + [ConfigurationHelp(remarks: new[] { "Is used to link or redirect to your website." }, Example = "http://www.arkserver.net")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(1)] + [ValidUrl(Optional = true, ErrorMessage = "{0} is not a valid URL")] + public string BotUrl { get; set; } + + [JsonProperty(PropertyName = "appUrl")] + [Display(Name = "Web App URL", Description = "External url pointing to the Web App")] + [ConfigurationHelp(remarks: new[] { "Is used to link or redirect to the Companion App (Web App)." }, Example = "http://app.arkserver.net")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(2)] + [ValidUrl(Optional = true, ErrorMessage = "{0} is not a valid URL")] + public string AppUrl { get; set; } + + [JsonProperty(PropertyName = "arkMultipliers")] + [Display(Name = "ARK Multipliers", Description = "Server specific multipliers")] + [ConfigurationHelp(remarks: new[] { "ARK configuration multipliers used on your servers and required for accurate calculations throughout the application." })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(3)] + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] + [ValidateExpandable(ErrorMessage = "{0} contain field(s) that are invalid")] + public ArkMultipliersConfigSection ArkMultipliers { get; set; } + + [JsonProperty(PropertyName = "discord")] + [Display(Name = "Discord", Description = "Discord bot settings")] + [ConfigurationHelp(remarks: new[] { "Settings specific to the Discord bot feature. The Discord bot allows administrators to manage servers using commands in Discord." })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(4)] + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] + [ValidateExpandable(ErrorMessage = "{0} contain field(s) that are invalid")] + public DiscordConfigSection Discord { get; set; } + + [JsonProperty(PropertyName = "userRoles")] + [Display(Name = "User Roles", Description = "Explicit steam user role assignment")] + [ConfigurationHelp(remarks: new[] { "Multiple roles can be configured and each contains a list of steam ids who belong to that role. Roles are used in Companion App (Web App) access control to grant access to specific pages/features." })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(5)] + [Editor(typeof(CustomCollectionEditor), typeof(CustomCollectionEditor))] + [Required(ErrorMessage = "{0} is not set")] + [ValidateCollection(ErrorMessage = "{0} contains item(s) that are invalid")] + public UserRolesConfigSection UserRoles { get; set; } + + [JsonProperty(PropertyName = "accessControl")] + [Display(Name = "Access Control", Description = "Per-feature role based access control configuration")] + [ConfigurationHelp(remarks: new[] { "Contain a predefined set of pages/features to grant access to. Each page/feature contains a list of roles that have access to that particular resource. Roles are connected to steam users in the User Roles setting." })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(6)] + [Required(ErrorMessage = "{0} is not set")] + public AccessControlConfigSection AccessControl { get; set; } + + [JsonProperty(PropertyName = "backups")] + [Display(Name = "Backups", Description = "Savegame backups")] + [ConfigurationHelp(remarks: new[] { "Settings specific to the savegame backup feature which optionally can be configured to take backups each time a savegame change is detected." })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(7)] + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] + [ValidateExpandable(ErrorMessage = "{0} contain field(s) that are invalid")] + public BackupsConfigSection Backups { get; set; } + + [JsonProperty(PropertyName = "webAppRedirectListenPrefix")] + [Display(Name = "Web App Redirect Listen Prefix(es)", Description = "Http listen prefix(es) that are redirected to BotUrl")] + [ConfigurationHelp(remarks: new[] { "Used to redirect alternate URLs to the actual Companion App (Web App) URL. Typically used to redirect HTTP requests to a secure HTTPS connection when SSL is enabled." }, Example = "http://+:80/")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(8)] + //todo: validate this listen prefix + public string[] WebAppRedirectListenPrefix { get; set; } + + [JsonProperty(PropertyName = "powershellFilePath")] + [Display(Name = "Powershell Executable Path", Description = "Absolute file path of the powershell executable")] + [DefaultValue(@"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe")] + [ConfigurationHelp(remarks: new[] { "This is the path to the PowerShell executable on your system. It is used when `Use Powershell Output Redirect` is configured for a server instance to relay SteamCmd status back to ARK Bot." })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(9)] + [Editor(typeof(OpenFilePathEditor), typeof(OpenFilePathEditor))] + [OpenFilePathEditor(Filter = "Executable files (*.exe)|*.exe|All files (*.*)|*.*")] + [FileExists(ErrorMessage = "{0} is not set or the file path does not exist")] + //todo: only used with Server.ServerManagement.UsePowershellOutputRedirect + public string PowershellFilePath { get; set; } + + [JsonProperty(PropertyName = "ssl")] + [Display(Name = "SSL", Description = "Configure Web App and WebAPI to use SSL with a free certificate from Lets Encrypt")] + [ConfigurationHelp(remarks: new[] + { + "Enabling SSL (HTTPS) is important to protect users against session hijacking. With SSL enabled the bot will attempt to issue a free SSL-certificate using Lets Encrypt. Once the SSL-certificate has been issued, it is valid for 90 days, after which it must be renewed.\r\n", + "For the SSL-certificate to be issued you need to prove that you control the domain name; the domain must be pointed to your public IP and port 80 must be open externally and available for the bot to bind locally.\r\n" + })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(10)] + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] + [ValidateExpandable(ErrorMessage = "{0} contain field(s) that are invalid")] + public SslConfigSection Ssl { get; set; } + + [JsonProperty(PropertyName = "webApiListenPrefix")] + [Display(Name = "Web API Listen Prefix", Description = "Http listen prefix assigned to the Web API")] + [DefaultValue("http://+:60001/")] + [ConfigurationHelp(remarks: new[] { + "Listen prefix is a simple canonical form to express the schema, host, port and relative URI to reserve for a web listener.\r\n", + "Typically the primary thing you might change is the port which is the decimal number after `:`. This is the local port that the listener will attempt to bind to.\r\n", + "With SSL is enabled the schema should be changed from `http` to `https`.\r\n", + "[Learn more about listen prefixes](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364698(v=vs.85).aspx)\r\n" + })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(11)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate this listen prefix + [RegularExpressionCustom(@"^https://.*", IfMethod = nameof(IsSslEnabled), ErrorMessage = "{0} should be `https` when SSL is enabled")] + [RegularExpressionCustom(@"^http://.*", IfMethod = nameof(IsSslDisabled), ErrorMessage = "{0} should be `http` when SSL is disabled")] + + public string WebApiListenPrefix { get; set; } + + [JsonProperty(PropertyName = "webAppListenPrefix")] + [Display(Name = "Web App Listen Prefix", Description = "Http listen prefix assigned to the Companion App (Web App)")] + [DefaultValue("http://+:80/")] + [ConfigurationHelp(remarks: new [] { + "Listen prefix is a simple canonical form to express the schema, host, port and relative URI to reserve for a web listener.\r\n", + "Typically the primary thing you might change is the port which is the decimal number after `:`. This is the local port that the listener will attempt to bind to.\r\n", + "With SSL is enabled the schema should be changed from `http` to `https`.\r\n", + "[Learn more about listen prefixes](https://msdn.microsoft.com/en-us/library/windows/desktop/aa364698(v=vs.85).aspx)\r\n" + })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(12)] + [MinLength(1, ErrorMessage = "{0} is not set")] + //todo: validate this listen prefix + [RegularExpressionCustom(@"^https://.*", IfMethod = nameof(IsSslEnabled), ErrorMessage = "{0} should be `https` when SSL is enabled")] + [RegularExpressionCustom(@"^http://.*", IfMethod = nameof(IsSslDisabled), ErrorMessage = "{0} should be `http` when SSL is disabled")] + public string WebAppListenPrefix { get; set; } + + [JsonProperty(PropertyName = "tempFileOutputDirPath")] + [Display(Name = "Temporary Files Directory", Description = "An existing directory path where temporary binary files can be stored (zip-files etc.)")] + [DefaultValue("%TEMP%\\ArkBot")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(13)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryPathIsValid(ErrorMessage = "{0} is not set or the directory path is not valid")] + public string TempFileOutputDirPath { get; set; } + + + // Optional Advanced + + [JsonProperty(PropertyName = "savegameExtractionMaxDegreeOfParallelism")] + [Display(Name = "Savegame Extraction Max Degree Of Parallelism", Description = "Max degree of parallelism to use for savegame extraction")] + [DefaultValue(null)] + [ConfigurationHelp(remarks: new [] { "No need to change this setting unless you are experiencing out of memory exceptions." })] + [Category(ConfigurationCategory.Advanced)] + [PropertyOrder(0)] + [RangeOptional(1, 32, Optional = true, ErrorMessage = "{0} must be empty or between 1-32")] + public int? SavegameExtractionMaxDegreeOfParallelism { get; set; } + + [JsonProperty(PropertyName = "useCompatibilityChangeWatcher")] + [Display(Name = "Use Compatibility Change Watcher", Description = "Use timer based .ark save file watcher rather than the default (based on FileSystemWatcher)")] + [DefaultValue(true)] + [ConfigurationHelp(remarks: new[] { "An alternative method of watching for file changes that offer better compatibility with a wide range of systems." })] + [Category(ConfigurationCategory.Advanced)] + [PropertyOrder(1)] + public bool UseCompatibilityChangeWatcher { get; set; } + + + // Debugging, Logging etc. + + [JsonProperty(PropertyName = "discordLogLevel")] + [Display(Name = "Discord Log Level", Description = "Log level for Discord.NET")] + [Category(ConfigurationCategory.Debug)] + [PropertyOrder(0)] + public LogSeverity DiscordLogLevel { get; set; } + + [JsonProperty(PropertyName = "anonymizeWebApiData")] + [Display(Name = "Anonymize Web API Data", Description = "Anonymize all data in the WebAPI. Used to create data dumps for demoing the web-app")] + [Category(ConfigurationCategory.Debug)] + [PropertyOrder(1)] + public bool AnonymizeWebApiData { get; set; } + + //[JsonProperty(PropertyName = "test")] + //[Display(Name = "Test", Description = "Test")] + //[Category(ConfigurationCategory.Debug)] + //[PropertyOrder(2)] + //[ExpandableObject] + //[Required(ErrorMessage = "{0} is not set")] + //[ValidateExpandable(ErrorMessage = "{0} contain field(s) that are invalid")] + //public Test1ConfigSection Test { get; set; } + + + // Validation methods + + private bool IsSslEnabled() + { + return Ssl.Enabled; + } + + private bool IsSslDisabled() + { + return !Ssl.Enabled; + } + } +} diff --git a/ArkBot/Configuration/Model/ConfigurationCategories.cs b/ArkBot/Configuration/Model/ConfigurationCategories.cs new file mode 100644 index 0000000..5d2a357 --- /dev/null +++ b/ArkBot/Configuration/Model/ConfigurationCategories.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ArkBot.Configuration.Model +{ + internal static class ConfigurationCategory + { + /// + /// Settings that must be changed (environment specific) + /// + internal const string Required = "Required"; + /// + /// Settings that are either optional or may be left at default + /// + internal const string Optional = "Optional"; + + /// + /// Optional settings for advanced configurations + /// + internal const string Advanced = "Advanced"; + + /// + /// Optional setting for debugging, logging etc. + /// + internal const string Debug = "Debug"; + } +} diff --git a/ArkBot/Configuration/Model/DiscordConfigSection.cs b/ArkBot/Configuration/Model/DiscordConfigSection.cs new file mode 100644 index 0000000..f70ed74 --- /dev/null +++ b/ArkBot/Configuration/Model/DiscordConfigSection.cs @@ -0,0 +1,71 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + public class DiscordConfigSection + { + public DiscordConfigSection() + { + DiscordBotEnabled = true; + AccessControl = new AccessControlConfigSection(); + } + + public override string ToString() => $"Discord ({(DiscordBotEnabled ? "Enabled" : "Disabled")})"; + + [JsonProperty(PropertyName = "discordBotEnabled")] + [Display(Name = "Discord Bot Enabled", Description = "Option to enable/disable the discord bot component")] + public bool DiscordBotEnabled { get; set; } + + [JsonProperty(PropertyName = "botToken")] + [Display(Name = "Bot Token", Description = "Bot authentication token from https://discordapp.com/developers")] + public string BotToken { get; set; } + + [JsonProperty(PropertyName = "enabledChannels")] + [Display(Name = "Enabled Channels", Description = "A list of channels where the bot will listen to and answer commands")] + public string[] EnabledChannels { get; set; } + + [JsonProperty(PropertyName = "infoTopicChannel")] + [Display(Name = "Info Topic Channel", Description = "Channel where topic is set to display information about last update, next update and how to use bot commands")] + public string InfoTopicChannel { get; set; } + + [JsonProperty(PropertyName = "announcementChannel")] + [Display(Name = "Announcement Channel", Description = "Channel where announcements are made (votes etc.)")] + public string AnnouncementChannel { get; set; } + + [JsonProperty(PropertyName = "memberRoleName")] + [Display(Name = "Member Role Name", Description = "The name of the member role in Discord")] + public string MemberRoleName { get; set; } + + [JsonProperty(PropertyName = "disableDeveloperFetchSaveData")] + [Display(Name = "Disable Developer Fetch Save Data", Description = "Diable users in \"developer\"-role fetching json or save file data")] + public bool DisableDeveloperFetchSaveData { get; set; } + + [JsonProperty(PropertyName = "accessControl")] + [Display(Name = "Access Control", Description = "Per-feature role based access control configuration")] + public AccessControlConfigSection AccessControl { get; set; } + + [JsonProperty(PropertyName = "steamOpenIdRelyingServiceListenPrefix")] + [Display(Name = "Steam Open ID Relying Server Listen Prefix", Description = "Http listen prefix for Steam OpenID Relying Party webservice (requires a port that is open to external connections)")] + public string SteamOpenIdRelyingServiceListenPrefix { get; set; } + + [JsonProperty(PropertyName = "steamOpenIdRedirectUri")] + [Display(Name = "Steam Open ID Redirect URL", Description = "Publicly accessible url for incoming Steam OpenID Relying Party webservice connections (requires a port that is open to external connections)")] + public string SteamOpenIdRedirectUri { get; set; } + } +} diff --git a/ArkBot/IConfig.cs b/ArkBot/Configuration/Model/IConfig.cs similarity index 81% rename from ArkBot/IConfig.cs rename to ArkBot/Configuration/Model/IConfig.cs index af8b9fe..e83c1b7 100644 --- a/ArkBot/IConfig.cs +++ b/ArkBot/Configuration/Model/IConfig.cs @@ -2,7 +2,7 @@ using ArkBot.Configuration; using Discord; -namespace ArkBot +namespace ArkBot.Configuration.Model { public interface IConfig { @@ -14,7 +14,7 @@ public interface IConfig string SteamApiKey { get; set; } string TempFileOutputDirPath { get; set; } DiscordConfigSection Discord { get; set; } - Dictionary UserRoles { get; set; } + UserRolesConfigSection UserRoles { get; set; } AccessControlConfigSection AccessControl { get; set; } BackupsConfigSection Backups { get; set; } string WebApiListenPrefix { get; set; } @@ -27,7 +27,9 @@ public interface IConfig bool AnonymizeWebApiData { get; set; } LogSeverity DiscordLogLevel { get; set; } - ServerConfigSection[] Servers { get; set; } - ClusterConfigSection[] Clusters { get; set; } + ServersConfigSection Servers { get; set; } + ClustersConfigSection Clusters { get; set; } + + //Test1ConfigSection Test { get; set; } } } \ No newline at end of file diff --git a/ArkBot/Configuration/Model/ServerConfigSection.cs b/ArkBot/Configuration/Model/ServerConfigSection.cs new file mode 100644 index 0000000..807a18f --- /dev/null +++ b/ArkBot/Configuration/Model/ServerConfigSection.cs @@ -0,0 +1,134 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + [DisplayName("Server Instance")] + [CategoryOrder(ConfigurationCategory.Required, 0)] + [CategoryOrder(ConfigurationCategory.Optional, 1)] + [CategoryOrder(ConfigurationCategory.Advanced, 2)] + [CategoryOrder(ConfigurationCategory.Debug, 3)] + public class ServerConfigSection + { + public ServerConfigSection() + { + ServerManagement = new ServerManagementConfigSection(); + } + + public override string ToString() => Key; + + // Required + + [JsonProperty(PropertyName = "key")] + [Display(Name = "Key", Description = "Unique key (tag name) for this server instance")] + [ConfigurationHelp(remarks: new [] { + "Used to identify a particular server instance in Discord commands, Companion App etc." + }, Example = "`server1`, `server2`, `server3`")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(0)] + [MinLength(1, ErrorMessage = "{0} is not set")] + [RegularExpression(@"^[a-z0-9_\-]+$", ErrorMessage = "{0} must consist of letters (a-z), numbers (0-9), dashes (-) and underscores (_)")] + public string Key { get; set; } + + [JsonProperty(PropertyName = "saveFilePath")] + [Display(Name = "Save File Path", Description = "The savegame (`.ark`) to extract data from and watch for changes")] + [ConfigurationHelp(remarks: new [] { @"Savegames are found in your ARK installation folder under `ShooterGame\Saved\SavedArks\`." }, + Example = @"`C:\ARK Servers\server1\ShooterGame\Saved\SavedArks\TheIsland.ark`")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(1)] + [Editor(typeof(OpenFilePathEditor), typeof(OpenFilePathEditor))] + [OpenFilePathEditor(Filter = "ARK savegame files (*.ark)|*.ark|All files (*.*)|*.*")] + [FileExists(ErrorMessage = "{0} is not set or the file path does not exist")] + public string SaveFilePath { get; set; } + + [JsonProperty(PropertyName = "ip")] + [Display(Name = "IP Address", Description = "The address used to connect to this server instance")] + [ConfigurationHelp(remarks: new [] { "Use your servers external IP address unless you have other requirements."}, + Example = "`127.0.0.1`")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(2)] + [MinLength(1, ErrorMessage = "{0} is not set")] + public string Ip { get; set; } + + [JsonProperty(PropertyName = "queryPort")] + [Display(Name = "Query Port", Description = "The port used to query to this server instance")] + [ConfigurationHelp(remarks: new [] { "Use same value as `?QueryPort=` from the command used to start your server." }, Example = "`27015`")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(3)] + [Range(1, 65535, ErrorMessage = "{0} must be between 1-65635")] + public int QueryPort { get; set; } + + // Optional + + [JsonProperty(PropertyName = "clusterKey")] + [Display(Name = "Cluster Key", Description = "Optional key for the cluster instance this server is part of")] + [ConfigurationHelp(remarks: new[] { "Only used if your server is part of a cluster." }, instructions: new [] { + @"1. Configure a cluster instance in ARK Bot.", + @"2. Connect all servers in the cluster by specifying the unique cluster key in this field." + }, Example = "`cluster1`")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(0)] + [RegularExpression(@"^[a-z0-9_\-]+$", ErrorMessage = "{0} must be empty or consist of letters (a-z), numbers (0-9), dashes (-) and underscores (_)")] + public string ClusterKey { get; set; } + + [JsonProperty(PropertyName = "displayAddress")] + [Display(Name = "Display Address", Description = "The public address used to connect to the server")] + [ConfigurationHelp(remarks: new [] { "Used for displaying server urls and for steam connection links." }, + Example = "`arkserver.net:27015`")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(1)] + public string DisplayAddress { get; set; } + + [JsonProperty(PropertyName = "rconPort")] + [Display(Name = "RCON Port", Description = "The port used to connect to this server instance over rcon")] + [ConfigurationHelp(remarks: new[] { "Use same value as `?RCONPort=` from the command used to start your server." }, Example = "`27020`")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(2)] + [RangeOptional(1, 65535, Optional = true, ErrorMessage = "{0} must be empty or between 1-65635")] + public int? RconPort { get; set; } + + [JsonProperty(PropertyName = "rconPassword")] + [Display(Name = "RCON Password", Description = "The password used to connect to this server instance via rcon")] + [ConfigurationHelp(remarks: new[] { "Use same value as `?ServerAdminPassword=` from the command used to start your server." }, Example = "`password`")] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(3)] + public string RconPassword { get; set; } + + [JsonProperty(PropertyName = "serverManagement")] + [Display(Name = "Server Management", Description = "Configure server management features available through Discord commands")] + [ConfigurationHelp(remarks: new[] { "Includes features like start, restart, stop, update etc." })] + [Category(ConfigurationCategory.Optional)] + [PropertyOrder(4)] + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] + public ServerManagementConfigSection ServerManagement { get; set; } + + + // Advanced + + [JsonProperty(PropertyName = "disableChatNotifications")] + [Display(Name = "Disable Chat Notifications", Description = "Option to disable chat notifications for this server instance")] + [ConfigurationHelp(remarks: new[] { "This option is used together with ARK Server API and ARK Cross Server Chat plugin to controll which servers are notified on countdowns.\r\n", + "By default ARK Bot will notify all servers. When using ARK Cross Server Chat only a single server should be notified since all incoming chat messages will be relayed to the rest of the cluster by the plugin." })] + [Category(ConfigurationCategory.Advanced)] + [PropertyOrder(0)] + public bool DisableChatNotifications { get; set; } + } +} diff --git a/ArkBot/Configuration/Model/ServerManagementConfigSection.cs b/ArkBot/Configuration/Model/ServerManagementConfigSection.cs new file mode 100644 index 0000000..9f5bd89 --- /dev/null +++ b/ArkBot/Configuration/Model/ServerManagementConfigSection.cs @@ -0,0 +1,86 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class ServerManagementConfigSection + { + public override string ToString() => $"Server Management ({(Enabled ? "Enabled" : "Disabled")})"; + + [JsonProperty(PropertyName = "enabled")] + [Display(Name = "Enabled", Description = "Option to enable server management features for this server instance")] + [DefaultValue(true)] + [PropertyOrder(0)] + public bool Enabled { get; set; } + + [JsonProperty(PropertyName = "serverExecutablePath")] + [Display(Name = "Server Executable Path", Description = "Path of the server executable (`ShooterGameServer.exe`)")] + [ConfigurationHelp(remarks: new[] { @"Normally found in your ARK installation folder under `ShooterGame\Binaries\Win64\`." }, + Example = @"`C:\ARK Servers\server1\ShooterGame\Binaries\Win64\ShooterGameServer.exe`")] + [PropertyOrder(1)] + [Editor(typeof(OpenFilePathEditor), typeof(OpenFilePathEditor))] + [OpenFilePathEditor(Filter = "Executable files (*.exe)|*.exe|All files (*.*)|*.*")] + [FileExists(IfMethod = nameof(IsEnabled), ErrorMessage = "{0} file path does not exist")] + public string ServerExecutablePath { get; set; } + + [JsonProperty(PropertyName = "serverExecutableArguments")] + [Display(Name = "Server Executable Arguments", Description = "Command line arguments used when starting the server instance")] + [ConfigurationHelp(remarks: new[] { "Make sure to include `-serverkey=server1` and to set it to match your own unique server key. It is used by the server management features to know which `ShooterGameServer.exe` process is which when multiple servers are hosted on the same PC." }, + Example = @"`TheIsland?listen?Port=7777?QueryPort=27015?RCONPort=27020?RCONEnabled=True?SessionName=Server1?ServerPassword=?ServerAdminPassword=password?SpectatorPassword=password?MaxPlayers=5 -culture=en -nosteamclient -clusterid=cluster1 -ClusterDirOverride=""C:\ARK Servers\cluster1"" -serverkey=server1`")] + [PropertyOrder(2)] + [MinLengthOptional(1, IfMethod = nameof(IsEnabled), ErrorMessage = "{0} is not set")] + public string ServerExecutableArguments { get; set; } + + [JsonProperty(PropertyName = "steamCmdExecutablePath")] + [Display(Name = "Steam Cmd Executable Path", Description = "Path of the steamcmd executable (`SteamCMD.exe`)")] + [ConfigurationHelp(remarks: new[] { @"The Steam Console Client or SteamCMD is a command-line version of the Steam client. It is used update Steam servers and mods." }, + Example = @"`C:\SteamCMD\SteamCMD.exe`")] + [PropertyOrder(3)] + [Editor(typeof(OpenFilePathEditor), typeof(OpenFilePathEditor))] + [OpenFilePathEditor(Filter = "Executable files (*.exe)|*.exe|All files (*.*)|*.*")] + [FileExists(IfMethod = nameof(IsEnabled), ErrorMessage = "{0} is not set or the file path does not exist")] + public string SteamCmdExecutablePath { get; set; } + + [JsonProperty(PropertyName = "serverInstallDirPath")] + [Display(Name = "Server Install Directory Path", Description = "Path of the server installation directory")] + [ConfigurationHelp(remarks: new[] { @"Used in SteamCMD update operations as the parameter for `force_install_dir`." }, + Example = @"`C:\ARK Servers\server1`")] + [PropertyOrder(4)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryExists(IfMethod = nameof(IsEnabled), ErrorMessage = "{0} directory path does not exist")] + public string ServerInstallDirPath { get; set; } + + [JsonProperty(PropertyName = "usePowershellOutputRedirect")] + [Display(Name = "Use PowerShell Output Redirect", Description = "Use alternative PowerShell/file based output redirect for update progress notifications")] + [DefaultValue(true)] + [ConfigurationHelp(remarks: new[] { "Compatibility option to pipe SteamCMD outout through PowerShell rather than redirecting the standard output.\r\n", + "Works on most servers - compared to standard output redirect which only works on some."})] + [PropertyOrder(5)] + public bool UsePowershellOutputRedirect { get; set; } + + + // Validation methods + + private bool IsEnabled() + { + return Enabled; + } + } +} diff --git a/ArkBot/Configuration/Model/ServersConfigSection.cs b/ArkBot/Configuration/Model/ServersConfigSection.cs new file mode 100644 index 0000000..cc4d6ed --- /dev/null +++ b/ArkBot/Configuration/Model/ServersConfigSection.cs @@ -0,0 +1,27 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class ServersConfigSection : List + { + public override string ToString() => "Servers" + (Count > 0 ? $" ({(string.Join(", ", this.Select(x => x.Key)))})" : ""); + } +} diff --git a/ArkBot/Configuration/Model/SslConfigSection.cs b/ArkBot/Configuration/Model/SslConfigSection.cs new file mode 100644 index 0000000..ae0df1e --- /dev/null +++ b/ArkBot/Configuration/Model/SslConfigSection.cs @@ -0,0 +1,64 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class SslConfigSection + { + public SslConfigSection() + { + Domains = new string[] { }; + } + + public override string ToString() => $"SSL ({(Enabled ? "Enabled" : "Disabled")})"; + + [JsonProperty(PropertyName = "enabled")] + [Display(Name = "Enabled", Description = "Toggle ssl.")] + public bool Enabled { get; set; } + + [JsonProperty(PropertyName = "challengeListenPrefix")] + [Display(Name = "Challenge Listen Prefix", Description = "Http listen prefix for ssl challenge request (external port must be 80)")] + public string ChallengeListenPrefix { get; set; } + + [JsonProperty(PropertyName = "name")] + [Display(Name = "Name", Description = "Friendly name of the certificate")] + public string Name { get; set; } + + [JsonProperty(PropertyName = "password")] + [Display(Name = "Password", Description = "Private password")] + public string Password { get; set; } + + [JsonProperty(PropertyName = "email")] + [Display(Name = "Email", Description = "Registration contact email")] + public string Email { get; set; } + + [JsonProperty(PropertyName = "domains")] + [Display(Name = "Domain name(s)", Description = "Domain name(s) to issue the certificate for")] + public string[] Domains { get; set; } + + [JsonProperty(PropertyName = "ports")] + [Display(Name = "Ports", Description = "Ports to bind the ssl certificate to")] + public int[] Ports { get; set; } + + [JsonProperty(PropertyName = "useCompatibilityNonSNIBindings")] + [Display(Name = "Use Compatibility non-SNI Bindings", Description = "Use non SNI SSL bindings for previous Windows OS (before Windows 8/2012)")] + public bool UseCompatibilityNonSNIBindings { get; set; } + } +} diff --git a/ArkBot/Configuration/Model/UserRolesConfigSection.cs b/ArkBot/Configuration/Model/UserRolesConfigSection.cs new file mode 100644 index 0000000..5a3f14e --- /dev/null +++ b/ArkBot/Configuration/Model/UserRolesConfigSection.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class UserRolesConfigSection : List + { + public override string ToString() => "User Roles" + (Count > 0 ? $" ({(string.Join(", ", this.Select(x => x.Role)))})" : ""); + } +} diff --git a/ArkBot/Configuration/Model/UsersInRoleConfig.cs b/ArkBot/Configuration/Model/UsersInRoleConfig.cs new file mode 100644 index 0000000..a623343 --- /dev/null +++ b/ArkBot/Configuration/Model/UsersInRoleConfig.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using ArkBot.Configuration.Validation; +using Newtonsoft.Json; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + [DisplayName("User Role")] + [CategoryOrder(ConfigurationCategory.Required, 0)] + [CategoryOrder(ConfigurationCategory.Optional, 1)] + [CategoryOrder(ConfigurationCategory.Advanced, 2)] + [CategoryOrder(ConfigurationCategory.Debug, 3)] + public class UsersInRoleConfig + { + public UsersInRoleConfig() + { + SteamIds = new List(); + } + + public override string ToString() => Role; + + [JsonProperty(PropertyName = "role")] + [Display(Name = "Role", Description = "Name of the role")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(1)] + [MinLengthOptional(1, ErrorMessage = "{0} is not set")] + public string Role { get; set; } + + [JsonProperty(PropertyName = "steamIds")] + [Display(Name = "Steam IDs", Description = "Steam IDs that are assigned to this role")] + [Category(ConfigurationCategory.Required)] + [PropertyOrder(2)] + [Required(ErrorMessage = "{0} is not set")] + public List SteamIds { get; set; } + } +} diff --git a/ArkBot/Configuration/Model/_temp_test.cs b/ArkBot/Configuration/Model/_temp_test.cs new file mode 100644 index 0000000..d82c646 --- /dev/null +++ b/ArkBot/Configuration/Model/_temp_test.cs @@ -0,0 +1,137 @@ +using Newtonsoft.Json; +using System; +using System.Collections; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ArkBot.Configuration; +using ArkBot.Configuration.Validation; +using Discord; +using Microsoft.IdentityModel; +using PropertyChanged; +using Validar; +using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration.Model +{ + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class Test1ConfigSection + { + public override string ToString() => $"Test ({(Enabled ? "Enabled" : "Disabled")})"; + + public Test1ConfigSection() + { + Test = new Test2ConfigSection(); + } + + [JsonProperty(PropertyName = "enabled")] + [Display(Name = "Enabled", Description = "Option to enable")] + [PropertyOrder(0)] + public bool Enabled { get; set; } + + [JsonProperty(PropertyName = "directoryPath")] + [Display(Name = "Directory Path", Description = "Directory path")] + [PropertyOrder(1)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryExists(IfMethod = nameof(IsEnabled), ErrorMessage = "{0} directory path does not exist")] + public string DirectoryPath { get; set; } + + [JsonProperty(PropertyName = "test")] + [Display(Name = "Test", Description = "Test")] + [PropertyOrder(2)] + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] + [ValidateExpandable(ErrorMessage = "{0} contain field(s) that are invalid")] + public Test2ConfigSection Test { get; set; } + + // Validation methods + + private bool IsEnabled() + { + return Enabled; + } + } + + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class Test2ConfigSection + { + public override string ToString() => $"Test ({(Enabled ? "Enabled" : "Disabled")})"; + + public Test2ConfigSection() + { + Test = new Test3ConfigSection(); + } + + [JsonProperty(PropertyName = "enabled")] + [Display(Name = "Enabled", Description = "Option to enable")] + [PropertyOrder(0)] + public bool Enabled { get; set; } + + [JsonProperty(PropertyName = "directoryPath")] + [Display(Name = "Directory Path", Description = "Directory path")] + [PropertyOrder(1)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryExists(IfMethod = nameof(IsEnabled), ErrorMessage = "{0} directory path does not exist")] + public string DirectoryPath { get; set; } + + [JsonProperty(PropertyName = "test")] + [Display(Name = "Test", Description = "Test")] + [PropertyOrder(2)] + [ExpandableObject] + [Required(ErrorMessage = "{0} is not set")] + [ValidateExpandable(ErrorMessage = "{0} contain field(s) that are invalid")] + public Test3ConfigSection Test { get; set; } + + // Validation methods + + private bool IsEnabled() + { + return Enabled; + } + } + + [AddINotifyPropertyChangedInterface] + [InjectValidation] + public class Test3ConfigSection + { + public override string ToString() => $"Test ({(Enabled ? "Enabled" : "Disabled")})"; + + public Test3ConfigSection() + { + Servers = new ServersConfigSection(); + } + + [JsonProperty(PropertyName = "enabled")] + [Display(Name = "Enabled", Description = "Option to enable")] + [PropertyOrder(0)] + public bool Enabled { get; set; } + + [JsonProperty(PropertyName = "directoryPath")] + [Display(Name = "Directory Path", Description = "Directory path")] + [PropertyOrder(1)] + [Editor(typeof(DirectoryPathEditor), typeof(DirectoryPathEditor))] + [DirectoryExists(IfMethod = nameof(IsEnabled), ErrorMessage = "{0} directory path does not exist")] + public string DirectoryPath { get; set; } + + [JsonProperty(PropertyName = "servers")] + [Display(Name = "Servers", Description = "Server instance configurations")] + [PropertyOrder(2)] + [Editor(typeof(CustomCollectionEditor), typeof(CustomCollectionEditor))] + [Required(ErrorMessage = "{0} is not set")] + [ValidateCollection(ErrorMessage = "{0} contains item(s) that are invalid")] + public ServersConfigSection Servers { get; set; } + + // Validation methods + + private bool IsEnabled() + { + return Enabled; + } + } +} diff --git a/ArkBot/Configuration/MyCustomTypeDescriptor.cs b/ArkBot/Configuration/MyCustomTypeDescriptor.cs deleted file mode 100644 index 24f9a65..0000000 --- a/ArkBot/Configuration/MyCustomTypeDescriptor.cs +++ /dev/null @@ -1,313 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Xceed.Wpf.Toolkit.PropertyGrid.Attributes; -using System.ComponentModel; -using System.Reflection; -using System.Windows; -using System.Windows.Controls; -using System.Windows.Data; -using System.Windows.Media; -using Xceed.Wpf.Toolkit; -using Xceed.Wpf.Toolkit.PropertyGrid; -using Xceed.Wpf.Toolkit.PropertyGrid.Editors; - -namespace ArkBot.Configuration -{ - [ReadOnly(true)] - [TypeConverter(typeof(MyCustomTypeDescriptor))] - [ExpandableObject] - public class AccessControlConfigSection : Dictionary - { - - } - - [TypeConverter(typeof(MyCustomTypeDescriptor2>))] - [ExpandableObject] - public class AccessControlFeatureGroup : Dictionary> - { - - } - - public class StringArrayEditorWithPreview : PrimitiveTypeCollectionEditor2 - { - protected override void SetControlProperties(PropertyItem propertyItem) - { - base.SetControlProperties(propertyItem); - Editor.Content = null; - } - - public override FrameworkElement ResolveEditor(PropertyItem propertyItem) - { - var editor = base.ResolveEditor(propertyItem); - return editor; - } - } - - public class PrimitiveTypeCollectionEditor2 : TypeEditor - { - protected override void SetControlProperties(PropertyItem propertyItem) - { - Editor.BorderThickness = new System.Windows.Thickness(0); - } - - protected override void SetValueDependencyProperty() - { - ValueProperty = PrimitiveTypeCollectionControl2.ItemsSourceProperty; - } - - protected override void ResolveValueBinding(PropertyItem propertyItem) - { - var type = propertyItem.PropertyType; - Editor.ItemsSourceType = type; - - if (type.BaseType == typeof(System.Array)) - { - Editor.ItemType = type.GetElementType(); - } - else - { - var typeArguments = type.GetGenericArguments(); - if (typeArguments.Length > 0) - { - Editor.ItemType = typeArguments[0]; - } - } - - base.ResolveValueBinding(propertyItem); - } - } - - public class PrimitiveTypeCollectionControl2 : PrimitiveTypeCollectionControl - { - protected override void OnTextChanged(string oldValue, string newValue) - { - base.OnTextChanged(oldValue, newValue); - Content = newValue?.Replace("\r\n", "; "); - } - } - - public class MyCustomTypeDescriptor : ExpandableObjectConverter - { - public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) - { - if (value is IDictionary) - { - IDictionary list = value as IDictionary; - PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null); - - var num = 0; - foreach (var kv in list) - { - propDescriptions.Add(new ListItemPropertyDescriptor(list, kv.Key, num++)); - } - //IEnumerator enumerator = list.GetEnumerator(); - //int counter = -1; - //while (enumerator.MoveNext()) - //{ - // counter++; - - - //} - return propDescriptions; - } - else - { - return base.GetProperties(context, value, attributes); - } - } - } - - public class ListItemPropertyDescriptor : PropertyDescriptor - { - private readonly IDictionary owner; - private readonly T index; - private readonly int order; - - public ListItemPropertyDescriptor(IDictionary owner, T index, int order) : base("[" + index + "]", null) - { - this.owner = owner; - this.index = index; - this.order = order; - } - - public override AttributeCollection Attributes - { - get - { - var attributes = TypeDescriptor.GetAttributes(GetValue(null), false); - //If the Xceed expandable object attribute is not applied then apply it - //if (!attributes.OfType().Any()) - //{ - // attributes = AddAttribute(new ExpandableObjectAttribute(), attributes); - //} - - //set the xceed order attribute - attributes = AddAttribute(new DisplayNameAttribute(index.ToString()), attributes); - attributes = AddAttribute(new PropertyOrderAttribute(order), attributes); - - return attributes; - } - } - private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes) - { - Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1]; - oldAttributes.CopyTo(newAttributes, 1); - newAttributes[0] = newAttribute; - - return new AttributeCollection(newAttributes); - } - - public override bool CanResetValue(object component) - { - return false; - } - - public override object GetValue(object component) - { - return Value; - } - - private T2 Value - => owner[index]; - - public override void ResetValue(object component) - { - throw new NotImplementedException(); - } - - public override void SetValue(object component, object value) - { - owner[index] = (T2)value; - } - - public override bool ShouldSerializeValue(object component) - { - return false; - } - - public override Type ComponentType - => owner.GetType(); - - public override bool IsReadOnly - => true; - - public override Type PropertyType - => Value?.GetType(); - - } - - public class MyCustomTypeDescriptor2 : ExpandableObjectConverter - { - public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes) - { - if (value is IDictionary) - { - IDictionary list = value as IDictionary; - PropertyDescriptorCollection propDescriptions = new PropertyDescriptorCollection(null); - - var num = 0; - foreach (var kv in list) - { - propDescriptions.Add(new ListItemPropertyDescriptor2(list, kv.Key, num++)); - } - //IEnumerator enumerator = list.GetEnumerator(); - //int counter = -1; - //while (enumerator.MoveNext()) - //{ - // counter++; - - - //} - return propDescriptions; - } - else - { - return base.GetProperties(context, value, attributes); - } - } - } - - public class ListItemPropertyDescriptor2 : PropertyDescriptor - { - private readonly IDictionary owner; - private readonly T index; - private readonly int order; - - public ListItemPropertyDescriptor2(IDictionary owner, T index, int order) : base("[" + index + "]", null) - { - this.owner = owner; - this.index = index; - this.order = order; - } - - public override AttributeCollection Attributes - { - get - { - var attributes = TypeDescriptor.GetAttributes(GetValue(null), false); - //If the Xceed expandable object attribute is not applied then apply it - //if (!attributes.OfType().Any()) - //{ - // attributes = AddAttribute(new ExpandableObjectAttribute(), attributes); - //} - - //set the xceed order attribute - attributes = AddAttribute(new DisplayNameAttribute(index.ToString()), attributes); - attributes = AddAttribute(new PropertyOrderAttribute(order), attributes); - attributes = AddAttribute(new EditorAttribute(typeof(StringArrayEditorWithPreview), typeof(StringArrayEditorWithPreview)), attributes); - - return attributes; - } - } - private AttributeCollection AddAttribute(Attribute newAttribute, AttributeCollection oldAttributes) - { - Attribute[] newAttributes = new Attribute[oldAttributes.Count + 1]; - oldAttributes.CopyTo(newAttributes, 1); - newAttributes[0] = newAttribute; - - return new AttributeCollection(newAttributes); - } - - public override bool CanResetValue(object component) - { - return false; - } - - public override object GetValue(object component) - { - return Value; - } - - private T2 Value - => owner[index]; - - public override void ResetValue(object component) - { - throw new NotImplementedException(); - } - - public override void SetValue(object component, object value) - { - owner[index] = (T2)value; - } - - public override bool ShouldSerializeValue(object component) - { - return false; - } - - public override Type ComponentType - => owner.GetType(); - - public override bool IsReadOnly - => false; - - public override Type PropertyType - => Value?.GetType(); - - } -} diff --git a/ArkBot/Configuration/OpenFilePathEditor.cs b/ArkBot/Configuration/OpenFilePathEditor.cs index 0b49080..c49302d 100644 --- a/ArkBot/Configuration/OpenFilePathEditor.cs +++ b/ArkBot/Configuration/OpenFilePathEditor.cs @@ -41,14 +41,14 @@ public FrameworkElement ResolveEditor(PropertyItem propertyItem) Width = GridLength.Auto }); - TextBox textBox = new TextBox(); + TextBox textBox = new TextBox { BorderThickness = new Thickness(0), Padding = new Thickness(3) }; textBox.HorizontalAlignment = HorizontalAlignment.Stretch; Binding binding = new Binding("Value"); //bind to the Value property of the PropertyItem binding.Source = propertyItem; binding.Mode = BindingMode.TwoWay; BindingOperations.SetBinding(textBox, TextBox.TextProperty, binding); - Button button = new Button(); + Button button = new Button { MinWidth = 19 }; button.Content = "..."; button.Tag = propertyItem; button.Click += button_Click; @@ -66,6 +66,8 @@ private void button_Click(object sender, RoutedEventArgs e) if (null == item) return; var path = item.Value as string; + if (path != null) path = Environment.ExpandEnvironmentVariables(path); + var fi = !string.IsNullOrEmpty(path) && File.Exists(path) ? new FileInfo(path) : null; using (var dialog = new System.Windows.Forms.OpenFileDialog diff --git a/ArkBot/Configuration/PrimitiveTypeCollectionControlWithPreview.cs b/ArkBot/Configuration/PrimitiveTypeCollectionControlWithPreview.cs new file mode 100644 index 0000000..a4ed786 --- /dev/null +++ b/ArkBot/Configuration/PrimitiveTypeCollectionControlWithPreview.cs @@ -0,0 +1,27 @@ +using ArkBot.Extensions; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Media; +using Xceed.Wpf.Toolkit; + +namespace ArkBot.Configuration +{ + public class PrimitiveTypeCollectionControlWithPreview : PrimitiveTypeCollectionControl + { + public PrimitiveTypeCollectionControlWithPreview() + { + Loaded += PrimitiveTypeCollectionControlWithPreview_Loaded; + } + + private void PrimitiveTypeCollectionControlWithPreview_Loaded(object sender, System.Windows.RoutedEventArgs e) + { + foreach (var tb in this.FindVisualChildren()) tb.Foreground = Brushes.Gray; + } + + protected override void OnTextChanged(string oldValue, string newValue) + { + base.OnTextChanged(oldValue, newValue); + Content = newValue?.Replace("\r\n", ", "); + } + } +} diff --git a/ArkBot/Configuration/StringArrayEditorWithPreview.cs b/ArkBot/Configuration/StringArrayEditorWithPreview.cs new file mode 100644 index 0000000..b09fcd3 --- /dev/null +++ b/ArkBot/Configuration/StringArrayEditorWithPreview.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using System.Windows; +using Xceed.Wpf.Toolkit.PropertyGrid; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Configuration +{ + public class StringArrayEditorWithPreview : TypeEditor + { + public override FrameworkElement ResolveEditor(PropertyItem propertyItem) + { + var editor = base.ResolveEditor(propertyItem); + return editor; + } + + protected override void SetControlProperties(PropertyItem propertyItem) + { + Editor.BorderThickness = new System.Windows.Thickness(0); + Editor.Content = null; + } + + protected override void SetValueDependencyProperty() + { + ValueProperty = PrimitiveTypeCollectionControlWithPreview.ItemsSourceProperty; + } + + protected override void ResolveValueBinding(PropertyItem propertyItem) + { + var type = propertyItem.PropertyType; + Editor.ItemsSourceType = type; + + if (type.BaseType == typeof(System.Array)) + { + Editor.ItemType = type.GetElementType(); + } + else if (type.BaseType.IsGenericType && (type.BaseType.GetGenericTypeDefinition() == typeof(List<>))) + { + var typeArguments = type.BaseType.GetGenericArguments(); + if (typeArguments.Length > 0) + { + Editor.ItemType = typeArguments[0]; + } + } + else + { + var typeArguments = type.GetGenericArguments(); + if (typeArguments.Length > 0) + { + Editor.ItemType = typeArguments[0]; + } + } + + base.ResolveValueBinding(propertyItem); + } + } +} diff --git a/ArkBot/Configuration/TypeToDisplayNameConverter.cs b/ArkBot/Configuration/TypeToDisplayNameConverter.cs new file mode 100644 index 0000000..27940e5 --- /dev/null +++ b/ArkBot/Configuration/TypeToDisplayNameConverter.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace ArkBot.Configuration +{ + public class TypeToDisplayNameConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + Type t = (Type)value; + var attrs = t.GetCustomAttributes(false).Cast().ToArray(); + var displayAttr = attrs.OfType().FirstOrDefault(); + var displayNameAttr = attrs.OfType().FirstOrDefault(); + return displayNameAttr?.DisplayName ?? displayAttr?.Name ?? t.Name; + } + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + return value; + } + } +} diff --git a/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs b/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs index 7121157..cfd67aa 100644 --- a/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs +++ b/ArkBot/Configuration/Validation/DirectoryExistsAttribute.cs @@ -15,13 +15,12 @@ public sealed class DirectoryExistsAttribute : IfValidationAttribute { protected override ValidationResult IsValid(object value, ValidationContext validationContext) { - var result = base.IfMethodValid(value, validationContext); - if (result != null) return result; - - return !string.IsNullOrWhiteSpace(value as string) && Directory.Exists((string) value) + var result = IfMethodValid(value, validationContext); + if (result.Item1 != IfValidResult.ContinueValidation) return result.Item2; + return !string.IsNullOrWhiteSpace(value as string) && Directory.Exists(Environment.ExpandEnvironmentVariables((string) value)) ? ValidationResult.Success : new ValidationResult(String.Format(CultureInfo.CurrentCulture, ErrorMessageString, - validationContext.MemberName), new [] { validationContext.MemberName }); + validationContext.DisplayName ?? validationContext.MemberName), new [] { validationContext.MemberName }); } } } diff --git a/ArkBot/Configuration/Validation/DirectoryPathIsValidAttribute.cs b/ArkBot/Configuration/Validation/DirectoryPathIsValidAttribute.cs new file mode 100644 index 0000000..0f17608 --- /dev/null +++ b/ArkBot/Configuration/Validation/DirectoryPathIsValidAttribute.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class DirectoryPathIsValidAttribute : IfValidationAttribute + { + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + var result = IfMethodValid(value, validationContext); + if (result.Item1 != IfValidResult.ContinueValidation) return result.Item2; + + var success = !string.IsNullOrEmpty(value as string); + if (success) + { + try + { + Path.GetFullPath(Environment.ExpandEnvironmentVariables((string)value)); + } + catch { success = false; } + } + + return success + ? ValidationResult.Success + : new ValidationResult(String.Format(CultureInfo.CurrentCulture, ErrorMessageString, + validationContext.DisplayName ?? validationContext.MemberName), new [] { validationContext.MemberName }); + } + } +} diff --git a/ArkBot/Configuration/Validation/FileExistsAttribute.cs b/ArkBot/Configuration/Validation/FileExistsAttribute.cs index 9279773..e2b9912 100644 --- a/ArkBot/Configuration/Validation/FileExistsAttribute.cs +++ b/ArkBot/Configuration/Validation/FileExistsAttribute.cs @@ -16,12 +16,12 @@ public sealed class FileExistsAttribute : IfValidationAttribute protected override ValidationResult IsValid(object value, ValidationContext validationContext) { var result = base.IfMethodValid(value, validationContext); - if (result != null) return result; + if (result.Item1 != IfValidResult.ContinueValidation) return result.Item2; - return !string.IsNullOrWhiteSpace(value as string) && File.Exists((string) value) + return !string.IsNullOrWhiteSpace(value as string) && File.Exists(Environment.ExpandEnvironmentVariables((string) value)) ? ValidationResult.Success : new ValidationResult(String.Format(CultureInfo.CurrentCulture, ErrorMessageString, - validationContext.MemberName), new [] { validationContext.MemberName }); + validationContext.DisplayName ?? validationContext.MemberName), new [] { validationContext.MemberName }); } } } diff --git a/ArkBot/Configuration/Validation/IfValidationAttribute.cs b/ArkBot/Configuration/Validation/IfValidationAttribute.cs index bbdeb53..24b0ea4 100644 --- a/ArkBot/Configuration/Validation/IfValidationAttribute.cs +++ b/ArkBot/Configuration/Validation/IfValidationAttribute.cs @@ -10,25 +10,27 @@ namespace ArkBot.Configuration.Validation { - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public enum IfValidResult { NotValid, Valid, ContinueValidation } + + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)] public abstract class IfValidationAttribute : ValidationAttribute { public string IfMethod { get; set; } - protected ValidationResult IfMethodValid(object value, ValidationContext validationContext) + protected Tuple IfMethodValid(object value, ValidationContext validationContext) { if (IfMethod != null) { var ifMethodInfo = validationContext.ObjectType.GetMethod(IfMethod, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (ifMethodInfo == null) - return new ValidationResult( - $"IfMethod '{validationContext.ObjectType.Name}.{IfMethod}' could not be found!", new[] { validationContext.MemberName }); + return Tuple.Create(IfValidResult.NotValid, new ValidationResult( + $"IfMethod '{validationContext.ObjectType.Name}.{IfMethod}' could not be found!", new[] { validationContext.MemberName })); if (!(bool) ifMethodInfo.Invoke(validationContext.ObjectInstance, null)) - return ValidationResult.Success; + return Tuple.Create(IfValidResult.Valid, ValidationResult.Success); } - return null; + return Tuple.Create(IfValidResult.ContinueValidation, ValidationResult.Success); } } } diff --git a/ArkBot/Configuration/Validation/MinLengthOptionalAttribute.cs b/ArkBot/Configuration/Validation/MinLengthOptionalAttribute.cs new file mode 100644 index 0000000..a5ed8a2 --- /dev/null +++ b/ArkBot/Configuration/Validation/MinLengthOptionalAttribute.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RazorEngine.Compilation.ImpromptuInterface.InvokeExt; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class MinLengthOptionalAttribute : IfValidationAttribute + { + public bool Optional { get; set; } + + private MinLengthAttribute _attr; + + public MinLengthOptionalAttribute(int length) + { + _attr = new MinLengthAttribute(length); + } + + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + if (Optional && value == null) return ValidationResult.Success; + + var result = IfMethodValid(value, validationContext); + if (result.Item1 != IfValidResult.ContinueValidation) return result.Item2; + + return _attr.IsValid(value) + ? ValidationResult.Success + : new ValidationResult(String.Format(CultureInfo.CurrentCulture, ErrorMessageString, + validationContext.DisplayName ?? validationContext.MemberName), new[] { validationContext.MemberName }); + } + } +} diff --git a/ArkBot/Configuration/Validation/RegularExpressionCustomAttribute.cs b/ArkBot/Configuration/Validation/RegularExpressionCustomAttribute.cs new file mode 100644 index 0000000..3683764 --- /dev/null +++ b/ArkBot/Configuration/Validation/RegularExpressionCustomAttribute.cs @@ -0,0 +1,36 @@ +using System; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.Text.RegularExpressions; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] + public sealed class RegularExpressionCustomAttribute : IfValidationAttribute + { + private object _typeId = new object(); + public override object TypeId => _typeId; + + public bool Optional { get; set; } + + private string _pattern; + + public RegularExpressionCustomAttribute(string pattern) + { + _pattern = pattern; + } + + protected override ValidationResult IsValid(object value, ValidationContext validationContext) + { + if (Optional && value == null) return ValidationResult.Success; + + var result = IfMethodValid(value, validationContext); + if (result.Item1 != IfValidResult.ContinueValidation) return result.Item2; + + return value != null && Regex.IsMatch(value as string, _pattern) + ? ValidationResult.Success + : new ValidationResult(String.Format(CultureInfo.CurrentCulture, ErrorMessageString, + validationContext.DisplayName ?? validationContext.MemberName), new[] { validationContext.MemberName }); + } + } +} diff --git a/ArkBot/Configuration/Validation/ValidateCollectionAttribute.cs b/ArkBot/Configuration/Validation/ValidateCollectionAttribute.cs new file mode 100644 index 0000000..34fe477 --- /dev/null +++ b/ArkBot/Configuration/Validation/ValidateCollectionAttribute.cs @@ -0,0 +1,44 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RazorEngine.Compilation.ImpromptuInterface.InvokeExt; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class ValidateCollectionAttribute : ValidationAttribute + { + + public ValidateCollectionAttribute() : base() + { + } + + public override bool IsValid(object value) + { + if (value is System.Collections.ICollection) + { + var collection = value as System.Collections.ICollection; + foreach (var item in collection) + { + var ei = item as INotifyDataErrorInfo; + if (ei == null || !ei.HasErrors) continue; + + return false; + } + } + + return true; + } + + public override string FormatErrorMessage(string name) + { + return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name); + } + } +} diff --git a/ArkBot/Configuration/Validation/ValidateExpandableAttribute.cs b/ArkBot/Configuration/Validation/ValidateExpandableAttribute.cs new file mode 100644 index 0000000..94b39f4 --- /dev/null +++ b/ArkBot/Configuration/Validation/ValidateExpandableAttribute.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using RazorEngine.Compilation.ImpromptuInterface.InvokeExt; + +namespace ArkBot.Configuration.Validation +{ + [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = false)] + public sealed class ValidateExpandableAttribute : ValidationAttribute + { + + public ValidateExpandableAttribute() : base() + { + } + + public override bool IsValid(object value) + { + var ei = value as INotifyDataErrorInfo; + if (ei == null) return true; + + var fi = value.GetType().GetField("validationTemplate", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic); + (fi?.GetValue(value) as ArkBot.Configuration.Validation.ValidationTemplate)?.Validate(); + + if (!ei.HasErrors) return true; + + return false; + } + + public override string FormatErrorMessage(string name) + { + return String.Format(CultureInfo.CurrentCulture, ErrorMessageString, name); + } + } +} diff --git a/ArkBot/Configuration/Validation/ValidationTemplate.cs b/ArkBot/Configuration/Validation/ValidationTemplate.cs index 3db0ce8..eb3b738 100644 --- a/ArkBot/Configuration/Validation/ValidationTemplate.cs +++ b/ArkBot/Configuration/Validation/ValidationTemplate.cs @@ -22,13 +22,19 @@ public ValidationTemplate(INotifyPropertyChanged target) _validationContext = new ValidationContext(target, null, null); _validationResults = new List(); Validator.TryValidateObject(target, _validationContext, _validationResults, true); - target.PropertyChanged += Validate; + target.PropertyChanged += target_PropertyChanged; } - void Validate(object sender, PropertyChangedEventArgs e) + void target_PropertyChanged(object sender, PropertyChangedEventArgs e) + { + Validate(); + } + + public void Validate() { _validationResults.Clear(); Validator.TryValidateObject(_target, _validationContext, _validationResults, true); + var hashSet = new HashSet(_validationResults.SelectMany(x => x.MemberNames)); foreach (var error in hashSet) { diff --git a/ArkBot/Constants.cs b/ArkBot/Constants.cs index bfa32e6..cef1e44 100644 --- a/ArkBot/Constants.cs +++ b/ArkBot/Constants.cs @@ -25,6 +25,8 @@ public string DatabaseFilePath private string _databaseFilePath => "|DataDirectory|Database\\Database.sdf"; public string DatabaseConnectionString => $"Data Source={_databaseFilePath};Max Database Size=4091"; public string OpenidresponsetemplatePath => @"Resources\openidresponse.html"; + public string ConfigurationHelpTemplatePath => @"Resources\configurationHelp.html"; + public string AboutTemplatePath => @"Resources\about.html"; public string SavedStateFilePath => "savedstate.json"; public string ArkServerProcessName => "ShooterGameServer"; } diff --git a/ArkBot/Controls/About.xaml b/ArkBot/Controls/About.xaml new file mode 100644 index 0000000..a5e07a7 --- /dev/null +++ b/ArkBot/Controls/About.xaml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + diff --git a/ArkBot/Controls/About.xaml.cs b/ArkBot/Controls/About.xaml.cs new file mode 100644 index 0000000..e46f5dd --- /dev/null +++ b/ArkBot/Controls/About.xaml.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using ArkBot.Browser; +using ArkBot.Configuration; +using ArkBot.Helpers; +using ArkBot.ViewModel; +using CefSharp; +using Markdig; +using Nito.AsyncEx; +using RazorEngine.Configuration; +using RazorEngine.Templating; +using Xceed.Wpf.Toolkit.PropertyGrid; +using Xceed.Wpf.Toolkit.PropertyGrid.Editors; + +namespace ArkBot.Controls +{ + /// + /// Interaction logic for About.xaml + /// + public partial class About : UserControl + { + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register("Model", typeof(AboutViewModel), typeof(About), new FrameworkPropertyMetadata()); + + public AboutViewModel Model + { + get { return GetValue(ModelProperty) as AboutViewModel; } + set { SetValue(ModelProperty, value); } + } + + public About() + { + InitializeComponent(); + + AboutBrowser.IsBrowserInitializedChanged += AboutBrowser_IsBrowserInitializedChanged; + var reqHandler = new RequestEventHandler(); + reqHandler.OnBeforeBrowseEvent += ReqHandler_OnBeforeBrowseEvent; + AboutBrowser.RequestHandler = reqHandler; + } + + private void ReqHandler_OnBeforeBrowseEvent(object sender, Browser.EventArgs.OnBeforeBrowseEventArgs e) + { + if (e.Request.Url.Equals("http://tmp/", StringComparison.OrdinalIgnoreCase)) return; + else if (e.Request.Url.StartsWith("navigate://", StringComparison.OrdinalIgnoreCase)) + { + var r = new Regex(@"^navigate://(?.+)$"); + var to = r.Match(e.Request.Url)?.Groups["to"].Value; + if(!string.IsNullOrWhiteSpace(to)) + { + switch(to.ToLower()) + { + case "configuration": + Workspace.Instance.Configuration.IsActive = true; + break; + } + } + + e.CancelNavigation = true; + return; + } + + e.CancelNavigation = true; + Process.Start(e.Request.Url); + } + + private async void AboutBrowser_IsBrowserInitializedChanged(object sender, DependencyPropertyChangedEventArgs e) + { + if ((bool) e.NewValue) + { + // Note: For these to work, make sure Address is not set in Browser Control + string html = await Model.RunCompileTemplate(new AboutViewModel.AboutTemplateViewModel { hasConfig = Model.HasValidConfig }); + AboutBrowser.LoadHtml(html, "http://tmp/"); + } + } + } +} diff --git a/ArkBot/Controls/Configuration.xaml b/ArkBot/Controls/Configuration.xaml index b23f986..66c59e6 100644 --- a/ArkBot/Controls/Configuration.xaml +++ b/ArkBot/Controls/Configuration.xaml @@ -7,61 +7,84 @@ xmlns:local="clr-namespace:ArkBot.Controls" xmlns:extensions="clr-namespace:ArkBot.Extensions" xmlns:system="clr-namespace:System;assembly=mscorlib" - xmlns:autoscroll="clr-namespace:ArkBot.ViewModel" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" + xmlns:wpf="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf" + xmlns:cef="clr-namespace:CefSharp;assembly=CefSharp.Core" + xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" + xmlns:behaviours="clr-namespace:ArkBot.Browser.Behaviours" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="300"> + - + + - + + + + + + - + - - - + + + - - - - - - + - - - - - + + + + + + + + + diff --git a/ArkBot/Controls/Configuration.xaml.cs b/ArkBot/Controls/Configuration.xaml.cs index 4246208..062e862 100644 --- a/ArkBot/Controls/Configuration.xaml.cs +++ b/ArkBot/Controls/Configuration.xaml.cs @@ -1,12 +1,30 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.ComponentModel; +using System.ComponentModel.DataAnnotations; using System.Diagnostics; using System.Linq; using System.Reflection; +using System.Security.Cryptography.X509Certificates; using System.Text; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Interactivity; +using ArkBot.Browser; +using ArkBot.Configuration; +using ArkBot.Extensions; +using ArkBot.Helpers; +using ArkBot.ViewModel; +using CefSharp; +using Markdig; +using Nito.AsyncEx; +using RazorEngine.Configuration; +using RazorEngine.Templating; +using Xceed.Wpf.Toolkit; using Xceed.Wpf.Toolkit.PropertyGrid; using Xceed.Wpf.Toolkit.PropertyGrid.Editors; @@ -17,48 +35,262 @@ namespace ArkBot.Controls /// public partial class Configuration : UserControl { - public static readonly DependencyProperty ModelProperty = DependencyProperty.Register("Model", typeof(Config), typeof(Configuration), new FrameworkPropertyMetadata()); + public static readonly DependencyProperty ModelProperty = DependencyProperty.Register("Model", typeof(ConfigurationViewModel), typeof(Configuration), new FrameworkPropertyMetadata()); - public Config Model + public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register("SelectedObject", typeof(object), typeof(Configuration), new UIPropertyMetadata(null /*, new PropertyChangedCallback(Configuration.OnSelectedObjectChanged)*/)); + + public static readonly DependencyProperty IsReadOnlyProperty = DependencyProperty.Register("IsReadOnly", typeof(bool), typeof(Configuration), new UIPropertyMetadata(false)); + + //public static readonly RoutedEvent SelectedObjectChangedEvent = EventManager.RegisterRoutedEvent("SelectedObjectChanged", RoutingStrategy.Bubble, typeof(RoutedPropertyChangedEventHandler), typeof(Configuration)); + + public ConfigurationViewModel Model { - get { return GetValue(ModelProperty) as Config; } + get { return GetValue(ModelProperty) as ConfigurationViewModel; } set { SetValue(ModelProperty, value); } } + public object SelectedObject + { + get { return GetValue(SelectedObjectProperty); } + set { SetValue(SelectedObjectProperty, value); } + } + + public bool IsReadOnly + { + get { return (bool)GetValue(IsReadOnlyProperty); } + set { SetValue(IsReadOnlyProperty, value); } + } + + private bool _propSelected = false; + private PropertyItem _summaryBrowserSelectedProp; + public Configuration() { + //todo: must fix collection validation callback (it probably does not work for collection that are inside expandable sections) + //todo: must make expandable sections show validation messages from ValidateExpandableAttribute where they contain fields that are invalid + InitializeComponent(); - ConfigurationPropertyGrid.PropertyValueChanged += ConfigurationPropertyGrid_PropertyValueChanged; - ConfigurationPropertyGrid.PreparePropertyItem += ConfigurationPropertyGrid_PreparePropertyItem; + PART_PropertyGrid.SelectedObjectChanged += ConfigurationPropertyGrid_SelectedObjectChanged; + PART_PropertyGrid.PropertyValueChanged += ConfigurationPropertyGrid_PropertyValueChanged; + PART_PropertyGrid.SelectedPropertyItemChanged += ConfigurationPropertyGrid_SelectedPropertyItemChanged; + PART_PropertyGrid.LayoutUpdated += PART_PropertyGrid_LayoutUpdated; + PART_PropertyGrid.PropertyChanged += PART_PropertyGrid_PropertyChanged; + + SummaryBrowser.IsBrowserInitializedChanged += SummaryBrowser_IsBrowserInitializedChanged; + var reqHandler = new RequestEventHandler(); + reqHandler.OnBeforeBrowseEvent += ReqHandler_OnBeforeBrowseEvent; + SummaryBrowser.RequestHandler = reqHandler; + + //SelectedObject = "{Binding SelectedItem, RelativeSource={RelativeSource TemplatedParent}}" + //IsReadOnly = "{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" + + //var myBinding = new System.Windows.Data.Binding("SelectedItem"); + //myBinding.Source = Model; + //PART_PropertyGrid.SetBinding(PropertyGrid.SelectedObjectProperty, myBinding); + } + + private async void PART_PropertyGrid_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if (e.PropertyName.Equals("Filter")) + { + await UpdateValidation(); + } + } + + //private int _selectedObjectChangedCounter = 0; + //private int _lastLayoutUpdatedForSelectedObjectChangedCounter = 0; + + private void PART_PropertyGrid_LayoutUpdated(object sender, EventArgs e) + { + //var grids = PART_PropertyGrid.FindVisualChildrenWithPath("PropertyItem/Border/Grid").ToArray(); + //if (grids == null) return; + //foreach(var grid in grids) + //{ + // var binding = new Binding() + // { + // Source = grid.ColumnDefinitions[0], + // Path = new PropertyPath("Width"), + // Mode = BindingMode.OneWay, + // }; + + // grid.ColumnDefinitions[0].SetBinding(MaxWidthProperty, binding); + //} + + //this does not work with sorting options + //if (_selectedObjectChangedCounter > _lastLayoutUpdatedForSelectedObjectChangedCounter) + //{ + //var expandSites = PART_PropertyGrid.FindVisualChildrenWithPath("Expander[expander]/Grid/Border[ExpandSite]"); + //foreach (var exp in expandSites) + //{ + // exp.Padding = new Thickness(exp.Padding.Left, exp.Padding.Top, 23, exp.Padding.Bottom); //add some padding on the right side to make room for validation adorners + //} + + //var expandSites = PART_PropertyGrid.FindVisualChildrenWithPath("PropertyItem/Border"); + //foreach (var exp in expandSites) + //{ + // exp.Padding = new Thickness(exp.Padding.Left, exp.Padding.Top, 23, exp.Padding.Bottom); //add some padding on the right side to make room for validation adorners + //} + + //var expandSites = PART_PropertyGrid.FindVisualChildrenWithPath("PropertyItemsControl[PART_PropertyItemsControl]/Border/ScrollViewer/Grid/ScrollContentPresenter/ItemsPresenter/VirtualizingStackPanel"); + //foreach (var exp in expandSites) + //{ + // exp.Margin = new Thickness(exp.Margin.Left, exp.Margin.Top, 23, exp.Margin.Bottom); //add some margin on the right side to make room for validation adorners + //} + + //_lastLayoutUpdatedForSelectedObjectChangedCounter = _selectedObjectChangedCounter; + //} + } + + //private static void OnSelectedObjectChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) + //{ + // var grid = o as PropertyGrid; + // if (grid != null) + // { + // //protected virtual void OnSelectedObjectChanged(object oldValue, object newValue) + // var mi = typeof(PropertyGrid).GetMethod("OnSelectedObjectChanged", BindingFlags.Instance | BindingFlags.NonPublic); + // if (mi != null) + // { + // mi.Invoke(grid, new[] { e.OldValue, e.NewValue }); + // } + // //grid.OnSelectedObjectChanged(e.OldValue, e.NewValue); + // } + //} + + + private async void ConfigurationPropertyGrid_SelectedObjectChanged(object sender, RoutedPropertyChangedEventArgs e) + { + //_selectedObjectChangedCounter++; + + // without this recursive collection validation errors do not get set + await UpdateValidation(trigger: true); + + _propSelected = SelectFirstProp(); } - private void ConfigurationPropertyGrid_PreparePropertyItem(object sender, PropertyItemEventArgs e) + private bool SelectFirstProp() { - if (e.PropertyItem.Name.Equals("ServerExecutableArguments", StringComparison.Ordinal)) + if (!SummaryBrowser.IsBrowserInitialized) return false; + + var prop = PART_PropertyGrid.Properties?.Cast().FirstOrDefault(); + if (prop == null) return false; + + PART_PropertyGrid.SelectedProperty = prop; + + return true; + } + + private void ReqHandler_OnBeforeBrowseEvent(object sender, Browser.EventArgs.OnBeforeBrowseEventArgs e) + { + if (e.Request.Url.Equals("http://tmp/", StringComparison.OrdinalIgnoreCase)) return; + else if (e.Request.Url.StartsWith("navigate://", StringComparison.OrdinalIgnoreCase)) { - e.PropertyItem.Editor.Height = 100; + var r = new Regex(@"^navigate://(?.+)$"); + var to = r.Match(e.Request.Url)?.Groups["to"].Value; + if (!string.IsNullOrWhiteSpace(to)) + { + switch (to.ToLower()) + { + case "restore-default-value": + PART_PropertyGrid.Dispatcher.Invoke(new Action(() => { + var defaultAttr = _summaryBrowserSelectedProp?.PropertyDescriptor.Attributes.OfType().FirstOrDefault(); + if (defaultAttr != null) _summaryBrowserSelectedProp.Value = defaultAttr.Value; + })); + + break; + } + } + + e.CancelNavigation = true; + return; + } + + e.CancelNavigation = true; + Process.Start(e.Request.Url); + } + + private async void ConfigurationPropertyGrid_SelectedPropertyItemChanged(object sender, RoutedPropertyChangedEventArgs e) + { + await UpdateBrowser(); + } + + private async Task UpdateBrowser() + { + var prop = PART_PropertyGrid.SelectedPropertyItem as PropertyItem; + if (SummaryBrowser.IsBrowserInitialized && prop != null) + { + _summaryBrowserSelectedProp = prop; + var attr = prop.PropertyDescriptor.Attributes.OfType().FirstOrDefault(); + var defaultAttr = prop.PropertyDescriptor.Attributes.OfType().FirstOrDefault(); + var remarks = attr?.Remarks != null ? Markdown.ToHtml(attr.Remarks) : null; + var instructions = attr?.Instructions != null ? Markdown.ToHtml(attr.Instructions) : null; + var example = attr?.Example != null ? Markdown.ToHtml(attr.Example) : null; + var defaultValue = defaultAttr?.Value != null ? defaultAttr.Value.ToString() : null; + var desc = prop.GetBindingExpression(PropertyItem.ValueProperty)?.DataItem as DependencyObject; + var html = await Model.RunCompileTemplate(new ConfigurationViewModel.HelpTemplateViewModel + { + displayName = prop.DisplayName, + description = prop.Description, + remarks = remarks, + instructions = instructions, + example = example, + defaultValue = defaultValue, + validationError = desc != null ? Validation.GetHasError(desc) ? Validation.GetErrors(desc)[0]?.ErrorContent.ToString() : null : null + }); + + //if (Validation.GetHasError(descriptor)) + //{ + // var errors = Validation.GetErrors(descriptor); + // Validation.MarkInvalid(be, errors[0]); + //} + + SummaryBrowser.LoadHtml(html, "http://tmp/"); + } + } + + private void SummaryBrowser_IsBrowserInitializedChanged(object sender, DependencyPropertyChangedEventArgs e) + { + if ((bool) e.NewValue) + { + if (!_propSelected) _propSelected = SelectFirstProp(); + + // Note: For these to work, make sure Address is not set in Browser Control + //SummaryBrowser.LoadHtml("Test

Html Encoded in URL 2!

", "http://tmp/"); + + //SummaryBrowser.Load("about:blank"); + //SummaryBrowser.LoadString(@"Test

Html Encoded in URL 2!

", "http://tmp/"); } } /// /// PropertyGrid only updates validation for the PropertyItem that was changed by default. This is a way to force it to update all properties in order to support dependencies. PropertyGrid is built for .NET 4 and does not support the ValidatesOnNotifyDataErrors binding property. /// - private void ConfigurationPropertyGrid_PropertyValueChanged(object sender, Xceed.Wpf.Toolkit.PropertyGrid.PropertyValueChangedEventArgs e) + private async void ConfigurationPropertyGrid_PropertyValueChanged(object sender, Xceed.Wpf.Toolkit.PropertyGrid.PropertyValueChangedEventArgs e) { var modifiedPropertyItem = e.OriginalSource as PropertyItem; if (modifiedPropertyItem != null) { - var mi = typeof(PropertyItem).GetMethod("SetRedInvalidBorder", - BindingFlags.Instance | BindingFlags.NonPublic); - if (mi == null) return; + await UpdateValidation(modifiedPropertyItem, true); + } + } - var grid = sender as PropertyGrid; - UpdateRecursive(mi, modifiedPropertyItem, grid.Properties.Cast()); + internal async Task UpdateValidation(PropertyItem modifiedPropertyItem = null, bool trigger = false) + { + // trigger a full revalidation + if (trigger && PART_PropertyGrid?.SelectedObject != null) + { + var fi = PART_PropertyGrid?.SelectedObject.GetType().GetField("validationTemplate", BindingFlags.Instance | BindingFlags.NonPublic); + (fi?.GetValue(PART_PropertyGrid?.SelectedObject) as ArkBot.Configuration.Validation.ValidationTemplate)?.Validate(); } + + if (PART_PropertyGrid?.Properties == null) return; + + UpdateRecursive(modifiedPropertyItem, PART_PropertyGrid.Properties.Cast()); + + await UpdateBrowser(); } - private void UpdateRecursive(MethodInfo miSetRedInvalidBorder, PropertyItem modifiedPropertyItem, IEnumerable properties) + private void UpdateRecursive(PropertyItem modifiedPropertyItem, IEnumerable properties) { foreach (var prop in properties) { @@ -68,14 +300,159 @@ private void UpdateRecursive(MethodInfo miSetRedInvalidBorder, PropertyItem modi if (be != null) { be.UpdateSource(); - miSetRedInvalidBorder.Invoke(prop, new[] { be }); + SetRedInvalidBorder(be); } if (prop.IsExpandable) { - UpdateRecursive(miSetRedInvalidBorder, modifiedPropertyItem, prop.Properties.Cast()); + UpdateRecursive(modifiedPropertyItem, prop.Properties.Cast()); } + //if (prop.Editor is CollectionControlButton && prop.Value is System.Collections.ICollection) + //{ + // var collection = prop.Value as System.Collections.ICollection; + // foreach (var item in collection) + // { + // var validationContext = new ValidationContext(item, null, null); + // var validationResults = new List(); + // Validator.TryValidateObject(item, validationContext, validationResults, true); + // var r = validationResults.FirstOrDefault(); + // if (r != null) + // { + // Validation.MarkInvalid(be, new ValidationError(new DataErrorValidationRule(), be, r.ErrorMessage, null)); + // break; + // } + // } + //} } } + + internal void SetRedInvalidBorder(BindingExpression be) + { + if ((be != null) && IsBaseTypeName("DescriptorPropertyDefinitionBase", be.DataItem.GetType().BaseType)) + { + var descriptor = be.DataItem as DependencyObject; + if (Validation.GetHasError(descriptor)) + { + var errors = Validation.GetErrors(descriptor); + Validation.MarkInvalid(be, errors[0]); + } + } + } + + //internal List ValidationGetErrors(DependencyObject descriptor) + //{ + // var result = new List(); + + // if (Validation.GetHasError(descriptor)) + // { + // result.AddRange(Validation.GetErrors(descriptor)); + // } + + // if(descriptor.) + + // return null; + //} + + internal bool IsBaseTypeName(string name, Type t) + { + if (t == null) return false; + if (t.Name.Equals(name)) return true; + + return IsBaseTypeName(name, t.BaseType); + } + } + + // Fix ScrollViewer stealing mouse wheel events preventing the PropertyGrid from scrolling in ExpandableProperties + public static class BubbleScrollBehavior + { + public static readonly DependencyProperty BubbleScrollProperty = + DependencyProperty.RegisterAttached("BubbleScroll", typeof(bool), typeof(BubbleScrollBehavior), new PropertyMetadata(false, BubbleScrollPropertyChanged)); + + + public static void BubbleScrollPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + var e = obj as UIElement; + if (e != null && (bool)args.NewValue) + { + e.PreviewMouseWheel += AssociatedObject_PreviewMouseWheel; + } + else + { + e.PreviewMouseWheel -= AssociatedObject_PreviewMouseWheel; + } + } + + private static void AssociatedObject_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e) + { + if (sender is ScrollViewer && !e.Handled) + { + e.Handled = true; + var eventArg = new System.Windows.Input.MouseWheelEventArgs(e.MouseDevice, e.Timestamp, e.Delta); + eventArg.RoutedEvent = UIElement.MouseWheelEvent; + eventArg.Source = sender; + var parent = ((Control)sender).Parent as UIElement; + parent.RaiseEvent(eventArg); + } + } + + public static bool GetBubbleScroll(DependencyObject obj) + { + return (bool)obj.GetValue(BubbleScrollProperty); + } + + public static void SetBubbleScroll(DependencyObject obj, bool value) + { + obj.SetValue(BubbleScrollProperty, value); + } + } + + class IsPropertyGridConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + var control = value as DependencyObject; + if (value == null) return false; + var result = control.FindVisualParents().Take(2).Any(x => x is PropertyItemBase); + + return result; + } + + public object ConvertBack(object value, Type targetType, object parameter + , System.Globalization.CultureInfo culture) + { + throw new NotImplementedException(); + } + } + + public static class SetGridColumnBehavior + { + public static readonly DependencyProperty SetGridColumnProperty = + DependencyProperty.RegisterAttached("SetGridColumn", typeof(bool), typeof(SetGridColumnBehavior), new PropertyMetadata(false, SetGridColumnPropertyChanged)); + + + public static void SetGridColumnPropertyChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) + { + var e = obj as Grid; + if (e != null && (bool)args.NewValue) + { + var b = new Binding(); + b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, + typeof(PropertyGrid), 1); + b.Path = new PropertyPath("NameColumnWidth"); + + BindingOperations.SetBinding(e.ColumnDefinitions[0], ColumnDefinition.MaxWidthProperty, b); + //e.ColumnDefinitions[0].MinWidth = 200; //not working - grip bugged and unusable after resizing + } + } + + public static bool GetSetGridColumn(DependencyObject obj) + { + return (bool)obj.GetValue(SetGridColumnProperty); + } + + public static void SetSetGridColumn(DependencyObject obj, bool value) + { + obj.SetValue(SetGridColumnProperty, value); + } } } diff --git a/ArkBot/Data/ArkSpeciesStats.cs b/ArkBot/Data/ArkSpeciesStats.cs index c471ddf..90e9149 100644 --- a/ArkBot/Data/ArkSpeciesStats.cs +++ b/ArkBot/Data/ArkSpeciesStats.cs @@ -1,4 +1,5 @@ -using ArkBot.Helpers; +using ArkBot.Configuration.Model; +using ArkBot.Helpers; using Newtonsoft.Json; using System; using System.Collections.Generic; diff --git a/ArkBot/Discord/ArkDiscordBot.cs b/ArkBot/Discord/ArkDiscordBot.cs index ea11f87..7f21d22 100644 --- a/ArkBot/Discord/ArkDiscordBot.cs +++ b/ArkBot/Discord/ArkDiscordBot.cs @@ -29,6 +29,7 @@ using Discord.WebSocket; using RazorEngine.Compilation.ImpromptuInterface; using VDS.Common.Collections.Enumerations; +using ArkBot.Configuration.Model; namespace ArkBot.Discord { diff --git a/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs b/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs index 5e259e0..c894956 100644 --- a/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs +++ b/ArkBot/Discord/Command/RoleRestrictedPreconditionAttribute.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; +using ArkBot.Configuration.Model; using Discord.Commands; using Discord.WebSocket; diff --git a/ArkBot/Discord/DiscordManager.cs b/ArkBot/Discord/DiscordManager.cs index ec8d796..27c5ccb 100644 --- a/ArkBot/Discord/DiscordManager.cs +++ b/ArkBot/Discord/DiscordManager.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading.Tasks; using Discord.WebSocket; +using ArkBot.Configuration.Model; namespace ArkBot.Discord { diff --git a/ArkBot/Extensions/DependencyObjectExtensions.cs b/ArkBot/Extensions/DependencyObjectExtensions.cs new file mode 100644 index 0000000..2f12269 --- /dev/null +++ b/ArkBot/Extensions/DependencyObjectExtensions.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using System.Threading.Tasks; +using System.Windows; + +namespace ArkBot.Extensions +{ + public static class DependencyObjectExtensions + { + public static IEnumerable FindVisualChildrenWithPath(this DependencyObject depObj, string path) where T : DependencyObject + { + if (path == null || depObj == null) yield break; + + var r = new Regex(@"^(?.+?)(?:\[(?.+?)\])?$", RegexOptions.Singleline | RegexOptions.IgnoreCase); + var segments = path.Split('/').Select(x => + { + var m = r.Match(x); + return Tuple.Create(m?.Groups["type"].Value, m?.Groups["name"].Value); + }).ToArray(); + + foreach (var item in FindVisualChildrenWithPathInternal(depObj, segments)) + { + yield return item; + } + } + + private static IEnumerable FindVisualChildrenWithPathInternal(this DependencyObject depObj, Tuple[] path, int currentIndex = 0) where T : DependencyObject + { + if (depObj == null || !(path?.Length > 0)) yield break; + + for (int i = 0; i < System.Windows.Media.VisualTreeHelper.GetChildrenCount(depObj); i++) + { + DependencyObject child = System.Windows.Media.VisualTreeHelper.GetChild(depObj, i); + if (child?.GetType().Name.Equals(path[currentIndex].Item1) == true + && (path[currentIndex].Item2 == null || (child as FrameworkElement)?.Name.Equals(path[currentIndex].Item2) == true)) + { + if (currentIndex == path.Length - 1) yield return child as T; + else + { + foreach (T childOfChild in FindVisualChildrenWithPathInternal(child, path, currentIndex + 1)) + { + yield return childOfChild; + } + } + } + else + { + foreach (T childOfChild in FindVisualChildrenWithPathInternal(child, path, 0)) + { + yield return childOfChild; + } + } + } + } + + public static IEnumerable FindVisualChildren(this DependencyObject depObj) where T : DependencyObject + { + if (depObj != null) + { + for (int i = 0; i < System.Windows.Media.VisualTreeHelper.GetChildrenCount(depObj); i++) + { + DependencyObject child = System.Windows.Media.VisualTreeHelper.GetChild(depObj, i); + if (child != null && child is T) + { + yield return (T)child; + } + + foreach (T childOfChild in FindVisualChildren(child)) + { + yield return childOfChild; + } + } + } + } + + public static IEnumerable FindVisualParents(this DependencyObject depObj) + { + if (depObj != null) + { + + DependencyObject parent = System.Windows.Media.VisualTreeHelper.GetParent(depObj); + if (parent != null) + { + yield return parent; + } + + foreach (var parentOfParent in FindVisualParents(parent)) + { + yield return parentOfParent; + } + } + } + } +} diff --git a/ArkBot/Helpers/ArkDataHelper.cs b/ArkBot/Helpers/ArkDataHelper.cs index e2c0207..e15c3e9 100644 --- a/ArkBot/Helpers/ArkDataHelper.cs +++ b/ArkBot/Helpers/ArkDataHelper.cs @@ -1,4 +1,5 @@ -using ArkBot.Data; +using ArkBot.Configuration.Model; +using ArkBot.Data; using System; using System.Collections.Generic; using System.Linq; diff --git a/ArkBot/Helpers/WebApiHelper.cs b/ArkBot/Helpers/WebApiHelper.cs index e7b7b87..27f1e28 100644 --- a/ArkBot/Helpers/WebApiHelper.cs +++ b/ArkBot/Helpers/WebApiHelper.cs @@ -1,4 +1,5 @@ -using ArkBot.WebApi.Model; +using ArkBot.Configuration.Model; +using ArkBot.WebApi.Model; using System; using System.Collections.Generic; using System.Linq; @@ -23,7 +24,11 @@ public static UserViewModel GetUser(ClaimsPrincipal authuser, IConfig config) { var name = authuser?.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name")?.Value; var steamId = authuser?.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier")?.Value; - if (steamId != null) steamId = steamId.Replace("http://steamcommunity.com/openid/id/", ""); + if (steamId != null) + { + steamId = steamId.Replace("http://steamcommunity.com/openid/id/", ""); + steamId = steamId.Replace("https://steamcommunity.com/openid/id/", ""); + } if (authuser != null) { @@ -47,7 +52,7 @@ public static UserViewModel GetUser(ClaimsPrincipal authuser, IConfig config) public static string[] GetRolesForUser(IConfig config, string steamId) { - var roles = (!string.IsNullOrEmpty(steamId) ? config.UserRoles?.Where(x => x.Value?.Contains(steamId) == true).Select(x => x.Key).ToList() : null) ?? new List(); + var roles = (!string.IsNullOrEmpty(steamId) ? config.UserRoles?.Where(x => x.SteamIds?.Contains(steamId) == true).Select(x => x.Role).ToList() : null) ?? new List(); //default roles roles.Add("guest"); diff --git a/ArkBot/IConstants.cs b/ArkBot/IConstants.cs index dc4827b..511222d 100644 --- a/ArkBot/IConstants.cs +++ b/ArkBot/IConstants.cs @@ -4,6 +4,8 @@ public interface IConstants { string DatabaseConnectionString { get; } string OpenidresponsetemplatePath { get; } + string ConfigurationHelpTemplatePath { get; } + string AboutTemplatePath { get; } string DatabaseFilePath { get; } string SavedStateFilePath { get; } string ArkServerProcessName { get; } diff --git a/ArkBot/Layout/PaneStyleSelector.cs b/ArkBot/Layout/PaneStyleSelector.cs index 46358be..ff3b047 100644 --- a/ArkBot/Layout/PaneStyleSelector.cs +++ b/ArkBot/Layout/PaneStyleSelector.cs @@ -13,6 +13,7 @@ public class PaneStyleSelector : StyleSelector { public Style ConsoleStyle { get; set; } public Style ConfigurationStyle { get; set; } + public Style AboutStyle { get; set; } public override Style SelectStyle(object item, DependencyObject container) { @@ -20,6 +21,8 @@ public override Style SelectStyle(object item, DependencyObject container) return ConsoleStyle; if (item is ConfigurationViewModel) return ConfigurationStyle; + if (item is AboutViewModel) + return AboutStyle; return base.SelectStyle(item, container); } diff --git a/ArkBot/Layout/PaneTemplateSelector.cs b/ArkBot/Layout/PaneTemplateSelector.cs index 046e4aa..9382707 100644 --- a/ArkBot/Layout/PaneTemplateSelector.cs +++ b/ArkBot/Layout/PaneTemplateSelector.cs @@ -14,6 +14,7 @@ public class PaneTemplateSelector : DataTemplateSelector { public DataTemplate ConsoleTemplate { get; set; } public DataTemplate ConfigurationTemplate { get; set; } + public DataTemplate AboutTemplate { get; set; } public override DataTemplate SelectTemplate(object item, DependencyObject container) { @@ -23,6 +24,8 @@ public override DataTemplate SelectTemplate(object item, DependencyObject contai return ConsoleTemplate; if (item is ConfigurationViewModel) return ConfigurationTemplate; + if (item is AboutViewModel) + return AboutTemplate; return base.SelectTemplate(item, container); } diff --git a/ArkBot/MainWindow.xaml b/ArkBot/MainWindow.xaml index d48ec04..8830c04 100644 --- a/ArkBot/MainWindow.xaml +++ b/ArkBot/MainWindow.xaml @@ -8,6 +8,8 @@ xmlns:controls="clr-namespace:ArkBot.Controls" xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit" xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock" + xmlns:xcpt="http://schemas.xceed.com/wpf/xaml/themes" + xmlns:xctt="http://schemas.xceed.com/wpf/xaml/toolkit/themes" xmlns:localThemes="http://schemas.xceed.com/wpf/xaml/avalondock/themes" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:sw="clr-namespace:System.Windows;assembly=mscorlib" @@ -15,7 +17,7 @@ xmlns:prism="http://prismlibrary.com/" mc:Ignorable="d" x:Name="mainWindow" - Title="ARK Bot" MinWidth="800" MinHeight="600" Width="800" Height="600" WindowStartupLocation="CenterScreen" Icon="basket_empty.ico"> + Title="ARK Bot" MinWidth="600" MinHeight="500" Width="800" Height="800" WindowStartupLocation="CenterScreen" Icon="basket_empty.ico"> @@ -61,6 +63,8 @@ + + @@ -85,9 +89,23 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ArkBot/ViewModel/AboutViewModel.cs b/ArkBot/ViewModel/AboutViewModel.cs new file mode 100644 index 0000000..afe5afc --- /dev/null +++ b/ArkBot/ViewModel/AboutViewModel.cs @@ -0,0 +1,97 @@ +using ArkBot.Commands; +using ArkBot.Helpers; +using Newtonsoft.Json; +using Nito.AsyncEx; +using Prism.Commands; +using PropertyChanged; +using RazorEngine.Configuration; +using RazorEngine.Templating; +using System; +using System.Collections.Generic; +using System.Collections.ObjectModel; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; + +namespace ArkBot.ViewModel +{ + public sealed class AboutViewModel : TabViewModel, IDisposable + { + public class AboutTemplateViewModel + { + public bool hasConfig { get; set; } + } + + public bool HasValidConfig { get; set; } + + private Lazy _razorEngineService = new Lazy(() => + { + var razorConfig = new TemplateServiceConfiguration + { + DisableTempFileLocking = true, + CachingProvider = new DefaultCachingProvider(t => { }) + }; + + return RazorEngine.Templating.RazorEngineService.Create(razorConfig); + }); + public Lazy RazorEngineService => _razorEngineService; + + private AsyncLazy _template = new AsyncLazy(async () => await FileHelper.ReadAllTextTaskAsync(new Constants().AboutTemplatePath)); + + + private AboutViewModel() : base("About", "About") + { + } + + private async Task InitializeAsync() + { + await RunCompileTemplate(new AboutTemplateViewModel { hasConfig = true }); + return this; + } + + public static Task CreateAsync(bool isVisible = false) + { + var ret = new AboutViewModel { IsVisible = isVisible }; + return ret.InitializeAsync(); + } + + public async Task RunCompileTemplate(AboutTemplateViewModel model) + { + var template = await _template; + var html = RazorEngineService.Value.RunCompile(template, template, typeof(AboutTemplateViewModel), model); + return html; + } + + #region IDisposable Support + private bool disposedValue = false; + + private void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + if (_razorEngineService != null && _razorEngineService.IsValueCreated) + { + _razorEngineService.Value.Dispose(); + _razorEngineService = null; + } + } + + disposedValue = true; + } + } + + public void Dispose() + { + Dispose(true); + } + #endregion + } +} diff --git a/ArkBot/ViewModel/ConfigurationViewModel.cs b/ArkBot/ViewModel/ConfigurationViewModel.cs index c188286..817215b 100644 --- a/ArkBot/ViewModel/ConfigurationViewModel.cs +++ b/ArkBot/ViewModel/ConfigurationViewModel.cs @@ -1,7 +1,12 @@ using ArkBot.Commands; using ArkBot.Helpers; +using ArkBot.WpfCommands; using Newtonsoft.Json; +using Nito.AsyncEx; using Prism.Commands; +using PropertyChanged; +using RazorEngine.Configuration; +using RazorEngine.Templating; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -17,12 +22,108 @@ namespace ArkBot.ViewModel { - public class ConfigurationViewModel : TabViewModel + public sealed class ConfigurationViewModel : TabViewModel, IDisposable { - public Config Config { get; set; } + public class HelpTemplateViewModel + { + public string displayName { get; set; } + public string description { get; set; } + public string remarks { get; set; } + public string instructions { get; set; } + public string example { get; set; } + public string defaultValue { get; set; } + public string validationError { get; set; } + } + + public object Config { get; set; } + + private Lazy _razorEngineService = new Lazy(() => + { + var razorConfig = new TemplateServiceConfiguration + { + DisableTempFileLocking = true, + CachingProvider = new DefaultCachingProvider(t => { }) + }; + + return RazorEngine.Templating.RazorEngineService.Create(razorConfig); + }); + public Lazy RazorEngineService => _razorEngineService; + + private AsyncLazy _template = new AsyncLazy(async () => await FileHelper.ReadAllTextTaskAsync(new Constants().ConfigurationHelpTemplatePath)); + + private ConfigurationViewModel() : base("Configuration", "Configuration") + { + } + + private async Task InitializeAsync() + { + await RunCompileTemplate(new HelpTemplateViewModel { displayName = "", description = "", instructions = "", example = "", defaultValue = null }); + return this; + } + + public static Task CreateAsync(bool isVisible = false) + { + var ret = new ConfigurationViewModel { IsVisible = isVisible }; + return ret.InitializeAsync(); + } + + public async Task RunCompileTemplate(HelpTemplateViewModel model) + { + var template = await _template; + var html = RazorEngineService.Value.RunCompile(template, template, typeof(HelpTemplateViewModel), model); + return html; + } + + public ICommand SaveConfig => _saveConfig ?? (_saveConfig = new RelayCommand(parameter => OnSaveConfig(parameter), parameter => CanSaveConfig(parameter))); + private RelayCommand _saveConfig; + + private bool CanSaveConfig(object parameter) + { + return true; + } + + private void OnSaveConfig(object parameter) + { + //if (!File.Exists(Constants.ConfigFilePath)) return; + + var result = MessageBox.Show("Are you sure you want to save this configuration?", "Save current configuration", MessageBoxButton.YesNo, MessageBoxImage.Question); + + if (result != MessageBoxResult.Yes) return; + + try + { + var json = JsonConvert.SerializeObject(Config, Formatting.Indented); + File.WriteAllText(Workspace.Constants.ConfigFilePath, json); + } + catch + { + } + } + + #region IDisposable Support + private bool disposedValue = false; + + private void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + if (_razorEngineService != null && _razorEngineService.IsValueCreated) + { + _razorEngineService.Value.Dispose(); + _razorEngineService = null; + } + } + + disposedValue = true; + } + } - public ConfigurationViewModel() : base("Configuration", "Configuration") + public void Dispose() { + Dispose(true); } + #endregion } } diff --git a/ArkBot/ViewModel/ConsoleViewModel.cs b/ArkBot/ViewModel/ConsoleViewModel.cs index d29d6b3..9c2cfc1 100644 --- a/ArkBot/ViewModel/ConsoleViewModel.cs +++ b/ArkBot/ViewModel/ConsoleViewModel.cs @@ -2,6 +2,7 @@ using ArkBot.Helpers; using Newtonsoft.Json; using Prism.Commands; +using PropertyChanged; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -17,17 +18,30 @@ namespace ArkBot.ViewModel { - public class ConsoleViewModel : TabViewModel + public sealed class ConsoleViewModel : TabViewModel { public ObservableCollection ConsoleOutput { get; set; } - public ConsoleViewModel() : base("Console", "Console") + private ConsoleViewModel() : base("Console", "Console") { ConsoleOutput = new ObservableCollection(); } + private async Task InitializeAsync() + { + return this; + } + + public static Task CreateAsync(bool isVisible = false) + { + var ret = new ConsoleViewModel { IsVisible = isVisible }; + return ret.InitializeAsync(); + } + public void AddLog(string message) { + if (message == null) return; + Application.Current.Dispatcher.Invoke(delegate { ConsoleOutput.Add(message.TrimEnd('\n', '\r')); diff --git a/ArkBot/ViewModel/PaneViewModel.cs b/ArkBot/ViewModel/PaneViewModel.cs index be728ec..ef756b2 100644 --- a/ArkBot/ViewModel/PaneViewModel.cs +++ b/ArkBot/ViewModel/PaneViewModel.cs @@ -1,4 +1,5 @@ -using System; +using PropertyChanged; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -17,55 +18,12 @@ public PaneViewModel(string contentId, string title) //public ImageSource IconSource { get; protected set; } - public string Title - { - get { return _title; } - set - { - if (_title == value) return; - - _title = value; - RaisePropertyChanged(nameof(Title)); - } - } - private string _title; + public string Title { get; set; } - public string ContentId - { - get { return _contentId; } - set - { - if (_contentId == value) return; - _contentId = value; - RaisePropertyChanged(nameof(ContentId)); - } - } - private string _contentId; + public string ContentId { get; set; } - public bool IsSelected - { - get { return _isSelected; } - set - { - if (_isSelected == value) return; + public bool IsSelected { get; set; } - _isSelected = value; - RaisePropertyChanged(nameof(IsSelected)); - } - } - private bool _isSelected; - - public bool IsActive - { - get { return _isActive; } - set - { - if (_isActive == value) return; - - _isActive = value; - RaisePropertyChanged(nameof(IsActive)); - } - } - private bool _isActive; + public bool IsActive { get; set; } } } diff --git a/ArkBot/ViewModel/ToolViewModel.cs b/ArkBot/ViewModel/ToolViewModel.cs index 8b69ab1..c3cdaa5 100644 --- a/ArkBot/ViewModel/ToolViewModel.cs +++ b/ArkBot/ViewModel/ToolViewModel.cs @@ -1,4 +1,5 @@ -using System; +using PropertyChanged; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -15,17 +16,6 @@ public ToolViewModel(string contentId, string name) : base(contentId, name) public string Name { get; private set; } - public bool IsVisible - { - get { return _isVisible; } - set - { - if (_isVisible == value) return; - - _isVisible = value; - RaisePropertyChanged(nameof(IsVisible)); - } - } - private bool _isVisible = true; + public bool IsVisible { get; set; } } } diff --git a/ArkBot/ViewModel/ViewModelBase.cs b/ArkBot/ViewModel/ViewModelBase.cs index 7f35cfb..3a2554b 100644 --- a/ArkBot/ViewModel/ViewModelBase.cs +++ b/ArkBot/ViewModel/ViewModelBase.cs @@ -1,4 +1,5 @@ -using System; +using PropertyChanged; +using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; @@ -11,6 +12,9 @@ public abstract class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; - protected virtual void RaisePropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + public virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } } } diff --git a/ArkBot/ViewModel/Workspace.cs b/ArkBot/ViewModel/Workspace.cs index e01b0db..bae3108 100644 --- a/ArkBot/ViewModel/Workspace.cs +++ b/ArkBot/ViewModel/Workspace.cs @@ -49,28 +49,38 @@ using ArkSavegameToolkitNet.Domain; using Discord.Net.Providers.WS4Net; using AppFunc = System.Func, System.Threading.Tasks.Task>; +using Nito.AsyncEx; +using Markdig; +using PropertyChanged; +using ArkBot.Configuration.Model; namespace ArkBot.ViewModel { - public class Workspace : ViewModelBase, IDisposable + public sealed class Workspace : ViewModelBase, IDisposable { public struct Constants { public const string ConfigFilePath = @"config.json"; + public const string DefaultConfigFilePath = @"defaultconfig.json"; public const string LayoutFilePath = @".\Layout.config"; } - public static Workspace Instance => _instance ?? (_instance = new Workspace()); + public static Workspace Instance => _instance; private static Workspace _instance; - public IEnumerable Panes => _panes ?? (_panes = new PaneViewModel[] { Console, Configuration }); - private PaneViewModel[] _panes; + public static AsyncLazy AsyncInstance = new AsyncLazy(async () => + { + return _instance ?? await CreateAsync(); + }); + + public ObservableCollection Panes { get; private set; } + + public ConsoleViewModel Console { get; private set; } + + public ConfigurationViewModel Configuration { get; private set; } + + public AboutViewModel About { get; private set; } - public ConsoleViewModel Console => _console ?? (_console = new ConsoleViewModel()); - private ConsoleViewModel _console; - - public ConfigurationViewModel Configuration => _configuration ?? (_configuration = new ConfigurationViewModel()); - private ConfigurationViewModel _configuration; public DelegateCommand ClosingCommand { get; private set; } @@ -85,22 +95,7 @@ public struct Constants internal static IContainer Container { get; set; } - public bool SkipExtractNextRestart - { - get - { - return _skipExtractNextRestart; - } - - set - { - if (value == _skipExtractNextRestart) return; - - _skipExtractNextRestart = value; - RaisePropertyChanged(nameof(SkipExtractNextRestart)); - } - } - private bool _skipExtractNextRestart; + public bool SkipExtractNextRestart { get; set; } private SavedState _savedstate = null; private IDisposable _webapi; @@ -110,15 +105,38 @@ public bool SkipExtractNextRestart private ArkContextManager _contextManager; internal IConfig _config; - public Workspace() + private Workspace() { //do not create viewmodels or load data here, or avalondock layout deserialization will fail + Panes = new ObservableCollection(); ManuallyUpdateServers = new ObservableCollection(); ManuallyUpdateClusters = new ObservableCollection(); ClosingCommand = new DelegateCommand(OnClosing); + PropertyChanged += Workspace_PropertyChanged; _webappRedirects = new List(); + + //if markdig is not used it will not be loaded before being used by razor template (hack) + var tmp = Markdown.ToHtml(@"**hack**"); + } + + private async Task InitializeAsync() + { + Console = await ConsoleViewModel.CreateAsync(true); + Configuration = await ConfigurationViewModel.CreateAsync(true); + About = await AboutViewModel.CreateAsync(true); + Panes.AddRange(new PaneViewModel[] { About, Console, Configuration }); + + await Init(); + + return this; + } + + private static Task CreateAsync() + { + _instance = new Workspace(); + return _instance.InitializeAsync(); } private void Workspace_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) @@ -149,7 +167,7 @@ private void OnClosing(System.ComponentModel.CancelEventArgs e) if (_runDiscordBotTask != null) { _runDiscordBotCts?.Cancel(); - Task.WaitAny(_runDiscordBotTask); + if (_runDiscordBotTask.Status == TaskStatus.Running) Task.WaitAny(_runDiscordBotTask); } } @@ -207,13 +225,6 @@ internal async Task Init() log4net.Config.XmlConfigurator.Configure(); - //load config and check for errors - if (!File.Exists(Constants.ConfigFilePath)) - { - WriteAndWaitForKey($@"The required file config.json is missing from application directory. Please copy defaultconfig.json, set the correct values for your environment and restart the application."); - return; - } - if (!new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator)) { WriteAndWaitForKey($@"This application must be run as administrator in order to function properly."); @@ -222,229 +233,56 @@ internal async Task Init() _config = null; string exceptionMessage = null; - try + if (File.Exists(Constants.ConfigFilePath)) { - _config = JsonConvert.DeserializeObject(File.ReadAllText(Constants.ConfigFilePath)); - if (_config.Discord == null) _config.Discord = new DiscordConfigSection(); - } - catch (Exception ex) - { - exceptionMessage = ex.Message; - } - if (_config == null) - { - WriteAndWaitForKey( - $@"The required file config.json is empty or contains errors. Please copy defaultconfig.json, set the correct values for your environment and restart the application.", - exceptionMessage); - return; - } - - var sb = new StringBuilder(); - if (string.IsNullOrWhiteSpace(_config.BotName)) - { - sb.AppendLine($@"Error: {nameof(_config.BotName)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BotName))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.TempFileOutputDirPath) || !Directory.Exists(_config.TempFileOutputDirPath)) - { - sb.AppendLine($@"Error: {nameof(_config.TempFileOutputDirPath)} is not a valid directory path."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.TempFileOutputDirPath))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.GoogleApiKey)) - { - sb.AppendLine($@"Error: {nameof(_config.GoogleApiKey)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.GoogleApiKey))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.SteamApiKey)) - { - sb.AppendLine($@"Error: {nameof(_config.SteamApiKey)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.SteamApiKey))}"); - sb.AppendLine(); - } - if (_config.Backups.BackupsEnabled && (string.IsNullOrWhiteSpace(_config.Backups.BackupsDirectoryPath) || !FileHelper.IsValidDirectoryPath(_config.Backups.BackupsDirectoryPath))) - { - sb.AppendLine($@"Error: {nameof(_config.Backups.BackupsDirectoryPath)} is not a valid directory path."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.Backups.BackupsDirectoryPath))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.WebApiListenPrefix)) - { - sb.AppendLine($@"Error: {nameof(_config.WebApiListenPrefix)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.WebApiListenPrefix))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.WebAppListenPrefix)) - { - sb.AppendLine($@"Error: {nameof(_config.WebAppListenPrefix)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.WebAppListenPrefix))}"); - sb.AppendLine(); - } - if (_config.Ssl?.Enabled == true) - { - if (string.IsNullOrWhiteSpace(_config.Ssl.Name)) - { - sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.Name)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.Name))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.Ssl.Password)) - { - sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.Password)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.Password))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.Ssl.Email)) - { - sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.Email)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.Email))}"); - sb.AppendLine(); - } - if (!(_config.Ssl.Domains?.Length >= 1) || _config.Ssl.Domains.Any(x => string.IsNullOrWhiteSpace(x))) + try { - sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.Domains)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.Domains))}"); - sb.AppendLine(); + _config = JsonConvert.DeserializeObject(File.ReadAllText(Constants.ConfigFilePath)); + if (_config.Discord == null) _config.Discord = new DiscordConfigSection(); } - if (string.IsNullOrWhiteSpace(_config.Ssl.ChallengeListenPrefix)) + catch (Exception ex) { - sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.ChallengeListenPrefix)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.ChallengeListenPrefix))}"); - sb.AppendLine(); + exceptionMessage = ex.Message; } } - if (_config.Discord.DiscordBotEnabled) + var hasValidConfig = _config != null; + if (_config == null) { - if (string.IsNullOrWhiteSpace(_config.Discord.BotToken)) - { - sb.AppendLine($@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.BotToken)} is not set."); - sb.AppendLine($@"Expected value: { - ValidationHelper.GetDescriptionForMember(_config.Discord, nameof(_config.Discord.BotToken)) - }"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.Discord.SteamOpenIdRedirectUri)) - { - sb.AppendLine($@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.SteamOpenIdRedirectUri)} is not set."); - sb.AppendLine($@"Expected value: { - ValidationHelper.GetDescriptionForMember(_config.Discord, - nameof(_config.Discord.SteamOpenIdRedirectUri)) - }"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)) + //load defaultconfig + if (!File.Exists(Constants.DefaultConfigFilePath)) { - sb.AppendLine( - $@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)} is not set."); - sb.AppendLine($@"Expected value: { - ValidationHelper.GetDescriptionForMember(_config.Discord, - nameof(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)) - }"); - sb.AppendLine(); + WriteAndWaitForKey($@"The required file defaultconfig.json is missing from application directory. Please redownload the application."); + return; } - if (string.IsNullOrWhiteSpace(_config.Discord.MemberRoleName)) _config.Discord.MemberRoleName = "ark"; - } - var clusterkeys = _config.Clusters?.Select(x => x.Key).ToArray(); - var serverkeys = _config.Servers?.Select(x => x.Key).ToArray(); - if (serverkeys?.Length > 0 && serverkeys.Length != serverkeys.Distinct(StringComparer.OrdinalIgnoreCase).Count()) - { - sb.AppendLine($@"Error: {nameof(_config.Servers)} contain non-unique keys."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.Servers))}"); - sb.AppendLine(); - } - if (clusterkeys?.Length > 0 && clusterkeys.Length != clusterkeys.Distinct(StringComparer.OrdinalIgnoreCase).Count()) - { - sb.AppendLine($@"Error: {nameof(_config.Clusters)} contain non-unique keys."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.Clusters))}"); - sb.AppendLine(); - } - if (_config.Servers?.Length > 0) - { - foreach (var server in _config.Servers) + try { - if (server.Cluster != null && !clusterkeys.Contains(server.Cluster)) - { - sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.Cluster)} reference missing cluster key ""{server.Cluster}""."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.Cluster))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(server.SaveFilePath) || !File.Exists(server.SaveFilePath)) - { - sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.SaveFilePath)} is not a valid file path for server instance ""{server.Key}""."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.SaveFilePath))}"); - sb.AppendLine(); - } - if (string.IsNullOrWhiteSpace(server.Ip)) - { - sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.Ip)} is not set for server instance ""{server.Key}""."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.Ip))}"); - sb.AppendLine(); - } - if (server.QueryPort <= 0) - { - sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.QueryPort)} is not valid for server instance ""{server.Key}""."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.QueryPort))}"); - sb.AppendLine(); - } - //if (server.RconPort <= 0) - //{ - // sb.AppendLine($@"Error: {nameof(config.Servers)}.{nameof(server.RconPort)} is not valid for server instance ""{server.Key}""."); - // sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.RconPort))}"); - // sb.AppendLine(); - //} + _config = JsonConvert.DeserializeObject(File.ReadAllText(Constants.DefaultConfigFilePath)); } - } - if (_config.Clusters?.Length > 0) - { - foreach (var cluster in _config.Clusters) + catch (Exception ex) { - if (string.IsNullOrWhiteSpace(cluster.SavePath) || !Directory.Exists(cluster.SavePath)) - { - sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(cluster.SavePath)} is not a valid directory path for cluster instance ""{cluster.Key}""."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(cluster, nameof(cluster.SavePath))}"); - sb.AppendLine(); - } } + + WriteAndWaitForKey( + $@"The file config.json is empty or contains errors. Skipping automatic startup...", + exceptionMessage); } Configuration.Config = _config as Config; + About.HasValidConfig = hasValidConfig; - return; - - //todo: for now this section is not really needed unless !imprintcheck is used - //if (config.ArkMultipliers == null) - //{ - // sb.AppendLine($@"Error: {nameof(config.ArkMultipliers)} section is missing from config file."); - // sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(config, nameof(config.ArkMultipliers))}"); - // sb.AppendLine(); - //} - - if (_config.AnonymizeWebApiData) + if (!hasValidConfig) { - System.Console.WriteLine("Anonymizing all data in the WebAPI (anonymizeWebApiData=true)" + Environment.NewLine); + About.IsActive = true; + return; } - - //load aliases and check integrity - var aliases = ArkSpeciesAliases.Instance; - if (aliases == null || !aliases.CheckIntegrity) + else { - sb.AppendLine($@"Error: ""{ArkSpeciesAliases._filepath}"" is missing, contains invalid json or duplicate aliases."); - if (aliases != null) - { - foreach (var duplicateAlias in aliases.Aliases?.SelectMany(x => x).GroupBy(x => x) - .Where(g => g.Count() > 1) - .Select(g => g.Key)) - { - sb.AppendLine($@"Duplicate alias: ""{duplicateAlias}"""); - } - } - sb.AppendLine(); + About.IsVisible = false; + Console.IsActive = true; } - var errors = sb.ToString(); + string errors = ValidateConfig(); if (errors.Length > 0) { WriteAndWaitForKey(errors); @@ -489,7 +327,7 @@ internal async Task Init() { var options = new SteamOpenIdOptions { - ListenPrefixes = new[] {_config.Discord.SteamOpenIdRelyingServiceListenPrefix}, + ListenPrefixes = new[] { _config.Discord.SteamOpenIdRelyingServiceListenPrefix }, RedirectUri = _config.Discord.SteamOpenIdRedirectUri, }; openId = new BarebonesSteamOpenId(options, @@ -505,7 +343,7 @@ internal async Task Init() { var html = await FileHelper.ReadAllTextTaskAsync(constants.OpenidresponsetemplatePath); return service.RunCompile(html, constants.OpenidresponsetemplatePath, null, - new {Success = success, botName = _config.BotName, botUrl = _config.BotUrl}); + new { Success = success, botName = _config.BotName, botUrl = _config.BotUrl }); } })); } @@ -540,6 +378,7 @@ internal async Task Init() builder.RegisterType().As().SingleInstance(); builder.RegisterType(); builder.RegisterType().As().SingleInstance(); + builder.RegisterType().AsSelf(); builder.RegisterInstance(constants).As(); builder.RegisterInstance(_savedstate).As(); builder.RegisterInstance(_config as Config).As(); @@ -603,7 +442,7 @@ internal async Task Init() _contextManager = Container.Resolve(); //server/cluster contexts - if (_config.Clusters?.Length > 0) + if (_config.Clusters?.Count > 0) { foreach (var cluster in _config.Clusters) { @@ -612,15 +451,15 @@ internal async Task Init() } } - if (_config.Servers?.Length > 0) + if (_config.Servers?.Count > 0) { var playerLastActiveService = Container.Resolve(); var backupService = Container.Resolve(); foreach (var server in _config.Servers) { - var clusterContext = _contextManager.GetCluster(server.Cluster); + var clusterContext = _contextManager.GetCluster(server.ClusterKey); var context = Container.Resolve( - new TypedParameter(typeof(ServerConfigSection), server), + new TypedParameter(typeof(ServerConfigSection), server), new TypedParameter(typeof(ArkClusterContext), clusterContext)); var initTask = context.Initialize(); //fire and forget _contextManager.AddServer(context); @@ -823,7 +662,7 @@ await Task.Run(() => { proc.WaitForExit(); exitCode = proc.ExitCode; //only add (last cmd) is interesting - } + } }); } @@ -869,6 +708,215 @@ await Task.Run(() => } } + private string ValidateConfig() + { + var sb = new StringBuilder(); + if (string.IsNullOrWhiteSpace(_config.BotName)) + { + sb.AppendLine($@"Error: {nameof(_config.BotName)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BotName))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.TempFileOutputDirPath) || !Directory.Exists(_config.TempFileOutputDirPath)) + { + sb.AppendLine($@"Error: {nameof(_config.TempFileOutputDirPath)} is not a valid directory path."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.TempFileOutputDirPath))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.GoogleApiKey)) + { + sb.AppendLine($@"Error: {nameof(_config.GoogleApiKey)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.GoogleApiKey))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.SteamApiKey)) + { + sb.AppendLine($@"Error: {nameof(_config.SteamApiKey)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.SteamApiKey))}"); + sb.AppendLine(); + } + if (_config.Backups.BackupsEnabled && (string.IsNullOrWhiteSpace(_config.Backups.BackupsDirectoryPath) || !FileHelper.IsValidDirectoryPath(_config.Backups.BackupsDirectoryPath))) + { + sb.AppendLine($@"Error: {nameof(_config.Backups.BackupsDirectoryPath)} is not a valid directory path."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.Backups.BackupsDirectoryPath))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.WebApiListenPrefix)) + { + sb.AppendLine($@"Error: {nameof(_config.WebApiListenPrefix)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.WebApiListenPrefix))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.WebAppListenPrefix)) + { + sb.AppendLine($@"Error: {nameof(_config.WebAppListenPrefix)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.WebAppListenPrefix))}"); + sb.AppendLine(); + } + if (_config.Ssl?.Enabled == true) + { + if (string.IsNullOrWhiteSpace(_config.Ssl.Name)) + { + sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.Name)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.Name))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Ssl.Password)) + { + sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.Password)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.Password))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Ssl.Email)) + { + sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.Email)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.Email))}"); + sb.AppendLine(); + } + if (!(_config.Ssl.Domains?.Length >= 1) || _config.Ssl.Domains.Any(x => string.IsNullOrWhiteSpace(x))) + { + sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.Domains)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.Domains))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Ssl.ChallengeListenPrefix)) + { + sb.AppendLine($@"Error: {nameof(_config.Ssl)}.{nameof(_config.Ssl.ChallengeListenPrefix)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config.Ssl, nameof(_config.Ssl.ChallengeListenPrefix))}"); + sb.AppendLine(); + } + } + if (_config.Discord.DiscordBotEnabled) + { + if (string.IsNullOrWhiteSpace(_config.Discord.BotToken)) + { + sb.AppendLine($@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.BotToken)} is not set."); + sb.AppendLine($@"Expected value: { + ValidationHelper.GetDescriptionForMember(_config.Discord, nameof(_config.Discord.BotToken)) + }"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Discord.SteamOpenIdRedirectUri)) + { + sb.AppendLine($@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.SteamOpenIdRedirectUri)} is not set."); + sb.AppendLine($@"Expected value: { + ValidationHelper.GetDescriptionForMember(_config.Discord, + nameof(_config.Discord.SteamOpenIdRedirectUri)) + }"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)) + { + sb.AppendLine( + $@"Error: {nameof(_config.Discord)}.{nameof(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)} is not set."); + sb.AppendLine($@"Expected value: { + ValidationHelper.GetDescriptionForMember(_config.Discord, + nameof(_config.Discord.SteamOpenIdRelyingServiceListenPrefix)) + }"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(_config.Discord.MemberRoleName)) _config.Discord.MemberRoleName = "ark"; + } + + var clusterkeys = _config.Clusters?.Select(x => x.Key).ToArray(); + var serverkeys = _config.Servers?.Select(x => x.Key).ToArray(); + if (serverkeys?.Length > 0 && serverkeys.Length != serverkeys.Distinct(StringComparer.OrdinalIgnoreCase).Count()) + { + sb.AppendLine($@"Error: {nameof(_config.Servers)} contain non-unique keys."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.Servers))}"); + sb.AppendLine(); + } + if (clusterkeys?.Length > 0 && clusterkeys.Length != clusterkeys.Distinct(StringComparer.OrdinalIgnoreCase).Count()) + { + sb.AppendLine($@"Error: {nameof(_config.Clusters)} contain non-unique keys."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.Clusters))}"); + sb.AppendLine(); + } + if (_config.Servers?.Count > 0) + { + foreach (var server in _config.Servers) + { + if (server.ClusterKey != null && !clusterkeys.Contains(server.ClusterKey)) + { + sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.ClusterKey)} reference missing cluster key ""{server.ClusterKey}""."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.ClusterKey))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(server.SaveFilePath) || !File.Exists(server.SaveFilePath)) + { + sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.SaveFilePath)} is not a valid file path for server instance ""{server.Key}""."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.SaveFilePath))}"); + sb.AppendLine(); + } + if (string.IsNullOrWhiteSpace(server.Ip)) + { + sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.Ip)} is not set for server instance ""{server.Key}""."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.Ip))}"); + sb.AppendLine(); + } + if (server.QueryPort <= 0) + { + sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(server.QueryPort)} is not valid for server instance ""{server.Key}""."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.QueryPort))}"); + sb.AppendLine(); + } + //if (server.RconPort <= 0) + //{ + // sb.AppendLine($@"Error: {nameof(config.Servers)}.{nameof(server.RconPort)} is not valid for server instance ""{server.Key}""."); + // sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(server, nameof(server.RconPort))}"); + // sb.AppendLine(); + //} + } + } + if (_config.Clusters?.Count > 0) + { + foreach (var cluster in _config.Clusters) + { + if (string.IsNullOrWhiteSpace(cluster.SavePath) || !Directory.Exists(cluster.SavePath)) + { + sb.AppendLine($@"Error: {nameof(_config.Servers)}.{nameof(cluster.SavePath)} is not a valid directory path for cluster instance ""{cluster.Key}""."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(cluster, nameof(cluster.SavePath))}"); + sb.AppendLine(); + } + } + } + + //return; + + //todo: for now this section is not really needed unless !imprintcheck is used + //if (config.ArkMultipliers == null) + //{ + // sb.AppendLine($@"Error: {nameof(config.ArkMultipliers)} section is missing from config file."); + // sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(config, nameof(config.ArkMultipliers))}"); + // sb.AppendLine(); + //} + + if (_config.AnonymizeWebApiData) + { + System.Console.WriteLine("Anonymizing all data in the WebAPI (anonymizeWebApiData=true)" + Environment.NewLine); + } + + //load aliases and check integrity + var aliases = ArkSpeciesAliases.Instance; + if (aliases == null || !aliases.CheckIntegrity) + { + sb.AppendLine($@"Error: ""{ArkSpeciesAliases._filepath}"" is missing, contains invalid json or duplicate aliases."); + if (aliases != null) + { + foreach (var duplicateAlias in aliases.Aliases?.SelectMany(x => x).GroupBy(x => x) + .Where(g => g.Count() > 1) + .Select(g => g.Key)) + { + sb.AppendLine($@"Duplicate alias: ""{duplicateAlias}"""); + } + } + sb.AppendLine(); + } + + var errors = sb.ToString(); + return errors; + } + private Task _runDiscordBotTask; private CancellationTokenSource _runDiscordBotCts; @@ -923,23 +971,50 @@ public async Task RunDiscordBot() #region IDisposable Support private bool disposedValue = false; - protected virtual void Dispose(bool disposing) + private void Dispose(bool disposing) { if (!disposedValue) { if (disposing) { + try + { + Configuration?.Dispose(); + } + catch (Exception ex) + { + Logging.LogException(@"Exception in Workspace::Dispose (Configuration) when closing application", ex, GetType(), LogLevel.DEBUG, ExceptionLevel.Ignored); + } + Configuration = null; + + try + { + About?.Dispose(); + } + catch (Exception ex) + { + Logging.LogException(@"Exception in Workspace::Dispose (About) when closing application", ex, GetType(), LogLevel.DEBUG, ExceptionLevel.Ignored); + } + About = null; + try { _webapi?.Dispose(); - } catch (ObjectDisposedException) { } + } + catch (Exception ex) + { + Logging.LogException(@"Exception in Workspace::Dispose (WebApi) when closing application", ex, GetType(), LogLevel.DEBUG, ExceptionLevel.Ignored); + } _webapi = null; try { _webapp?.Dispose(); } - catch (ObjectDisposedException) { } + catch (Exception ex) + { + Logging.LogException(@"Exception in Workspace::Dispose (WebApp) when closing application", ex, GetType(), LogLevel.DEBUG, ExceptionLevel.Ignored); + } _webapp = null; foreach (var redir in _webappRedirects.ToArray()) @@ -948,7 +1023,10 @@ protected virtual void Dispose(bool disposing) { redir?.Dispose(); } - catch (ObjectDisposedException) { } + catch (Exception ex) + { + Logging.LogException(@"Exception in Workspace::Dispose (WebAppRedirects) when closing application", ex, GetType(), LogLevel.DEBUG, ExceptionLevel.Ignored); + } _webappRedirects.Remove(redir); } } diff --git a/ArkBot/Voting/Handlers/BanVoteHandler.cs b/ArkBot/Voting/Handlers/BanVoteHandler.cs index 1d6d06b..4930c50 100644 --- a/ArkBot/Voting/Handlers/BanVoteHandler.cs +++ b/ArkBot/Voting/Handlers/BanVoteHandler.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Database.Model; using ArkBot.Extensions; diff --git a/ArkBot/Voting/Handlers/DestroyWildDinosVoteHandler.cs b/ArkBot/Voting/Handlers/DestroyWildDinosVoteHandler.cs index 4470e24..9563636 100644 --- a/ArkBot/Voting/Handlers/DestroyWildDinosVoteHandler.cs +++ b/ArkBot/Voting/Handlers/DestroyWildDinosVoteHandler.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Database.Model; using ArkBot.Extensions; diff --git a/ArkBot/Voting/Handlers/IVoteHandler.cs b/ArkBot/Voting/Handlers/IVoteHandler.cs index 36fe1d0..9e5cc90 100644 --- a/ArkBot/Voting/Handlers/IVoteHandler.cs +++ b/ArkBot/Voting/Handlers/IVoteHandler.cs @@ -4,6 +4,7 @@ using ArkBot.Database.Model; using Discord; using ArkBot.Ark; +using ArkBot.Configuration.Model; namespace ArkBot.Voting.Handlers { diff --git a/ArkBot/Voting/Handlers/RestartServerVoteHandler.cs b/ArkBot/Voting/Handlers/RestartServerVoteHandler.cs index 8453486..8fd1a3b 100644 --- a/ArkBot/Voting/Handlers/RestartServerVoteHandler.cs +++ b/ArkBot/Voting/Handlers/RestartServerVoteHandler.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Database.Model; using ArkBot.Extensions; diff --git a/ArkBot/Voting/Handlers/SetTimeOfDayVoteHandler.cs b/ArkBot/Voting/Handlers/SetTimeOfDayVoteHandler.cs index 4665a3a..7b73486 100644 --- a/ArkBot/Voting/Handlers/SetTimeOfDayVoteHandler.cs +++ b/ArkBot/Voting/Handlers/SetTimeOfDayVoteHandler.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Database.Model; using ArkBot.Extensions; diff --git a/ArkBot/Voting/Handlers/UnbanVoteHandler.cs b/ArkBot/Voting/Handlers/UnbanVoteHandler.cs index ca87d1e..e1040ef 100644 --- a/ArkBot/Voting/Handlers/UnbanVoteHandler.cs +++ b/ArkBot/Voting/Handlers/UnbanVoteHandler.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Database.Model; using ArkBot.Extensions; diff --git a/ArkBot/Voting/Handlers/UpdateServerVoteHandler.cs b/ArkBot/Voting/Handlers/UpdateServerVoteHandler.cs index 885840a..246b632 100644 --- a/ArkBot/Voting/Handlers/UpdateServerVoteHandler.cs +++ b/ArkBot/Voting/Handlers/UpdateServerVoteHandler.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Database.Model; using ArkBot.Extensions; diff --git a/ArkBot/Voting/VotingManager.cs b/ArkBot/Voting/VotingManager.cs index 47c191e..67c2b38 100644 --- a/ArkBot/Voting/VotingManager.cs +++ b/ArkBot/Voting/VotingManager.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Database.Model; using ArkBot.Discord; diff --git a/ArkBot/WebApi/AccessControlAuthorizationFilter.cs b/ArkBot/WebApi/AccessControlAuthorizationFilter.cs index a470a7e..dff63c4 100644 --- a/ArkBot/WebApi/AccessControlAuthorizationFilter.cs +++ b/ArkBot/WebApi/AccessControlAuthorizationFilter.cs @@ -1,4 +1,5 @@ -using ArkBot.Helpers; +using ArkBot.Configuration.Model; +using ArkBot.Helpers; using ArkBot.WebApi.Controllers; using Autofac.Integration.WebApi; using System; diff --git a/ArkBot/WebApi/Controllers/AdminServerController.cs b/ArkBot/WebApi/Controllers/AdminServerController.cs index 10d9ffd..1715370 100644 --- a/ArkBot/WebApi/Controllers/AdminServerController.cs +++ b/ArkBot/WebApi/Controllers/AdminServerController.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Extensions; using ArkBot.Helpers; diff --git a/ArkBot/WebApi/Controllers/AdministerController.cs b/ArkBot/WebApi/Controllers/AdministerController.cs index 594ac00..d06bcfb 100644 --- a/ArkBot/WebApi/Controllers/AdministerController.cs +++ b/ArkBot/WebApi/Controllers/AdministerController.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Extensions; using ArkBot.Helpers; diff --git a/ArkBot/WebApi/Controllers/AuthenticationController.cs b/ArkBot/WebApi/Controllers/AuthenticationController.cs index db49aec..cee0eca 100644 --- a/ArkBot/WebApi/Controllers/AuthenticationController.cs +++ b/ArkBot/WebApi/Controllers/AuthenticationController.cs @@ -1,4 +1,5 @@ -using ArkBot.Helpers; +using ArkBot.Configuration.Model; +using ArkBot.Helpers; using Microsoft.Owin.Security; using System; using System.Collections.Generic; @@ -57,7 +58,11 @@ public async Task LoginCallback(string returnUrl) claims.Add(new Claim(ClaimTypes.AuthenticationMethod, "Steam")); var steamId = claims?.FirstOrDefault(x => x.Type.Equals("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier", StringComparison.OrdinalIgnoreCase))?.Value; - if (steamId != null) steamId = steamId.Replace("http://steamcommunity.com/openid/id/", ""); + if (steamId != null) + { + steamId = steamId.Replace("http://steamcommunity.com/openid/id/", ""); + steamId = steamId.Replace("https://steamcommunity.com/openid/id/", ""); + } if (!string.IsNullOrEmpty(steamId)) { var roles = WebApiHelper.GetRolesForUser(_config, steamId); diff --git a/ArkBot/WebApi/Controllers/BaseApiController.cs b/ArkBot/WebApi/Controllers/BaseApiController.cs index fb6d10c..e992771 100644 --- a/ArkBot/WebApi/Controllers/BaseApiController.cs +++ b/ArkBot/WebApi/Controllers/BaseApiController.cs @@ -6,6 +6,7 @@ using System.Threading.Tasks; using System.Web.Http; using ArkBot.Configuration; +using ArkBot.Configuration.Model; namespace ArkBot.WebApi.Controllers { @@ -43,7 +44,7 @@ public bool HasFeatureAccess(string featureGroup, string featureName, string for if (accessControl == null) return false; var fg = (AccessControlFeatureGroup)null; if (!accessControl.TryGetValue(featureGroup, out fg)) return false; - var rf = (List)null; + var rf = (AccessControlFeatureRoles)null; if (!fg.TryGetValue(featureName, out rf)) return false; var user = WebApiHelper.GetUser(Request, _config); diff --git a/ArkBot/WebApi/Controllers/MapController.cs b/ArkBot/WebApi/Controllers/MapController.cs index c1255a4..98c07e8 100644 --- a/ArkBot/WebApi/Controllers/MapController.cs +++ b/ArkBot/WebApi/Controllers/MapController.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Data; using ArkBot.ViewModel; using ArkBot.WebApi.Model; diff --git a/ArkBot/WebApi/Controllers/PlayerController.cs b/ArkBot/WebApi/Controllers/PlayerController.cs index e7e2180..b26d36a 100644 --- a/ArkBot/WebApi/Controllers/PlayerController.cs +++ b/ArkBot/WebApi/Controllers/PlayerController.cs @@ -12,6 +12,7 @@ using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Web.Http; +using ArkBot.Configuration.Model; namespace ArkBot.WebApi.Controllers { @@ -130,6 +131,7 @@ internal static PlayerServerViewModel BuildViewModelForTransferedPlayer( //there will be no player profile so most data cannot be set //a tribe where the player is a member may exist tho + //note: potentially there could be multiple tribes with the same player, which player.Tribe protects us against. here we just select the first one which is not optimal var tribe = context.Tribes?.FirstOrDefault(x => playerIds.Any(y => x.MemberIds.Contains((int)y))); if (tribe == null) return null; var playerId = playerIds.First(x => tribe.MemberIds.Contains((int)x)); @@ -169,7 +171,7 @@ internal static PlayerServerViewModel BuildViewModelForPlayer( bool incKibblesEggs, bool incTribeLog) { - var tribe = player.TribeId.HasValue ? context.Tribes.FirstOrDefault(x => x.Id == player.TribeId.Value) : null; + var tribe = player.Tribe; var vm = new PlayerServerViewModel { ClusterKey = context.Config.Key, @@ -210,8 +212,9 @@ internal static List BuildCreatureViewModelsForPlayerId( var result = new List(); if (context.TamedCreatures != null) { + var player = context.Players?.FirstOrDefault(x => x.Id == playerId); var playercreatures = context.NoRafts.Where(x => x.TargetingTeam == playerId || (x.OwningPlayerId.HasValue && x.OwningPlayerId == playerId)).ToArray(); - var tribe = context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains((int)playerId)); + var tribe = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains((int)playerId)); var tribecreatures = tribe != null ? context.NoRafts.Where(x => x.TargetingTeam == tribe.Id && !playercreatures.Any(y => y.Id == x.Id)).ToArray() : new ArkTamedCreature[] { }; foreach (var item in playercreatures.Select(x => new { c = x, o = "player" }).Concat(tribecreatures.Select(x => new { c = x, o = "tribe" }))) { @@ -324,7 +327,7 @@ internal static PlayerClusterViewModel BuildClusterViewModelForPlayer(ArkCluster internal static List BuildKibblesAndEggsViewModelsForPlayerId(ArkServerContext context, int playerId) { var player = context.Players?.FirstOrDefault(x => x.Id == playerId); - var tribe = context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId)); + var tribe = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId)); //PrimalItemConsumable_Egg_Kaprosuchus_C, PrimalItemConsumable_Egg_Kaprosuchus_Fertilized_C, PrimalItemConsumable_Egg_Wyvern_Fertilized_Lightning_C var _rEgg = new Regex(@"^PrimalItemConsumable_Egg_(?.+?)_C$", RegexOptions.Singleline); @@ -374,7 +377,7 @@ internal static List BuildKibblesAndEggsViewModelsForPlay internal static List BuildCropPlotViewModelsForPlayerId(ArkServerContext context, int playerId) { var player = context.Players?.FirstOrDefault(x => x.Id == playerId); - var tribe = context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId)); + var tribe = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId)); var cropPlots = new[] { player?.Structures, tribe?.Structures }.Where(x => x != null).SelectMany(x => x).OfType().Where(x => x.PlantedCropClassName != null).ToArray(); @@ -422,7 +425,7 @@ internal static double GetFertilizerQuantityFromItems(ArkItem[] cropPlotInventor internal static List BuildElectricalGeneratorViewModelsForPlayerId(ArkServerContext context, int playerId) { var player = context.Players?.FirstOrDefault(x => x.Id == playerId); - var tribe = context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId)); + var tribe = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId)); var electricalGenerators = new[] { player?.Structures, tribe?.Structures }.Where(x => x != null).SelectMany(x => x).OfType().ToArray(); @@ -442,7 +445,7 @@ internal static List BuildElectricalGeneratorViewM internal static List BuildTribeLogViewModelsForPlayerId(ArkServerContext context, int playerId, int? limit = null) { var player = context.Players?.FirstOrDefault(x => x.Id == playerId); - var tribe = context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId)); + var tribe = player != null ? player.Tribe : context.Tribes?.FirstOrDefault(x => x.MemberIds.Contains(playerId)); var tribelogs = tribe?.Logs?.Reverse().Take(limit ?? tribe.Logs.Length).Select(x => Data.TribeLog.FromLog(x)).ToArray() ?? new TribeLog[] { }; var results = tribelogs.Select(x => diff --git a/ArkBot/WebApi/Controllers/ServerController.cs b/ArkBot/WebApi/Controllers/ServerController.cs index 4ab1d0e..6099468 100644 --- a/ArkBot/WebApi/Controllers/ServerController.cs +++ b/ArkBot/WebApi/Controllers/ServerController.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Extensions; using ArkBot.Helpers; diff --git a/ArkBot/WebApi/Controllers/ServersController.cs b/ArkBot/WebApi/Controllers/ServersController.cs index ff03b46..38a9fb1 100644 --- a/ArkBot/WebApi/Controllers/ServersController.cs +++ b/ArkBot/WebApi/Controllers/ServersController.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Extensions; using ArkBot.Helpers; @@ -77,20 +78,20 @@ public async Task Get() { var serverContext = _contextManager.GetServer(context.Config.Key); var status = serverContext.Steam.GetServerStatusCached(); - if (status == null || status.Item1 == null || status.Item2 == null) - { - //Server status is currently unavailable - } - else - { - var info = status.Item1; - var rules = status.Item2; - var playerinfos = status.Item3; - - var m = new Regex(@"^(?.+?)\s+-\s+\(v(?\d+\.\d+)\)?$", RegexOptions.IgnoreCase | RegexOptions.Singleline).Match(info.Name); - var name = m.Success ? m.Groups["name"].Value : info.Name; - var version = m.Success ? m.Groups["version"] : null; - var currentTime = rules.FirstOrDefault(x => x.Name == "DayTime_s")?.Value; + //if (status == null || status.Item1 == null || status.Item2 == null) + //{ + // //Server status is currently unavailable + //} + //else + //{ + var info = status?.Item1; + var rules = status?.Item2; + var playerinfos = status?.Item3; + + var m = info != null ? new Regex(@"^(?.+?)\s+-\s+\(v(?\d+\.\d+)\)?$", RegexOptions.IgnoreCase | RegexOptions.Singleline).Match(info.Name) : null; + var name = m?.Success == true ? m.Groups["name"].Value : (info?.Name ?? context.Config.Key); + var version = m?.Success == true ? m.Groups["version"] : null; + var currentTime = rules?.FirstOrDefault(x => x.Name == "DayTime_s")?.Value; var tamedDinosCount = context.TamedCreatures?.Count(); var uploadedDinosCount = context.CloudCreatures?.Count(); var wildDinosCount = context.WildCreatures?.Count(); @@ -111,11 +112,11 @@ public async Task Get() { Key = anonymizedServer?.Key ?? context.Config.Key, Name = anonymizedServer?.Name ?? name, - Address = anonymizedServer?.Address ?? context.Config.DisplayAddress ?? info.Address, + Address = anonymizedServer?.Address ?? context.Config.DisplayAddress ?? info?.Address, Version = version?.ToString(), - OnlinePlayerCount = info.Players, - OnlinePlayerMax = info.MaxPlayers, - MapName = info.Map, + OnlinePlayerCount = info?.Players ?? 0, + OnlinePlayerMax = info?.MaxPlayers ?? 0, + MapName = info?.Map, InGameTime = currentTime, TamedCreatureCount = tamedDinosCount ?? 0, CloudCreatureCount = uploadedDinosCount ?? 0, @@ -195,7 +196,7 @@ public async Task Get() } result.Servers.Add(sr); - } + //} } foreach (var context in _contextManager.Clusters) @@ -204,7 +205,7 @@ public async Task Get() { Key = context.Config.Key, ServerKeys = _contextManager.Servers - .Where(x => x.Config.Cluster.Equals(context.Config.Key, StringComparison.OrdinalIgnoreCase)) + .Where(x => x.Config.ClusterKey.Equals(context.Config.Key, StringComparison.OrdinalIgnoreCase)) .Select(x => x.Config.Key).ToArray() }; result.Clusters.Add(cc); diff --git a/ArkBot/WebApi/Controllers/StructuresController.cs b/ArkBot/WebApi/Controllers/StructuresController.cs index 5b0da21..6735f25 100644 --- a/ArkBot/WebApi/Controllers/StructuresController.cs +++ b/ArkBot/WebApi/Controllers/StructuresController.cs @@ -1,5 +1,6 @@ using Accord.Collections; using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Database; using ArkBot.Extensions; using ArkBot.Helpers; diff --git a/ArkBot/WebApi/Controllers/WildCreaturesController.cs b/ArkBot/WebApi/Controllers/WildCreaturesController.cs index 3c139ed..bc3e079 100644 --- a/ArkBot/WebApi/Controllers/WildCreaturesController.cs +++ b/ArkBot/WebApi/Controllers/WildCreaturesController.cs @@ -1,4 +1,5 @@ using ArkBot.Ark; +using ArkBot.Configuration.Model; using ArkBot.Data; using ArkBot.Database; using ArkBot.Extensions; diff --git a/ArkBot/WebApi/WebApiStartup.cs b/ArkBot/WebApi/WebApiStartup.cs index f6c28a2..7c293b4 100644 --- a/ArkBot/WebApi/WebApiStartup.cs +++ b/ArkBot/WebApi/WebApiStartup.cs @@ -25,6 +25,8 @@ using System.Security.Claims; using Microsoft.Owin.Security.Jwt; using Microsoft.Owin.Security.Cookies; +using ArkBot.Configuration.Model; +using ArkBot.OpenID; namespace ArkBot.WebApi { @@ -77,7 +79,7 @@ public void Configuration(IAppBuilder appBuilder, IConfig _config, IContainer co AuthenticationMode = Microsoft.Owin.Security.AuthenticationMode.Passive, }); - appBuilder.UseSteamAuthentication(applicationKey: _config.SteamApiKey); + appBuilder.UseSteamAuthenticationNew(applicationKey: _config.SteamApiKey); appBuilder.UseWebApi(config); appBuilder.MapSignalR(hubConfig); diff --git a/ArkBot/WebApp/WebAppStartup.cs b/ArkBot/WebApp/WebAppStartup.cs index 4202442..a0c6df8 100644 --- a/ArkBot/WebApp/WebAppStartup.cs +++ b/ArkBot/WebApp/WebAppStartup.cs @@ -1,4 +1,4 @@ -using ArkBot.ViewModel; +using ArkBot.ViewModel; using Autofac; using Autofac.Core; using Autofac.Integration.SignalR; @@ -20,6 +20,10 @@ using System.Web.Http; using Nancy.Conventions; using System.IO; +using Nancy.Bootstrappers.Autofac; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using ArkBot.Configuration.Model; namespace ArkBot.WebApp { @@ -35,7 +39,7 @@ public void Configuration(IAppBuilder appBuilder, IConfig _config, IContainer co appBuilder.UseCors(CorsOptions.AllowAll); appBuilder.UseNancy(new Nancy.Owin.NancyOptions { - Bootstrapper = new CustomBootstrapper() + Bootstrapper = new CustomBootstrapper(container) }); //appBuilder.UseFileServer(new FileServerOptions //{ @@ -45,8 +49,20 @@ public void Configuration(IAppBuilder appBuilder, IConfig _config, IContainer co } } - public class CustomBootstrapper : DefaultNancyBootstrapper, IRootPathProvider + public class CustomBootstrapper : AutofacNancyBootstrapper, IRootPathProvider { + private IContainer _container; + + public CustomBootstrapper(IContainer container) + { + _container = container; + } + + protected override ILifetimeScope GetApplicationContainer() + { + return _container; + } + protected override void ConfigureConventions(NancyConventions nancyConventions) { base.ConfigureConventions(nancyConventions); @@ -69,14 +85,25 @@ public string GetRootPath() public class SinglePageApplicationModule : NancyModule { - public SinglePageApplicationModule() + private IConfig _config; + + public SinglePageApplicationModule(IConfig config) { + _config = config; + Get[""] = _ => { return Response.AsFile(@"index.html"); }; Get[@"^(?.*)$"] = parameters => { + if (parameters["path"].Value.Equals("config.js")) + { + var portStr = new Regex(@":(?\d+)(?:/|$)").Match(_config.WebApiListenPrefix)?.Groups["port"].Value; + var success = int.TryParse(portStr, out var port); + var js = $"var config = {JsonConvert.SerializeObject(new { webapi = new { port = success ? port : (int?)null } }, Formatting.None)};"; + return Response.AsText(js, "application/javascript"); + } if (File.Exists(Path.Combine(Response.RootPath, parameters["path"].Value))) return Response.AsFile((string)parameters["path"].Value); return Response.AsFile(@"index.html"); }; diff --git a/ArkBot/WebApp/dist/index.html b/ArkBot/WebApp/dist/index.html index 2d2fb66..2b3b6af 100644 --- a/ArkBot/WebApp/dist/index.html +++ b/ArkBot/WebApp/dist/index.html @@ -9,6 +9,7 @@ + @@ -18,5 +19,5 @@

Loading...

- + diff --git a/ArkBot/WebApp/dist/inline.8d8c7910f2f1b97eeb2d.bundle.js b/ArkBot/WebApp/dist/inline.8d8c7910f2f1b97eeb2d.bundle.js new file mode 100644 index 0000000..3660f8b --- /dev/null +++ b/ArkBot/WebApp/dist/inline.8d8c7910f2f1b97eeb2d.bundle.js @@ -0,0 +1 @@ +!function(e){function r(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}var n=window.webpackJsonp;window.webpackJsonp=function(t,c,a){for(var u,i,f,l=0,s=[];l/gi,window.location.protocol).replace(/\/gi,window.location.hostname)},l.ctorParameters=function(){return[{type:t.e}]},l}()},"+SUW":function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},"+T68":function(l,n,u){"use strict";function t(l){return ll._24(0,[(l()(),ll._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,4,"div",[["class","w3-panel theme-l2"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h3",[["class","theme-text-l1-light"]],null,null,null,null,null)),(l()(),ll._26(null,["Loading..."])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,[" \n"]))],null,null)}function e(l){return ll._24(0,[(l()(),ll._25(0,null,null,10,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,7,"div",[["class","w3-panel w3-red"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),ll._26(null,["Error!"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),ll._26(null,["No data could be loaded for the given server key."])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,[" \n"]))],null,null)}function r(l){return ll._24(0,[(l()(),ll._26(null,["\n Character Name\n "]))],null,null)}function i(l){return ll._24(0,[(l()(),ll._25(0,null,null,2,"a",[],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==ll._29(l,1).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),ll._27(335872,null,0,nl.D,[nl.g,nl.v,ul.f],{routerLink:[0,"routerLink"]},null),(l()(),ll._26(null,["",""]))],function(l,n){l(n,1,0,"/player/"+n.parent.context.$implicit.SteamId)},function(l,n){l(n,0,0,ll._29(n,1).target,ll._29(n,1).href),l(n,2,0,n.parent.context.$implicit.CharacterName)})}function a(l){return ll._24(0,[(l()(),ll._26(null,["",""]))],null,function(l,n){l(n,0,0,n.parent.context.$implicit.CharacterName)})}function o(l){return ll._24(0,[(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,2,null,i)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),ll._34(65536,ul.q,[ll.O]),(l()(),ll._28(0,[["player_no_link",2]],null,0,null,a)),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,2,0,ll._33(n,2,0,ll._29(n,3).transform(u.dataService.hasFeatureAccessObservable("pages","player",n.context.$implicit.SteamId))),ll._29(n,4))},null)}function s(l){return ll._24(0,[(l()(),ll._26(null,["\n Tribe Name\n "]))],null,null)}function c(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.TribeName)})}function _(l){return ll._24(0,[(l()(),ll._26(null,["\n Last Active\n "]))],null,null)}function p(l){return ll._24(0,[(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"relative-time",[],null,null,null,tl.a,tl.b)),ll._27(122880,null,0,el.a,[ll.O],{time:[0,"time"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){l(n,2,0,n.context.$implicit.LastActiveTime)},null)}function d(l){return ll._24(0,[(l()(),ll._25(0,null,null,49,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["Players"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,43,"ark-data-table",[["orderByColumn","last_active"],["trackByProp","Id"]],null,null,null,rl.a,rl.b)),ll._27(57344,null,2,il.a,[ll.O],{rows:[0,"rows"],trackByProp:[1,"trackByProp"],sortFunctions:[2,"sortFunctions"],orderByColumn:[3,"orderByColumn"]},null),ll._35(301989888,1,{modeTemplates:1}),ll._35(301989888,2,{columnTemplates:1}),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"ark-dt-mode",[["columnKeys","character_name,tribe_name,last_active"],["key","default"],["name","Default"]],null,null,null,null,null)),ll._27(8192,[[1,4]],0,al.a,[],{key:[0,"key"],name:[1,"name"],columnKeys:[2,"columnKeys"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","character_name"],["thenSort","last_active"],["title","Sort by Character Name"]],null,null,null,null,null)),ll._27(8192,[[2,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,3,{cellTemplate:0}),ll._35(167772160,4,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[4,2]],null,1,null,r)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[3,2]],null,1,null,o)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","tribe_name"],["thenSort","character_name"],["title","Sort by Tribe Name"]],null,null,null,null,null)),ll._27(8192,[[2,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,5,{cellTemplate:0}),ll._35(167772160,6,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[6,2]],null,1,null,s)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[5,2]],null,1,null,c)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","last_active"],["thenSort","character_name"],["title","Sort by Last Active"]],null,null,null,null,null)),ll._27(8192,[[2,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,7,{cellTemplate:0}),ll._35(167772160,8,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[8,2]],null,1,null,_)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[7,2]],null,1,null,p)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n"]))],function(l,n){var u=n.component;l(n,6,0,u.filteredPlayers,"Id",u.playerSortFunctions,"last_active"),l(n,11,0,"default","Default","character_name,tribe_name,last_active"),l(n,14,0,"character_name","last_active","Sort by Character Name",!0),l(n,26,0,"tribe_name","character_name","Sort by Tribe Name",!0),l(n,38,0,"last_active","character_name","Sort by Last Active",!0)},null)}function f(l){return ll._24(0,[(l()(),ll._26(null,["\n Tribe Name\n "]))],null,null)}function m(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.Name)})}function h(l){return ll._24(0,[(l()(),ll._26(null,["\n Members\n "]))],null,null)}function v(l){return ll._24(0,[(l()(),ll._25(0,null,null,2,"a",[],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==ll._29(l,1).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),ll._27(335872,null,0,nl.D,[nl.g,nl.v,ul.f],{routerLink:[0,"routerLink"]},null),(l()(),ll._26(null,["",""]))],function(l,n){l(n,1,0,"/player/"+n.parent.context.$implicit)},function(l,n){var u=n.component;l(n,0,0,ll._29(n,1).target,ll._29(n,1).href);var t=null;l(n,2,0,(null==(t=u.getTribeMember(n.parent.context.$implicit))?null:t.CharacterName)||n.parent.context.$implicit)})}function g(l){return ll._24(0,[(l()(),ll._26(null,["",""]))],null,function(l,n){var u=n.component,t=null;l(n,0,0,(null==(t=u.getTribeMember(n.parent.context.$implicit))?null:t.CharacterName)||n.parent.context.$implicit)})}function y(l){return ll._24(0,[(l()(),ll._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),ll._26(null,[", "]))],null,null)}function S(l){return ll._24(0,[(l()(),ll._25(0,null,null,5,"span",[],null,null,null,null,null)),(l()(),ll._28(8388608,null,null,1,null,v)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),ll._28(0,[["tribe_member_no_link",2]],null,0,null,g)),(l()(),ll._28(8388608,null,null,1,null,y)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,2,0,n.component.dataService.hasFeatureAccess("pages","player",n.context.$implicit),ll._29(n,3)),l(n,5,0,!n.context.last)},null)}function b(l){return ll._24(0,[(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,S)),ll._27(401408,null,0,ul.n,[ll.S,ll._5,ll.v],{ngForOf:[0,"ngForOf"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){l(n,2,0,n.context.$implicit.MemberSteamIds)},null)}function w(l){return ll._24(0,[(l()(),ll._26(null,["\n Last Active\n "]))],null,null)}function k(l){return ll._24(0,[(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"relative-time",[],null,null,null,tl.a,tl.b)),ll._27(122880,null,0,el.a,[ll.O],{time:[0,"time"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){l(n,2,0,n.context.$implicit.LastActiveTime)},null)}function C(l){return ll._24(0,[(l()(),ll._25(0,null,null,49,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["Tribes"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,43,"ark-data-table",[["orderByColumn","last_active"],["trackByProp","Id"]],null,null,null,rl.a,rl.b)),ll._27(57344,null,2,il.a,[ll.O],{rows:[0,"rows"],trackByProp:[1,"trackByProp"],sortFunctions:[2,"sortFunctions"],orderByColumn:[3,"orderByColumn"]},null),ll._35(301989888,9,{modeTemplates:1}),ll._35(301989888,10,{columnTemplates:1}),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"ark-dt-mode",[["columnKeys","tribe_name,members,last_active"],["key","default"],["name","Default"]],null,null,null,null,null)),ll._27(8192,[[9,4]],0,al.a,[],{key:[0,"key"],name:[1,"name"],columnKeys:[2,"columnKeys"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","tribe_name"],["thenSort","last_active"],["title","Sort by Tribe Name"]],null,null,null,null,null)),ll._27(8192,[[10,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,11,{cellTemplate:0}),ll._35(167772160,12,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[12,2]],null,1,null,f)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[11,2]],null,1,null,m)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","members"]],null,null,null,null,null)),ll._27(8192,[[10,4]],2,ol.a,[],{key:[0,"key"]},null),ll._35(167772160,13,{cellTemplate:0}),ll._35(167772160,14,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[14,2]],null,1,null,h)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[13,2]],null,1,null,b)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","last_active"],["thenSort","tribe_name"],["title","Sort by Last Active"]],null,null,null,null,null)),ll._27(8192,[[10,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,15,{cellTemplate:0}),ll._35(167772160,16,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[16,2]],null,1,null,w)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[15,2]],null,1,null,k)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n"]))],function(l,n){var u=n.component;l(n,6,0,u.filteredTribes,"Id",u.tribeSortFunctions,"last_active"),l(n,11,0,"default","Default","tribe_name,members,last_active"),l(n,14,0,"tribe_name","last_active","Sort by Tribe Name",!0),l(n,26,0,"members"),l(n,38,0,"last_active","tribe_name","Sort by Last Active",!0)},null)}function I(l){return ll._24(0,[(l()(),ll._26(null,["\n Species\n "]))],null,null)}function x(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.Name)})}function O(l){return ll._24(0,[(l()(),ll._26(null,["\n Class Name\n "]))],null,null)}function A(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.ClassName)})}function T(l){return ll._24(0,[(l()(),ll._26(null,["\n Aliases\n "]))],null,null)}function F(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.Aliases.length>0?n.context.$implicit.Aliases.join(", "):"")})}function M(l){return ll._24(0,[(l()(),ll._26(null,["\n Count\n "]))],null,null)}function L(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "])),ll._32(1)],null,function(l,n){l(n,0,0,ll._33(n,0,0,l(n,1,0,ll._29(n.parent.parent,0),n.context.$implicit.Count)))})}function P(l){return ll._24(0,[(l()(),ll._26(null,["\n Fraction\n "]))],null,null)}function N(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "])),ll._32(2)],null,function(l,n){l(n,0,0,ll._33(n,0,0,l(n,1,0,ll._29(n.parent.parent,1),n.context.$implicit.Fraction,"1.0-4")))})}function B(l){return ll._24(0,[(l()(),ll._25(0,null,null,76,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,4,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["Wild Statistics "])),(l()(),ll._25(0,null,null,2,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(1),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,67,"ark-data-table",[["orderByColumn","species"],["trackByProp","ClassName"]],null,null,null,rl.a,rl.b)),ll._27(57344,null,2,il.a,[ll.O],{rows:[0,"rows"],trackByProp:[1,"trackByProp"],sortFunctions:[2,"sortFunctions"],orderByColumn:[3,"orderByColumn"]},null),ll._35(301989888,17,{modeTemplates:1}),ll._35(301989888,18,{columnTemplates:1}),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"ark-dt-mode",[["columnKeys","species,class_name,aliases,count,fraction"],["key","default"],["name","Default"]],null,null,null,null,null)),ll._27(8192,[[17,4]],0,al.a,[],{key:[0,"key"],name:[1,"name"],columnKeys:[2,"columnKeys"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","species"],["thenSort","count"],["title","Sort by Species"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,19,{cellTemplate:0}),ll._35(167772160,20,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[20,2]],null,1,null,I)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[19,2]],null,1,null,x)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","class_name"],["thenSort","count"],["title","Sort by Class Name"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,21,{cellTemplate:0}),ll._35(167772160,22,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[22,2]],null,1,null,O)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[21,2]],null,1,null,A)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","aliases"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"]},null),ll._35(167772160,23,{cellTemplate:0}),ll._35(167772160,24,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[24,2]],null,1,null,T)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[23,2]],null,1,null,F)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","count"],["thenSort","species"],["title","Sort by Count"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,25,{cellTemplate:0}),ll._35(167772160,26,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[26,2]],null,1,null,M)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[25,2]],null,1,null,L)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","fraction"],["thenSort","species"],["title","Sort by Fraction"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,27,{cellTemplate:0}),ll._35(167772160,28,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[28,2]],null,1,null,P)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[27,2]],null,1,null,N)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n"]))],function(l,n){var u=n.component;l(n,9,0,u.wild.Statistics.Species,"ClassName",u.wildStatisticsSortFunctions,"species"),l(n,14,0,"default","Default","species,class_name,aliases,count,fraction"),l(n,17,0,"species","count","Sort by Species",!0),l(n,29,0,"class_name","count","Sort by Class Name",!0),l(n,41,0,"aliases"),l(n,53,0,"count","species","Sort by Count",!0),l(n,65,0,"fraction","species","Sort by Fraction",!0)},function(l,n){var u=n.component;l(n,5,0,ll._33(n,5,0,l(n,6,0,ll._29(n.parent,0),(null==u.wild.Statistics.Species?null:u.wild.Statistics.Species.length)||0)))})}function K(l){return ll._24(0,[(l()(),ll._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),ll._26(null,["There are no creatures..."]))],null,null)}function j(l){return ll._24(0,[(l()(),ll._25(0,null,null,3,"option",[],null,null,null,null,null)),ll._27(73728,null,0,sl.k,[ll.K,ll.J,[2,sl.l]],{value:[0,"value"]},null),ll._27(73728,null,0,sl.m,[ll.K,ll.J,[8,null]],{value:[0,"value"]},null),(l()(),ll._26(null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.component.wild.Species[n.context.$implicit].Name||n.context.$implicit)})}function $(l){return ll._24(0,[(l()(),ll._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("stats")&&t}return t},null,null)),ll._27(139264,null,0,ul.m,[ll.v,ll.w,ll.K,ll.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),ll._31(["theme-d1"]),(l()(),ll._26(null,["Base Stats"]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCreaturesMode("stats")))},function(l,n){l(n,0,0,100/n.component.numCreatureTabs())})}function R(l){return ll._24(0,[(l()(),ll._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("ids")&&t}return t},null,null)),ll._27(139264,null,0,ul.m,[ll.v,ll.w,ll.K,ll.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),ll._31(["theme-d1"]),(l()(),ll._26(null,["IDs"]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCreaturesMode("ids")))},function(l,n){l(n,0,0,100/n.component.numCreatureTabs())})}function D(l){return ll._24(0,[(l()(),ll._25(0,null,null,12,"div",[["class","w3-bar theme-l2 w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("status")&&t}return t},null,null)),ll._27(139264,null,0,ul.m,[ll.v,ll.w,ll.K,ll.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),ll._31(["theme-d1"]),(l()(),ll._26(null,["Overview"])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,$)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,R)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,"w3-bar-item w3-button w3-mobile",l(n,4,0,u.activeCreaturesMode("status"))),l(n,8,0,u.dataService.hasFeatureAccess("server","wildcreatures-basestats")),l(n,11,0,u.dataService.hasFeatureAccess("server","wildcreatures-ids"))},function(l,n){l(n,2,0,100/n.component.numCreatureTabs())})}function E(l){return ll._24(0,[(l()(),ll._25(0,null,null,16,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by X"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("x")&&t}return t},null,null)),(l()(),ll._26(null,["X"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Y"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("y")&&t}return t},null,null)),(l()(),ll._26(null,["Y"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Z"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("z")&&t}return t},null,null)),(l()(),ll._26(null,["Z"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Latitude"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("latitude")&&t}return t},null,null)),(l()(),ll._26(null,["Lat"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Longitude"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("longitude")&&t}return t},null,null)),(l()(),ll._26(null,["Lng"])),(l()(),ll._26(null,["\n "]))],null,null)}function U(l){return ll._24(0,[(l()(),ll._25(0,null,null,23,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Health"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_health")&&t}return t},null,null)),(l()(),ll._26(null,["HP"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Stamina"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_stamina")&&t}return t},null,null)),(l()(),ll._26(null,["ST"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Oxygen"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_oxygen")&&t}return t},null,null)),(l()(),ll._26(null,["OX"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Food"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_food")&&t}return t},null,null)),(l()(),ll._26(null,["FO"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Weight"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_weight")&&t}return t},null,null)),(l()(),ll._26(null,["WE"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Melee"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_melee")&&t}return t},null,null)),(l()(),ll._26(null,["ME"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Speed"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_speed")&&t}return t},null,null)),(l()(),ll._26(null,["SP"])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "]))],null,null)}function z(l){return ll._24(0,[(l()(),ll._25(0,null,null,7,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by ID1"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("id1")&&t}return t},null,null)),(l()(),ll._26(null,["ID1"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by ID2"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("id2")&&t}return t},null,null)),(l()(),ll._26(null,["ID2"])),(l()(),ll._26(null,["\n "]))],null,null)}function J(l){return ll._24(0,[(l()(),ll._25(0,null,null,2,"tr",[],null,null,null,null,null)),(l()(),ll._25(0,null,null,1,"td",[],[[8,"colSpan",0]],null,null,null,null)),(l()(),ll._26(null,["No matching creatures..."]))],null,function(l,n){var u=n.component;l(n,1,0,u.activeCreaturesMode("status")?8:u.activeCreaturesMode("stats")?10:5)})}function G(l){return ll._24(0,[(l()(),ll._25(0,null,null,18,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(2),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(2),(l()(),ll._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.parent.context.$implicit.X),l(n,6,0,n.parent.context.$implicit.Y),l(n,9,0,n.parent.context.$implicit.Z),l(n,12,0,ll._33(n,12,0,l(n,13,0,ll._29(n.parent.parent.parent.parent,0),n.parent.context.$implicit.Latitude,"1.1-1"))),l(n,16,0,ll._33(n,16,0,l(n,17,0,ll._29(n.parent.parent.parent.parent,0),n.parent.context.$implicit.Longitude,"1.1-1")))})}function H(l){return ll._24(0,[(l()(),ll._25(0,null,null,23,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "]))],null,function(l,n){l(n,3,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Health),l(n,6,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Stamina),l(n,9,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Oxygen),l(n,12,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Food),l(n,15,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Weight),l(n,18,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Melee),l(n,21,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.MovementSpeed)})}function X(l){return ll._24(0,[(l()(),ll._25(0,null,null,7,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.parent.context.$implicit.Id1),l(n,6,0,n.parent.context.$implicit.Id2)})}function W(l){return ll._24(0,[(l()(),ll._25(0,null,null,19,"tr",[],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,G)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,H)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,X)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,12,0,u.activeCreaturesMode("status")),l(n,15,0,u.activeCreaturesMode("stats")),l(n,18,0,u.activeCreaturesMode("ids"))},function(l,n){var u=n.component;l(n,3,0,n.context.$implicit.Gender),l(n,6,0,n.context.$implicit.BaseLevel),l(n,9,0,u.wild.Species[u.selectedSpecies].IsTameable&&1==n.context.$implicit.IsTameable?"Yes":"No")})}function V(l){return ll._24(0,[(l()(),ll._25(0,null,null,55,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,9,"select",[["class","w3-select w3-border w3-round-xlarge w3-large w3-margin-bottom border-theme theme-l1"],["style","padding: 8px;"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"blur"]],function(l,n,u){var t=!0,e=l.component;if("change"===n){t=!1!==ll._29(l,3).onChange(u.target.value)&&t}if("blur"===n){t=!1!==ll._29(l,3).onTouched()&&t}if("ngModelChange"===n){e.selectedSpecies=u;t=!1!==e.filterAndSortWild()&&t}return t},null,null)),ll._27(8192,null,0,sl.l,[ll.J,ll.K],null,null),ll._37(512,null,sl.g,function(l){return[l]},[sl.l]),ll._27(335872,null,0,sl.h,[[8,null],[8,null],[8,null],[2,sl.g]],{model:[0,"model"]},{update:"ngModelChange"}),ll._37(1024,null,sl.i,null,[sl.h]),ll._27(8192,null,0,sl.j,[sl.i],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,j)),ll._27(401408,null,0,ul.n,[ll.S,ll._5,ll.v],{ngForOf:[0,"ngForOf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,D)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,37,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,34,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,22,"thead",[],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,19,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Gender"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("gender")&&t}return t},null,null)),(l()(),ll._26(null,["Gender"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Base Level"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("base_level")&&t}return t},null,null)),(l()(),ll._26(null,["Base Level"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Tameable"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("tameable")&&t}return t},null,null)),(l()(),ll._26(null,["Tameable"])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,E)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,U)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,z)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,7,"tbody",[],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,J)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,W)),ll._27(401408,null,0,ul.n,[ll.S,ll._5,ll.v],{ngForOf:[0,"ngForOf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,5,0,u.selectedSpecies),l(n,10,0,u.species),l(n,15,0,u.numCreatureTabs()>1),l(n,35,0,u.activeCreaturesMode("status")),l(n,38,0,u.activeCreaturesMode("stats")),l(n,41,0,u.activeCreaturesMode("ids")),l(n,48,0,!((null==u.filteredCreatures?null:u.filteredCreatures.length)>0)),l(n,51,0,u.filteredCreatures)},function(l,n){l(n,2,0,ll._29(n,7).ngClassUntouched,ll._29(n,7).ngClassTouched,ll._29(n,7).ngClassPristine,ll._29(n,7).ngClassDirty,ll._29(n,7).ngClassValid,ll._29(n,7).ngClassInvalid,ll._29(n,7).ngClassPending)})}function Y(l){return ll._24(0,[(l()(),ll._25(0,null,null,26,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,17,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),ll._25(0,null,null,0,"a",[["id","creatures"]],null,null,null,null,null)),(l()(),ll._25(0,null,null,8,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),ll._26(null,["Wild Creatures "])),(l()(),ll._25(0,null,null,2,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(1),(l()(),ll._26(null,[" / "])),(l()(),ll._25(0,null,null,2,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(1),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,2,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),ll._25(0,null,null,1,"button",[["class","w3-button theme-d1 w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.openMap(u)&&t}return t},null,null)),(l()(),ll._26(null,["Show Map"])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,K)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,V)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"]))],function(l,n){var u=n.component;l(n,22,0,!((null==u.species?null:u.species.length)>0)),l(n,25,0,(null==u.species?null:u.species.length)>0)},function(l,n){var u=n.component;l(n,9,0,ll._33(n,9,0,l(n,10,0,ll._29(n.parent,0),(null==u.filteredCreatures?null:u.filteredCreatures.length)||0))),l(n,13,0,ll._33(n,13,0,l(n,14,0,ll._29(n.parent,0),(null==u.wild?null:null==u.wild.Statistics?null:u.wild.Statistics.CreatureCount)||0)))})}function q(l){return ll._24(0,[ll._34(0,ul.p,[ll.t]),ll._34(0,ul.r,[ll.t]),(l()(),ll._28(8388608,null,null,1,null,t)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,e)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,d)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,C)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,B)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,Y)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._25(0,null,null,17,"div",[["class","w3-modal"],["id","modal_map"]],[[4,"display",null]],null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,14,"div",[["class","w3-modal-content w3-card-4 w3-animate-zoom"],["style","font-size: 0;"]],null,[[null,"clickOutside"],["document","click"]],function(l,n,u){var t=!0,e=l.component;if("document:click"===n){t=!1!==ll._29(l,23).onClick(u,u.target)&&t}if("clickOutside"===n){t=!1!==e.closeMap(u)&&t}return t},null,null)),ll._27(8192,null,0,_l.a,[ll.K],null,{clickOutside:"clickOutside"}),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,[" \n "])),(l()(),ll._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.showMap=!1)&&t}return t},null,null)),(l()(),ll._26(null,["×"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),ll._26(null,["Map"])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"arkmap",[],null,null,null,pl.a,pl.b)),ll._27(286720,null,0,dl.a,[],{mapName:[0,"mapName"],points:[1,"points"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,0==u.loaded||(u.isMenuActive("wildcreatures")||u.isMenuActive("wildcreatures-statistics"))&&0==u.creaturesLoaded),l(n,6,0,1==u.loaded&&null==u.server),l(n,9,0,u.isMenuActive("players")&&u.server&&u.dataService.hasFeatureAccess("server","players")),l(n,12,0,u.isMenuActive("tribes")&&u.server&&u.dataService.hasFeatureAccess("server","tribes")),l(n,15,0,u.isMenuActive("wildcreatures-statistics")&&u.creaturesLoaded&&u.dataService.hasFeatureAccess("server","wildcreatures-statistics")),l(n,18,0,u.isMenuActive("wildcreatures")&&u.creaturesLoaded&&u.dataService.hasFeatureAccess("server","wildcreatures")),l(n,35,0,null==u.server?null:u.server.MapName,u.points)},function(l,n){l(n,20,0,n.component.showMap?"block":"none")})}function Q(l){return ll._24(0,[(l()(),ll._25(0,null,null,1,"app-server",[],null,null,null,q,yl)),ll._27(122880,null,0,cl.a,[nl.v,nl.g,fl.a,ml.a,hl.a,vl.a,ll.O],null,null)],function(l,n){l(n,1,0)},null)}var Z=u("ZfYc"),ll=u("3j3K"),nl=u("5oXY"),ul=u("2Je8"),tl=u("6Nb/"),el=u("0onv"),rl=u("fYAd"),il=u("0jRk"),al=u("joX7"),ol=u("jWPz"),sl=u("NVOs"),cl=u("qn86"),_l=u("8zLQ"),pl=u("I9JA"),dl=u("5305"),fl=u("lHWG"),ml=u("ATz5"),hl=u("+Lwu"),vl=u("XLrO");u.d(n,"a",function(){return Sl});var gl=[Z.a],yl=ll._23({encapsulation:0,styles:gl,data:{}}),Sl=ll._30("app-server",cl.a,Q,{},{},[])},"+qYp":function(l,n,u){"use strict";var t=u("ATz5"),e=u("3MNG"),r=u("+Lwu");u.d(n,"a",function(){return i});var i=function(){function l(l,n,u){this.dataService=l,this.messageService=n,this.notificationsService=u,this.menuOption=void 0}return l.prototype.ngOnInit=function(){var l=this;this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.showServerUpdateNotification(n)}),this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n})},l.prototype.ngOnDestroy=function(){this.serverUpdatedSubscription.unsubscribe(),this.menuOptionSubscription.unsubscribe()},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.ctorParameters=function(){return[{type:t.a},{type:r.a},{type:e.a}]},l}()},"+rAa":function(l,n,u){"use strict";function t(l,n,u,t){var e=i(l,n,u);if(void 0!=e)return e;var r=Math.pow(10,t),a=void 0!=t?Math.round(l*r)/r:l,o=void 0!=t?Math.round(n*r)/r:n;return a>o?u?1:-1:an?u?1:-1:l0&&(this._currentMode=this._modes[0].key)}}},enumerable:!0,configurable:!0}),Object.defineProperty(l.prototype,"columnTemplates",{set:function(l){if(l){var n=l.toArray();if(n.length){for(var u=[],t=0,e=n;t=this._rows.length&&(n=this._rows.length-1),this._fromRow=parseInt(""+n),this.ref.markForCheck()},l.prototype.setViewOffsetRelative=function(l){this.setViewOffset(this._fromRow+l)},l.prototype.setFirstPage=function(){this.isFirstPage()||this.setViewOffset(0)},l.prototype.setPrevPage=function(){this.isFirstPage()||this.setViewOffsetRelative(-this._numRows)},l.prototype.setNextPage=function(){this.isLastPage()||this.setViewOffsetRelative(this._numRows)},l.prototype.setLastPage=function(){this.isLastPage()||this.setViewOffset(this._rows.length-this._numRows)},l.prototype.isFirstPage=function(){return this._fromRow<=0},l.prototype.isLastPage=function(){return this._fromRow>=this._rows.length-this._numRows},l.prototype.setViewLimit=function(l){this._numRows=parseInt(""+(l>0?l:1e6)),this.ref.markForCheck()},l.prototype.getLastRowOffset=function(){var l=this._fromRow+this._numRows;return l>this._rows.length?this._rows.length:l},l.ctorParameters=function(){return[{type:t.O}]},l}()},"0onv":function(l,n,u){"use strict";var t=u("3j3K"),e=u("Gvdl"),r=(u.n(e),u("PJh5"));u.n(r);u.d(n,"a",function(){return i});var i=function(){function l(l){this.ref=l,this._time=new e.BehaviorSubject(void 0)}return Object.defineProperty(l.prototype,"time",{get:function(){return this._time.getValue()},set:function(l){this._time.next(l)},enumerable:!0,configurable:!0}),l.prototype.ngOnInit=function(){var l=this;this._timeSubscription=this._time.subscribe(function(n){l.update()}),this._counter=e.Observable.interval(1e3).map(function(l){return l}),this._counterSubscription=this._counter.subscribe(function(n){return l.update()})},l.prototype.ngOnDestroy=function(){this._timeSubscription.unsubscribe(),this._counterSubscription.unsubscribe()},l.prototype.update=function(){var l=this.toRelativeDate(this.time);l!=this._str&&(this._str=l,this.ref.markForCheck())},l.prototype.toRelativeDate=function(l){return r(new Date(l)).fromNow()},l.ctorParameters=function(){return[{type:t.O}]},l}()},"1A80":function(l,n,u){"use strict";function t(l){return o._24(0,[(l()(),o._25(0,null,null,4,"span",[],null,null,null,null,null)),(l()(),o._26(null,["Logged in as "," | "])),(l()(),o._25(0,null,null,1,"a",[],[[8,"href",4]],null,null,null,null)),(l()(),o._26(null,["Logout"])),(l()(),o._26(null,[" | "]))],null,function(l,n){var u=n.component;l(n,1,0,u.dataService.Servers.User.Name),l(n,2,0,u.getLogoutUrl())})}function e(l){return o._24(0,[(l()(),o._25(0,null,null,3,"span",[],null,null,null,null,null)),(l()(),o._25(0,null,null,1,"a",[["href","#"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.openLogin(u)&&t}return t},null,null)),(l()(),o._26(null,["Login"])),(l()(),o._26(null,[" | "]))],null,null)}function r(l){return o._24(0,[(l()(),o._25(0,null,null,1,"simple-notifications",[],null,null,null,s.a,s.b)),o._27(122880,null,0,c.a,[_.a],{options:[0,"options"]},null),(l()(),o._26(null,["\n"])),(l()(),o._26(null,["\n\n"])),(l()(),o._25(8388608,null,null,1,"router-outlet",[["name","menu"]],null,null,null,null,null)),o._27(73728,null,0,p.z,[p.l,o.S,o.T,[8,"menu"]],null,null),(l()(),o._26(null,["\n"])),(l()(),o._25(0,null,null,22,"div",[["id","page"]],null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,16,"div",[["class","w3-bar"]],null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"breadcrumb",[["class","breadcrumb w3-bar-item"],["prefix","Home"]],null,null,null,d.a,d.b)),o._27(385024,null,0,f.a,[p.g,m.a],{useBootstrap:[0,"useBootstrap"],prefix:[1,"prefix"]},null),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,10,"div",[["class","w3-bar-item w3-right w3-tiny theme-l1"]],null,null,null,null,null)),(l()(),o._28(8388608,null,null,1,null,t)),o._27(8192,null,0,h.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null),(l()(),o._28(8388608,null,null,1,null,e)),o._27(8192,null,0,h.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null),(l()(),o._26(null,["Theme: "])),(l()(),o._25(0,null,null,1,"a",[["href","#"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setTheme("light")&&t}return t},null,null)),(l()(),o._26(null,["Light"])),(l()(),o._26(null,[" | "])),(l()(),o._25(0,null,null,1,"a",[["href","#"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setTheme("dark")&&t}return t},null,null)),(l()(),o._26(null,["Dark"])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n "])),(l()(),o._25(8388608,null,null,1,"router-outlet",[],null,null,null,null,null)),o._27(73728,null,0,p.z,[p.l,o.S,o.T,[8,null]],null,null),(l()(),o._26(null,["\n"])),(l()(),o._26(null,["\n"])),(l()(),o._25(0,null,null,31,"div",[["class","w3-modal"],["id","modal_login"]],[[4,"display",null]],null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,28,"div",[["class","w3-modal-content w3-card-4 w3-animate-zoom"],["style","font-size: 0;"]],null,[[null,"clickOutside"],["document","click"]],function(l,n,u){var t=!0,e=l.component;if("document:click"===n){t=!1!==o._29(l,34).onClick(u,u.target)&&t}if("clickOutside"===n){t=!1!==e.closeLogin(u)&&t}return t},null,null)),o._27(8192,null,0,g.a,[o.K],null,{clickOutside:"clickOutside"}),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),o._26(null,[" \n "])),(l()(),o._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.showLogin=!1)&&t}return t},null,null)),(l()(),o._26(null,["×"])),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),o._26(null,["Log In"])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,15,"form",[["class","w3-container theme-l2 w3-medium"],["method","post"],["ngNoForm",""]],[[8,"action",4]],null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,12,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),o._26(null,["To give you access to personal information, first, we must verify your identity."])),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),o._26(null,["Please authenticate with our app through Steam by clicking on the button below."])),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,0,"input",[["name","returnUrl"],["type","hidden"]],[[8,"value",0]],null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"button",[["class","w3-button w3-block theme-d1 w3-section w3-padding"],["name","provider"],["title","Log in using your Steam account"],["type","submit"]],null,null,null,null,null)),(l()(),o._26(null,["Go to Steam"])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n"]))],function(l,n){var u=n.component;l(n,1,0,u.notificationOptions),l(n,12,0,!1,"Home"),l(n,16,0,null==u.dataService.Servers?null:null==u.dataService.Servers.User?null:u.dataService.Servers.User.SteamId),l(n,18,0,!(null==u.dataService.Servers?null:null==u.dataService.Servers.User?null:u.dataService.Servers.User.SteamId))},function(l,n){var u=n.component;l(n,31,0,u.showLogin?"block":"none"),l(n,45,0,u.getLoginUrl()),l(n,55,0,u.currentUrl)})}function i(l){return o._24(0,[(l()(),o._25(0,null,null,1,"body",[],[[8,"className",0]],null,null,r,w)),o._27(122880,null,0,v.a,[y.a,S.a,m.a,_.a,p.g],null,null)],function(l,n){l(n,1,0)},function(l,n){l(n,0,0,o._29(n,1).getTheme())})}var a=u("Ni5f"),o=u("3j3K"),s=u("XhEa"),c=u("B8cY"),_=u("XLrO"),p=u("5oXY"),d=u("if6N"),f=u("v8ur"),m=u("aT6V"),h=u("2Je8"),v=u("YWx4"),g=u("8zLQ"),y=u("ATz5"),S=u("lHWG");u.d(n,"a",function(){return k});var b=[a.a],w=o._23({encapsulation:0,styles:b,data:{}}),k=o._30("body",v.a,i,{},{},[])},"1AkI":function(l,n,u){"use strict";function t(l){return c._24(0,[(l()(),c._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._29(l.parent,2).activate("players")&&t}return t},null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._31(["theme-d1"]),(l()(),c._26(null,["Players"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,c._29(n.parent,2).active("players")))},null)}function e(l){return c._24(0,[(l()(),c._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._29(l.parent,2).activate("tribes")&&t}return t},null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._31(["theme-d1"]),(l()(),c._26(null,["Tribes"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,c._29(n.parent,2).active("tribes")))},null)}function r(l){return c._24(0,[(l()(),c._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._29(l.parent,2).activate("wildcreatures-statistics")&&t}return t},null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._31(["theme-d1"]),(l()(),c._26(null,["Wild Statistics"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,c._29(n.parent,2).active("wildcreatures-statistics")))},null)}function i(l){return c._24(0,[(l()(),c._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._29(l.parent,2).activate("wildcreatures")&&t}return t},null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._31(["theme-d1"]),(l()(),c._26(null,["Wild Creatures"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,c._29(n.parent,2).active("wildcreatures")))},null)}function a(l){return c._24(0,[c._35(201326592,1,{menu:0}),(l()(),c._25(0,null,null,20,"app-menu",[],null,null,null,p.a,p.b)),c._27(122880,[[1,4],["menu",4]],0,d.a,[f.a],null,null),(l()(),c._26(0,["\n "])),(l()(),c._25(0,null,0,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),c._26(null,["Server"])),(l()(),c._26(0,["\n "])),(l()(),c._25(0,null,0,13,"div",[["class","w3-cell-row theme-l2"]],null,null,null,null,null)),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,t)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,e)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,r)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,i)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._26(0,["\n"]))],function(l,n){var u=n.component;l(n,2,0),l(n,10,0,u.dataService.hasFeatureAccess("server","players")),l(n,13,0,u.dataService.hasFeatureAccess("server","tribes")),l(n,16,0,u.dataService.hasFeatureAccess("server","wildcreatures-statistics")),l(n,19,0,u.dataService.hasFeatureAccess("server","wildcreatures"))},null)}function o(l){return c._24(0,[(l()(),c._25(0,null,null,1,"app-server-menu",[],[[8,"className",0]],null,null,a,v)),c._27(57344,null,0,m.a,[f.a],null,null)],function(l,n){l(n,1,0)},function(l,n){l(n,0,0,c._29(n,1).menu.className)})}var s=u("nJHW"),c=u("3j3K"),_=u("2Je8"),p=u("coiB"),d=u("8kYA"),f=u("ATz5"),m=u("7xIs");u.d(n,"a",function(){return g});var h=[s.a],v=c._23({encapsulation:0,styles:h,data:{}}),g=c._30("app-server-menu",m.a,o,{},{},[])},"2dXI":function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},5305:function(l,n,u){"use strict";var t=u("kZql"),e=u("f4AQ");u.n(e);u.d(n,"a",function(){return r});var r=function(){function l(){this.width=1024,this.height=1024,this.zoom=e.zoom().scaleExtent([1,10])}return l.prototype.imageLoaded=function(l){var n=this;this.img=l,this.width=l.naturalWidth,this.height=l.naturalHeight,window.setTimeout(function(){n.resize(),n.redraw()},100)},l.prototype.resize=function(){},l.prototype.zoomed=function(){var l=e.zoomTransform(this.canvasRef.nativeElement),n=this.canvasRef.nativeElement.getContext("2d");n.setTransform(1,0,0,1,0,0),n.clearRect(0,0,this.width,this.height),n.translate(l.x,l.y),n.scale(l.k,l.k),this.redraw()},l.prototype.redraw=function(){var l=this.canvasRef.nativeElement.getContext("2d");if(l.drawImage(this.img,0,0),null!=this.points)for(var n=0,u=this.points;n/gi,window.location.protocol).replace(/\/gi,window.location.hostname)},l.ctorParameters=function(){return[]},l}()},"6Nb/":function(l,n,u){"use strict";function t(l){return i._24(2,[(l()(),i._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),i._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component._str)})}function e(l){return i._24(0,[(l()(),i._25(0,null,null,1,"relative-time",[],null,null,null,t,s)),i._27(122880,null,0,a.a,[i.O],null,null)],function(l,n){l(n,1,0)},null)}var r=u("/tjS"),i=u("3j3K"),a=u("0onv");u.d(n,"b",function(){return s}),n.a=t;var o=[r.a],s=i._23({encapsulation:0,styles:o,data:{}});i._30("relative-time",a.a,e,{time:"time"},{},[])},"7MbP":function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},"7T2B":function(l,n,u){"use strict";var t=u("3j3K");u.d(n,"a",function(){return e});var e=function(){function l(){this.callback=new t.Q,this.confirming=!1}return l.prototype.ngOnInit=function(){},l.prototype.onClick=function(l){var n=this;this.confirming?l.detail>=3&&(window.clearTimeout(this.resetTimeout),this.confirming=!1,this.callback.emit()):(this.confirming=!0,this.resetTimeout=window.setTimeout(function(){n.confirming=!1},5e3))},l.ctorParameters=function(){return[]},l}()},"7xIs":function(l,n,u){"use strict";var t=u("ATz5");u.d(n,"a",function(){return e});var e=function(){function l(l){this.dataService=l}return l.prototype.ngOnInit=function(){this.dataService.hasFeatureAccess("server","players")?this.menu.activate("players"):this.dataService.hasFeatureAccess("server","tribes")?this.menu.activate("tribes"):this.dataService.hasFeatureAccess("server","wildcreatures-statistics")?this.menu.activate("wildcreatures-statistics"):this.dataService.hasFeatureAccess("server","wildcreatures")&&this.menu.activate("wildcreatures")},l.ctorParameters=function(){return[{type:t.a}]},l}()},"8kYA":function(l,n,u){"use strict";var t=u("ATz5");u.d(n,"a",function(){return e});var e=function(){function l(l){this.dataService=l,this.menuOption=void 0,this.menuVisible=!1,this.className="menucontainer"}return l.prototype.ngOnInit=function(){var l=this;this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n})},l.prototype.ngOnDestroy=function(){this.menuOptionSubscription.unsubscribe()},l.prototype.activate=function(l){this.dataService.SetMenuOption(l)},l.prototype.active=function(l){return this.menuOption==l},l.prototype.toggleMenu=function(){this.menuVisible=!this.menuVisible},l.ctorParameters=function(){return[{type:t.a}]},l}()},"8zLQ":function(l,n,u){"use strict";var t=u("3j3K");u.d(n,"a",function(){return e});var e=function(){function l(l){this._elementRef=l,this.clickOutside=new t.Q}return l.prototype.onClick=function(l,n){if(n){this._elementRef.nativeElement.contains(n)||this.clickOutside.emit(l)}},l.ctorParameters=function(){return[{type:t.K}]},l}()},ATz5:function(l,n,u){"use strict";var t=u("3j3K"),e=u("Gvdl"),r=(u.n(e),u("lHWG")),i=u("+Lwu"),a=u("kZql"),o=u("PJh5");u.n(o);u.d(n,"a",function(){return s});var s=function(){function l(l,n){var u=this;this.httpService=l,this.messageService=n,this._servers=new e.BehaviorSubject(void 0),this.menuOption=new e.BehaviorSubject(void 0),this.ServersUpdated$=new t.Q,n.serverUpdated$.subscribe(function(l){return u.updateServer(l)})}return Object.defineProperty(l.prototype,"MenuOption",{get:function(){return this.menuOption.asObservable()},enumerable:!0,configurable:!0}),l.prototype.SetMenuOption=function(l){this.menuOption.next(l)},l.prototype.getServers=function(){var l=this;return this.httpService.getServers().then(function(n){l.Servers=n;var u=n?n.User:void 0;return l.UserSteamId=u&&u.SteamId?u.SteamId:void 0,l._servers.next(n),l.ServersUpdated$.emit(n),!0}).catch(function(n){return l.Servers=null,l.UserSteamId=void 0,l._servers.next(null),l.ServersUpdated$.emit(null),!1})},l.prototype.updateServer=function(l){this.getServers()},l.prototype.hasFeatureAccess=function(l,n,u){var t=this.Servers?this.Servers.AccessControl:void 0;if(!t)return!1;var e=t[l];if(!e)return!1;var r=e[n];if(!r)return!1;var i=this.Servers?this.Servers.User:void 0,a=i&&i.Roles?i.Roles.slice(0):[];i&&i.SteamId&&i.SteamId==u&&a.push("self");for(var o=function(l){if(r.find(function(n){return l.toLowerCase()===n.toLowerCase()}))return{value:!0}},s=0,c=a;s0&&e.push(t+"d"),(t>0||u>0)&&e.push(u+"h"),(t>0||u>0||n>0)&&e.push(n+"m"),e.push(l+"s"),this._str=e.join(" "),this._ready=!1,this.state._completed=!1},l.prototype.ngOnInit=function(){var l=this;this._timeSubscription=this._time.subscribe(function(n){l.updateDiff(n),l.update()}),this._notificationSubscription=this._notification.subscribe(function(l){}),this._counter=t.Observable.interval(1e3).map(function(n){return l.updateDiff(void 0),n}),this._counterSubscription=this._counter.subscribe(function(n){return l.update()})},l.prototype.ngOnDestroy=function(){this._timeSubscription.unsubscribe(),this._notificationSubscription.unsubscribe(),this._counterSubscription.unsubscribe()},l.ctorParameters=function(){return[]},l}()},DGJX:function(l,n,u){"use strict";function t(l){return v._24(0,[(l()(),v._25(0,null,null,2,null,null,null,null,null,null,null)),(l()(),v._26(null,["Last Active: ",""])),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null))],null,function(l,n){var u=n.component;l(n,1,0,u.dataService.toRelativeDate(u.currentOwner.LastActiveTime))})}function e(l){return v._24(0,[(l()(),v._25(0,null,null,3,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,2,"confirm-button",[],null,[[null,"callback"]],function(l,n,u){var t=!0,e=l.component;if("callback"===n){t=!1!==e.destroyCurrentArea(u)&&t}return t},g.a,g.b)),v._27(57344,null,0,y.a,[],{width:[0,"width"]},{callback:"callback"}),(l()(),v._26(0,["Destroy this area"]))],function(l,n){l(n,2,0,100)},null)}function r(l){return v._24(0,[(l()(),v._25(0,null,null,31,null,null,null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),v._26(null,[" \n "])),(l()(),v._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.hideContextMenu()&&t}return t},null,null)),(l()(),v._26(null,["×"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,19,"div",[["class","w3-container w3-medium theme-l2"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,9,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._26(null,["\n Coords: ",", ",""])),v._32(2),v._32(2),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,t)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "," structures\n "])),v._32(1),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"button",[["class","w3-button theme-d1"],["style","width: 100%;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setSelectedOwner(e.currentOwner)&&t}return t},null,null)),(l()(),v._26(null,["Show only areas for this team"])),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,e)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "]))],function(l,n){var u=n.component;l(n,20,0,u.currentOwner.LastActiveTime),l(n,29,0,u.dataService.hasFeatureAccess("admin-server","structures-rcon"))},function(l,n){var u=n.component;l(n,8,0,u.currentOwner.Name),l(n,14,0,v._33(n,14,0,l(n,15,0,v._29(n.parent,0),u.currentArea.Latitude,"1.0-1")),v._33(n,14,1,l(n,16,0,v._29(n.parent,0),u.currentArea.Longitude,"1.0-1"))),l(n,21,0,v._33(n,21,0,l(n,22,0,v._29(n.parent,0),u.currentArea.StructureCount)))})}function i(l){return v._24(0,[(l()(),v._25(0,null,null,2,null,null,null,null,null,null,null)),(l()(),v._26(null,["Last Active: ",""])),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null))],null,function(l,n){var u=n.component;l(n,1,0,u.dataService.toRelativeDate(u.currentOwner.LastActiveTime))})}function a(l){return v._24(0,[(l()(),v._25(0,null,null,3,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,2,"confirm-button",[],null,[[null,"callback"]],function(l,n,u){var t=!0,e=l.component;if("callback"===n){t=!1!==e.destroyAllStructuresForTeam(u)&&t}return t},g.a,g.b)),v._27(57344,null,0,y.a,[],{width:[0,"width"]},{callback:"callback"}),(l()(),v._26(0,["Destroy all structures"]))],function(l,n){l(n,2,0,100)},null)}function o(l){return v._24(0,[(l()(),v._25(0,null,null,3,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,2,"confirm-button",[],null,[[null,"callback"]],function(l,n,u){var t=!0,e=l.component;if("callback"===n){t=!1!==e.destroyDinosForTeam(u)&&t}return t},g.a,g.b)),v._27(57344,null,0,y.a,[],{width:[0,"width"]},{callback:"callback"}),(l()(),v._26(0,["Destroy all creatures"]))],function(l,n){l(n,2,0,100)},null)}function s(l){return v._24(0,[(l()(),v._25(0,null,null,36,null,null,null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),v._26(null,[" \n "])),(l()(),v._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.hideContextMenu()&&t}return t},null,null)),(l()(),v._26(null,["×"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,24,"div",[["class","w3-container w3-medium theme-l2"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,11,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,i)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "," areas"])),v._32(1),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),v._26(null,["\n "," structures"])),v._32(1),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),v._26(null,["\n "," creatures\n "])),v._32(1),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"button",[["class","w3-button theme-d1"],["style","width: 100%;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setSelectedOwner(e.currentOwner)&&t}return t},null,null)),(l()(),v._26(null,["Show only areas for this team"])),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,a)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,o)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "]))],function(l,n){var u=n.component;l(n,16,0,u.currentOwner.LastActiveTime),l(n,31,0,u.dataService.hasFeatureAccess("admin-server","structures-rcon")),l(n,34,0,u.dataService.hasFeatureAccess("admin-server","structures-rcon"))},function(l,n){var u=n.component;l(n,8,0,u.currentOwner.Name),l(n,17,0,v._33(n,17,0,l(n,18,0,v._29(n.parent,0),u.currentOwner.AreaCount))),l(n,20,0,v._33(n,20,0,l(n,21,0,v._29(n.parent,0),u.currentOwner.StructureCount))),l(n,23,0,v._33(n,23,0,l(n,24,0,v._29(n.parent,0),u.currentOwner.CreatureCount)))})}function c(l){return v._24(0,[(l()(),v._25(0,null,null,16,null,null,null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),v._26(null,[" \n "])),(l()(),v._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.hideContextMenu()&&t}return t},null,null)),(l()(),v._26(null,["×"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,4,"div",[["class","w3-container w3-medium theme-l2"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._26(null,["\n ","\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "]))],null,function(l,n){var u=n.component;l(n,8,0,u.modalInfo.Header),l(n,14,0,u.modalInfo.Message)})}function _(l){return v._24(0,[(l()(),v._25(0,null,null,3,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),v._25(0,null,null,2,"confirm-button",[["class","w3-right"]],null,[[null,"callback"]],function(l,n,u){var t=!0,e=l.component;if("callback"===n){t=!1!==e.saveWorld(u)&&t}return t},g.a,g.b)),v._27(57344,null,0,y.a,[],{width:[0,"width"]},{callback:"callback"}),(l()(),v._26(0,["Save World"]))],function(l,n){l(n,2,0,void 0)},null)}function p(l){return v._24(0,[(l()(),v._25(0,null,null,30,"tr",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,8,"td",[],null,null,null,null,null)),(l()(),v._25(0,null,null,6,"input",[["type","radio"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,e=l.component;if("input"===n){t=!1!==v._29(l,4)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==v._29(l,4).onTouched()&&t}if("compositionstart"===n){t=!1!==v._29(l,4)._compositionStart()&&t}if("compositionend"===n){t=!1!==v._29(l,4)._compositionEnd(u.target.value)&&t}if("change"===n){t=!1!==v._29(l,5).onChange()&&t}if("blur"===n){t=!1!==v._29(l,5).onTouched()&&t}if("ngModelChange"===n){t=!1!==(e.selectedOwner=u)&&t}if("change"===n){t=!1!==e.updateSelection()&&t}return t},null,null)),v._27(8192,null,0,b.d,[v.J,v.K,[2,b.e]],null,null),v._27(106496,null,0,b.f,[v.J,v.K,b.a,v.W],{value:[0,"value"]},null),v._37(512,null,b.g,function(l,n){return[l,n]},[b.d,b.f]),v._27(335872,null,0,b.h,[[8,null],[8,null],[8,null],[2,b.g]],{model:[0,"model"]},{update:"ngModelChange"}),v._37(1024,null,b.i,null,[b.h]),v._27(8192,null,0,b.j,[b.i],null,null),(l()(),v._26(null,[" ",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"button",[["class","w3-button theme-d1 w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.showOwnerModal(u,l.context.$implicit)&&t}return t},null,null)),(l()(),v._26(null,["Options"])),(l()(),v._26(null,["\n "]))],function(l,n){var u=n.component;l(n,5,0,n.context.$implicit),l(n,7,0,u.selectedOwner)},function(l,n){var u=n.component;l(n,3,0,v._29(n,9).ngClassUntouched,v._29(n,9).ngClassTouched,v._29(n,9).ngClassPristine,v._29(n,9).ngClassDirty,v._29(n,9).ngClassValid,v._29(n,9).ngClassInvalid,v._29(n,9).ngClassPending),l(n,10,0,n.context.$implicit.Name),l(n,13,0,n.context.$implicit.Type),l(n,16,0,n.context.$implicit.AreaCount),l(n,19,0,n.context.$implicit.StructureCount),l(n,22,0,n.context.$implicit.CreatureCount),l(n,25,0,u.dataService.toRelativeDate(n.context.$implicit.LastActiveTime))})}function d(l){return v._24(0,[(l()(),v._25(0,null,null,56,null,null,null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,15,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),v._26(null,["Player/Tribe Locations"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,8,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,5,"div",[["class","w3-clear"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"button",[["class","w3-button theme-d1 w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.reset(u)&&t}return t},null,null)),(l()(),v._26(null,["Reset"])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,36,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,33,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,24,"thead",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,21,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),v._26(null,["Name"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),v._26(null,["Type"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Location Count"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setOwnerSort("locations")&&t}return t},null,null)),(l()(),v._26(null,["A#"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Structure Count"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setOwnerSort("structures")&&t}return t},null,null)),(l()(),v._26(null,["S#"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[["title","Creature Count"]],null,null,null,null,null)),(l()(),v._26(null,["C#"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Last Active Time"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setOwnerSort("lastactive")&&t}return t},null,null)),(l()(),v._26(null,["Last Active"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,0,"th",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,p)),v._27(401408,null,0,S.n,[v.S,v._5,v.v],{ngForOf:[0,"ngForOf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n"]))],function(l,n){l(n,52,0,n.component.ownersSorted)},null)}function f(l){return v._24(0,[v._34(0,S.p,[v.t]),v._35(201326592,1,{mapContainer:0}),v._35(201326592,2,{contextMenu:0}),(l()(),v._26(null,["\n"])),(l()(),v._25(0,[[2,0],["contextMenu",1]],null,14,"div",[["class","contextMenu w3-modal"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,11,"div",[["class","w3-modal-content w3-card-4 w3-animate-zoom"],["style","font-size: 0;"]],null,[[null,"clickOutside"],["document","click"]],function(l,n,u){var t=!0,e=l.component;if("document:click"===n){t=!1!==v._29(l,7).onClick(u,u.target)&&t}if("clickOutside"===n){t=!1!==e.hideContextMenu()&&t}return t},null,null)),v._27(8192,null,0,k.a,[v.K],null,{clickOutside:"clickOutside"}),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,r)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,s)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,c)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n"])),(l()(),v._26(null,["\n\n"])),(l()(),v._25(0,null,null,9,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,3,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),v._25(0,null,null,0,"a",[["id","structures"]],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),v._26(null,["Structures"])),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,_)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n"])),(l()(),v._26(null,["\n\n"])),(l()(),v._25(0,null,null,14,"div",[["class","wrapper"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,9,"div",[["class","buttons"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"button",[["class","w3-button theme-d1"],["style","padding: 3px 6px;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.zoomIn()&&t}return t},null,null)),(l()(),v._25(0,null,null,1,"i",[["class","material-icons w3-xxlarge"]],null,null,null,null,null)),(l()(),v._26(null,["add"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"button",[["class","w3-button theme-d1"],["style","padding: 3px 6px;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.zoomOut()&&t}return t},null,null)),(l()(),v._25(0,null,null,1,"i",[["class","material-icons w3-xxlarge"]],null,null,null,null,null)),(l()(),v._26(null,["remove"])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,[[1,0],["map",1]],null,0,"div",[["class","map"]],null,null,null,null,null)),(l()(),v._26(null,["\n"])),(l()(),v._26(null,["\n\n"])),(l()(),v._28(8388608,null,null,1,null,d)),v._27(8192,null,0,S.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,10,0,u.currentArea&&u.currentOwner),l(n,13,0,u.currentOwner&&!u.currentArea),l(n,16,0,u.modalInfo),l(n,28,0,u.dataService.hasFeatureAccess("admin-server","structures-rcon")),l(n,48,0,u.ownersSorted)},null)}function m(l){return v._24(0,[(l()(),v._25(0,null,null,1,"arkmap-structures",[],null,null,null,f,O)),v._27(385024,null,0,w.a,[C.a,I.a,v.e],null,null)],function(l,n){l(n,1,0)},null)}var h=u("Dn8Y"),v=u("3j3K"),g=u("r8sF"),y=u("7T2B"),S=u("2Je8"),b=u("NVOs"),w=u("lCrv"),k=u("8zLQ"),C=u("ATz5"),I=u("lHWG");u.d(n,"b",function(){return O}),n.a=f;var x=[h.a],O=v._23({encapsulation:2,styles:x,data:{}});v._30("arkmap-structures",w.a,m,{structures:"structures",serverKey:"serverKey",mapName:"mapName"},{},[])},Dn8Y:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=['.map canvas,.map svg{position:absolute;top:0;left:0;width:100%}rect.overlay{fill:transparent}.wrapper{position:relative}.wrapper:after{padding-top:100%;display:block;content:""}.wrapper .buttons{position:absolute;left:5px;top:5px;opacity:.75;z-index:2}']},Fnlp:function(l,n,u){"use strict";var t=u("ATz5"),e=u("3MNG"),r=u("+Lwu");u.d(n,"a",function(){return i});var i=function(){function l(l,n,u){this.dataService=l,this.messageService=n,this.notificationsService=u,this.menuOption=void 0,this.demoMode=!1}return l.prototype.ngOnInit=function(){var l=this;this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.showServerUpdateNotification(n)}),this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n}),this.demoMode="true"==localStorage.getItem("demoMode")},l.prototype.ngOnDestroy=function(){this.serverUpdatedSubscription.unsubscribe(),this.menuOptionSubscription.unsubscribe()},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.prototype.toggleDemoMode=function(){var l="true"!=localStorage.getItem("demoMode");this.demoMode=l,localStorage.setItem("demoMode",l+"")},l.ctorParameters=function(){return[{type:t.a},{type:r.a},{type:e.a}]},l}()},FxpQ:function(l,n,u){"use strict";var t=u("ATz5"),e=u("3MNG"),r=u("+Lwu");u.d(n,"a",function(){return i});var i=function(){function l(l,n,u){this.dataService=l,this.messageService=n,this.notificationsService=u,this.menuOption=void 0}return l.prototype.ngOnInit=function(){var l=this;this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.showServerUpdateNotification(n)}),this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n})},l.prototype.ngOnDestroy=function(){this.serverUpdatedSubscription.unsubscribe(),this.menuOptionSubscription.unsubscribe()},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.ctorParameters=function(){return[{type:t.a},{type:r.a},{type:e.a}]},l}()},I9JA:function(l,n,u){"use strict";function t(l){return r._24(0,[r._35(201326592,1,{canvasRef:0}),(l()(),r._25(0,[[1,0],["myCanvas",1]],null,0,"canvas",[["style","width: 100%;"]],[[8,"width",0],[8,"height",0]],null,null,null,null))],null,function(l,n){var u=n.component;l(n,1,0,u.width,u.height)})}function e(l){return r._24(0,[(l()(),r._25(0,null,null,1,"arkmap",[],null,null,null,t,o)),r._27(286720,null,0,i.a,[],null,null)],null,null)}var r=u("3j3K"),i=u("5305");u.d(n,"b",function(){return o}),n.a=t;var a=[],o=r._23({encapsulation:2,styles:a,data:{}});r._30("arkmap",i.a,e,{mapName:"mapName",points:"points"},{},[])},Iksp:function(l,n,u){"use strict";var t=u("KZxv"),e=u("RiXa"),r=u("qn86"),i=u("JLFQ"),a=u("e/mT"),o=u("+w0e"),s=u("JKTH"),c=u("7xIs"),_=u("08Wm"),p=u("+qYp"),d=u("FxpQ"),f=u("Fnlp");u.d(n,"a",function(){return m});var m=(o.a,t.a,e.a,o.a,r.a,c.a,o.a,a.a,_.a,o.a,i.a,s.a,f.a,p.a,d.a,function(){function l(){}return l}())},J8nT:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=function(){function l(){}return l}()},JKTH:function(l,n,u){"use strict";var t=u("ATz5");u.d(n,"a",function(){return e});var e=function(){function l(l){this.dataService=l}return l.prototype.ngOnInit=function(){this.menu.activate("overview")},l.ctorParameters=function(){return[{type:t.a}]},l}()},JLFQ:function(l,n,u){"use strict";var t=u("ATz5"),e=u("3MNG"),r=u("+Lwu");u.d(n,"a",function(){return i});var i=function(){function l(l,n,u){this.dataService=l,this.messageService=n,this.notificationsService=u,this.menuOption=void 0,this.serverCount=0,this.onlinePlayerCount=0}return l.prototype.ngOnInit=function(){var l=this;this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.showServerUpdateNotification(n)}),this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n}),this.serversUpdatedSubscription=this.dataService.ServersUpdated$.subscribe(function(n){l.updateData(n)}),this.serverUpdateInterval=window.setInterval(function(){l.dataService.updateServer(null)},6e4),this.updateData(this.dataService.Servers)},l.prototype.ngOnDestroy=function(){this.serverUpdatedSubscription.unsubscribe(),this.menuOptionSubscription.unsubscribe(),this.serversUpdatedSubscription.unsubscribe(),window.clearInterval(this.serverUpdateInterval)},l.prototype.updateData=function(l){var n=0,u=0;if(l&&l.Servers){n=l.Servers.length;for(var t=0,e=l.Servers;t0?u[0]:null);var t=Object.keys(n.Clusters);l.clusterKey&&void 0!=t.find(function(n){return n==l.clusterKey})||(l.clusterKey=t.length>0?t[0]:null),l.player=n,l.filterAndSort(),l.sortCluster(),l.filterCluster(),l.loaded=!0,l.ref.detectChanges()}).catch(function(n){l.player=null,l.filteredCreatures=null,l.imprintCreatures=null,l.filteredClusterCreatures=null,l.loaded=!0})},l.prototype.ngOnInit=function(){var l=this;this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n}),this.steamId=this.route.snapshot.params.playerid,this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.updateServer(n)}),this.getPlayer()},l.prototype.ngOnDestroy=function(){this.menuOptionSubscription.unsubscribe(),this.serverUpdatedSubscription.unsubscribe()},l.prototype.haveMatingCooldown=function(l){return null!=l.NextMating&&new Date(l.NextMating)>new Date},l.prototype.active=function(l){return this.serverKey==l},l.prototype.activate=function(l){this.serverKey=l,this.filterAndSort()},l.prototype.serverWidth=function(){return 100/Object.keys(this.player.Servers).length},l.prototype.activeCluster=function(l){return this.clusterKey==l},l.prototype.activateCluster=function(l){this.clusterKey=l,this.sortCluster(),this.filterCluster()},l.prototype.clusterWidth=function(){return 100/Object.keys(this.player.Clusters).length},l.prototype.sort=function(){var l=this,n="-"!=this.creaturesSortField[0],u=this.creaturesSortFunctions[this.creaturesSortField.replace(/^\-/,"")],t=this.creaturesAltSortFields.split(",").map(function(n){var u={};return u.asc="-"!=n[0],u.sortFunc=l.creaturesSortFunctions[n.replace(/^\-/,"")],u});this.filteredCreatures.sort(function(l,e){var r=u(l,e,n);if(0==r)for(var i=0,a=t;i=0||null!=n.Name&&n.Name.toLowerCase().indexOf(l)>=0})}var n=this.player.Servers[this.serverKey].Creatures.filter(function(l){return null!=l.BabyAge});n.sort(function(l,n){return new Date(l.BabyNextCuddle)new Date(n.BabyNextCuddle)?1:0}),this.imprintCreatures=n;for(var u=[],t=0,e=this.filteredCreatures;tn.Level?-1:l.Level=0||null!=n.Name&&n.Name.toLowerCase().indexOf(l)>=0})}},l.prototype.run=function(){if(null==this.steamId||""==this.steamId)return this.player=null,this.filteredCreatures=null,void(this.imprintCreatures=null);this.getPlayer()},l.prototype.openMap=function(l){this.showMap=!0,l.stopPropagation()},l.prototype.closeMap=function(l){this.showMap=!1},l.prototype.updateServer=function(l){this.getPlayer(),this.showServerUpdateNotification(l)},l.prototype.haveCluster=function(){return null!=this.player&&Object.keys(this.player.Clusters).length>0},l.prototype.sumKibbleAndEggs=function(){return void 0!=this.player.Servers[this.serverKey].KibblesAndEggs?this.player.Servers[this.serverKey].KibblesAndEggs.reduce(function(l,n){return l+n.KibbleCount+n.EggCount},0):0},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.prototype.getStateForCreature=function(l){if(l){var n=this.creatureStates[l.Id1+"_"+l.Id2];return n||(n={imprintNotifications:!0},this.creatureStates[l.Id1+"_"+l.Id2]=n),n}},l.prototype.toggleImprintNotificationForCreature=function(l){var n=this.getStateForCreature(l);n.imprintNotifications=!n.imprintNotifications},l.prototype.activeCreaturesMode=function(l){return l==this.creaturesMode},l.prototype.activateCreaturesMode=function(l){this.creaturesMode=l},l.prototype.setCreaturesSort=function(l){var n=this.creaturesSortField==l;this.creaturesSortField=n?"-"+l:l,this.creaturesAltSortFields="latitude"==l?n?"-longitude,name":"longitude,name":"longitude"==l?n?"-latitude,name":"latitude,name":"name",this.sort()},l.prototype.copyCreature=function(l){},l.prototype.getCurrentServer=function(){var l=this;if(this.dataService&&this.dataService.Servers&&this.dataService.Servers.Servers){return this.dataService.Servers.Servers.find(function(n){return n.Key==l.serverKey})}},l.prototype.numCreatureTabs=function(){var l=1;return this.dataService.hasFeatureAccess("player","creatures-basestats",this.steamId)&&(l+=1),this.dataService.hasFeatureAccess("player","creatures-ids",this.steamId)&&(l+=1),l},l.ctorParameters=function(){return[{type:e.v},{type:e.g},{type:o.a},{type:i.a},{type:a.a},{type:r.a},{type:t.O}]},l}()},Layn:function(l,n,u){"use strict";function t(l){return s._24(0,[(l()(),s._25(0,null,null,0,"div",[["class","icon"]],[[8,"innerHTML",1]],null,null,null,null))],null,function(l,n){l(n,0,0,n.component.safeSvg)})}function e(l){return s._24(0,[(l()(),s._25(0,null,null,11,"div",[],null,null,null,null,null)),(l()(),s._26(null,["\n "])),(l()(),s._25(0,null,null,1,"div",[["class","sn-title"]],null,null,null,null,null)),(l()(),s._26(null,["",""])),(l()(),s._26(null,["\n "])),(l()(),s._25(0,null,null,2,"div",[["class","sn-content"]],null,null,null,null,null)),(l()(),s._26(null,["",""])),s._32(2),(l()(),s._26(null,["\n\n "])),(l()(),s._28(8388608,null,null,1,null,t)),s._27(8192,null,0,c.l,[s.S,s._5],{ngIf:[0,"ngIf"]},null),(l()(),s._26(null,["\n "]))],function(l,n){l(n,10,0,"bare"!==n.component.item.icon)},function(l,n){var u=n.component;l(n,3,0,u.item.title),l(n,6,0,s._33(n,6,0,l(n,7,0,s._29(n.parent,0),u.item.content,u.maxLength)))})}function r(l){return s._24(0,[(l()(),s._25(0,null,null,0,"div",[],[[8,"innerHTML",1]],null,null,null,null))],null,function(l,n){l(n,0,0,n.component.item.html)})}function i(l){return s._24(0,[(l()(),s._25(0,null,null,5,"div",[["class","sn-progress-loader"]],null,null,null,null,null)),(l()(),s._26(null,["\n "])),(l()(),s._25(0,null,null,2,"span",[],null,null,null,null,null)),s._27(139264,null,0,c.o,[s.w,s.K,s.J],{ngStyle:[0,"ngStyle"]},null),s._31(["width"]),(l()(),s._26(null,["\n "]))],function(l,n){l(n,3,0,l(n,4,0,n.component.progressWidth+"%"))},null)}function a(l){return s._24(0,[s._34(0,_.a,[]),(l()(),s._26(null,["\n "])),(l()(),s._25(0,null,null,12,"div",[["class","simple-notification"]],[[24,"@enterLeave",0]],[[null,"click"],[null,"mouseenter"],[null,"mouseleave"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.onClick(u)&&t}if("mouseenter"===n){t=!1!==e.onEnter()&&t}if("mouseleave"===n){t=!1!==e.onLeave()&&t}return t},null,null)),s._27(139264,null,0,c.m,[s.v,s.w,s.K,s.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s._31(["alert","error","warn","success","info","bare","rtl-mode"]),(l()(),s._26(null,["\n\n "])),(l()(),s._28(8388608,null,null,1,null,e)),s._27(8192,null,0,c.l,[s.S,s._5],{ngIf:[0,"ngIf"]},null),(l()(),s._26(null,["\n "])),(l()(),s._28(8388608,null,null,1,null,r)),s._27(8192,null,0,c.l,[s.S,s._5],{ngIf:[0,"ngIf"]},null),(l()(),s._26(null,["\n\n "])),(l()(),s._28(8388608,null,null,1,null,i)),s._27(8192,null,0,c.l,[s.S,s._5],{ngIf:[0,"ngIf"]},null),(l()(),s._26(null,["\n\n "])),(l()(),s._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,u.theClass,l(n,4,0,"alert"===u.item.type,"error"===u.item.type,"warn"===u.item.type,"success"===u.item.type,"info"===u.item.type,"bare"===u.item.type,u.rtl)),l(n,7,0,!u.item.html),l(n,10,0,u.item.html),l(n,13,0,u.showProgressBar)},function(l,n){l(n,2,0,n.component.item.state)})}function o(l){return s._24(0,[(l()(),s._25(0,null,null,1,"simple-notification",[],null,null,null,a,h)),s._27(122880,null,0,p.a,[d.a,f.q,s.e],null,null)],function(l,n){l(n,1,0)},null)}var s=u("3j3K"),c=u("2Je8"),_=u("g/xi"),p=u("Ev1B"),d=u("XLrO"),f=u("Qbdm");u.d(n,"b",function(){return h}),n.a=a;var m=["\n .simple-notification {\n width: 100%;\n padding: 10px 20px;\n box-sizing: border-box;\n position: relative;\n float: left;\n margin-bottom: 10px;\n color: #fff;\n cursor: pointer;\n transition: all 0.5s;\n }\n\n .simple-notification .sn-title {\n margin: 0;\n padding: 0 50px 0 0;\n line-height: 30px;\n font-size: 20px;\n }\n\n .simple-notification .sn-content {\n margin: 0;\n font-size: 16px;\n padding: 0 50px 0 0;\n line-height: 20px;\n }\n\n .simple-notification .icon {\n position: absolute;\n box-sizing: border-box;\n top: 0;\n right: 0;\n width: 70px;\n height: 70px;\n padding: 10px;\n }\n\n .simple-notification .icon svg {\n fill: #fff;\n width: 100%;\n height: 100%;\n }\n\n .simple-notification .icon svg g {\n fill: #fff;\n }\n\n .simple-notification.rtl-mode {\n direction: rtl;\n }\n\n .simple-notification.rtl-mode .sn-content {\n padding: 0 0 0 50px;\n }\n\n .simple-notification.rtl-mode svg {\n left: 0;\n right: auto;\n }\n\n .simple-notification.error { background: #F44336; }\n .simple-notification.success { background: #8BC34A; }\n .simple-notification.alert { background: #ffdb5b; }\n .simple-notification.info { background: #03A9F4; }\n .simple-notification.warn { background: #ffdb5b; }\n\n .simple-notification .sn-progress-loader {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 5px;\n }\n\n .simple-notification .sn-progress-loader span {\n float: left;\n height: 100%;\n }\n\n .simple-notification.success .sn-progress-loader span { background: #689F38; }\n .simple-notification.error .sn-progress-loader span { background: #D32F2F; }\n .simple-notification.alert .sn-progress-loader span { background: #edc242; }\n .simple-notification.info .sn-progress-loader span { background: #0288D1; }\n .simple-notification.warn .sn-progress-loader span { background: #edc242; }\n .simple-notification.bare .sn-progress-loader span { background: #ccc; }\n\n .simple-notification.warn div .sn-title { color: #444; }\n .simple-notification.warn div .sn-content { color: #444; }\n "],h=s._23({encapsulation:2,styles:m,data:{animation:[{name:"enterLeave",definitions:[{type:0,name:"fromRight",styles:{type:6,styles:{opacity:1,transform:"translateX(0)"}}},{type:1,expr:"* => fromRight",animation:[{type:6,styles:{opacity:0,transform:"translateX(5%)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"fromRightOut",styles:{type:6,styles:{opacity:0,transform:"translateX(-5%)"}}},{type:1,expr:"fromRight => fromRightOut",animation:[{type:6,styles:{opacity:1,transform:"translateX(0)"}},{type:4,styles:null,timings:"300ms ease-in-out"}]},{type:0,name:"fromLeft",styles:{type:6,styles:{opacity:1,transform:"translateX(0)"}}},{type:1,expr:"* => fromLeft",animation:[{type:6,styles:{opacity:0,transform:"translateX(-5%)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"fromLeftOut",styles:{type:6,styles:{opacity:0,transform:"translateX(5%)"}}},{type:1,expr:"fromLeft => fromLeftOut",animation:[{type:6,styles:{opacity:1,transform:"translateX(0)"}},{type:4,styles:null,timings:"300ms ease-in-out"}]},{type:0,name:"scale",styles:{type:6,styles:{opacity:1,transform:"scale(1)"}}},{type:1,expr:"* => scale",animation:[{type:6,styles:{opacity:0,transform:"scale(0)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"scaleOut",styles:{type:6,styles:{opacity:0,transform:"scale(0)"}}},{type:1,expr:"scale => scaleOut",animation:[{type:6,styles:{opacity:1,transform:"scale(1)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"rotate",styles:{type:6,styles:{opacity:1,transform:"rotate(0deg)"}}},{type:1,expr:"* => rotate",animation:[{type:6,styles:{opacity:0,transform:"rotate(5deg)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"rotateOut",styles:{type:6,styles:{opacity:0,transform:"rotate(-5deg)"}}},{type:1,expr:"rotate => rotateOut",animation:[{type:6,styles:{opacity:1,transform:"rotate(0deg)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]}]}]}});s._30("simple-notification",p.a,o,{timeOut:"timeOut",showProgressBar:"showProgressBar",pauseOnHover:"pauseOnHover",clickToClose:"clickToClose",maxLength:"maxLength",theClass:"theClass",rtl:"rtl",animate:"animate",position:"position",item:"item"},{},[])},Ni5f:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},OO5M:function(l,n,u){"use strict";function t(l){return i._24(0,[(l()(),i._25(0,null,null,10,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,7,"div",[["class","w3-panel w3-red"]],null,null,null,null,null)),(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),i._26(null,["Connection error"])),(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),i._26(null,["The application was unable to connect to the Web API. This could be due to a configuration error..."])),(l()(),i._26(null,["\n "])),(l()(),i._26(null,[" \n "]))],null,null)}function e(l){return i._24(0,[(l()(),i._25(0,null,null,1,"app-connection-error",[],null,null,null,t,p)),i._27(122880,null,0,a.a,[o.a,s.a,c.a],null,null)],function(l,n){l(n,1,0)},null)}var r=u("UYln"),i=u("3j3K"),a=u("FxpQ"),o=u("ATz5"),s=u("+Lwu"),c=u("XLrO");u.d(n,"a",function(){return d});var _=[r.a],p=i._23({encapsulation:0,styles:_,data:{}}),d=i._30("app-connection-error",a.a,e,{},{},[])},RWZN:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},RdYi:function(l,n,u){"use strict";function t(l){return o._24(0,[(l()(),o._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),o._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component._str)})}function e(l){return o._24(0,[(l()(),o._25(0,null,null,3,"button",[["class","w3-button w3-small"],["style","padding: 4px 8px;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.state._completed=!e.state._completed)&&t}return t},null,null)),o._27(139264,null,0,s.m,[o.v,o.w,o.K,o.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),o._31(["theme-d1","theme-l2","theme-hover"]),(l()(),o._26(null,["",""]))],function(l,n){var u=n.component;l(n,1,0,"w3-button w3-small",l(n,2,0,u.state._completed,!u.state._completed&&u._ready,!u.state._completed&&u._ready))},function(l,n){l(n,3,0,n.component.state._completed?"Completed":"Ready")})}function r(l){return o._24(0,[(l()(),o._28(8388608,null,null,1,null,t)),o._27(8192,null,0,s.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null),(l()(),o._28(8388608,null,null,1,null,e)),o._27(8192,null,0,s.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,1,0,!u._ready),l(n,3,0,u._ready)},null)}function i(l){return o._24(0,[(l()(),o._25(0,null,null,1,"timer",[],null,null,null,r,p)),o._27(122880,null,0,c.a,[],null,null)],function(l,n){l(n,1,0)},null)}var a=u("SWNH"),o=u("3j3K"),s=u("2Je8"),c=u("CzL3");u.d(n,"b",function(){return p}),n.a=r;var _=[a.a],p=o._23({encapsulation:0,styles:_,data:{}});o._30("timer",c.a,i,{state:"state",time:"time",notification:"notification"},{},[])},RiXa:function(l,n,u){"use strict";var t=u("5oXY"),e=u("ATz5");u.d(n,"a",function(){return r});var r=function(){function l(l,n){this.route=l,this.dataService=n}return l.prototype.ngOnInit=function(){this.steamId=this.route.snapshot.params.playerid,this.dataService.hasFeatureAccess("player","profile",this.steamId)?this.menu.activate("profile"):this.dataService.hasFeatureAccess("player","creatures",this.steamId)?this.menu.activate("creatures"):this.dataService.hasFeatureAccess("player","creatures-cloud",this.steamId)?this.menu.activate("creatures_cloud"):this.dataService.hasFeatureAccess("player","breeding",this.steamId)?this.menu.activate("breeding"):this.dataService.hasFeatureAccess("player","crops",this.steamId)?this.menu.activate("crop_plots"):this.dataService.hasFeatureAccess("player","generators",this.steamId)?this.menu.activate("electrical_generators"):this.dataService.hasFeatureAccess("player","kibbles-eggs",this.steamId)?this.menu.activate("kibbles_and_eggs"):this.dataService.hasFeatureAccess("player","tribelog",this.steamId)&&this.menu.activate("tribelog")},l.ctorParameters=function(){return[{type:t.v},{type:e.a}]},l}()},SQlA:function(l,n,u){"use strict";function t(l){return a._24(0,[(l()(),a._25(0,null,null,1,"i",[["class","material-icons"],["style","margin: -5px 5px -5px -5px; vertical-align: middle;"]],null,null,null,null,null)),(l()(),a._26(null,["check"]))],null,null)}function e(l){return a._24(0,[(l()(),a._25(0,null,null,8,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),a._26(null,["\n "])),(l()(),a._25(0,null,null,5,"button",[["class","w3-button"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.toggleDemoMode()&&t}return t},null,null)),a._27(139264,null,0,s.m,[a.v,a.w,a.K,a.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),a._31(["theme-d1","theme-l2","theme-hover"]),(l()(),a._28(8388608,null,null,1,null,t)),a._27(8192,null,0,s.l,[a.S,a._5],{ngIf:[0,"ngIf"]},null),(l()(),a._26(null,["",""])),(l()(),a._26(null,["\n"]))],function(l,n){var u=n.component;l(n,3,0,"w3-button",l(n,4,0,u.demoMode,!u.demoMode,!u.demoMode)),l(n,6,0,u.demoMode)},function(l,n){l(n,7,0,n.component.demoMode?"Demo Mode Enabled":"Enable Demo Mode")})}function r(l){return a._24(0,[(l()(),a._25(0,null,null,1,"app-developer",[],null,null,null,e,f)),a._27(122880,null,0,o.a,[c.a,_.a,p.a],null,null)],function(l,n){l(n,1,0)},null)}var i=u("7MbP"),a=u("3j3K"),o=u("Fnlp"),s=u("2Je8"),c=u("ATz5"),_=u("+Lwu"),p=u("XLrO");u.d(n,"a",function(){return m});var d=[i.a],f=a._23({encapsulation:0,styles:d,data:{}}),m=a._30("app-developer",o.a,r,{},{},[])},SWNH:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},SWoV:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},UYln:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},XhEa:function(l,n,u){"use strict";function t(l){return i._24(0,[(l()(),i._25(0,null,null,2,"simple-notification",[],null,null,null,a.a,a.b)),i._27(122880,null,0,o.a,[s.a,c.q,i.e],{timeOut:[0,"timeOut"],showProgressBar:[1,"showProgressBar"],pauseOnHover:[2,"pauseOnHover"],clickToClose:[3,"clickToClose"],maxLength:[4,"maxLength"],theClass:[5,"theClass"],rtl:[6,"rtl"],animate:[7,"animate"],position:[8,"position"],item:[9,"item"]},null),(l()(),i._26(null,["\n "]))],function(l,n){var u=n.component;l(n,1,0,u.timeOut,u.showProgressBar,u.pauseOnHover,u.clickToClose,u.maxLength,u.theClass,u.rtl,u.animate,n.context.index,n.context.$implicit)},null)}function e(l){return i._24(0,[(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,5,"div",[["class","simple-notification-wrapper"]],null,null,null,null,null)),i._27(139264,null,0,_.m,[i.v,i.w,i.K,i.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(l()(),i._26(null,["\n "])),(l()(),i._28(8388608,null,null,1,null,t)),i._27(401408,null,0,_.n,[i.S,i._5,i.v],{ngForOf:[0,"ngForOf"]},null),(l()(),i._26(null,["\n "])),(l()(),i._26(null,["\n "]))],function(l,n){var u=n.component;l(n,2,0,"simple-notification-wrapper",u.position),l(n,5,0,u.notifications)},null)}function r(l){return i._24(0,[(l()(),i._25(0,null,null,1,"simple-notifications",[],null,null,null,e,f)),i._27(122880,null,0,p.a,[s.a],null,null)],function(l,n){l(n,1,0)},null)}var i=u("3j3K"),a=u("Layn"),o=u("Ev1B"),s=u("XLrO"),c=u("Qbdm"),_=u("2Je8"),p=u("B8cY");u.d(n,"b",function(){return f}),n.a=e;var d=["\n .simple-notification-wrapper {\n position: fixed;\n width: 300px;\n z-index: 1000;\n }\n \n .simple-notification-wrapper.left { left: 20px; }\n .simple-notification-wrapper.top { top: 20px; }\n .simple-notification-wrapper.right { right: 20px; }\n .simple-notification-wrapper.bottom { bottom: 20px; }\n \n @media (max-width: 340px) {\n .simple-notification-wrapper {\n width: auto;\n left: 20px;\n right: 20px;\n }\n }\n "],f=i._23({encapsulation:2,styles:d,data:{}});i._30("simple-notifications",p.a,r,{options:"options"},{onCreate:"onCreate",onDestroy:"onDestroy"},[])},YWx4:function(l,n,u){"use strict";var t=u("5oXY"),e=u("3MNG"),r=u("hHgl"),i=u("ATz5"),a=u("lHWG"),o=u("kZql");u.d(n,"a",function(){return s});var s=function(){function l(l,n,u,t,e){this.dataService=l,this.httpService=n,this.breadcrumbService=u,this.notificationsService=t,this.router=e,this.notificationOptions={position:["top","right"],timeOut:1e3,lastOnBottom:!1},this.showLogin=!1,this.currentUrl="/",this.serversUpdatedBefore=!1,this.loading=!0,u.addFriendlyNameForRoute("/accessdenied","Access Denied"),u.addFriendlyNameForRoute("/connectionerror","Connection error"),u.hideRoute("/player"),u.hideRoute("/servers"),u.hideRoute("/server"),u.hideRoute("/admin"),u.addCallbackForRouteRegex("^/player/.+$",this.getNameForPlayer)}return l.prototype.ngOnInit=function(){var l=this;this.routerEventsSubscription=this.router.events.subscribe(function(n){l.navigationInterceptor(n)}),this.currentUrl=window.location.href||"/",this.serversUpdatedSubscription=this.dataService.ServersUpdated$.subscribe(function(n){l.serversUpdatedBefore||!n||n.User&&n.User.SteamId||(l.showLogin=!0),l.serversUpdatedBefore=!0})},l.prototype.ngOnDestroy=function(){this.routerEventsSubscription.unsubscribe(),this.serversUpdatedSubscription.unsubscribe()},l.prototype.navigationInterceptor=function(l){l instanceof t.A?this.loading=!0:l instanceof t.y?this.loading=!1:l instanceof t.B?this.loading=!1:l instanceof t.C&&(this.loading=!1)},l.prototype.getNameForPlayer=function(l){return"Player"},l.prototype.getTheme=function(){return localStorage.getItem("theme")||"light"},l.prototype.setTheme=function(l){return localStorage.setItem("theme",l),!1},l.prototype.openLogin=function(l){this.showLogin=!0,l.stopPropagation(),l.preventDefault()},l.prototype.closeLogin=function(l){this.showLogin=!1},l.prototype.getLoginUrl=function(){return this.httpService.getApiBaseUrl()+"/authentication/login"},l.prototype.getLogoutUrl=function(){return o.a.demo?"":this.httpService.getApiBaseUrl()+"/authentication/logout?returnUrl="+this.currentUrl},l.ctorParameters=function(){return[{type:i.a},{type:a.a},{type:r.a},{type:e.a},{type:t.g}]},l}()},ZfYc:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},beiT:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=["tr th.orderBy{cursor:pointer}a.w3-button.disabled{color:#a9a9a9}a.w3-button.disabled:hover{color:#a9a9a9!important;background-color:transparent!important;opacity:1!important;cursor:default}"]},coiB:function(l,n,u){"use strict";function t(l){return i._24(0,[(l()(),i._25(0,null,null,11,"div",[["class","w3-sidebar theme-l2"],["id","menu"],["style","min-height: 52px;"]],null,null,null,null,null)),(l()(),i._26(null,[" \n "])),(l()(),i._25(0,null,null,1,"button",[["class","w3-button w3-xlarge w3-display-topright"],["id","menubtn"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.toggleMenu()&&t}return t},null,null)),(l()(),i._26(null,["☰"])),(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,5,"section",[["class","w3-container"],["id","menucontent"]],null,null,null,null,null)),i._27(139264,null,0,o.m,[i.v,i.w,i.K,i.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),i._31(["hide"]),(l()(),i._26(null,["\n "])),i._36(null,0),(l()(),i._26(null,["\n "])),(l()(),i._26(null,["\n"]))],function(l,n){l(n,6,0,"w3-container",l(n,7,0,!n.component.menuVisible))},null)}function e(l){return i._24(0,[(l()(),i._25(0,null,null,1,"app-menu",[],null,null,null,t,_)),i._27(122880,null,0,a.a,[s.a],null,null)],function(l,n){l(n,1,0)},null)}var r=u("+SUW"),i=u("3j3K"),a=u("8kYA"),o=u("2Je8"),s=u("ATz5");u.d(n,"b",function(){return _}),n.a=t;var c=[r.a],_=i._23({encapsulation:0,styles:c,data:{}});i._30("app-menu",a.a,e,{},{},["*"])},"e/mT":function(l,n,u){"use strict";var t=u("5oXY"),e=u("3MNG"),r=u("ATz5"),i=u("+Lwu"),a=u("lHWG");u.d(n,"a",function(){return o});var o=function(){function l(l,n,u,t,e,r){this.route=l,this.router=n,this.httpService=u,this.dataService=t,this.messageService=e,this.notificationsService=r,this.menuOption=void 0,this.loaded=!1,this.loadedStructures=!1}return l.prototype.getServer=function(){var l=this;this.httpService.getAdminServer(this.serverKey).then(function(n){l.server=n,l.loaded=!0}).catch(function(n){l.server=null,l.loaded=!0})},l.prototype.getStructures=function(){var l=this;this.httpService.getStructures(this.serverKey).then(function(n){l.structures=n,l.loadedStructures=!0}).catch(function(n){l.structures=void 0,l.loadedStructures=!0})},l.prototype.ngOnInit=function(){var l=this;this.serverKey=this.route.snapshot.params.id,this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){l.menuOption=n,"structures"==l.menuOption&&l.getStructures()}),this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){l.serverKey==n&&(l.updateServer(),l.showServerUpdateNotification(n))}),this.getServer()},l.prototype.ngOnDestroy=function(){this.menuOptionSubscription.unsubscribe(),this.serverUpdatedSubscription.unsubscribe()},l.prototype.getTribeMember=function(l){return this.server.Players.find(function(n){return n.SteamId==l})},l.prototype.updateServer=function(){this.getServer()},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.ctorParameters=function(){return[{type:t.v},{type:t.g},{type:a.a},{type:r.a},{type:i.a},{type:e.a}]},l}()},fYAd:function(l,n,u){"use strict";function t(l){return y._24(0,[(l()(),y._25(0,null,null,4,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCurrentMode(l.parent.context.$implicit.key)&&t}return t},null,null)),y._27(139264,null,0,S.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["theme-d1"]),y._34(65536,S.q,[y.O]),(l()(),y._26(null,["",""]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.isCurrentMode(n.parent.context.$implicit.key)))},function(l,n){var u=n.component;l(n,0,0,100/y._33(n,0,0,y._29(n,3).transform(u.numEnabledModes))),l(n,4,0,n.parent.context.$implicit.name)})}function e(l){return y._24(0,[(l()(),y._25(0,null,null,5,null,null,null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,2,null,t)),y._27(8192,null,0,S.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),y._34(65536,S.q,[y.O]),(l()(),y._26(null,["\n "]))],function(l,n){l(n,3,0,y._33(n,3,0,y._29(n,4).transform(n.context.$implicit.enabled)))},null)}function r(l){return y._24(0,[(l()(),y._25(0,null,null,4,"div",[["class","w3-bar theme-l2 w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,e)),y._27(401408,null,0,S.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(l()(),y._26(null,["\n"]))],function(l,n){var u=n.component;l(n,3,0,u._modes,u.trackByKey)},null)}function i(l){return y._24(0,[(l()(),y._26(null,["\n "]))],null,null)}function a(l){return y._24(0,[(l()(),y._28(8388608,null,null,1,null,i)),y._27(270336,null,0,S.s,[y.S],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(l()(),y._28(0,null,null,0))],function(l,n){l(n,1,0,n.parent.parent.context.$implicit.headerTemplate)},null)}function o(l){return y._24(0,[(l()(),y._25(0,null,null,6,"th",[],[[8,"title",0]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.orderBy(l.parent.context.$implicit.key,u)&&t}return t},null,null)),y._27(139264,null,0,S.m,[y.v,y.w,y.K,y.J],{ngClass:[0,"ngClass"]},null),y._31(["orderBy"]),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,a)),y._27(8192,null,0,S.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),(l()(),y._26(null,["\n "]))],function(l,n){l(n,1,0,l(n,2,0,n.parent.context.$implicit.orderBy)),l(n,5,0,n.parent.context.$implicit.headerTemplate)},function(l,n){l(n,0,0,y._38(1,"",n.parent.context.$implicit.title,""))})}function s(l){return y._24(0,[(l()(),y._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,o)),y._27(8192,null,0,S.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),(l()(),y._26(null,["\n "]))],function(l,n){l(n,3,0,n.component.showColumn(n.context.$implicit.key))},null)}function c(l){return y._24(0,[(l()(),y._26(null,["\n "]))],null,null)}function _(l){return y._24(0,[(l()(),y._28(8388608,null,null,2,null,c)),y._27(270336,null,0,S.s,[y.S],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),y._31(["$implicit"]),(l()(),y._28(0,null,null,0))],function(l,n){l(n,1,0,l(n,2,0,n.parent.parent.parent.context.$implicit),n.parent.parent.context.$implicit.cellTemplate)},null)}function p(l){return y._24(0,[(l()(),y._25(0,null,null,4,"td",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,_)),y._27(8192,null,0,S.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),(l()(),y._26(null,["\n "]))],function(l,n){l(n,3,0,n.parent.context.$implicit.cellTemplate)},null)}function d(l){return y._24(0,[(l()(),y._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,p)),y._27(8192,null,0,S.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),(l()(),y._26(null,["\n "]))],function(l,n){l(n,3,0,n.component.showColumn(n.context.$implicit.key))},null)}function f(l){return y._24(0,[(l()(),y._25(0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,d)),y._27(401408,null,0,S.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(l()(),y._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,u._columnTemplates,u.trackByKey)},null)}function m(l){return y._24(0,[(l()(),y._25(0,null,null,3,"option",[],null,null,null,null,null)),y._27(73728,null,0,b.k,[y.K,y.J,[2,b.l]],{value:[0,"value"]},null),y._27(73728,null,0,b.m,[y.K,y.J,[8,null]],{value:[0,"value"]},null),(l()(),y._26(null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit.value),l(n,2,0,n.context.$implicit.value)},function(l,n){l(n,3,0,n.context.$implicit.text)})}function h(l){return y._24(2,[(l()(),y._28(8388608,null,null,2,null,r)),y._27(8192,null,0,S.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),y._34(65536,S.q,[y.O]),(l()(),y._26(null,["\n"])),(l()(),y._25(0,null,null,21,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,18,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,7,"thead",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,4,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,s)),y._27(401408,null,0,S.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,6,"tbody",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,3,null,f)),y._27(401408,null,0,S.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),y._34(65536,S.q,[y.O]),y._34(0,S.t,[]),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n"])),(l()(),y._26(null,["\n"])),(l()(),y._25(0,null,null,59,"div",[["class","w3-cell-row w3-margin-top"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,56,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,53,"table",[["class","w3-responsive w3-right w3-small"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,51,"tbody",[],null,null,null,null,null)),(l()(),y._25(0,null,null,49,"tr",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,32,"td",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,29,"div",[["class","w3-bar w3-border border-theme"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button w3-border-right border-theme"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setFirstPage()&&t}return t},null,null)),y._27(139264,null,0,S.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["«"])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button device-tiny-show"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setPrevPage()&&t}return t},null,null)),y._27(139264,null,0,S.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["❮"])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button w3-border-right border-theme device-tiny-hide"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setPrevPage()&&t}return t},null,null)),y._27(139264,null,0,S.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["❮"])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,1,"span",[["class","device-tiny-hide"]],null,null,null,null,null)),(l()(),y._26(null,[" "," - "," of "," "])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button w3-border-left border-theme w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setLastPage()&&t}return t},null,null)),y._27(139264,null,0,S.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["»"])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button w3-border-left border-theme w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setNextPage()&&t}return t},null,null)),y._27(139264,null,0,S.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["❯"])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,12,"td",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,9,"select",[["class","w3-select w3-border border-theme theme-l1"],["style","max-width: 200px; padding: 12px 5px;"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"blur"]],function(l,n,u){var t=!0,e=l.component;if("change"===n){t=!1!==y._29(l,73).onChange(u.target.value)&&t}if("blur"===n){t=!1!==y._29(l,73).onTouched()&&t}if("ngModelChange"===n){t=!1!==e.setViewLimit(u)&&t}return t},null,null)),y._27(8192,null,0,b.l,[y.J,y.K],null,null),y._37(512,null,b.g,function(l){return[l]},[b.l]),y._27(335872,null,0,b.h,[[8,null],[8,null],[8,null],[2,b.g]],{model:[0,"model"]},{update:"ngModelChange"}),y._37(1024,null,b.i,null,[b.h]),y._27(8192,null,0,b.j,[b.i],null,null),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,m)),y._27(401408,null,0,S.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"]},null),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n"]))],function(l,n){var u=n.component;l(n,1,0,y._33(n,1,0,y._29(n,2).transform(u.numEnabledModes))>1),l(n,13,0,u._columnTemplates,u.trackByKey),l(n,20,0,y._33(n,20,0,y._29(n,22).transform(y._33(n,20,0,y._29(n,21).transform(u._rows$)),u._fromRow,u._fromRow+u._numRows)),u.trackByRow),l(n,41,0,"w3-button w3-border-right border-theme",l(n,42,0,u.isFirstPage())),l(n,46,0,"w3-button device-tiny-show",l(n,47,0,u.isFirstPage())),l(n,51,0,"w3-button w3-border-right border-theme device-tiny-hide",l(n,52,0,u.isFirstPage())),l(n,59,0,"w3-button w3-border-left border-theme w3-right",l(n,60,0,u.isLastPage())),l(n,64,0,"w3-button w3-border-left border-theme w3-right",l(n,65,0,u.isLastPage())),l(n,75,0,u._numRows),l(n,80,0,u._viewOptions)},function(l,n){var u=n.component;l(n,56,0,u._fromRow,u.getLastRowOffset(),u._rows.length),l(n,72,0,y._29(n,77).ngClassUntouched,y._29(n,77).ngClassTouched,y._29(n,77).ngClassPristine,y._29(n,77).ngClassDirty,y._29(n,77).ngClassValid,y._29(n,77).ngClassInvalid,y._29(n,77).ngClassPending)})}function v(l){return y._24(0,[(l()(),y._25(0,null,null,3,"ark-data-table",[],null,null,null,h,C)),y._27(57344,null,2,w.a,[y.O],null,null),y._35(301989888,1,{modeTemplates:1}),y._35(301989888,2,{columnTemplates:1})],function(l,n){l(n,1,0)},null)}var g=u("beiT"),y=u("3j3K"),S=u("2Je8"),b=u("NVOs"),w=u("0jRk");u.d(n,"b",function(){return C}),n.a=h;var k=[g.a],C=y._23({encapsulation:2,styles:k,data:{}});y._30("ark-data-table",w.a,v,{rows:"rows",trackByProp:"trackByProp",sortFunctions:"sortFunctions",orderByColumn:"orderByColumn"},{},[])},h5ac:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},if6N:function(l,n,u){"use strict";function t(l){return c._24(0,[(l()(),c._25(0,null,null,1,"a",[["role","button"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.navigateTo("/")&&t}return t},null,null)),(l()(),c._26(null,["",""]))],null,function(l,n){l(n,1,0,n.parent.context.$implicit)})}function e(l){return c._24(0,[(l()(),c._25(0,null,null,1,"a",[["role","button"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.navigateTo(l.parent.context.$implicit)&&t}return t},null,null)),(l()(),c._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component.friendlyName(n.parent.context.$implicit))})}function r(l){return c._24(0,[(l()(),c._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),c._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component.friendlyName(n.parent.context.$implicit))})}function i(l){return c._24(0,[(l()(),c._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),c._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component.friendlyName("/"))})}function a(l){return c._24(0,[(l()(),c._25(0,null,null,16,"li",[],null,null,null,null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{ngClass:[0,"ngClass"]},null),c._31(["breadcrumb-item","active"]),(l()(),c._26(null,[" "])),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,t)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,e)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,r)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,i)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "]))],function(l,n){var u=n.component;l(n,1,0,l(n,2,0,u.useBootstrap,n.context.last)),l(n,6,0,!n.context.last&&n.context.$implicit==u.prefix),l(n,9,0,!n.context.last&&n.context.$implicit!=u.prefix),l(n,12,0,n.context.last),l(n,15,0,n.context.last&&n.context.$implicit==u.prefix)},null)}function o(l){return c._24(0,[(l()(),c._26(null,["\n "])),(l()(),c._25(0,null,null,4,"ul",[],[[2,"breadcrumb",null]],null,null,null,null)),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,a)),c._27(401408,null,0,_.n,[c.S,c._5,c.v],{ngForOf:[0,"ngForOf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._26(null,["\n "]))],function(l,n){l(n,4,0,n.component._urls)},function(l,n){l(n,1,0,n.component.useBootstrap)})}function s(l){return c._24(0,[(l()(),c._25(0,null,null,1,"breadcrumb",[],null,null,null,o,h)),c._27(385024,null,0,p.a,[d.g,f.a],null,null)],function(l,n){l(n,1,0)},null)}var c=u("3j3K"),_=u("2Je8"),p=u("v8ur"),d=u("5oXY"),f=u("aT6V");u.d(n,"b",function(){return h}),n.a=o;var m=[],h=c._23({encapsulation:2,styles:m,data:{}});c._30("breadcrumb",p.a,s,{useBootstrap:"useBootstrap",prefix:"prefix"},{},[])},jWPz:function(l,n,u){"use strict";var t=u("3j3K");u.d(n,"c",function(){return e}),u.d(n,"b",function(){return r}),u.d(n,"a",function(){return i});var e=function(){function l(l){this.template=l}return l.ctorParameters=function(){return[{type:t._5}]},l}(),r=function(){function l(l){this.template=l}return l.ctorParameters=function(){return[{type:t._5}]},l}(),i=function(){function l(){}return l}()},joX7:function(l,n,u){"use strict";var t=u("Gvdl");u.n(t);u.d(n,"a",function(){return e});var e=function(){function l(){this.enabled=t.Observable.of(!0)}return Object.defineProperty(l.prototype,"columnKeys",{set:function(l){this._columnKeys=l,this.ColumnKeys=this._columnKeys.split(",")},enumerable:!0,configurable:!0}),l}()},jxRA:function(l,n,u){"use strict";function t(l){return o._24(0,[(l()(),o._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==o._29(l.parent.parent,2).activate(l.context.$implicit.Key)&&t}return t},null,null)),o._27(139264,null,0,s.m,[o.v,o.w,o.K,o.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),o._31(["theme-d1"]),(l()(),o._26(null,["",""]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,o._29(n.parent.parent,2).active(n.context.$implicit.Key)))},function(l,n){l(n,3,0,n.context.$implicit.Key)})}function e(l){return o._24(0,[(l()(),o._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._28(8388608,null,null,1,null,t)),o._27(401408,null,0,s.n,[o.S,o._5,o.v],{ngForOf:[0,"ngForOf"]},null),(l()(),o._26(null,["\n "]))],function(l,n){l(n,3,0,n.component.dataService.Servers.Servers)},null)}function r(l){return o._24(0,[o._35(201326592,1,{menu:0}),(l()(),o._25(0,null,null,16,"app-menu",[],null,null,null,c.a,c.b)),o._27(122880,[[1,4],["menu",4]],0,_.a,[p.a],null,null),(l()(),o._26(0,["\n "])),(l()(),o._25(0,null,0,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),o._26(null,["Servers"])),(l()(),o._26(0,["\n "])),(l()(),o._25(0,null,0,9,"div",[["class","w3-cell-row theme-l2"]],null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==o._29(l,2).activate("overview")&&t}return t},null,null)),o._27(139264,null,0,s.m,[o.v,o.w,o.K,o.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),o._31(["theme-d1"]),(l()(),o._26(null,["Overview"])),(l()(),o._26(null,["\n "])),(l()(),o._28(8388608,null,null,1,null,e)),o._27(8192,null,0,s.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null),(l()(),o._26(null,["\n "])),(l()(),o._26(0,["\n"]))],function(l,n){var u=n.component;l(n,2,0),l(n,10,0,"w3-button w3-cell w3-mobile",l(n,11,0,o._29(n,2).active("overview"))),l(n,15,0,void 0!=u.dataService.Servers&&u.dataService.hasFeatureAccess("home","serverdetails"))},null)}function i(l){return o._24(0,[(l()(),o._25(0,null,null,1,"app-server-list-menu",[],[[8,"className",0]],null,null,r,m)),o._27(57344,null,0,d.a,[p.a],null,null)],function(l,n){l(n,1,0)},function(l,n){l(n,0,0,o._29(n,1).menu.className)})}var a=u("mjI6"),o=u("3j3K"),s=u("2Je8"),c=u("coiB"),_=u("8kYA"),p=u("ATz5"),d=u("JKTH");u.d(n,"a",function(){return h});var f=[a.a],m=o._23({encapsulation:0,styles:f,data:{}}),h=o._30("app-server-list-menu",d.a,i,{},{},[])},kZql:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t={production:!0,demo:!1,demoDate:null,apiBaseUrl:"//:60001/api",signalrBaseUrl:"//:60001/signalr"}},kke6:function(l,n,u){"use strict";var t=u("3j3K"),e=u("Iksp"),r=u("5oXY"),i=u("2Je8"),a=u("ktkS"),o=u("Qbdm"),s=u("NVOs"),c=u("Fzro"),_=u("KN8t"),p=u("zsCj"),d=u("J8nT"),f=u("aT6V"),m=u("XLrO"),h=u("lHWG"),v=u("+Lwu"),g=u("ATz5"),y=u("AcJ7"),S=u("+w0e"),b=u("nuuw"),w=u("ofcV"),k=u("+T68"),C=u("1AkI"),I=u("+KJ1"),x=u("0VGx"),O=u("nMh6"),A=u("jxRA"),T=u("SQlA"),F=u("0ME9"),M=u("OO5M"),L=u("1A80"),P=u("KZxv"),N=u("RiXa"),B=u("qn86"),K=u("7xIs"),j=u("e/mT"),$=u("08Wm"),R=u("JLFQ"),D=u("JKTH"),E=u("Fnlp"),U=u("+qYp"),z=u("FxpQ"),J=u("1GJ2");u.d(n,"a",function(){return X});var G=this&&this.__extends||function(){var l=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(l,n){l.__proto__=n}||function(l,n){for(var u in n)n.hasOwnProperty(u)&&(l[u]=n[u])};return function(n,u){function t(){this.constructor=n}l(n,u),n.prototype=null===u?Object.create(u):(t.prototype=u.prototype,new t)}}(),H=function(l){function n(n){return l.call(this,n,[b.a,w.a,k.a,C.a,I.a,x.a,O.a,A.a,T.a,F.a,M.a,L.a],[L.a])||this}return G(n,l),Object.defineProperty(n.prototype,"_LOCALE_ID_29",{get:function(){return null==this.__LOCALE_ID_29&&(this.__LOCALE_ID_29="en-US"),this.__LOCALE_ID_29},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_NgLocalization_30",{get:function(){return null==this.__NgLocalization_30&&(this.__NgLocalization_30=new i.a(this._LOCALE_ID_29)),this.__NgLocalization_30},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_APP_ID_31",{get:function(){return null==this.__APP_ID_31&&(this.__APP_ID_31=t.b()),this.__APP_ID_31},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_IterableDiffers_32",{get:function(){return null==this.__IterableDiffers_32&&(this.__IterableDiffers_32=t.c()),this.__IterableDiffers_32},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_KeyValueDiffers_33",{get:function(){return null==this.__KeyValueDiffers_33&&(this.__KeyValueDiffers_33=t.d()),this.__KeyValueDiffers_33},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_DomSanitizer_34",{get:function(){return null==this.__DomSanitizer_34&&(this.__DomSanitizer_34=new o.b(this.parent.get(o.c))),this.__DomSanitizer_34},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Sanitizer_35",{get:function(){return null==this.__Sanitizer_35&&(this.__Sanitizer_35=this._DomSanitizer_34),this.__Sanitizer_35},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_HAMMER_GESTURE_CONFIG_36",{get:function(){return null==this.__HAMMER_GESTURE_CONFIG_36&&(this.__HAMMER_GESTURE_CONFIG_36=new o.d),this.__HAMMER_GESTURE_CONFIG_36},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_EVENT_MANAGER_PLUGINS_37",{get:function(){return null==this.__EVENT_MANAGER_PLUGINS_37&&(this.__EVENT_MANAGER_PLUGINS_37=[new o.e(this.parent.get(o.c)),new o.f(this.parent.get(o.c)),new o.g(this.parent.get(o.c),this._HAMMER_GESTURE_CONFIG_36)]),this.__EVENT_MANAGER_PLUGINS_37},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_EventManager_38",{get:function(){return null==this.__EventManager_38&&(this.__EventManager_38=new o.h(this._EVENT_MANAGER_PLUGINS_37,this.parent.get(t.e))),this.__EventManager_38},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵDomSharedStylesHost_39",{get:function(){return null==this.__ɵDomSharedStylesHost_39&&(this.__ɵDomSharedStylesHost_39=new o.i(this.parent.get(o.c))),this.__ɵDomSharedStylesHost_39},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵDomRendererFactory2_40",{get:function(){return null==this.__ɵDomRendererFactory2_40&&(this.__ɵDomRendererFactory2_40=new o.j(this._EventManager_38,this._ɵDomSharedStylesHost_39)),this.__ɵDomRendererFactory2_40},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_AnimationDriver_41",{get:function(){return null==this.__AnimationDriver_41&&(this.__AnimationDriver_41=_.a()),this.__AnimationDriver_41},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵAnimationStyleNormalizer_42",{get:function(){return null==this.__ɵAnimationStyleNormalizer_42&&(this.__ɵAnimationStyleNormalizer_42=_.b()),this.__ɵAnimationStyleNormalizer_42},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵAnimationEngine_43",{get:function(){return null==this.__ɵAnimationEngine_43&&(this.__ɵAnimationEngine_43=new _.c(this._AnimationDriver_41,this._ɵAnimationStyleNormalizer_42)),this.__ɵAnimationEngine_43},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_RendererFactory2_44",{get:function(){return null==this.__RendererFactory2_44&&(this.__RendererFactory2_44=_.d(this._ɵDomRendererFactory2_40,this._ɵAnimationEngine_43,this.parent.get(t.e))),this.__RendererFactory2_44},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵSharedStylesHost_45",{get:function(){return null==this.__ɵSharedStylesHost_45&&(this.__ɵSharedStylesHost_45=this._ɵDomSharedStylesHost_39),this.__ɵSharedStylesHost_45},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Testability_46",{get:function(){return null==this.__Testability_46&&(this.__Testability_46=new t.f(this.parent.get(t.e))),this.__Testability_46},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Meta_47",{get:function(){return null==this.__Meta_47&&(this.__Meta_47=new o.k(this.parent.get(o.c))),this.__Meta_47},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Title_48",{get:function(){return null==this.__Title_48&&(this.__Title_48=new o.l(this.parent.get(o.c))),this.__Title_48},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵi_49",{get:function(){return null==this.__ɵi_49&&(this.__ɵi_49=new s.a),this.__ɵi_49},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_BrowserXhr_50",{get:function(){return null==this.__BrowserXhr_50&&(this.__BrowserXhr_50=new c.a),this.__BrowserXhr_50},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ResponseOptions_51",{get:function(){return null==this.__ResponseOptions_51&&(this.__ResponseOptions_51=new c.b),this.__ResponseOptions_51},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_XSRFStrategy_52",{get:function(){return null==this.__XSRFStrategy_52&&(this.__XSRFStrategy_52=c.c()),this.__XSRFStrategy_52},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_XHRBackend_53",{get:function(){return null==this.__XHRBackend_53&&(this.__XHRBackend_53=new c.d(this._BrowserXhr_50,this._ResponseOptions_51,this._XSRFStrategy_52)),this.__XHRBackend_53},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_RequestOptions_54",{get:function(){return null==this.__RequestOptions_54&&(this.__RequestOptions_54=new c.e),this.__RequestOptions_54},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Http_55",{get:function(){return null==this.__Http_55&&(this.__Http_55=c.f(this._XHRBackend_53,this._RequestOptions_54)),this.__Http_55},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ActivatedRoute_56",{get:function(){return null==this.__ActivatedRoute_56&&(this.__ActivatedRoute_56=r.a(this._Router_16)),this.__ActivatedRoute_56},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_NoPreloading_57",{get:function(){return null==this.__NoPreloading_57&&(this.__NoPreloading_57=new r.b),this.__NoPreloading_57},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_PreloadingStrategy_58",{get:function(){return null==this.__PreloadingStrategy_58&&(this.__PreloadingStrategy_58=this._NoPreloading_57),this.__PreloadingStrategy_58},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_RouterPreloader_59",{get:function(){return null==this.__RouterPreloader_59&&(this.__RouterPreloader_59=new r.c(this._Router_16,this._NgModuleFactoryLoader_14,this._Compiler_13,this,this._PreloadingStrategy_58)),this.__RouterPreloader_59},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_PreloadAllModules_60",{get:function(){return null==this.__PreloadAllModules_60&&(this.__PreloadAllModules_60=new r.d),this.__PreloadAllModules_60},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ROUTER_INITIALIZER_61",{get:function(){return null==this.__ROUTER_INITIALIZER_61&&(this.__ROUTER_INITIALIZER_61=r.e(this._ɵg_3)),this.__ROUTER_INITIALIZER_61},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_APP_BOOTSTRAP_LISTENER_62",{get:function(){return null==this.__APP_BOOTSTRAP_LISTENER_62&&(this.__APP_BOOTSTRAP_LISTENER_62=[this._ROUTER_INITIALIZER_61]),this.__APP_BOOTSTRAP_LISTENER_62},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_BreadcrumbService_63",{get:function(){return null==this.__BreadcrumbService_63&&(this.__BreadcrumbService_63=new f.a),this.__BreadcrumbService_63},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_NotificationsService_64",{get:function(){return null==this.__NotificationsService_64&&(this.__NotificationsService_64=new m.a),this.__NotificationsService_64},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_HttpService_65",{get:function(){return null==this.__HttpService_65&&(this.__HttpService_65=new h.a(this._Http_55)),this.__HttpService_65},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_MessageService_66",{get:function(){return null==this.__MessageService_66&&(this.__MessageService_66=new v.a(this.parent.get(t.e))),this.__MessageService_66},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_DataService_67",{get:function(){return null==this.__DataService_67&&(this.__DataService_67=new g.a(this._HttpService_65,this._MessageService_66)),this.__DataService_67},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_DataServiceResolver_68",{get:function(){return null==this.__DataServiceResolver_68&&(this.__DataServiceResolver_68=new y.a(this._DataService_67,this._Router_16)),this.__DataServiceResolver_68},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_AccessControlRouteGuardService_69",{get:function(){return null==this.__AccessControlRouteGuardService_69&&(this.__AccessControlRouteGuardService_69=new S.a(this._DataService_67,this._Router_16)),this.__AccessControlRouteGuardService_69},enumerable:!0,configurable:!0}),n.prototype.createInternal=function(){return this._ɵa_0=r.f(this.parent.get(r.g,null)),this._ErrorHandler_1=o.m(),this._NgProbeToken_2=[r.h()],this._ɵg_3=new r.i(this),this._APP_INITIALIZER_4=[t.g,o.n(this.parent.get(o.o,null),this._NgProbeToken_2),r.j(this._ɵg_3)],this._ApplicationInitStatus_5=new t.h(this._APP_INITIALIZER_4),this._ɵf_6=new t.i(this.parent.get(t.e),this.parent.get(t.j),this,this._ErrorHandler_1,this.componentFactoryResolver,this._ApplicationInitStatus_5),this._ApplicationRef_7=this._ɵf_6,this._UrlSerializer_8=new r.k,this._RouterOutletMap_9=new r.l,this._ROUTER_CONFIGURATION_10={},this._LocationStrategy_11=r.m(this.parent.get(i.b),this.parent.get(i.c,null),this._ROUTER_CONFIGURATION_10),this._Location_12=new i.d(this._LocationStrategy_11),this._Compiler_13=new t.k,this._NgModuleFactoryLoader_14=new t.l(this._Compiler_13,this.parent.get(t.m,null)),this._ROUTES_15=[[{path:"player/:playerid",canActivate:[S.a],data:{name:"player"},children:[{path:"",component:P.a},{path:"",component:N.a,outlet:"menu"}]},{path:"server/:id",canActivate:[S.a],data:{name:"server"},children:[{path:"",component:B.a},{path:"",component:K.a,outlet:"menu"}]},{path:"admin/:id",canActivate:[S.a],data:{name:"admin-server"},children:[{path:"",component:j.a},{path:"",component:$.a,outlet:"menu"}]},{path:"servers",canActivate:[S.a],data:{name:"home"},children:[{path:"",component:R.a},{path:"",component:D.a,outlet:"menu"}]},{path:"developer",component:E.a},{path:"accessdenied",component:U.a},{path:"connectionerror",component:z.a},{path:"",redirectTo:"/servers",pathMatch:"full"}]],this._Router_16=r.n(this._ApplicationRef_7,this._UrlSerializer_8,this._RouterOutletMap_9,this._Location_12,this,this._NgModuleFactoryLoader_14,this._Compiler_13,this._ROUTES_15,this._ROUTER_CONFIGURATION_10,this.parent.get(r.o,null),this.parent.get(r.p,null)),this._RouterModule_17=new r.q(this._ɵa_0,this._Router_16),this._CommonModule_18=new i.e,this._Ng2BreadcrumbModule_19=new a.a,this._ApplicationModule_20=new t.n(this._ApplicationRef_7),this._BrowserModule_21=new o.p(this.parent.get(o.p,null)),this._ɵba_22=new s.b,this._FormsModule_23=new s.c,this._HttpModule_24=new c.g,this._BrowserAnimationsModule_25=new _.e,this._SimpleNotificationsModule_26=new p.SimpleNotificationsModule,this._DataTableModule_27=new d.a,this._AppModule_28=new e.a,this._AppModule_28},n.prototype.getInternal=function(l,n){return l===r.r?this._ɵa_0:l===t.o?this._ErrorHandler_1:l===t.p?this._NgProbeToken_2:l===r.i?this._ɵg_3:l===t.q?this._APP_INITIALIZER_4:l===t.h?this._ApplicationInitStatus_5:l===t.i?this._ɵf_6:l===t.r?this._ApplicationRef_7:l===r.s?this._UrlSerializer_8:l===r.l?this._RouterOutletMap_9:l===r.t?this._ROUTER_CONFIGURATION_10:l===i.f?this._LocationStrategy_11:l===i.d?this._Location_12:l===t.k?this._Compiler_13:l===t.s?this._NgModuleFactoryLoader_14:l===r.u?this._ROUTES_15:l===r.g?this._Router_16:l===r.q?this._RouterModule_17:l===i.e?this._CommonModule_18:l===a.a?this._Ng2BreadcrumbModule_19:l===t.n?this._ApplicationModule_20:l===o.p?this._BrowserModule_21:l===s.b?this._ɵba_22:l===s.c?this._FormsModule_23:l===c.g?this._HttpModule_24:l===_.e?this._BrowserAnimationsModule_25:l===p.SimpleNotificationsModule?this._SimpleNotificationsModule_26:l===d.a?this._DataTableModule_27:l===e.a?this._AppModule_28:l===t.t?this._LOCALE_ID_29:l===i.g?this._NgLocalization_30:l===t.u?this._APP_ID_31:l===t.v?this._IterableDiffers_32:l===t.w?this._KeyValueDiffers_33:l===o.q?this._DomSanitizer_34:l===t.x?this._Sanitizer_35:l===o.r?this._HAMMER_GESTURE_CONFIG_36:l===o.s?this._EVENT_MANAGER_PLUGINS_37:l===o.h?this._EventManager_38:l===o.i?this._ɵDomSharedStylesHost_39:l===o.j?this._ɵDomRendererFactory2_40:l===J.a?this._AnimationDriver_41:l===J.b?this._ɵAnimationStyleNormalizer_42:l===J.c?this._ɵAnimationEngine_43:l===t.y?this._RendererFactory2_44:l===o.t?this._ɵSharedStylesHost_45:l===t.f?this._Testability_46:l===o.k?this._Meta_47:l===o.l?this._Title_48:l===s.a?this._ɵi_49:l===c.a?this._BrowserXhr_50:l===c.h?this._ResponseOptions_51:l===c.i?this._XSRFStrategy_52:l===c.d?this._XHRBackend_53:l===c.j?this._RequestOptions_54:l===c.k?this._Http_55:l===r.v?this._ActivatedRoute_56:l===r.b?this._NoPreloading_57:l===r.w?this._PreloadingStrategy_58:l===r.c?this._RouterPreloader_59:l===r.d?this._PreloadAllModules_60:l===r.x?this._ROUTER_INITIALIZER_61:l===t.z?this._APP_BOOTSTRAP_LISTENER_62:l===f.a?this._BreadcrumbService_63:l===m.a?this._NotificationsService_64:l===h.a?this._HttpService_65:l===v.a?this._MessageService_66:l===g.a?this._DataService_67:l===y.a?this._DataServiceResolver_68:l===S.a?this._AccessControlRouteGuardService_69:n},n.prototype.destroyInternal=function(){this._ɵf_6.ngOnDestroy(),this.__ɵDomSharedStylesHost_39&&this._ɵDomSharedStylesHost_39.ngOnDestroy(),this.__RouterPreloader_59&&this._RouterPreloader_59.ngOnDestroy()},n}(t.A),X=new t.B(H,e.a)},l3s9:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},lCrv:function(l,n,u){"use strict";var t=u("3j3K"),e=u("Gvdl"),r=(u.n(e),u("ATz5")),i=u("lHWG"),a=u("kZql"),o=u("f4AQ"),s=(u.n(o),u("PJh5"));u.n(s);u.d(n,"a",function(){return c});var c=function(){function l(l,n,u){this.dataService=l,this.httpService=n,this.zone=u,this._structures=new e.BehaviorSubject(void 0),this.keysGetter=Object.keys,this.ownerSortField="locations",this.ownerSortFunctions={locations:function(l,n){return l.AreaCount>n.AreaCount?-1:l.AreaCountn.StructureCount?-1:l.StructureCountn.StructureCount?-1:l.StructureCountn.LastActiveTime||void 0==n.LastActiveTime?1:0}},this.width=1024,this.height=1024,this.zoom=o.zoom().scaleExtent([1,8])}return Object.defineProperty(l.prototype,"structures",{get:function(){return this._structures.getValue()},set:function(l){this._structures.next(l)},enumerable:!0,configurable:!0}),l.prototype.ngOnInit=function(){var l=this;this._structuresSubscription=this._structures.subscribe(function(n){return l.update(n)});var n=this.mapContainer.nativeElement;this.map={},this.map.canvas=o.select(n).append("canvas").attr("width",1024).attr("height",1024).node().getContext("2d"),this.map.svg=o.select(n).append("svg").attr("viewBox","0 0 1024 1024").attr("preserveAspectRatio","xMidYMid").append("g").on("contextmenu",function(l,n){o.event.preventDefault()}),this.map.svg.append("rect").attr("class","overlay").attr("width",1024).attr("height",1024),this.map.x=o.scaleLinear().domain([0,1024]).range([0,1024]),this.map.y=o.scaleLinear().domain([0,1024]).range([0,1024]),o.select(n).call(this.zoom.on("zoom",function(){l.hideContextMenu(),l.redraw()})).on("wheel.zoom",null),this.structures&&this.updateMap()},l.prototype.ngOnDestroy=function(){this._structuresSubscription.unsubscribe()},l.prototype.zoomIn=function(){this.zoom.scaleBy(o.select(this.mapContainer.nativeElement),1.2)},l.prototype.zoomOut=function(){this.zoom.scaleBy(o.select(this.mapContainer.nativeElement),.8)},l.prototype.updateSelection=function(){var l=this;this.map.svg.circle.attr("display",function(n){var u=l.structures.Owners[n.OwnerId];return n.Removed||u.Removed||l.selectedOwner&&(!l.selectedOwner||l.selectedOwner.Id!=n.OwnerId)?"none":"block"}),this.redraw()},l.prototype.update=function(l){this.sortOwners(l),this.map&&this.updateMap()},l.prototype.sortOwners=function(l){var n=this.ownerSortFunctions[this.ownerSortField];if(l){var u=l.Owners.slice();u.sort(n),this.ownersSorted=u}else this.ownersSorted=void 0},l.prototype.updateMap=function(){var l=this;this.map.svg.nodes=this.structures.Areas,this.map.svg.draw=function(){l.map.svg.circle=l.map.svg.selectAll("circle").data(l.map.svg.nodes).enter().append("circle").attr("r",function(l){return l.RadiusPx<2?2:l.RadiusPx}).attr("fill","transparent").attr("stroke",function(n){var u=l.structures.Owners[n.OwnerId];return!!u.LastActiveTime&&s(new Date(u.LastActiveTime)).isSameOrAfter(s().subtract(28,"day"))&&(n.StructureCount>=100||n.TrashQuota<.5&&n.StructureCount>=10)?"magenta":"red"}).attr("stroke-width",function(n){var u=l.structures.Owners[n.OwnerId];return!!u.LastActiveTime&&s(new Date(u.LastActiveTime)).isSameOrAfter(s().subtract(28,"day"))&&(n.StructureCount>=100||n.TrashQuota<.5&&n.StructureCount>=10)?3:2}).attr("transform",l.map.svg.transform),l.map.svg.circle.on("click",function(n){o.event.preventDefault();var u={};u.x=o.event.pageX,u.y=o.event.pageY,l.showAreaModal(n,u)}),l.map.svg.circle.append("svg:title").text(function(n){var u=l.structures.Owners[n.OwnerId],t=u.LastActiveTime?s(new Date(u.LastActiveTime)).fromNow():null;return u.Name+": "+n.StructureCount+" structures\nCoords: "+n.Latitude+", "+n.Longitude+"\n"+(t?"Last active: "+t+"\n":"")+"---\n"+n.Structures.map(function(n){var u=l.structures.Types[n.t];return n.c+": "+(u?u.Name:n.t)}).join("\n")})},this.map.svg.draw(),this.map.svg.transform=function(n){return"translate("+l.map.x(n.TopoMapX)+","+l.map.y(n.TopoMapY)+")"},this.map.svg.circle.attr("transform",this.map.svg.transform)},l.prototype.imageLoaded=function(l){var n=this;this.img=l,this.width=l?l.naturalWidth:1024,this.height=l?l.naturalHeight:1024,window.setTimeout(function(){n.resize(),n.redraw()},100)},l.prototype.resize=function(){},l.prototype.redraw=function(){var l=this,n=o.zoomTransform(this.mapContainer.nativeElement);this.map.svg.attr("transform","translate("+n.x+","+n.y+") scale("+n.k+")"),n.k!=this.prevTransformK&&this.map.svg.circle.attr("stroke-width",function(u){var t=l.structures.Owners[u.OwnerId];return(!!t.LastActiveTime&&s(new Date(t.LastActiveTime)).isSameOrAfter(s().subtract(28,"day"))&&(u.StructureCount>=100||u.TrashQuota<.5&&u.StructureCount>=10)?3:2)/n.k});var u=this.map.canvas;u.setTransform(1,0,0,1,0,0),u.clearRect(0,0,1024,1024),u.translate(n.x,n.y),u.scale(n.k,n.k),this.img&&u.drawImage(this.img,0,0),this.prevTransformK=n.k},l.prototype.ngOnChanges=function(l){var n=this;if(null!=this.mapName){var u=new Image;u.onload=function(){return n.imageLoaded(u)},u.onerror=function(){return n.imageLoaded(void 0)},u.src=a.a.demo?"assets/demo/Ragnarok.jpg":this.getApiBaseUrl()+"/map/"+this.mapName,u.complete&&(u.onload=null,u.onerror=null,this.imageLoaded(u))}},l.prototype.getApiBaseUrl=function(){return a.a.apiBaseUrl.replace(/\/gi,window.location.protocol).replace(/\/gi,window.location.hostname)},l.prototype.reset=function(){this.selectedOwner=void 0,this.updateSelection()},l.prototype.setSelectedOwner=function(l){this.selectedOwner=l,this.updateSelection()},l.prototype.setOwnerSort=function(l){this.ownerSortField=l,this.sortOwners(this.structures)},l.prototype.showAreaModal=function(l,n){this.currentArea=l,this.currentOwner=this.structures.Owners[l.OwnerId],o.select(this.contextMenu.nativeElement).style("display","block"),o.event&&o.event.stopPropagation()},l.prototype.showOwnerModal=function(l,n){this.currentOwner=n,o.select(this.contextMenu.nativeElement).style("display","block"),l.stopPropagation()},l.prototype.showInfoModal=function(l,n){var u={};u.Header=l,u.Message=n,this.modalInfo=u,o.select(this.contextMenu.nativeElement).style("display","block"),o.event&&o.event.stopPropagation()},l.prototype.hideContextMenu=function(){o.select(this.contextMenu.nativeElement).style("display","none"),this.currentArea=void 0,this.currentOwner=void 0,this.modalInfo=void 0},l.prototype.destroyCurrentArea=function(l){var n=this;this.httpService.adminDestroyStructuresForTeamIdAtPosition(this.serverKey,this.currentOwner.OwnerId,this.currentArea.X,this.currentArea.Y,+this.currentArea.RadiusUu+1e3,1).then(function(l){n.currentArea.Removed=!0,n.currentOwner.AreaCount-=1,n.currentOwner.StructureCount-=n.currentArea.StructureCount,n.hideContextMenu(),n.showInfoModal("Action Successfull!",l.Message),n.updateSelection()}).catch(function(l){n.hideContextMenu();var u=l&&l._body?JSON.parse(l._body):void 0;n.showInfoModal("Action Failed...",u?u.Message:l.statusText)})},l.prototype.destroyAllStructuresForTeam=function(l){var n=this;this.httpService.adminDestroyAllStructuresForTeamId(this.serverKey,this.currentOwner.OwnerId).then(function(l){n.currentOwner.Removed=!0,n.currentOwner.AreaCount=0,n.currentOwner.StructureCount=0,n.hideContextMenu(),n.showInfoModal("Action Successfull!",l.Message),n.updateSelection()}).catch(function(l){n.hideContextMenu();var u=l&&l._body?JSON.parse(l._body):void 0;n.showInfoModal("Action Failed...",u?u.Message:l.statusText)})},l.prototype.destroyDinosForTeam=function(l){var n=this;this.httpService.adminDestroyDinosForTeamId(this.serverKey,this.currentOwner.OwnerId).then(function(l){n.currentOwner.CreatureCount=0,n.hideContextMenu(),n.showInfoModal("Action Successfull!",l.Message),n.updateSelection()}).catch(function(l){n.hideContextMenu();var u=l&&l._body?JSON.parse(l._body):void 0;n.showInfoModal("Action Failed...",u?u.Message:l.statusText)})},l.prototype.saveWorld=function(l){var n=this;this.httpService.adminSaveWorld(this.serverKey).then(function(l){n.hideContextMenu(),n.showInfoModal("Action Successfull!",l.Message)}).catch(function(l){n.hideContextMenu();var u=l&&l._body?JSON.parse(l._body):void 0;n.showInfoModal("Action Failed...",u?u.Message:l.statusText)})},l.ctorParameters=function(){return[{type:r.a},{type:i.a},{type:t.e}]},l}()},lHWG:function(l,n,u){"use strict";var t=u("Fzro"),e=u("eErF"),r=(u.n(e),u("kZql"));u.d(n,"a",function(){return i});var i=function(){function l(l){this.http=l,this.headers=new t.l({"Content-Type":"application/json"}),this.serversUrl="/servers",this.serverUrl="/server",this.wildCreaturesUrl="/wildcreatures",this.structuresUrl="/structures",this.adminServerUrl="/adminserver",this.administerUrl="/administer",this.playerUrl="/player"}return l.prototype.getOptions=function(){var l="true"==localStorage.getItem("demoMode"),n=new t.j({withCredentials:!0});return l&&(n.headers||(n.headers=new t.l),n.headers.append("demoMode","true")),n},l.prototype.getServers=function(){return this.http.get(""+this.getApiBaseUrl()+this.serversUrl+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getServer=function(l){return this.http.get(""+this.getApiBaseUrl()+this.serverUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getWildCreatures=function(l){return this.http.get(""+this.getApiBaseUrl()+this.wildCreaturesUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getStructures=function(l){return this.http.get(""+this.getApiBaseUrl()+this.structuresUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getPlayer=function(l){return this.http.get(""+this.getApiBaseUrl()+this.playerUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getAdminServer=function(l){return this.http.get(""+this.getApiBaseUrl()+this.adminServerUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.adminDestroyAllStructuresForTeamId=function(l,n){return this.http.get(""+this.getApiBaseUrl()+this.administerUrl+"/DestroyAllStructuresForTeamId/"+l+"?teamId="+n+"&t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.adminDestroyStructuresForTeamIdAtPosition=function(l,n,u,t,e,r){return this.http.get(""+this.getApiBaseUrl()+this.administerUrl+"/DestroyStructuresForTeamIdAtPosition/"+l+"?teamId="+n+"&x="+u+"&y="+t+"&radius="+e+"&rafts="+r+"&t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.adminDestroyDinosForTeamId=function(l,n){return this.http.get(""+this.getApiBaseUrl()+this.administerUrl+"/DestroyDinosForTeamId/"+l+"?teamId="+n+"&t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.adminSaveWorld=function(l){return this.http.get(""+this.getApiBaseUrl()+this.administerUrl+"/SaveWorld/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getApiBaseUrl=function(){return r.a.apiBaseUrl.replace(/\/gi,window.location.protocol).replace(/\/gi,window.location.hostname)},l.prototype.handleError=function(l){return Promise.reject(l.message||l)},l.ctorParameters=function(){return[{type:t.k}]},l}()},mjI6:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},nJHW:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},nMh6:function(l,n,u){"use strict";function t(l){return A._24(0,[(l()(),A._25(0,null,null,24,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["My Profile"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,18,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,4,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),A._26(null,["Hello, ",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,9,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),A._26(null,["\n Find your tames, view base stats and keep track of their food status. Get notified of pending imprints, the amount of fertilizer and gasoline remaining in your crops and generators. This and much more is available in your profile.\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,3,"p",[],null,null,null,null,null)),(l()(),A._25(0,null,null,2,"a",[["class",""],["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==A._29(l,20).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),A._27(335872,null,0,T.D,[T.g,T.v,F.f],{routerLink:[0,"routerLink"]},null),(l()(),A._26(null,["View my profile ❯"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n"]))],function(l,n){l(n,20,0,"/player/"+n.component.dataService.UserSteamId)},function(l,n){l(n,10,0,n.component.dataService.Servers.User.Name),l(n,19,0,A._29(n,20).target,A._29(n,20).href)})}function e(l){return A._24(0,[(l()(),A._25(0,null,null,2,"a",[["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==A._29(l,1).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),A._27(335872,null,0,T.D,[T.g,T.v,F.f],{routerLink:[0,"routerLink"]},null),(l()(),A._26(null,[""," - ",""]))],function(l,n){l(n,1,0,"/server/"+n.parent.context.$implicit.Key)},function(l,n){l(n,0,0,A._29(n,1).target,A._29(n,1).href),l(n,2,0,n.parent.context.$implicit.MapName,n.parent.context.$implicit.Key)})}function r(l){return A._24(0,[(l()(),A._26(null,[""," - ",""]))],null,function(l,n){l(n,0,0,n.parent.context.$implicit.MapName,n.parent.context.$implicit.Key)})}function i(l){return A._24(0,[(l()(),A._25(0,null,null,3,"p",[],null,null,null,null,null)),(l()(),A._25(0,null,null,2,"a",[["class",""],["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==A._29(l,2).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),A._27(335872,null,0,T.D,[T.g,T.v,F.f],{routerLink:[0,"routerLink"]},null),(l()(),A._26(null,["View server ❯"]))],function(l,n){l(n,2,0,"/server/"+n.parent.context.$implicit.Key)},function(l,n){l(n,1,0,A._29(n,2).target,A._29(n,2).href)})}function a(l){return A._24(0,[(l()(),A._25(0,null,null,3,"p",[],null,null,null,null,null)),(l()(),A._25(0,null,null,2,"a",[["class",""],["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==A._29(l,2).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),A._27(335872,null,0,T.D,[T.g,T.v,F.f],{routerLink:[0,"routerLink"]},null),(l()(),A._26(null,["Admin ❯"]))],function(l,n){l(n,2,0,"/admin/"+n.parent.context.$implicit.Key)},function(l,n){l(n,1,0,A._29(n,2).target,A._29(n,2).href)})}function o(l){return A._24(0,[(l()(),A._25(0,null,null,21,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,6,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,3,"h3",[],null,null,null,null,null)),(l()(),A._28(8388608,null,null,1,null,e)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),A._28(0,[["server_no_link",2]],null,0,null,r)),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,10,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"p",[["class","w3-small"]],null,null,null,null,null)),(l()(),A._26(null,["\n Last Update ",", Next Update ","\n "])),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,i)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,a)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "]))],function(l,n){var u=n.component;l(n,6,0,u.dataService.hasFeatureAccess("pages","server"),A._29(n,7)),l(n,16,0,u.dataService.hasFeatureAccess("pages","server")),l(n,19,0,u.dataService.hasFeatureAccess("pages","admin-server"))},function(l,n){l(n,13,0,n.context.$implicit.LastUpdate,n.context.$implicit.NextUpdate||"-")})}function s(l){return A._24(0,[(l()(),A._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Servers"])),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,o)),A._27(401408,null,0,F.n,[A.S,A._5,A.v],{ngForOf:[0,"ngForOf"]},null),(l()(),A._26(null,["\n"]))],function(l,n){l(n,6,0,n.component.dataService.Servers.Servers)},null)}function c(l){return A._24(0,[(l()(),A._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),A._26(null,["There are no players online..."]))],null,null)}function _(l){return A._24(0,[(l()(),A._25(0,null,null,19,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.SteamName),l(n,6,0,n.context.$implicit.CharacterName),l(n,9,0,n.context.$implicit.TribeName),l(n,12,0,n.context.$implicit.DiscordName),l(n,15,0,n.parent.context.$implicit.Key),l(n,18,0,n.context.$implicit.TimeOnline)})}function p(l){return A._24(0,[(l()(),A._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,_)),A._27(401408,null,0,F.n,[A.S,A._5,A.v],{ngForOf:[0,"ngForOf"]},null),(l()(),A._26(null,["\n "]))],function(l,n){l(n,3,0,n.context.$implicit.OnlinePlayers)},null)}function d(l){return A._24(0,[(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,29,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,26,"table",[["class","w3-table w3-striped w3-bordered border-theme"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,24,"tbody",[],null,null,null,null,null)),(l()(),A._25(0,null,null,19,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Steam Name"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Character Name"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Tribe Name"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Discord Tag"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Server"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Time Online"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,p)),A._27(401408,null,0,F.n,[A.S,A._5,A.v],{ngForOf:[0,"ngForOf"]},null),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "]))],function(l,n){l(n,28,0,n.component.dataService.Servers.Servers)},null)}function f(l){return A._24(0,[(l()(),A._25(0,null,null,11,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,3,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Online "])),(l()(),A._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,c)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),A._26(null,["\n "])),(l()(),A._28(0,[["online_players_list",2]],null,0,null,d)),(l()(),A._26(null,["\n"]))],function(l,n){l(n,8,0,0==n.component.onlinePlayerCount,A._29(n,10))},function(l,n){l(n,5,0,n.component.onlinePlayerCount)})}function m(l){return A._24(0,[(l()(),A._25(0,null,null,2,"a",[["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==A._29(l,1).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),A._27(335872,null,0,T.D,[T.g,T.v,F.f],{routerLink:[0,"routerLink"]},null),(l()(),A._26(null,["",""]))],function(l,n){l(n,1,0,"/server/"+n.parent.parent.context.$implicit.Key)},function(l,n){l(n,0,0,A._29(n,1).target,A._29(n,1).href),l(n,2,0,n.parent.parent.context.$implicit.Name)})}function h(l){return A._24(0,[(l()(),A._26(null,["",""]))],null,function(l,n){l(n,0,0,n.parent.parent.context.$implicit.Name)})}function v(l){return A._24(0,[(l()(),A._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),A._26(null,["There are no players online..."]))],null,null)}function g(l){return A._24(0,[(l()(),A._25(0,null,null,16,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.SteamName),l(n,6,0,n.context.$implicit.CharacterName),l(n,9,0,n.context.$implicit.TribeName),l(n,12,0,n.context.$implicit.DiscordName),l(n,15,0,n.context.$implicit.TimeOnline)})}function y(l){return A._24(0,[(l()(),A._25(0,null,null,23,"table",[["class","w3-table w3-striped w3-bordered border-theme"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,21,"tbody",[],null,null,null,null,null)),(l()(),A._25(0,null,null,16,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Steam Name"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Character Name"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Tribe Name"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Discord Tag"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),A._26(null,["Time Online"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,g)),A._27(401408,null,0,F.n,[A.S,A._5,A.v],{ngForOf:[0,"ngForOf"]},null),(l()(),A._26(null,["\n "]))],function(l,n){l(n,22,0,n.parent.parent.parent.parent.context.$implicit.OnlinePlayers)},null)}function S(l){return A._24(0,[(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,4,"div",[["class","w3-card-4 w3-responsive w3-margin-bottom"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,y)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "]))],function(l,n){l(n,4,0,n.component.isMenuActive(n.parent.parent.parent.context.$implicit.Key))},null)}function b(l){return A._24(0,[(l()(),A._25(0,null,null,11,null,null,null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,3,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Online "])),(l()(),A._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,v)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),A._26(null,["\n "])),(l()(),A._28(0,[["server_online_players_list",2]],null,0,null,S)),(l()(),A._26(null,["\n "]))],function(l,n){l(n,8,0,0==n.parent.parent.context.$implicit.OnlinePlayerCount,A._29(n,10))},function(l,n){l(n,5,0,n.parent.parent.context.$implicit.OnlinePlayerCount)})}function w(l){return A._24(0,[(l()(),A._25(0,null,null,155,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,148,"div",[["class","w3-card-4 w3-responsive w3-margin-bottom"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,6,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,3,"h3",[],null,null,null,null,null)),(l()(),A._28(8388608,null,null,1,null,m)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),A._28(0,[["serverdetails_no_link",2]],null,0,null,h)),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,137,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,134,"table",[["class","w3-table w3-bordered w3-small border-theme serverdetails"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,132,"tbody",[],null,null,null,null,null)),(l()(),A._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Address"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[["style","width: max-content;"]],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Version"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Player Slots"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Map"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["In-Game Day"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Tamed Creatures"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),A._32(1),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Cloud Creatures"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),A._32(1),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Wild Creatures"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),A._32(1),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Structures"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),A._32(1),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Players"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),A._32(1),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Tribes"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),A._32(1),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Last Update"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Next Update"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,7,"tr",[["style","border-bottom: none;"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["Uptime"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),A._26(null,["",""])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n\n "])),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,b)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null),(l()(),A._26(null,["\n "]))],function(l,n){var u=n.component;l(n,8,0,u.dataService.hasFeatureAccess("pages","server"),A._29(n,9)),l(n,154,0,u.dataService.hasFeatureAccess("home","online"))},function(l,n){var u=n.component;l(n,23,0,n.parent.context.$implicit.Address),l(n,32,0,n.parent.context.$implicit.Version),l(n,41,0,n.parent.context.$implicit.OnlinePlayerMax),l(n,50,0,n.parent.context.$implicit.MapName),l(n,59,0,n.parent.context.$implicit.InGameTime),l(n,68,0,A._33(n,68,0,l(n,69,0,A._29(n.parent.parent,0),n.parent.context.$implicit.TamedCreatureCount))),l(n,78,0,A._33(n,78,0,l(n,79,0,A._29(n.parent.parent,0),n.parent.context.$implicit.CloudCreatureCount))),l(n,88,0,A._33(n,88,0,l(n,89,0,A._29(n.parent.parent,0),n.parent.context.$implicit.WildCreatureCount))),l(n,98,0,A._33(n,98,0,l(n,99,0,A._29(n.parent.parent,0),n.parent.context.$implicit.StructureCount))),l(n,108,0,A._33(n,108,0,l(n,109,0,A._29(n.parent.parent,0),n.parent.context.$implicit.PlayerCount))),l(n,118,0,A._33(n,118,0,l(n,119,0,A._29(n.parent.parent,0),n.parent.context.$implicit.TribeCount))),l(n,128,0,n.parent.context.$implicit.LastUpdate),l(n,137,0,n.parent.context.$implicit.NextUpdate),l(n,146,0,n.parent.context.$implicit.ServerStarted?u.dataService.toRelativeDate(n.parent.context.$implicit.ServerStarted):"-")})}function k(l){return A._24(0,[(l()(),A._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._28(8388608,null,null,1,null,w)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null),(l()(),A._26(null,["\n"]))],function(l,n){var u=n.component;l(n,3,0,u.isMenuActive(n.context.$implicit.Key)&&void 0!=u.dataService.Servers&&u.dataService.hasFeatureAccess("home","serverdetails"))},null)}function C(l){return A._24(0,[(l()(),A._25(0,null,null,59,"section",[["class","w3-container margin-top"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),A._26(null,["External Resources"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,14,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,4,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),A._26(null,["Wiki"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,5,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"p",[],null,null,null,null,null)),(l()(),A._25(0,null,null,1,"a",[["href","http://ark.gamepedia.com/"],["style","text-decoration: none;"]],null,null,null,null,null)),(l()(),A._26(null,["Official ARK Survival Evolved Wiki ❯"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,21,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,4,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),A._26(null,["Taming Calculators"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,12,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,9,"ul",[["class","w3-ul"],["style","margin: 7px 0px;"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"li",[["style","padding-left: 0px;"]],null,null,null,null,null)),(l()(),A._25(0,null,null,1,"a",[["href","http://www.survive-ark.com/taming-calculator/"],["style","text-decoration: none;"]],null,null,null,null,null)),(l()(),A._26(null,["Survive ARK: Taming Calculator ❯"])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"li",[["style","padding-left: 0px;"]],null,null,null,null,null)),(l()(),A._25(0,null,null,1,"a",[["href","http://www.dododex.com/"],["style","text-decoration: none;"]],null,null,null,null,null)),(l()(),A._26(null,["Dododex: Taming Calculator ❯"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,14,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,4,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),A._26(null,["Creature Library and Breeding Suggestions"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,5,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),A._26(null,["\n "])),(l()(),A._25(0,null,null,2,"p",[],null,null,null,null,null)),(l()(),A._25(0,null,null,1,"a",[["href","https://github.com/cadon/ARKStatsExtractor"],["style","text-decoration: none;"]],null,null,null,null,null)),(l()(),A._26(null,["ARK Smart Breeding ❯"])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n "])),(l()(),A._26(null,["\n"]))],null,null)}function I(l){return A._24(0,[A._34(0,F.p,[A.t]),(l()(),A._28(8388608,null,null,1,null,t)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null),(l()(),A._26(null,["\n"])),(l()(),A._28(8388608,null,null,1,null,s)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null),(l()(),A._26(null,["\n"])),(l()(),A._28(8388608,null,null,1,null,f)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null),(l()(),A._26(null,["\n"])),(l()(),A._28(8388608,null,null,1,null,k)),A._27(401408,null,0,F.n,[A.S,A._5,A.v],{ngForOf:[0,"ngForOf"]},null),(l()(),A._26(null,["\n"])),(l()(),A._28(8388608,null,null,1,null,C)),A._27(8192,null,0,F.l,[A.S,A._5],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,2,0,u.isMenuActive("overview")&&void 0!=u.dataService.UserSteamId&&u.dataService.hasFeatureAccess("home","myprofile")&&u.dataService.hasFeatureAccess("pages","player",u.dataService.UserSteamId)),l(n,5,0,u.isMenuActive("overview")&&void 0!=u.dataService.Servers&&u.serverCount>0&&u.dataService.hasFeatureAccess("home","serverlist")),l(n,8,0,u.isMenuActive("overview")&&void 0!=u.dataService.Servers&&u.dataService.hasFeatureAccess("home","online")),l(n,11,0,null==u.dataService.Servers?null:u.dataService.Servers.Servers),l(n,14,0,u.isMenuActive("overview")&&u.dataService.hasFeatureAccess("home","externalresources"))},null)}function x(l){return A._24(0,[(l()(),A._25(0,null,null,1,"app-server-list",[],null,null,null,I,K)),A._27(122880,null,0,M.a,[L.a,P.a,N.a],null,null)],function(l,n){l(n,1,0)},null)}var O=u("BYL0"),A=u("3j3K"),T=u("5oXY"),F=u("2Je8"),M=u("JLFQ"),L=u("ATz5"),P=u("+Lwu"),N=u("XLrO");u.d(n,"a",function(){return j});var B=[O.a],K=A._23({encapsulation:0,styles:B,data:{}}),j=A._30("app-server-list",M.a,x,{},{},[])},nuuw:function(l,n,u){"use strict";function t(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"div",[["class","w3-panel theme-l2"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h3",[["class","theme-text-l1-light"]],null,null,null,null,null)),(l()(),wl._26(null,["Loading..."])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,[" \n"]))],null,null)}function e(l){return wl._24(0,[(l()(),wl._25(0,null,null,10,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"div",[["class","w3-panel w3-red"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),wl._26(null,["Error!"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),wl._26(null,["No data could be loaded for the given steam id."])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,[" \n"]))],null,null)}function r(l){return wl._24(0,[(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activate(l.context.$implicit)&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["",""]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.active(n.context.$implicit)))},function(l,n){l(n,0,0,n.component.serverWidth()),l(n,3,0,n.context.$implicit)})}function i(l){return wl._24(0,[(l()(),wl._25(0,null,null,4,"div",[["class","w3-bar theme-l2 w3-card-4"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,r)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,u.keysGetter(null==u.player?null:u.player.Servers))},null)}function a(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["Servers"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,i)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,6,0,null==u.player?null:u.player.Servers)},null)}function o(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Gender"]))],null,null)}function s(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Level"]))],null,null)}function c(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Engram Points"]))],null,null)}function _(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lat"]))],null,null)}function p(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lng"]))],null,null)}function d(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""]))],null,function(l,n){var u=n.component;l(n,1,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].Gender)})}function f(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""]))],null,function(l,n){var u=n.component;l(n,1,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].Level)})}function m(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(1)],null,function(l,n){var u=n.component;l(n,1,0,wl._33(n,1,0,l(n,2,0,wl._29(n.parent.parent,0),null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].EngramPoints)))})}function h(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2)],null,function(l,n){var u=n.component;l(n,1,0,wl._33(n,1,0,l(n,2,0,wl._29(n.parent.parent,0),null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].Latitude,"1.1-1")))})}function v(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2)],null,function(l,n){var u=n.component;l(n,1,0,wl._33(n,1,0,l(n,2,0,wl._29(n.parent.parent,0),null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].Longitude,"1.1-1")))})}function g(l){return wl._24(0,[(l()(),wl._25(0,null,null,83,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,0,"a",[["id","player"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["Player"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,76,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,73,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,34,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,31,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Character Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,o)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Tribe Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Steam Id"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Tribe Id"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,s)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,c)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,_)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,p)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Saved At"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,34,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,31,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,d)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,f)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,m)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,h)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,v)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,18,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,30,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,33,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,36,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,39,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,54,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,66,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,69,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,72,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,75,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId))},function(l,n){var u=n.component;l(n,51,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].CharacterName),l(n,57,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].TribeName),l(n,60,0,(null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].FakeSteamId)||(null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].SteamId)),l(n,63,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].TribeId),l(n,78,0,u.dataService.toDate(null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].SavedAt))})}function y(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no creatures..."]))],null,null)}function S(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"i",[["class","material-icons"],["style","cursor: pointer;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){e.creaturesFilter="";t=!1!==e.filterAndSort()&&t}return t},null,null)),(l()(),wl._26(null,["close"]))],null,null)}function b(l){return wl._24(0,[(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("stats")&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["Base Stats"]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCreaturesMode("stats")))},function(l,n){l(n,0,0,100/n.component.numCreatureTabs())})}function w(l){return wl._24(0,[(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("ids")&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["IDs"]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCreaturesMode("ids")))},function(l,n){l(n,0,0,100/n.component.numCreatureTabs())})}function k(l){return wl._24(0,[(l()(),wl._25(0,null,null,12,"div",[["class","w3-bar theme-l2 w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("status")&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["Overview / Status"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,b)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,w)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,"w3-bar-item w3-button w3-mobile",l(n,4,0,u.activeCreaturesMode("status"))),l(n,8,0,u.dataService.hasFeatureAccess("player","creatures-basestats",u.steamId)),l(n,11,0,u.dataService.hasFeatureAccess("player","creatures-ids",u.steamId))},function(l,n){l(n,2,0,100/n.component.numCreatureTabs())})}function C(l){return wl._24(0,[(l()(),wl._25(0,null,null,22,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Level"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("level")&&t}return t},null,null)),(l()(),wl._26(null,["Level"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Imprint"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("imprint")&&t}return t},null,null)),(l()(),wl._26(null,["Imprint"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Food"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("food")&&t}return t},null,null)),(l()(),wl._26(null,["Food"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Latitude"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("latitude")&&t}return t},null,null)),(l()(),wl._26(null,["Lat"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Longitude"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("longitude")&&t}return t},null,null)),(l()(),wl._26(null,["Lng"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Status"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Owner"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("owner")&&t}return t},null,null)),(l()(),wl._26(null,["Owner"])),(l()(),wl._26(null,["\n "]))],null,null)}function I(l){return wl._24(0,[(l()(),wl._25(0,null,null,23,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Health"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_health")&&t}return t},null,null)),(l()(),wl._26(null,["HP"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Stamina"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_stamina")&&t}return t},null,null)),(l()(),wl._26(null,["ST"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Oxygen"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_oxygen")&&t}return t},null,null)),(l()(),wl._26(null,["OX"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Food"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_food")&&t}return t},null,null)),(l()(),wl._26(null,["FO"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Weight"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_weight")&&t}return t},null,null)),(l()(),wl._26(null,["WE"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Melee"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_melee")&&t}return t},null,null)),(l()(),wl._26(null,["ME"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Speed"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_speed")&&t}return t},null,null)),(l()(),wl._26(null,["SP"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],null,null)}function x(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by ID1"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("id1")&&t}return t},null,null)),(l()(),wl._26(null,["ID1"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by ID2"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("id2")&&t}return t},null,null)),(l()(),wl._26(null,["ID2"])),(l()(),wl._26(null,["\n "]))],null,null)}function O(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"tr",[],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"td",[],[[8,"colSpan",0]],null,null,null,null)),(l()(),wl._26(null,["No matching creatures..."]))],null,function(l,n){l(n,1,0,n.component.activeCreaturesMode("ids")?6:11)})}function A(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),wl._26(null,["",""]))],null,function(l,n){l(n,1,0,n.parent.parent.context.$implicit.Level)})}function T(l){return wl._24(0,[(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 6em; position: relative;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,wl._33(n,3,0,l(n,4,0,wl._29(n.parent.parent.parent.parent.parent,1),n.parent.parent.context.$implicit.FoodStatus,"1.0-0"))),l(n,6,0,100*n.parent.parent.context.$implicit.FoodStatus)})}function F(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),wl._26(null,["Next mating ",""]))],null,function(l,n){l(n,1,0,n.component.dataService.toRelativeDate(n.parent.parent.context.$implicit.NextMating))})}function M(l){return wl._24(0,[(l()(),wl._25(0,null,null,23,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,20,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),wl._26(null,["Baby"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,11,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 4em; position: relative; margin: 0em 0.5em;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._26(null,["cuddle ",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],null,function(l,n){var u=n.component;l(n,12,0,wl._33(n,12,0,l(n,13,0,wl._29(n.parent.parent.parent.parent.parent,1),n.parent.parent.context.$implicit.BabyAge,"1.0-0"))),l(n,15,0,100*n.parent.parent.context.$implicit.BabyAge),l(n,21,0,u.dataService.toRelativeDate(n.parent.parent.context.$implicit.BabyNextCuddle))})}function L(l){return wl._24(0,[(l()(),wl._25(0,null,null,35,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._28(8388608,null,null,1,null,A)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,T)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,F)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,M)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,4,0,n.parent.context.$implicit.BaseLevel!=n.parent.context.$implicit.Level),l(n,13,0,null!=n.parent.context.$implicit.FoodStatus),l(n,27,0,u.haveMatingCooldown(n.parent.context.$implicit)),l(n,30,0,null!=n.parent.context.$implicit.BabyAge)},function(l,n){l(n,7,0,wl._33(n,7,0,l(n,8,0,wl._29(n.parent.parent.parent.parent,1),n.parent.context.$implicit.Imprint,"1.0-0"))),l(n,17,0,wl._33(n,17,0,l(n,18,0,wl._29(n.parent.parent.parent.parent,0),n.parent.context.$implicit.Latitude,"1.1-1"))),l(n,21,0,wl._33(n,21,0,l(n,22,0,wl._29(n.parent.parent.parent.parent,0),n.parent.context.$implicit.Longitude,"1.1-1"))),l(n,34,0,n.parent.context.$implicit.OwnerType)})}function P(l){return wl._24(0,[(l()(),wl._25(0,null,null,23,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Health),l(n,6,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Stamina),l(n,9,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Oxygen),l(n,12,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Food),l(n,15,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Weight),l(n,18,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Melee),l(n,21,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.MovementSpeed)})}function N(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.parent.context.$implicit.Id1),l(n,6,0,n.parent.context.$implicit.Id2)})}function B(l){return wl._24(0,[(l()(),wl._25(0,null,null,24,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,L)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,P)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,N)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,17,0,u.activeCreaturesMode("status")),l(n,20,0,u.activeCreaturesMode("stats")),l(n,23,0,u.activeCreaturesMode("ids"))},function(l,n){l(n,3,0,n.context.$implicit.Name),l(n,7,0,n.context.$implicit.Species),l(n,11,0,n.context.$implicit.Gender),l(n,14,0,n.context.$implicit.BaseLevel)})}function K(l){return wl._24(0,[(l()(),wl._25(0,null,null,61,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,11,"div",[["class","inner-addon right-addon"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,S)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"input",[["class","w3-input w3-border w3-round-xlarge w3-large w3-margin-bottom border-theme theme-l1"],["placeholder","Filter"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,e=l.component;if("input"===n){t=!1!==wl._29(l,8)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==wl._29(l,8).onTouched()&&t}if("compositionstart"===n){t=!1!==wl._29(l,8)._compositionStart()&&t}if("compositionend"===n){t=!1!==wl._29(l,8)._compositionEnd(u.target.value)&&t}if("ngModelChange"===n){e.creaturesFilter=u;t=!1!==e.filterAndSort()&&t}return t},null,null)),wl._27(8192,null,0,Cl.d,[wl.J,wl.K,[2,Cl.e]],null,null),wl._37(512,null,Cl.g,function(l){return[l]},[Cl.d]),wl._27(335872,null,0,Cl.h,[[8,null],[8,null],[8,null],[2,Cl.g]],{model:[0,"model"]},{update:"ngModelChange"}),wl._37(1024,null,Cl.i,null,[Cl.h]),wl._27(8192,null,0,Cl.j,[Cl.i],null,null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,k)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,42,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,39,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,27,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,24,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Name"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("name")&&t}return t},null,null)),(l()(),wl._26(null,["Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Species"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("species")&&t}return t},null,null)),(l()(),wl._26(null,["Species"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Gender"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("gender")&&t}return t},null,null)),(l()(),wl._26(null,["Gender"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Base Level"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("base_level")&&t}return t},null,null)),(l()(),wl._26(null,["Base Level"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,C)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,I)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,x)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,O)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,B)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,5,0,null!=u.creaturesFilter&&""!=u.creaturesFilter),l(n,10,0,u.creaturesFilter),l(n,16,0,u.numCreatureTabs()>1),l(n,41,0,u.activeCreaturesMode("status")),l(n,44,0,u.activeCreaturesMode("stats")),l(n,47,0,u.activeCreaturesMode("ids")),l(n,54,0,!((null==u.filteredCreatures?null:u.filteredCreatures.length)>0)),l(n,57,0,u.filteredCreatures)},function(l,n){l(n,7,0,wl._29(n,12).ngClassUntouched,wl._29(n,12).ngClassTouched,wl._29(n,12).ngClassPristine,wl._29(n,12).ngClassDirty,wl._29(n,12).ngClassValid,wl._29(n,12).ngClassInvalid,wl._29(n,12).ngClassPending)})}function j(l){return wl._24(0,[(l()(),wl._25(0,null,null,21,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,12,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","creatures"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,3,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Creatures "])),(l()(),wl._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"button",[["class","w3-button theme-d1 w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.openMap(u)&&t}return t},null,null)),(l()(),wl._26(null,["Show Map"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,y)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,K)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,17,0,!((null==u.player.Servers[u.serverKey]?null:null==u.player.Servers[u.serverKey].Creatures?null:u.player.Servers[u.serverKey].Creatures.length)>0)),l(n,20,0,(null==u.player.Servers[u.serverKey]?null:null==u.player.Servers[u.serverKey].Creatures?null:u.player.Servers[u.serverKey].Creatures.length)>0)},function(l,n){l(n,9,0,n.component.filteredCreatures.length)})}function $(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"i",[["class","material-icons"],["style","margin: -5px 5px -5px -5px; vertical-align: middle;"]],null,null,null,null,null)),(l()(),wl._26(null,["check"]))],null,null)}function R(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no baby creatures..."]))],null,null)}function D(l){return wl._24(0,[(l()(),wl._25(0,null,null,0,"th",[],null,null,null,null,null))],null,null)}function E(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"input",[["class","w3-check w3-right"],["style","top: 0;"],["type","checkbox"]],[[8,"checked",0]],[[null,"change"]],function(l,n,u){var t=!0,e=l.component;if("change"===n){t=!1!==e.toggleImprintNotificationForCreature(l.parent.context.$implicit)&&t}return t},null,null))],null,function(l,n){l(n,1,0,n.component.getStateForCreature(n.parent.context.$implicit).imprintNotifications)})}function U(l){return wl._24(0,[(l()(),wl._25(0,null,null,42,"tr",[],null,null,null,null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{ngClass:[0,"ngClass"]},null),wl._31(["odd"]),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,11,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 6em; position: relative;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"timer",[],null,null,null,Il.a,Il.b)),wl._27(122880,null,0,xl.a,[],{state:[0,"state"],time:[1,"time"],notification:[2,"notification"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,E)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,1,0,l(n,2,0,n.context.index%2==1)),l(n,38,0,u.getStateForCreature(n.context.$implicit),n.context.$implicit.BabyNextCuddle,u.imprintNotifications),l(n,41,0,u.imprintNotifications)},function(l,n){var u=n.component;l(n,5,0,n.context.$implicit.Name),l(n,8,0,n.context.$implicit.Species),l(n,11,0,n.context.$implicit.Gender),l(n,14,0,n.context.$implicit.BaseLevel),l(n,17,0,wl._33(n,17,0,l(n,18,0,wl._29(n.parent.parent.parent,1),n.context.$implicit.Imprint,"1.0-0"))),l(n,25,0,wl._33(n,25,0,l(n,26,0,wl._29(n.parent.parent.parent,1),n.context.$implicit.BabyAge,"1.0-0"))),l(n,28,0,100*n.context.$implicit.BabyAge),l(n,34,0,u.dataService.toDate(n.context.$implicit.BabyFullyGrown))})}function z(l){return wl._24(0,[(l()(),wl._25(0,null,null,43,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,40,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,31,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,28,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Species"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Gender"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Base Level"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Imprint"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Progress"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Fully Grown At"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Next Imprint"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,D)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,U)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,33,0,u.imprintNotifications),l(n,40,0,u.imprintCreatures)},null)}function J(l){return wl._24(0,[(l()(),wl._25(0,null,null,26,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,16,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","imprint_timers"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,3,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Breeding "])),(l()(),wl._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,5,"button",[["class","w3-button w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.imprintNotifications=!e.imprintNotifications)&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1","theme-l2","theme-hover"]),(l()(),wl._28(8388608,null,null,1,null,$)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,R)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,z)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,13,0,"w3-button w3-right",l(n,14,0,u.imprintNotifications,!u.imprintNotifications,!u.imprintNotifications)),l(n,16,0,u.imprintNotifications),l(n,21,0,!((null==u.imprintCreatures?null:u.imprintCreatures.length)>0)),l(n,24,0,(null==u.imprintCreatures?null:u.imprintCreatures.length)>0)},function(l,n){var u=n.component;l(n,9,0,u.imprintCreatures.length),l(n,17,0,u.imprintNotifications?"Notifications Enabled":"Enable Notifications")})}function G(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no kibbles or eggs..."]))],null,null)}function H(l){return wl._24(0,[(l()(),wl._25(0,null,null,13,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.Name),l(n,6,0,n.context.$implicit.KibbleCount),l(n,9,0,n.context.$implicit.EggCount),l(n,12,0,n.context.$implicit.KibbleCount+n.context.$implicit.EggCount)})}function X(l){return wl._24(0,[(l()(),wl._25(0,null,null,28,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,25,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,16,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,13,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Kibbles"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Eggs"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Total"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,H)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,25,0,u.player.Servers[u.serverKey].KibblesAndEggs)},null)}function W(l){return wl._24(0,[(l()(),wl._25(0,null,null,18,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,9,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","kibblesandeggs"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,4,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Kibbles and Eggs "])),(l()(),wl._25(0,null,null,2,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,G)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,X)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,14,0,!((null==u.player.Servers[u.serverKey].KibblesAndEggs?null:u.player.Servers[u.serverKey].KibblesAndEggs.length)>0)),l(n,17,0,(null==u.player.Servers[u.serverKey].KibblesAndEggs?null:u.player.Servers[u.serverKey].KibblesAndEggs.length)>0)},function(l,n){var u=n.component;l(n,9,0,wl._33(n,9,0,l(n,10,0,wl._29(n.parent,0),u.sumKibbleAndEggs(),0)))})}function V(l){return wl._24(0,[(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCluster(l.context.$implicit)&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["",""]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCluster(n.context.$implicit)))},function(l,n){l(n,0,0,n.component.clusterWidth()),l(n,3,0,n.context.$implicit)})}function Y(l){return wl._24(0,[(l()(),wl._25(0,null,null,4,"div",[["class","w3-bar theme-l2 w3-card-4"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,V)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,u.keysGetter(null==u.player?null:u.player.Clusters))},null)}function q(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["Clusters"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,Y)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,6,0,null==u.player?null:u.player.Clusters)},null)}function Q(l){return wl._24(0,[(l()(),wl._25(0,null,null,11,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Creatures"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no creatures in the cloud..."])),(l()(),wl._26(null,["\n"]))],null,null)}function Z(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no creatures in the cloud..."]))],null,null)}function ll(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"i",[["class","material-icons"],["style","cursor: pointer;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){e.creaturesClusterFilter="";t=!1!==e.filterCluster()&&t}return t},null,null)),(l()(),wl._26(null,["close"]))],null,null)}function nl(l){return wl._24(0,[(l()(),wl._25(0,null,null,11,"div",[["class","inner-addon right-addon"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,ll)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"input",[["class","w3-input w3-border w3-round-xlarge w3-large w3-margin-bottom border-theme theme-l1"],["placeholder","Filter"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,e=l.component;if("input"===n){t=!1!==wl._29(l,6)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==wl._29(l,6).onTouched()&&t}if("compositionstart"===n){t=!1!==wl._29(l,6)._compositionStart()&&t}if("compositionend"===n){t=!1!==wl._29(l,6)._compositionEnd(u.target.value)&&t}if("ngModelChange"===n){e.creaturesClusterFilter=u;t=!1!==e.filterCluster()&&t}return t},null,null)),wl._27(8192,null,0,Cl.d,[wl.J,wl.K,[2,Cl.e]],null,null),wl._37(512,null,Cl.g,function(l){return[l]},[Cl.d]),wl._27(335872,null,0,Cl.h,[[8,null],[8,null],[8,null],[2,Cl.g]],{model:[0,"model"]},{update:"ngModelChange"}),wl._37(1024,null,Cl.i,null,[Cl.h]),wl._27(8192,null,0,Cl.j,[Cl.i],null,null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,null!=u.creaturesClusterFilter&&""!=u.creaturesClusterFilter),l(n,8,0,u.creaturesClusterFilter)},function(l,n){l(n,5,0,wl._29(n,10).ngClassUntouched,wl._29(n,10).ngClassTouched,wl._29(n,10).ngClassPristine,wl._29(n,10).ngClassDirty,wl._29(n,10).ngClassValid,wl._29(n,10).ngClassInvalid,wl._29(n,10).ngClassPending)})}function ul(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"tr",[],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"td",[["colspan","3"]],null,null,null,null,null)),(l()(),wl._26(null,["No matching creatures..."]))],null,null)}function tl(l){return wl._24(0,[(l()(),wl._25(0,null,null,10,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.Name),l(n,6,0,n.context.$implicit.Species),l(n,9,0,n.context.$implicit.Level)})}function el(l){return wl._24(0,[(l()(),wl._25(0,null,null,28,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,25,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,13,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,10,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Species"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Level"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,ul)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,tl)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,22,0,!((null==u.filteredClusterCreatures?null:u.filteredClusterCreatures.length)>0)),l(n,25,0,u.filteredClusterCreatures)},null)}function rl(l){return wl._24(0,[(l()(),wl._25(0,null,null,19,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,3,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Creatures "])),(l()(),wl._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,Z)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,nl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,el)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,12,0,!((null==u.player.Clusters[u.clusterKey]?null:null==u.player.Clusters[u.clusterKey].Creatures?null:u.player.Clusters[u.clusterKey].Creatures.length)>0)),l(n,15,0,(null==u.player.Clusters[u.clusterKey]?null:null==u.player.Clusters[u.clusterKey].Creatures?null:u.player.Clusters[u.clusterKey].Creatures.length)>0),l(n,18,0,(null==u.player.Clusters[u.clusterKey]?null:null==u.player.Clusters[u.clusterKey].Creatures?null:u.player.Clusters[u.clusterKey].Creatures.length)>0)},function(l,n){l(n,8,0,n.component.filteredClusterCreatures.length)})}function il(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no crops..."]))],null,null)}function al(l){return wl._24(0,[(l()(),wl._25(0,null,null,36,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,11,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 6em; position: relative;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(1),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.PlantedCropName||n.context.$implicit.PlantedCropClassName),l(n,6,0,n.context.$implicit.Size),l(n,13,0,wl._33(n,13,0,l(n,14,0,wl._29(n.parent.parent.parent,1),n.context.$implicit.FertilizerQuantity/n.context.$implicit.FertilizerMax,"1.0-0"))),l(n,16,0,n.context.$implicit.FertilizerQuantity/n.context.$implicit.FertilizerMax*100),l(n,22,0,wl._33(n,22,0,l(n,23,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.FertilizerQuantity))),l(n,26,0,wl._33(n,26,0,l(n,27,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.WaterAmount,"1.0-0"))),l(n,30,0,wl._33(n,30,0,l(n,31,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.Latitude,"1.1-1"))),l(n,34,0,wl._33(n,34,0,l(n,35,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.Longitude,"1.1-1")))})}function ol(l){return wl._24(0,[(l()(),wl._25(0,null,null,37,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,34,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,25,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,22,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Crop"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Size"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Fertilizer %"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Fertilizer Units"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Water"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lat"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lng"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,al)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,34,0,u.player.Servers[u.serverKey].CropPlots)},null)}function sl(l){return wl._24(0,[(l()(),wl._25(0,null,null,15,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,3,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","cropplots"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Crops"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,il)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,ol)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,11,0,!((null==u.player.Servers[u.serverKey].CropPlots?null:u.player.Servers[u.serverKey].CropPlots.length)>0)),l(n,14,0,(null==u.player.Servers[u.serverKey].CropPlots?null:u.player.Servers[u.serverKey].CropPlots.length)>0)},null)}function cl(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no electrical generators..."]))],null,null)}function _l(l){return wl._24(0,[(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 6em; position: relative;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,wl._33(n,3,0,l(n,4,0,wl._29(n.parent.parent.parent.parent,1),n.parent.context.$implicit.GasolineQuantity/800,"1.0-0"))),l(n,6,0,n.parent.context.$implicit.GasolineQuantity/800*100)})}function pl(l){return wl._24(0,[(l()(),wl._25(0,null,null,22,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,_l)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(1),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "]))],function(l,n){l(n,5,0,1==n.context.$implicit.Activated)},function(l,n){l(n,9,0,wl._33(n,9,0,l(n,10,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.GasolineQuantity))),l(n,13,0,1==n.context.$implicit.Activated?"Yes":"No"),l(n,16,0,wl._33(n,16,0,l(n,17,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.Latitude,"1.1-1"))),l(n,20,0,wl._33(n,20,0,l(n,21,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.Longitude,"1.1-1")))})}function dl(l){return wl._24(0,[(l()(),wl._25(0,null,null,31,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,28,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,19,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,16,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Gasoline %"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Gasoline Quantity"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Activated"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lat"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lng"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,pl)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,28,0,u.player.Servers[u.serverKey].ElectricalGenerators)},null)}function fl(l){return wl._24(0,[(l()(),wl._25(0,null,null,15,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,3,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","electricalgenerators"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Electrical Generators"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,cl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,dl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,11,0,!((null==u.player.Servers[u.serverKey].ElectricalGenerators?null:u.player.Servers[u.serverKey].ElectricalGenerators.length)>0)),l(n,14,0,(null==u.player.Servers[u.serverKey].ElectricalGenerators?null:u.player.Servers[u.serverKey].ElectricalGenerators.length)>0)},null)}function ml(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no tribe logs..."]))],null,null)}function hl(l){return wl._24(0,[(l()(),wl._25(0,null,null,10,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.Day),l(n,6,0,n.context.$implicit.Time),l(n,9,0,n.context.$implicit.Message)})}function vl(l){return wl._24(0,[(l()(),wl._25(0,null,null,25,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,22,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,13,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,10,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Day"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Time"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Message"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,hl)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,22,0,u.player.Servers[u.serverKey].TribeLog)},null)}function gl(l){return wl._24(0,[(l()(),wl._25(0,null,null,15,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,3,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","tribelog"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Tribe Log"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,ml)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,vl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,11,0,!((null==u.player.Servers[u.serverKey].TribeLog?null:u.player.Servers[u.serverKey].TribeLog.length)>0)),l(n,14,0,(null==u.player.Servers[u.serverKey].TribeLog?null:u.player.Servers[u.serverKey].TribeLog.length)>0)},null)}function yl(l){return wl._24(0,[wl._34(0,kl.p,[wl.t]),wl._34(0,kl.r,[wl.t]),(l()(),wl._28(8388608,null,null,1,null,t)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,e)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,a)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,g)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,j)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,J)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,W)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,q)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,Q)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,rl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,sl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,fl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,gl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._25(0,null,null,17,"div",[["class","w3-modal"],["id","modal_map"]],[[4,"display",null]],null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,14,"div",[["class","w3-modal-content w3-card-4 w3-animate-zoom"],["style","font-size: 0;"]],null,[[null,"clickOutside"],["document","click"]],function(l,n,u){var t=!0,e=l.component;if("document:click"===n){t=!1!==wl._29(l,44).onClick(u,u.target)&&t}if("clickOutside"===n){t=!1!==e.closeMap(u)&&t}return t},null,null)),wl._27(8192,null,0,Al.a,[wl.K],null,{clickOutside:"clickOutside"}),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,[" \n "])),(l()(),wl._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.showMap=!1)&&t}return t},null,null)),(l()(),wl._26(null,["×"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),wl._26(null,["Map"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"arkmap",[],null,null,null,Tl.a,Tl.b)),wl._27(286720,null,0,Fl.a,[],{mapName:[0,"mapName"],points:[1,"points"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,3,0,0==u.loaded),l(n,6,0,1==u.loaded&&null==u.player),l(n,9,0,!u.isMenuActive("creatures_cloud")&&void 0!=u.player),l(n,12,0,u.isMenuActive("profile")&&void 0!=u.player&&u.dataService.hasFeatureAccess("player","profile",u.steamId)),l(n,15,0,u.isMenuActive("creatures")&&void 0!=u.player&&u.dataService.hasFeatureAccess("player","creatures",u.steamId)),l(n,18,0,u.isMenuActive("breeding")&&void 0!=u.player&&u.dataService.hasFeatureAccess("player","breeding",u.steamId)),l(n,21,0,u.isMenuActive("kibbles_and_eggs")&&(null==u.player?null:u.player.Servers[u.serverKey])&&u.dataService.hasFeatureAccess("player","kibbles-eggs",u.steamId)),l(n,24,0,u.isMenuActive("creatures_cloud")&&u.haveCluster()),l(n,27,0,u.isMenuActive("creatures_cloud")&&!u.haveCluster()&&u.dataService.hasFeatureAccess("player","creatures-cloud",u.steamId)),l(n,30,0,u.isMenuActive("creatures_cloud")&&u.haveCluster()&&u.dataService.hasFeatureAccess("player","creatures-cloud",u.steamId)),l(n,33,0,u.isMenuActive("crop_plots")&&(null==u.player?null:u.player.Servers[u.serverKey])&&u.dataService.hasFeatureAccess("player","crops",u.steamId)),l(n,36,0,u.isMenuActive("electrical_generators")&&(null==u.player?null:u.player.Servers[u.serverKey])&&u.dataService.hasFeatureAccess("player","generators",u.steamId)),l(n,39,0,u.isMenuActive("tribelog")&&(null==u.player?null:u.player.Servers[u.serverKey])&&u.dataService.hasFeatureAccess("player","tribelog",u.steamId)),l(n,56,0,null==u.player?null:u.player.MapNames[u.serverKey],u.points)},function(l,n){l(n,41,0,n.component.showMap?"block":"none")})}function Sl(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"app-player",[],null,null,null,yl,jl)),wl._27(122880,null,0,Ol.a,[Ml.v,Ml.g,Ll.a,Pl.a,Nl.a,Bl.a,wl.O],null,null)],function(l,n){l(n,1,0)},null)}var bl=u("SWoV"),wl=u("3j3K"),kl=u("2Je8"),Cl=u("NVOs"),Il=u("RdYi"),xl=u("CzL3"),Ol=u("KZxv"),Al=u("8zLQ"),Tl=u("I9JA"),Fl=u("5305"),Ml=u("5oXY"),Ll=u("lHWG"),Pl=u("ATz5"),Nl=u("+Lwu"),Bl=u("XLrO");u.d(n,"a",function(){return $l});var Kl=[bl.a],jl=wl._23({encapsulation:0,styles:Kl,data:{}}),$l=wl._30("app-player",Ol.a,Sl,{},{},[])},ofcV:function(l,n,u){"use strict";function t(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("profile")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Profile"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("profile")))},null)}function e(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("creatures")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Creatures"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("creatures")))},null)}function r(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("creatures_cloud")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Creatures (Cloud)"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("creatures_cloud")))},null)}function i(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("breeding")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Breeding"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("breeding")))},null)}function a(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("crop_plots")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Crops"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("crop_plots")))},null)}function o(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("electrical_generators")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Electrical Generators"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("electrical_generators")))},null)}function s(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("kibbles_and_eggs")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Kibbles and Eggs"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("kibbles_and_eggs")))},null)}function c(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("tribelog")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Tribe Log"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("tribelog")))},null)}function _(l){return f._24(0,[f._35(201326592,1,{menu:0}),(l()(),f._25(0,null,null,32,"app-menu",[],null,null,null,h.a,h.b)),f._27(122880,[[1,4],["menu",4]],0,v.a,[g.a],null,null),(l()(),f._26(0,["\n "])),(l()(),f._25(0,null,0,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),f._26(null,["Player"])),(l()(),f._26(0,["\n "])),(l()(),f._25(0,null,0,25,"div",[["class","w3-cell-row theme-l2"]],null,null,null,null,null)),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,t)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,e)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,r)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,i)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,a)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,o)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,s)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,c)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._26(0,["\n"]))],function(l,n){var u=n.component;l(n,2,0),l(n,10,0,u.dataService.hasFeatureAccess("player","profile",u.steamId)),l(n,13,0,u.dataService.hasFeatureAccess("player","creatures",u.steamId)),l(n,16,0,u.dataService.hasFeatureAccess("player","creatures-cloud",u.steamId)),l(n,19,0,u.dataService.hasFeatureAccess("player","breeding",u.steamId)),l(n,22,0,u.dataService.hasFeatureAccess("player","crops",u.steamId)),l(n,25,0,u.dataService.hasFeatureAccess("player","generators",u.steamId)),l(n,28,0,u.dataService.hasFeatureAccess("player","kibbles-eggs",u.steamId)),l(n,31,0,u.dataService.hasFeatureAccess("player","tribelog",u.steamId))},null)}function p(l){return f._24(0,[(l()(),f._25(0,null,null,1,"app-player-menu",[],[[8,"className",0]],null,null,_,w)),f._27(57344,null,0,y.a,[S.v,g.a],null,null)],function(l,n){l(n,1,0)},function(l,n){l(n,0,0,f._29(n,1).menu.className)})}var d=u("l3s9"),f=u("3j3K"),m=u("2Je8"),h=u("coiB"),v=u("8kYA"),g=u("ATz5"),y=u("RiXa"),S=u("5oXY");u.d(n,"a",function(){return k});var b=[d.a],w=f._23({encapsulation:0,styles:b,data:{}}),k=f._30("app-player-menu",y.a,p,{},{},[])},qn86:function(l,n,u){"use strict";var t=u("3j3K"),e=u("5oXY"),r=u("3MNG"),i=u("PJh5"),a=(u.n(i),u("ATz5")),o=u("+Lwu"),s=u("lHWG"),c=u("+rAa");u.d(n,"a",function(){return _});var _=function(){function l(l,n,t,e,r,i,a){this.route=l,this.router=n,this.httpService=t,this.dataService=e,this.messageService=r,this.notificationsService=i,this.ref=a,this.menuOption=void 0,this.loaded=!1,this.creaturesLoaded=!1,this.keysGetter=Object.keys,this.showMap=!1,this.creaturesMode="status",this.creaturesSortField="base_level",this.creaturesAltSortFields="base_level,gender",this.creaturesSortFunctions={gender:function(l,n,t){return u.i(c.a)(l.Gender,n.Gender,t)},base_level:function(l,n,t){return u.i(c.b)(l.BaseLevel,n.BaseLevel,!t)},tameable:function(l,n,t){return u.i(c.b)(l.IsTameable,n.IsTameable,!t)},latitude:function(l,n,t){return u.i(c.c)(l.Latitude,n.Latitude,t,1)},longitude:function(l,n,t){return u.i(c.c)(l.Longitude,n.Longitude,t,1)},x:function(l,n,t){return u.i(c.c)(l.X,n.X,t,0)},y:function(l,n,t){return u.i(c.c)(l.Y,n.Y,t,0)},z:function(l,n,t){return u.i(c.c)(l.Z,n.Z,t,0)},stat_health:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Health:null,void 0!=n.BaseStats?n.BaseStats.Health:null,!t)},stat_stamina:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Stamina:null,void 0!=n.BaseStats?n.BaseStats.Stamina:null,!t)},stat_oxygen:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Oxygen:null,void 0!=n.BaseStats?n.BaseStats.Oxygen:null,!t)},stat_food:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Food:null,void 0!=n.BaseStats?n.BaseStats.Food:null,!t)},stat_weight:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Weight:null,void 0!=n.BaseStats?n.BaseStats.Weight:null,!t)},stat_melee:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Melee:null,void 0!=n.BaseStats?n.BaseStats.Melee:null,!t)},stat_speed:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.MovementSpeed:null,void 0!=n.BaseStats?n.BaseStats.MovementSpeed:null,!t)},id1:function(l,n,t){return u.i(c.b)(l.Id1,n.Id1,t)},id2:function(l,n,t){return u.i(c.b)(l.Id1,n.Id1,t)}},this.playerSortFunctions={character_name:function(l,n,t){return u.i(c.a)(l.CharacterName,n.CharacterName,t)},tribe_name:function(l,n,t){return u.i(c.a)(l.TribeName,n.TribeName,t)},last_active:function(l,n,t){return u.i(c.b)(l.LastActiveTime,n.LastActiveTime,!t)}},this.tribeSortFunctions={tribe_name:function(l,n,t){return u.i(c.a)(l.Name,n.Name,t)},last_active:function(l,n,t){return u.i(c.b)(l.LastActiveTime,n.LastActiveTime,!t)}},this.wildStatisticsSortFunctions={species:function(l,n,t){return u.i(c.a)(l.Name,n.Name,t)},class_name:function(l,n,t){return u.i(c.a)(l.ClassName,n.ClassName,t)},count:function(l,n,t){return u.i(c.b)(l.Count,n.Count,!t)},fraction:function(l,n,t){return u.i(c.c)(l.Fraction,n.Fraction,!t,4)}}}return l.prototype.getServer=function(){var l=this;this.httpService.getServer(this.serverKey).then(function(n){l.server=n,l.filter(),l.loaded=!0}).catch(function(n){l.server=null,l.filteredPlayers=null,l.filteredTribes=null,l.loaded=!0})},l.prototype.getWildCreatures=function(){var l=this;this.httpService.getWildCreatures(this.serverKey).then(function(n){l.wild=n,l.species=Object.keys(l.wild.Species).sort(function(n,t){return u.i(c.a)(l.wild.Species[n].Name||n,l.wild.Species[t].Name||t,!0)}),l.selectedSpecies&&void 0!=l.species.find(function(n){return n==l.selectedSpecies})||(l.selectedSpecies=l.species.length>0?l.species[0]:null),l.filterAndSortWild(),l.creaturesLoaded=!0,l.ref.detectChanges()}).catch(function(n){l.wild=null,l.species=null,l.filteredCreatures=null,l.creaturesLoaded=!0})},l.prototype.ngOnInit=function(){var l=this;this.accessControl_pages_player=this.dataService.hasFeatureAccessObservable("pages","player"),this.serverKey=this.route.snapshot.params.id,this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){l.menuOption=n,0!=l.creaturesLoaded||"wildcreatures"!=l.menuOption&&"wildcreatures-statistics"!=l.menuOption||l.getWildCreatures()}),this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){l.serverKey==n&&(l.updateServer(),l.showServerUpdateNotification(n))}),this.getServer()},l.prototype.ngOnDestroy=function(){this.menuOptionSubscription.unsubscribe(),this.serverUpdatedSubscription.unsubscribe()},l.prototype.filter=function(){this.filteredPlayers=this.server.Players.filter(function(l){return i(new Date(l.LastActiveTime)).isSameOrAfter(i().subtract(90,"day"))}),this.filteredTribes=this.server.Tribes.filter(function(l){return i(new Date(l.LastActiveTime)).isSameOrAfter(i().subtract(90,"day"))})},l.prototype.sortWild=function(){var l=this,n="-"!=this.creaturesSortField[0],u=this.creaturesSortFunctions[this.creaturesSortField.replace(/^\-/,"")],t=this.creaturesAltSortFields.split(",").map(function(n){var u={};return u.asc="-"!=n[0],u.sortFunc=l.creaturesSortFunctions[n.replace(/^\-/,"")],u});void 0!=this.filteredCreatures&&this.filteredCreatures.sort(function(l,e){var r=u(l,e,n);if(0==r)for(var i=0,a=t;i/gi,window.location.protocol).replace(/\/gi,window.location.hostname).replace(/\/gi,void 0!=config?config.webapi.port:"")},l.ctorParameters=function(){return[{type:t.e}]},l}()},"+SUW":function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},"+T68":function(l,n,u){"use strict";function t(l){return ll._24(0,[(l()(),ll._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,4,"div",[["class","w3-panel theme-l2"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h3",[["class","theme-text-l1-light"]],null,null,null,null,null)),(l()(),ll._26(null,["Loading..."])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,[" \n"]))],null,null)}function e(l){return ll._24(0,[(l()(),ll._25(0,null,null,10,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,7,"div",[["class","w3-panel w3-red"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),ll._26(null,["Error!"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),ll._26(null,["No data could be loaded for the given server key."])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,[" \n"]))],null,null)}function r(l){return ll._24(0,[(l()(),ll._26(null,["\n Character Name\n "]))],null,null)}function i(l){return ll._24(0,[(l()(),ll._25(0,null,null,2,"a",[],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==ll._29(l,1).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),ll._27(335872,null,0,nl.D,[nl.g,nl.v,ul.f],{routerLink:[0,"routerLink"]},null),(l()(),ll._26(null,["",""]))],function(l,n){l(n,1,0,"/player/"+n.parent.context.$implicit.SteamId)},function(l,n){l(n,0,0,ll._29(n,1).target,ll._29(n,1).href),l(n,2,0,n.parent.context.$implicit.CharacterName)})}function a(l){return ll._24(0,[(l()(),ll._26(null,["",""]))],null,function(l,n){l(n,0,0,n.parent.context.$implicit.CharacterName)})}function o(l){return ll._24(0,[(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,2,null,i)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),ll._34(65536,ul.q,[ll.O]),(l()(),ll._28(0,[["player_no_link",2]],null,0,null,a)),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,2,0,ll._33(n,2,0,ll._29(n,3).transform(u.dataService.hasFeatureAccessObservable("pages","player",n.context.$implicit.SteamId))),ll._29(n,4))},null)}function s(l){return ll._24(0,[(l()(),ll._26(null,["\n Tribe Name\n "]))],null,null)}function c(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.TribeName)})}function _(l){return ll._24(0,[(l()(),ll._26(null,["\n Last Active\n "]))],null,null)}function p(l){return ll._24(0,[(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"relative-time",[],null,null,null,tl.a,tl.b)),ll._27(122880,null,0,el.a,[ll.O],{time:[0,"time"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){l(n,2,0,n.context.$implicit.LastActiveTime)},null)}function d(l){return ll._24(0,[(l()(),ll._25(0,null,null,49,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["Players"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,43,"ark-data-table",[["orderByColumn","last_active"],["trackByProp","Id"]],null,null,null,rl.a,rl.b)),ll._27(57344,null,2,il.a,[ll.O],{rows:[0,"rows"],trackByProp:[1,"trackByProp"],sortFunctions:[2,"sortFunctions"],orderByColumn:[3,"orderByColumn"]},null),ll._35(301989888,1,{modeTemplates:1}),ll._35(301989888,2,{columnTemplates:1}),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"ark-dt-mode",[["columnKeys","character_name,tribe_name,last_active"],["key","default"],["name","Default"]],null,null,null,null,null)),ll._27(8192,[[1,4]],0,al.a,[],{key:[0,"key"],name:[1,"name"],columnKeys:[2,"columnKeys"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","character_name"],["thenSort","last_active"],["title","Sort by Character Name"]],null,null,null,null,null)),ll._27(8192,[[2,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,3,{cellTemplate:0}),ll._35(167772160,4,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[4,2]],null,1,null,r)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[3,2]],null,1,null,o)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","tribe_name"],["thenSort","character_name"],["title","Sort by Tribe Name"]],null,null,null,null,null)),ll._27(8192,[[2,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,5,{cellTemplate:0}),ll._35(167772160,6,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[6,2]],null,1,null,s)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[5,2]],null,1,null,c)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","last_active"],["thenSort","character_name"],["title","Sort by Last Active"]],null,null,null,null,null)),ll._27(8192,[[2,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,7,{cellTemplate:0}),ll._35(167772160,8,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[8,2]],null,1,null,_)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[7,2]],null,1,null,p)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n"]))],function(l,n){var u=n.component;l(n,6,0,u.filteredPlayers,"Id",u.playerSortFunctions,"last_active"),l(n,11,0,"default","Default","character_name,tribe_name,last_active"),l(n,14,0,"character_name","last_active","Sort by Character Name",!0),l(n,26,0,"tribe_name","character_name","Sort by Tribe Name",!0),l(n,38,0,"last_active","character_name","Sort by Last Active",!0)},null)}function f(l){return ll._24(0,[(l()(),ll._26(null,["\n Tribe Name\n "]))],null,null)}function m(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.Name)})}function h(l){return ll._24(0,[(l()(),ll._26(null,["\n Members\n "]))],null,null)}function v(l){return ll._24(0,[(l()(),ll._25(0,null,null,2,"a",[],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==ll._29(l,1).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),ll._27(335872,null,0,nl.D,[nl.g,nl.v,ul.f],{routerLink:[0,"routerLink"]},null),(l()(),ll._26(null,["",""]))],function(l,n){l(n,1,0,"/player/"+n.parent.context.$implicit)},function(l,n){var u=n.component;l(n,0,0,ll._29(n,1).target,ll._29(n,1).href);var t=null;l(n,2,0,(null==(t=u.getTribeMember(n.parent.context.$implicit))?null:t.CharacterName)||n.parent.context.$implicit)})}function g(l){return ll._24(0,[(l()(),ll._26(null,["",""]))],null,function(l,n){var u=n.component,t=null;l(n,0,0,(null==(t=u.getTribeMember(n.parent.context.$implicit))?null:t.CharacterName)||n.parent.context.$implicit)})}function y(l){return ll._24(0,[(l()(),ll._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),ll._26(null,[", "]))],null,null)}function b(l){return ll._24(0,[(l()(),ll._25(0,null,null,5,"span",[],null,null,null,null,null)),(l()(),ll._28(8388608,null,null,1,null,v)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),ll._28(0,[["tribe_member_no_link",2]],null,0,null,g)),(l()(),ll._28(8388608,null,null,1,null,y)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null)],function(l,n){l(n,2,0,n.component.dataService.hasFeatureAccess("pages","player",n.context.$implicit),ll._29(n,3)),l(n,5,0,!n.context.last)},null)}function S(l){return ll._24(0,[(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,b)),ll._27(401408,null,0,ul.n,[ll.S,ll._5,ll.v],{ngForOf:[0,"ngForOf"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){l(n,2,0,n.context.$implicit.MemberSteamIds)},null)}function w(l){return ll._24(0,[(l()(),ll._26(null,["\n Last Active\n "]))],null,null)}function k(l){return ll._24(0,[(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"relative-time",[],null,null,null,tl.a,tl.b)),ll._27(122880,null,0,el.a,[ll.O],{time:[0,"time"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){l(n,2,0,n.context.$implicit.LastActiveTime)},null)}function C(l){return ll._24(0,[(l()(),ll._25(0,null,null,49,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["Tribes"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,43,"ark-data-table",[["orderByColumn","last_active"],["trackByProp","Id"]],null,null,null,rl.a,rl.b)),ll._27(57344,null,2,il.a,[ll.O],{rows:[0,"rows"],trackByProp:[1,"trackByProp"],sortFunctions:[2,"sortFunctions"],orderByColumn:[3,"orderByColumn"]},null),ll._35(301989888,9,{modeTemplates:1}),ll._35(301989888,10,{columnTemplates:1}),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"ark-dt-mode",[["columnKeys","tribe_name,members,last_active"],["key","default"],["name","Default"]],null,null,null,null,null)),ll._27(8192,[[9,4]],0,al.a,[],{key:[0,"key"],name:[1,"name"],columnKeys:[2,"columnKeys"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","tribe_name"],["thenSort","last_active"],["title","Sort by Tribe Name"]],null,null,null,null,null)),ll._27(8192,[[10,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,11,{cellTemplate:0}),ll._35(167772160,12,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[12,2]],null,1,null,f)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[11,2]],null,1,null,m)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","members"]],null,null,null,null,null)),ll._27(8192,[[10,4]],2,ol.a,[],{key:[0,"key"]},null),ll._35(167772160,13,{cellTemplate:0}),ll._35(167772160,14,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[14,2]],null,1,null,h)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[13,2]],null,1,null,S)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","last_active"],["thenSort","tribe_name"],["title","Sort by Last Active"]],null,null,null,null,null)),ll._27(8192,[[10,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,15,{cellTemplate:0}),ll._35(167772160,16,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[16,2]],null,1,null,w)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[15,2]],null,1,null,k)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n"]))],function(l,n){var u=n.component;l(n,6,0,u.filteredTribes,"Id",u.tribeSortFunctions,"last_active"),l(n,11,0,"default","Default","tribe_name,members,last_active"),l(n,14,0,"tribe_name","last_active","Sort by Tribe Name",!0),l(n,26,0,"members"),l(n,38,0,"last_active","tribe_name","Sort by Last Active",!0)},null)}function I(l){return ll._24(0,[(l()(),ll._26(null,["\n Species\n "]))],null,null)}function x(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.Name)})}function O(l){return ll._24(0,[(l()(),ll._26(null,["\n Class Name\n "]))],null,null)}function A(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.ClassName)})}function T(l){return ll._24(0,[(l()(),ll._26(null,["\n Aliases\n "]))],null,null)}function F(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "]))],null,function(l,n){l(n,0,0,n.context.$implicit.Aliases.length>0?n.context.$implicit.Aliases.join(", "):"")})}function M(l){return ll._24(0,[(l()(),ll._26(null,["\n Count\n "]))],null,null)}function L(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "])),ll._32(1)],null,function(l,n){l(n,0,0,ll._33(n,0,0,l(n,1,0,ll._29(n.parent.parent,0),n.context.$implicit.Count)))})}function P(l){return ll._24(0,[(l()(),ll._26(null,["\n Fraction\n "]))],null,null)}function N(l){return ll._24(0,[(l()(),ll._26(null,["\n ","\n "])),ll._32(2)],null,function(l,n){l(n,0,0,ll._33(n,0,0,l(n,1,0,ll._29(n.parent.parent,1),n.context.$implicit.Fraction,"1.0-4")))})}function B(l){return ll._24(0,[(l()(),ll._25(0,null,null,76,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,4,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["Wild Statistics "])),(l()(),ll._25(0,null,null,2,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(1),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,67,"ark-data-table",[["orderByColumn","species"],["trackByProp","ClassName"]],null,null,null,rl.a,rl.b)),ll._27(57344,null,2,il.a,[ll.O],{rows:[0,"rows"],trackByProp:[1,"trackByProp"],sortFunctions:[2,"sortFunctions"],orderByColumn:[3,"orderByColumn"]},null),ll._35(301989888,17,{modeTemplates:1}),ll._35(301989888,18,{columnTemplates:1}),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"ark-dt-mode",[["columnKeys","species,class_name,aliases,count,fraction"],["key","default"],["name","Default"]],null,null,null,null,null)),ll._27(8192,[[17,4]],0,al.a,[],{key:[0,"key"],name:[1,"name"],columnKeys:[2,"columnKeys"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","species"],["thenSort","count"],["title","Sort by Species"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,19,{cellTemplate:0}),ll._35(167772160,20,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[20,2]],null,1,null,I)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[19,2]],null,1,null,x)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","class_name"],["thenSort","count"],["title","Sort by Class Name"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,21,{cellTemplate:0}),ll._35(167772160,22,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[22,2]],null,1,null,O)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[21,2]],null,1,null,A)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","aliases"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"]},null),ll._35(167772160,23,{cellTemplate:0}),ll._35(167772160,24,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[24,2]],null,1,null,T)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[23,2]],null,1,null,F)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","count"],["thenSort","species"],["title","Sort by Count"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,25,{cellTemplate:0}),ll._35(167772160,26,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[26,2]],null,1,null,M)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[25,2]],null,1,null,L)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"ark-dt-column",[["key","fraction"],["thenSort","species"],["title","Sort by Fraction"]],null,null,null,null,null)),ll._27(8192,[[18,4]],2,ol.a,[],{key:[0,"key"],thenSort:[1,"thenSort"],title:[2,"title"],orderBy:[3,"orderBy"]},null),ll._35(167772160,27,{cellTemplate:0}),ll._35(167772160,28,{headerTemplate:0}),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[28,2]],null,1,null,P)),ll._27(8192,null,0,ol.b,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(0,[[27,2]],null,1,null,N)),ll._27(8192,null,0,ol.c,[ll._5],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n"]))],function(l,n){var u=n.component;l(n,9,0,u.wild.Statistics.Species,"ClassName",u.wildStatisticsSortFunctions,"species"),l(n,14,0,"default","Default","species,class_name,aliases,count,fraction"),l(n,17,0,"species","count","Sort by Species",!0),l(n,29,0,"class_name","count","Sort by Class Name",!0),l(n,41,0,"aliases"),l(n,53,0,"count","species","Sort by Count",!0),l(n,65,0,"fraction","species","Sort by Fraction",!0)},function(l,n){var u=n.component;l(n,5,0,ll._33(n,5,0,l(n,6,0,ll._29(n.parent,0),(null==u.wild.Statistics.Species?null:u.wild.Statistics.Species.length)||0)))})}function K(l){return ll._24(0,[(l()(),ll._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),ll._26(null,["There are no creatures..."]))],null,null)}function j(l){return ll._24(0,[(l()(),ll._25(0,null,null,3,"option",[],null,null,null,null,null)),ll._27(73728,null,0,sl.k,[ll.K,ll.J,[2,sl.l]],{value:[0,"value"]},null),ll._27(73728,null,0,sl.m,[ll.K,ll.J,[8,null]],{value:[0,"value"]},null),(l()(),ll._26(null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit),l(n,2,0,n.context.$implicit)},function(l,n){l(n,3,0,n.component.wild.Species[n.context.$implicit].Name||n.context.$implicit)})}function $(l){return ll._24(0,[(l()(),ll._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("stats")&&t}return t},null,null)),ll._27(139264,null,0,ul.m,[ll.v,ll.w,ll.K,ll.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),ll._31(["theme-d1"]),(l()(),ll._26(null,["Base Stats"]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCreaturesMode("stats")))},function(l,n){l(n,0,0,100/n.component.numCreatureTabs())})}function R(l){return ll._24(0,[(l()(),ll._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("ids")&&t}return t},null,null)),ll._27(139264,null,0,ul.m,[ll.v,ll.w,ll.K,ll.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),ll._31(["theme-d1"]),(l()(),ll._26(null,["IDs"]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCreaturesMode("ids")))},function(l,n){l(n,0,0,100/n.component.numCreatureTabs())})}function D(l){return ll._24(0,[(l()(),ll._25(0,null,null,12,"div",[["class","w3-bar theme-l2 w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("status")&&t}return t},null,null)),ll._27(139264,null,0,ul.m,[ll.v,ll.w,ll.K,ll.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),ll._31(["theme-d1"]),(l()(),ll._26(null,["Overview"])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,$)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,R)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,"w3-bar-item w3-button w3-mobile",l(n,4,0,u.activeCreaturesMode("status"))),l(n,8,0,u.dataService.hasFeatureAccess("server","wildcreatures-basestats")),l(n,11,0,u.dataService.hasFeatureAccess("server","wildcreatures-ids"))},function(l,n){l(n,2,0,100/n.component.numCreatureTabs())})}function E(l){return ll._24(0,[(l()(),ll._25(0,null,null,16,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by X"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("x")&&t}return t},null,null)),(l()(),ll._26(null,["X"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Y"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("y")&&t}return t},null,null)),(l()(),ll._26(null,["Y"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Z"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("z")&&t}return t},null,null)),(l()(),ll._26(null,["Z"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Latitude"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("latitude")&&t}return t},null,null)),(l()(),ll._26(null,["Lat"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Longitude"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("longitude")&&t}return t},null,null)),(l()(),ll._26(null,["Lng"])),(l()(),ll._26(null,["\n "]))],null,null)}function U(l){return ll._24(0,[(l()(),ll._25(0,null,null,23,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Health"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_health")&&t}return t},null,null)),(l()(),ll._26(null,["HP"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Stamina"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_stamina")&&t}return t},null,null)),(l()(),ll._26(null,["ST"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Oxygen"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_oxygen")&&t}return t},null,null)),(l()(),ll._26(null,["OX"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Food"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_food")&&t}return t},null,null)),(l()(),ll._26(null,["FO"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Weight"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_weight")&&t}return t},null,null)),(l()(),ll._26(null,["WE"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Melee"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_melee")&&t}return t},null,null)),(l()(),ll._26(null,["ME"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Speed"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_speed")&&t}return t},null,null)),(l()(),ll._26(null,["SP"])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "]))],null,null)}function z(l){return ll._24(0,[(l()(),ll._25(0,null,null,7,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by ID1"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("id1")&&t}return t},null,null)),(l()(),ll._26(null,["ID1"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by ID2"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("id2")&&t}return t},null,null)),(l()(),ll._26(null,["ID2"])),(l()(),ll._26(null,["\n "]))],null,null)}function J(l){return ll._24(0,[(l()(),ll._25(0,null,null,2,"tr",[],null,null,null,null,null)),(l()(),ll._25(0,null,null,1,"td",[],[[8,"colSpan",0]],null,null,null,null)),(l()(),ll._26(null,["No matching creatures..."]))],null,function(l,n){var u=n.component;l(n,1,0,u.activeCreaturesMode("status")?8:u.activeCreaturesMode("stats")?10:5)})}function G(l){return ll._24(0,[(l()(),ll._25(0,null,null,18,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(2),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(2),(l()(),ll._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.parent.context.$implicit.X),l(n,6,0,n.parent.context.$implicit.Y),l(n,9,0,n.parent.context.$implicit.Z),l(n,12,0,ll._33(n,12,0,l(n,13,0,ll._29(n.parent.parent.parent.parent,0),n.parent.context.$implicit.Latitude,"1.1-1"))),l(n,16,0,ll._33(n,16,0,l(n,17,0,ll._29(n.parent.parent.parent.parent,0),n.parent.context.$implicit.Longitude,"1.1-1")))})}function H(l){return ll._24(0,[(l()(),ll._25(0,null,null,23,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "]))],null,function(l,n){l(n,3,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Health),l(n,6,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Stamina),l(n,9,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Oxygen),l(n,12,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Food),l(n,15,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Weight),l(n,18,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Melee),l(n,21,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.MovementSpeed)})}function X(l){return ll._24(0,[(l()(),ll._25(0,null,null,7,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.parent.context.$implicit.Id1),l(n,6,0,n.parent.context.$implicit.Id2)})}function W(l){return ll._24(0,[(l()(),ll._25(0,null,null,19,"tr",[],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),ll._26(null,["",""])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,G)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,H)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,X)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,12,0,u.activeCreaturesMode("status")),l(n,15,0,u.activeCreaturesMode("stats")),l(n,18,0,u.activeCreaturesMode("ids"))},function(l,n){var u=n.component;l(n,3,0,n.context.$implicit.Gender),l(n,6,0,n.context.$implicit.BaseLevel),l(n,9,0,u.wild.Species[u.selectedSpecies].IsTameable&&1==n.context.$implicit.IsTameable?"Yes":"No")})}function V(l){return ll._24(0,[(l()(),ll._25(0,null,null,55,null,null,null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,9,"select",[["class","w3-select w3-border w3-round-xlarge w3-large w3-margin-bottom border-theme theme-l1"],["style","padding: 8px;"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"blur"]],function(l,n,u){var t=!0,e=l.component;if("change"===n){t=!1!==ll._29(l,3).onChange(u.target.value)&&t}if("blur"===n){t=!1!==ll._29(l,3).onTouched()&&t}if("ngModelChange"===n){e.selectedSpecies=u;t=!1!==e.filterAndSortWild()&&t}return t},null,null)),ll._27(8192,null,0,sl.l,[ll.J,ll.K],null,null),ll._37(512,null,sl.g,function(l){return[l]},[sl.l]),ll._27(335872,null,0,sl.h,[[8,null],[8,null],[8,null],[2,sl.g]],{model:[0,"model"]},{update:"ngModelChange"}),ll._37(1024,null,sl.i,null,[sl.h]),ll._27(8192,null,0,sl.j,[sl.i],null,null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,j)),ll._27(401408,null,0,ul.n,[ll.S,ll._5,ll.v],{ngForOf:[0,"ngForOf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,D)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,37,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,34,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,22,"thead",[],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,19,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Gender"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("gender")&&t}return t},null,null)),(l()(),ll._26(null,["Gender"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Base Level"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("base_level")&&t}return t},null,null)),(l()(),ll._26(null,["Base Level"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Tameable"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("tameable")&&t}return t},null,null)),(l()(),ll._26(null,["Tameable"])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,E)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,U)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,z)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,7,"tbody",[],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,J)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,W)),ll._27(401408,null,0,ul.n,[ll.S,ll._5,ll.v],{ngForOf:[0,"ngForOf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,5,0,u.selectedSpecies),l(n,10,0,u.species),l(n,15,0,u.numCreatureTabs()>1),l(n,35,0,u.activeCreaturesMode("status")),l(n,38,0,u.activeCreaturesMode("stats")),l(n,41,0,u.activeCreaturesMode("ids")),l(n,48,0,!((null==u.filteredCreatures?null:u.filteredCreatures.length)>0)),l(n,51,0,u.filteredCreatures)},function(l,n){l(n,2,0,ll._29(n,7).ngClassUntouched,ll._29(n,7).ngClassTouched,ll._29(n,7).ngClassPristine,ll._29(n,7).ngClassDirty,ll._29(n,7).ngClassValid,ll._29(n,7).ngClassInvalid,ll._29(n,7).ngClassPending)})}function Y(l){return ll._24(0,[(l()(),ll._25(0,null,null,26,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,17,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,10,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),ll._25(0,null,null,0,"a",[["id","creatures"]],null,null,null,null,null)),(l()(),ll._25(0,null,null,8,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),ll._26(null,["Wild Creatures "])),(l()(),ll._25(0,null,null,2,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(1),(l()(),ll._26(null,[" / "])),(l()(),ll._25(0,null,null,2,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,["",""])),ll._32(1),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,2,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),ll._25(0,null,null,1,"button",[["class","w3-button theme-d1 w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.openMap(u)&&t}return t},null,null)),(l()(),ll._26(null,["Show Map"])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,K)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._28(8388608,null,null,1,null,V)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"]))],function(l,n){var u=n.component;l(n,22,0,!((null==u.species?null:u.species.length)>0)),l(n,25,0,(null==u.species?null:u.species.length)>0)},function(l,n){var u=n.component;l(n,9,0,ll._33(n,9,0,l(n,10,0,ll._29(n.parent,0),(null==u.filteredCreatures?null:u.filteredCreatures.length)||0))),l(n,13,0,ll._33(n,13,0,l(n,14,0,ll._29(n.parent,0),(null==u.wild?null:null==u.wild.Statistics?null:u.wild.Statistics.CreatureCount)||0)))})}function q(l){return ll._24(0,[ll._34(0,ul.p,[ll.t]),ll._34(0,ul.r,[ll.t]),(l()(),ll._28(8388608,null,null,1,null,t)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,e)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,d)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,C)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,B)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._28(8388608,null,null,1,null,Y)),ll._27(8192,null,0,ul.l,[ll.S,ll._5],{ngIf:[0,"ngIf"]},null),(l()(),ll._26(null,["\n"])),(l()(),ll._25(0,null,null,17,"div",[["class","w3-modal"],["id","modal_map"]],[[4,"display",null]],null,null,null,null)),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,14,"div",[["class","w3-modal-content w3-card-4 w3-animate-zoom"],["style","font-size: 0;"]],null,[[null,"clickOutside"],["document","click"]],function(l,n,u){var t=!0,e=l.component;if("document:click"===n){t=!1!==ll._29(l,23).onClick(u,u.target)&&t}if("clickOutside"===n){t=!1!==e.closeMap(u)&&t}return t},null,null)),ll._27(8192,null,0,_l.a,[ll.K],null,{clickOutside:"clickOutside"}),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),ll._26(null,[" \n "])),(l()(),ll._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.showMap=!1)&&t}return t},null,null)),(l()(),ll._26(null,["×"])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),ll._26(null,["Map"])),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "])),(l()(),ll._25(0,null,null,1,"arkmap",[],null,null,null,pl.a,pl.b)),ll._27(286720,null,0,dl.a,[],{mapName:[0,"mapName"],points:[1,"points"]},null),(l()(),ll._26(null,["\n "])),(l()(),ll._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,0==u.loaded||(u.isMenuActive("wildcreatures")||u.isMenuActive("wildcreatures-statistics"))&&0==u.creaturesLoaded),l(n,6,0,1==u.loaded&&null==u.server),l(n,9,0,u.isMenuActive("players")&&u.server&&u.dataService.hasFeatureAccess("server","players")),l(n,12,0,u.isMenuActive("tribes")&&u.server&&u.dataService.hasFeatureAccess("server","tribes")),l(n,15,0,u.isMenuActive("wildcreatures-statistics")&&u.creaturesLoaded&&u.dataService.hasFeatureAccess("server","wildcreatures-statistics")),l(n,18,0,u.isMenuActive("wildcreatures")&&u.creaturesLoaded&&u.dataService.hasFeatureAccess("server","wildcreatures")),l(n,35,0,null==u.server?null:u.server.MapName,u.points)},function(l,n){l(n,20,0,n.component.showMap?"block":"none")})}function Q(l){return ll._24(0,[(l()(),ll._25(0,null,null,1,"app-server",[],null,null,null,q,yl)),ll._27(122880,null,0,cl.a,[nl.v,nl.g,fl.a,ml.a,hl.a,vl.a,ll.O],null,null)],function(l,n){l(n,1,0)},null)}var Z=u("ZfYc"),ll=u("3j3K"),nl=u("5oXY"),ul=u("2Je8"),tl=u("6Nb/"),el=u("0onv"),rl=u("fYAd"),il=u("0jRk"),al=u("joX7"),ol=u("jWPz"),sl=u("NVOs"),cl=u("qn86"),_l=u("8zLQ"),pl=u("I9JA"),dl=u("5305"),fl=u("lHWG"),ml=u("ATz5"),hl=u("+Lwu"),vl=u("XLrO");u.d(n,"a",function(){return bl});var gl=[Z.a],yl=ll._23({encapsulation:0,styles:gl,data:{}}),bl=ll._30("app-server",cl.a,Q,{},{},[])},"+qYp":function(l,n,u){"use strict";var t=u("ATz5"),e=u("3MNG"),r=u("+Lwu");u.d(n,"a",function(){return i});var i=function(){function l(l,n,u){this.dataService=l,this.messageService=n,this.notificationsService=u,this.menuOption=void 0}return l.prototype.ngOnInit=function(){var l=this;this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.showServerUpdateNotification(n)}),this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n})},l.prototype.ngOnDestroy=function(){this.serverUpdatedSubscription.unsubscribe(),this.menuOptionSubscription.unsubscribe()},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.ctorParameters=function(){return[{type:t.a},{type:r.a},{type:e.a}]},l}()},"+rAa":function(l,n,u){"use strict";function t(l,n,u,t){var e=i(l,n,u);if(void 0!=e)return e;var r=Math.pow(10,t),a=void 0!=t?Math.round(l*r)/r:l,o=void 0!=t?Math.round(n*r)/r:n;return a>o?u?1:-1:an?u?1:-1:l0&&(this._currentMode=this._modes[0].key)}}},enumerable:!0,configurable:!0}),Object.defineProperty(l.prototype,"columnTemplates",{set:function(l){if(l){var n=l.toArray();if(n.length){for(var u=[],t=0,e=n;t=this._rows.length&&(n=this._rows.length-1),this._fromRow=parseInt(""+n),this.ref.markForCheck()},l.prototype.setViewOffsetRelative=function(l){this.setViewOffset(this._fromRow+l)},l.prototype.setFirstPage=function(){this.isFirstPage()||this.setViewOffset(0)},l.prototype.setPrevPage=function(){this.isFirstPage()||this.setViewOffsetRelative(-this._numRows)},l.prototype.setNextPage=function(){this.isLastPage()||this.setViewOffsetRelative(this._numRows)},l.prototype.setLastPage=function(){this.isLastPage()||this.setViewOffset(this._rows.length-this._numRows)},l.prototype.isFirstPage=function(){return this._fromRow<=0},l.prototype.isLastPage=function(){return this._fromRow>=this._rows.length-this._numRows},l.prototype.setViewLimit=function(l){this._numRows=parseInt(""+(l>0?l:1e6)),this.ref.markForCheck()},l.prototype.getLastRowOffset=function(){var l=this._fromRow+this._numRows;return l>this._rows.length?this._rows.length:l},l.ctorParameters=function(){return[{type:t.O}]},l}()},"0onv":function(l,n,u){"use strict";var t=u("3j3K"),e=u("Gvdl"),r=(u.n(e),u("PJh5"));u.n(r);u.d(n,"a",function(){return i});var i=function(){function l(l){this.ref=l,this._time=new e.BehaviorSubject(void 0)}return Object.defineProperty(l.prototype,"time",{get:function(){return this._time.getValue()},set:function(l){this._time.next(l)},enumerable:!0,configurable:!0}),l.prototype.ngOnInit=function(){var l=this;this._timeSubscription=this._time.subscribe(function(n){l.update()}),this._counter=e.Observable.interval(1e3).map(function(l){return l}),this._counterSubscription=this._counter.subscribe(function(n){return l.update()})},l.prototype.ngOnDestroy=function(){this._timeSubscription.unsubscribe(),this._counterSubscription.unsubscribe()},l.prototype.update=function(){var l=this.toRelativeDate(this.time);l!=this._str&&(this._str=l,this.ref.markForCheck())},l.prototype.toRelativeDate=function(l){return r(new Date(l)).fromNow()},l.ctorParameters=function(){return[{type:t.O}]},l}()},"1A80":function(l,n,u){"use strict";function t(l){return o._24(0,[(l()(),o._25(0,null,null,4,"span",[],null,null,null,null,null)),(l()(),o._26(null,["Logged in as "," | "])),(l()(),o._25(0,null,null,1,"a",[],[[8,"href",4]],null,null,null,null)),(l()(),o._26(null,["Logout"])),(l()(),o._26(null,[" | "]))],null,function(l,n){var u=n.component;l(n,1,0,u.dataService.Servers.User.Name),l(n,2,0,u.getLogoutUrl())})}function e(l){return o._24(0,[(l()(),o._25(0,null,null,3,"span",[],null,null,null,null,null)),(l()(),o._25(0,null,null,1,"a",[["href","#"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.openLogin(u)&&t}return t},null,null)),(l()(),o._26(null,["Login"])),(l()(),o._26(null,[" | "]))],null,null)}function r(l){return o._24(0,[(l()(),o._25(0,null,null,1,"simple-notifications",[],null,null,null,s.a,s.b)),o._27(122880,null,0,c.a,[_.a],{options:[0,"options"]},null),(l()(),o._26(null,["\n"])),(l()(),o._26(null,["\n\n"])),(l()(),o._25(8388608,null,null,1,"router-outlet",[["name","menu"]],null,null,null,null,null)),o._27(73728,null,0,p.z,[p.l,o.S,o.T,[8,"menu"]],null,null),(l()(),o._26(null,["\n"])),(l()(),o._25(0,null,null,22,"div",[["id","page"]],null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,16,"div",[["class","w3-bar"]],null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"breadcrumb",[["class","breadcrumb w3-bar-item"],["prefix","Home"]],null,null,null,d.a,d.b)),o._27(385024,null,0,f.a,[p.g,m.a],{useBootstrap:[0,"useBootstrap"],prefix:[1,"prefix"]},null),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,10,"div",[["class","w3-bar-item w3-right w3-tiny theme-l1"]],null,null,null,null,null)),(l()(),o._28(8388608,null,null,1,null,t)),o._27(8192,null,0,h.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null),(l()(),o._28(8388608,null,null,1,null,e)),o._27(8192,null,0,h.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null),(l()(),o._26(null,["Theme: "])),(l()(),o._25(0,null,null,1,"a",[["href","#"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setTheme("light")&&t}return t},null,null)),(l()(),o._26(null,["Light"])),(l()(),o._26(null,[" | "])),(l()(),o._25(0,null,null,1,"a",[["href","#"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setTheme("dark")&&t}return t},null,null)),(l()(),o._26(null,["Dark"])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n "])),(l()(),o._25(8388608,null,null,1,"router-outlet",[],null,null,null,null,null)),o._27(73728,null,0,p.z,[p.l,o.S,o.T,[8,null]],null,null),(l()(),o._26(null,["\n"])),(l()(),o._26(null,["\n"])),(l()(),o._25(0,null,null,31,"div",[["class","w3-modal"],["id","modal_login"]],[[4,"display",null]],null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,28,"div",[["class","w3-modal-content w3-card-4 w3-animate-zoom"],["style","font-size: 0;"]],null,[[null,"clickOutside"],["document","click"]],function(l,n,u){var t=!0,e=l.component;if("document:click"===n){t=!1!==o._29(l,34).onClick(u,u.target)&&t}if("clickOutside"===n){t=!1!==e.closeLogin(u)&&t}return t},null,null)),o._27(8192,null,0,g.a,[o.K],null,{clickOutside:"clickOutside"}),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),o._26(null,[" \n "])),(l()(),o._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.showLogin=!1)&&t}return t},null,null)),(l()(),o._26(null,["×"])),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),o._26(null,["Log In"])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,15,"form",[["class","w3-container theme-l2 w3-medium"],["method","post"],["ngNoForm",""]],[[8,"action",4]],null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,12,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),o._26(null,["To give you access to personal information, first, we must verify your identity."])),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),o._26(null,["Please authenticate with our app through Steam by clicking on the button below."])),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,0,"input",[["name","returnUrl"],["type","hidden"]],[[8,"value",0]],null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,1,"button",[["class","w3-button w3-block theme-d1 w3-section w3-padding"],["name","provider"],["title","Log in using your Steam account"],["type","submit"]],null,null,null,null,null)),(l()(),o._26(null,["Go to Steam"])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n "])),(l()(),o._26(null,["\n"]))],function(l,n){var u=n.component;l(n,1,0,u.notificationOptions),l(n,12,0,!1,"Home"),l(n,16,0,null==u.dataService.Servers?null:null==u.dataService.Servers.User?null:u.dataService.Servers.User.SteamId),l(n,18,0,!(null==u.dataService.Servers?null:null==u.dataService.Servers.User?null:u.dataService.Servers.User.SteamId))},function(l,n){var u=n.component;l(n,31,0,u.showLogin?"block":"none"),l(n,45,0,u.getLoginUrl()),l(n,55,0,u.currentUrl)})}function i(l){return o._24(0,[(l()(),o._25(0,null,null,1,"body",[],[[8,"className",0]],null,null,r,w)),o._27(122880,null,0,v.a,[y.a,b.a,m.a,_.a,p.g],null,null)],function(l,n){l(n,1,0)},function(l,n){l(n,0,0,o._29(n,1).getTheme())})}var a=u("Ni5f"),o=u("3j3K"),s=u("XhEa"),c=u("B8cY"),_=u("XLrO"),p=u("5oXY"),d=u("if6N"),f=u("v8ur"),m=u("aT6V"),h=u("2Je8"),v=u("YWx4"),g=u("8zLQ"),y=u("ATz5"),b=u("lHWG");u.d(n,"a",function(){return k});var S=[a.a],w=o._23({encapsulation:0,styles:S,data:{}}),k=o._30("body",v.a,i,{},{},[])},"1AkI":function(l,n,u){"use strict";function t(l){return c._24(0,[(l()(),c._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._29(l.parent,2).activate("players")&&t}return t},null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._31(["theme-d1"]),(l()(),c._26(null,["Players"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,c._29(n.parent,2).active("players")))},null)}function e(l){return c._24(0,[(l()(),c._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._29(l.parent,2).activate("tribes")&&t}return t},null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._31(["theme-d1"]),(l()(),c._26(null,["Tribes"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,c._29(n.parent,2).active("tribes")))},null)}function r(l){return c._24(0,[(l()(),c._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._29(l.parent,2).activate("wildcreatures-statistics")&&t}return t},null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._31(["theme-d1"]),(l()(),c._26(null,["Wild Statistics"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,c._29(n.parent,2).active("wildcreatures-statistics")))},null)}function i(l){return c._24(0,[(l()(),c._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==c._29(l.parent,2).activate("wildcreatures")&&t}return t},null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),c._31(["theme-d1"]),(l()(),c._26(null,["Wild Creatures"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,c._29(n.parent,2).active("wildcreatures")))},null)}function a(l){return c._24(0,[c._35(201326592,1,{menu:0}),(l()(),c._25(0,null,null,20,"app-menu",[],null,null,null,p.a,p.b)),c._27(122880,[[1,4],["menu",4]],0,d.a,[f.a],null,null),(l()(),c._26(0,["\n "])),(l()(),c._25(0,null,0,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),c._26(null,["Server"])),(l()(),c._26(0,["\n "])),(l()(),c._25(0,null,0,13,"div",[["class","w3-cell-row theme-l2"]],null,null,null,null,null)),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,t)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,e)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,r)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,i)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._26(0,["\n"]))],function(l,n){var u=n.component;l(n,2,0),l(n,10,0,u.dataService.hasFeatureAccess("server","players")),l(n,13,0,u.dataService.hasFeatureAccess("server","tribes")),l(n,16,0,u.dataService.hasFeatureAccess("server","wildcreatures-statistics")),l(n,19,0,u.dataService.hasFeatureAccess("server","wildcreatures"))},null)}function o(l){return c._24(0,[(l()(),c._25(0,null,null,1,"app-server-menu",[],[[8,"className",0]],null,null,a,v)),c._27(57344,null,0,m.a,[f.a],null,null)],function(l,n){l(n,1,0)},function(l,n){l(n,0,0,c._29(n,1).menu.className)})}var s=u("nJHW"),c=u("3j3K"),_=u("2Je8"),p=u("coiB"),d=u("8kYA"),f=u("ATz5"),m=u("7xIs");u.d(n,"a",function(){return g});var h=[s.a],v=c._23({encapsulation:0,styles:h,data:{}}),g=c._30("app-server-menu",m.a,o,{},{},[])},"2dXI":function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},5305:function(l,n,u){"use strict";var t=u("kZql"),e=u("f4AQ");u.n(e);u.d(n,"a",function(){return r});var r=function(){function l(){this.width=1024,this.height=1024,this.zoom=e.zoom().scaleExtent([1,10])}return l.prototype.imageLoaded=function(l){var n=this;this.img=l,this.width=l.naturalWidth,this.height=l.naturalHeight,window.setTimeout(function(){n.resize(),n.redraw()},100)},l.prototype.resize=function(){},l.prototype.zoomed=function(){var l=e.zoomTransform(this.canvasRef.nativeElement),n=this.canvasRef.nativeElement.getContext("2d");n.setTransform(1,0,0,1,0,0),n.clearRect(0,0,this.width,this.height),n.translate(l.x,l.y),n.scale(l.k,l.k),this.redraw()},l.prototype.redraw=function(){var l=this.canvasRef.nativeElement.getContext("2d");if(l.drawImage(this.img,0,0),null!=this.points)for(var n=0,u=this.points;n/gi,window.location.protocol).replace(/\/gi,window.location.hostname).replace(/\/gi,void 0!=config?config.webapi.port:"")},l.ctorParameters=function(){return[]},l}()},"6Nb/":function(l,n,u){"use strict";function t(l){return i._24(2,[(l()(),i._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),i._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component._str)})}function e(l){return i._24(0,[(l()(),i._25(0,null,null,1,"relative-time",[],null,null,null,t,s)),i._27(122880,null,0,a.a,[i.O],null,null)],function(l,n){l(n,1,0)},null)}var r=u("/tjS"),i=u("3j3K"),a=u("0onv");u.d(n,"b",function(){return s}),n.a=t;var o=[r.a],s=i._23({encapsulation:0,styles:o,data:{}});i._30("relative-time",a.a,e,{time:"time"},{},[])},"7MbP":function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},"7T2B":function(l,n,u){"use strict";var t=u("3j3K");u.d(n,"a",function(){return e});var e=function(){function l(){this.callback=new t.Q,this.confirming=!1}return l.prototype.ngOnInit=function(){},l.prototype.onClick=function(l){var n=this;this.confirming?l.detail>=3&&(window.clearTimeout(this.resetTimeout),this.confirming=!1,this.callback.emit()):(this.confirming=!0,this.resetTimeout=window.setTimeout(function(){n.confirming=!1},5e3))},l.ctorParameters=function(){return[]},l}()},"7xIs":function(l,n,u){"use strict";var t=u("ATz5");u.d(n,"a",function(){return e});var e=function(){function l(l){this.dataService=l}return l.prototype.ngOnInit=function(){this.dataService.hasFeatureAccess("server","players")?this.menu.activate("players"):this.dataService.hasFeatureAccess("server","tribes")?this.menu.activate("tribes"):this.dataService.hasFeatureAccess("server","wildcreatures-statistics")?this.menu.activate("wildcreatures-statistics"):this.dataService.hasFeatureAccess("server","wildcreatures")&&this.menu.activate("wildcreatures")},l.ctorParameters=function(){return[{type:t.a}]},l}()},"8kYA":function(l,n,u){"use strict";var t=u("ATz5");u.d(n,"a",function(){return e});var e=function(){function l(l){this.dataService=l,this.menuOption=void 0,this.menuVisible=!1,this.className="menucontainer"}return l.prototype.ngOnInit=function(){var l=this;this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n})},l.prototype.ngOnDestroy=function(){this.menuOptionSubscription.unsubscribe()},l.prototype.activate=function(l){this.dataService.SetMenuOption(l)},l.prototype.active=function(l){return this.menuOption==l},l.prototype.toggleMenu=function(){this.menuVisible=!this.menuVisible},l.ctorParameters=function(){return[{type:t.a}]},l}()},"8zLQ":function(l,n,u){"use strict";var t=u("3j3K");u.d(n,"a",function(){return e});var e=function(){function l(l){this._elementRef=l,this.clickOutside=new t.Q}return l.prototype.onClick=function(l,n){if(n){this._elementRef.nativeElement.contains(n)||this.clickOutside.emit(l)}},l.ctorParameters=function(){return[{type:t.K}]},l}()},ATz5:function(l,n,u){"use strict";var t=u("3j3K"),e=u("Gvdl"),r=(u.n(e),u("lHWG")),i=u("+Lwu"),a=u("kZql"),o=u("PJh5");u.n(o);u.d(n,"a",function(){return s});var s=function(){function l(l,n){var u=this;this.httpService=l,this.messageService=n,this._servers=new e.BehaviorSubject(void 0),this.menuOption=new e.BehaviorSubject(void 0),this.ServersUpdated$=new t.Q,n.serverUpdated$.subscribe(function(l){return u.updateServer(l)})}return Object.defineProperty(l.prototype,"MenuOption",{get:function(){return this.menuOption.asObservable()},enumerable:!0,configurable:!0}),l.prototype.SetMenuOption=function(l){this.menuOption.next(l)},l.prototype.getServers=function(){var l=this;return this.httpService.getServers().then(function(n){l.Servers=n;var u=n?n.User:void 0;return l.UserSteamId=u&&u.SteamId?u.SteamId:void 0,l._servers.next(n),l.ServersUpdated$.emit(n),!0}).catch(function(n){return l.Servers=null,l.UserSteamId=void 0,l._servers.next(null),l.ServersUpdated$.emit(null),!1})},l.prototype.updateServer=function(l){this.getServers()},l.prototype.hasFeatureAccess=function(l,n,u){var t=this.Servers?this.Servers.AccessControl:void 0;if(!t)return!1;var e=t[l];if(!e)return!1;var r=e[n];if(!r)return!1;var i=this.Servers?this.Servers.User:void 0,a=i&&i.Roles?i.Roles.slice(0):[];i&&i.SteamId&&i.SteamId==u&&a.push("self");for(var o=function(l){if(r.find(function(n){return l.toLowerCase()===n.toLowerCase()}))return{value:!0}},s=0,c=a;s0&&e.push(t+"d"),(t>0||u>0)&&e.push(u+"h"),(t>0||u>0||n>0)&&e.push(n+"m"),e.push(l+"s"),this._str=e.join(" "),this._ready=!1,this.state._completed=!1},l.prototype.ngOnInit=function(){var l=this;this._timeSubscription=this._time.subscribe(function(n){l.updateDiff(n),l.update()}),this._notificationSubscription=this._notification.subscribe(function(l){}),this._counter=t.Observable.interval(1e3).map(function(n){return l.updateDiff(void 0),n}),this._counterSubscription=this._counter.subscribe(function(n){return l.update()})},l.prototype.ngOnDestroy=function(){this._timeSubscription.unsubscribe(),this._notificationSubscription.unsubscribe(),this._counterSubscription.unsubscribe()},l.ctorParameters=function(){return[]},l}()},DGJX:function(l,n,u){"use strict";function t(l){return v._24(0,[(l()(),v._25(0,null,null,2,null,null,null,null,null,null,null)),(l()(),v._26(null,["Last Active: ",""])),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null))],null,function(l,n){var u=n.component;l(n,1,0,u.dataService.toRelativeDate(u.currentOwner.LastActiveTime))})}function e(l){return v._24(0,[(l()(),v._25(0,null,null,3,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,2,"confirm-button",[],null,[[null,"callback"]],function(l,n,u){var t=!0,e=l.component;if("callback"===n){t=!1!==e.destroyCurrentArea(u)&&t}return t},g.a,g.b)),v._27(57344,null,0,y.a,[],{width:[0,"width"]},{callback:"callback"}),(l()(),v._26(0,["Destroy this area"]))],function(l,n){l(n,2,0,100)},null)}function r(l){return v._24(0,[(l()(),v._25(0,null,null,31,null,null,null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),v._26(null,[" \n "])),(l()(),v._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.hideContextMenu()&&t}return t},null,null)),(l()(),v._26(null,["×"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,19,"div",[["class","w3-container w3-medium theme-l2"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,9,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._26(null,["\n Coords: ",", ",""])),v._32(2),v._32(2),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,t)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "," structures\n "])),v._32(1),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"button",[["class","w3-button theme-d1"],["style","width: 100%;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setSelectedOwner(e.currentOwner)&&t}return t},null,null)),(l()(),v._26(null,["Show only areas for this team"])),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,e)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "]))],function(l,n){var u=n.component;l(n,20,0,u.currentOwner.LastActiveTime),l(n,29,0,u.dataService.hasFeatureAccess("admin-server","structures-rcon"))},function(l,n){var u=n.component;l(n,8,0,u.currentOwner.Name),l(n,14,0,v._33(n,14,0,l(n,15,0,v._29(n.parent,0),u.currentArea.Latitude,"1.0-1")),v._33(n,14,1,l(n,16,0,v._29(n.parent,0),u.currentArea.Longitude,"1.0-1"))),l(n,21,0,v._33(n,21,0,l(n,22,0,v._29(n.parent,0),u.currentArea.StructureCount)))})}function i(l){return v._24(0,[(l()(),v._25(0,null,null,2,null,null,null,null,null,null,null)),(l()(),v._26(null,["Last Active: ",""])),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null))],null,function(l,n){var u=n.component;l(n,1,0,u.dataService.toRelativeDate(u.currentOwner.LastActiveTime))})}function a(l){return v._24(0,[(l()(),v._25(0,null,null,3,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,2,"confirm-button",[],null,[[null,"callback"]],function(l,n,u){var t=!0,e=l.component;if("callback"===n){t=!1!==e.destroyAllStructuresForTeam(u)&&t}return t},g.a,g.b)),v._27(57344,null,0,y.a,[],{width:[0,"width"]},{callback:"callback"}),(l()(),v._26(0,["Destroy all structures"]))],function(l,n){l(n,2,0,100)},null)}function o(l){return v._24(0,[(l()(),v._25(0,null,null,3,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,2,"confirm-button",[],null,[[null,"callback"]],function(l,n,u){var t=!0,e=l.component;if("callback"===n){t=!1!==e.destroyDinosForTeam(u)&&t}return t},g.a,g.b)),v._27(57344,null,0,y.a,[],{width:[0,"width"]},{callback:"callback"}),(l()(),v._26(0,["Destroy all creatures"]))],function(l,n){l(n,2,0,100)},null)}function s(l){return v._24(0,[(l()(),v._25(0,null,null,36,null,null,null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),v._26(null,[" \n "])),(l()(),v._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.hideContextMenu()&&t}return t},null,null)),(l()(),v._26(null,["×"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,24,"div",[["class","w3-container w3-medium theme-l2"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,11,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,i)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "," areas"])),v._32(1),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),v._26(null,["\n "," structures"])),v._32(1),(l()(),v._25(0,null,null,0,"br",[],null,null,null,null,null)),(l()(),v._26(null,["\n "," creatures\n "])),v._32(1),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"button",[["class","w3-button theme-d1"],["style","width: 100%;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setSelectedOwner(e.currentOwner)&&t}return t},null,null)),(l()(),v._26(null,["Show only areas for this team"])),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,a)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,o)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "]))],function(l,n){var u=n.component;l(n,16,0,u.currentOwner.LastActiveTime),l(n,31,0,u.dataService.hasFeatureAccess("admin-server","structures-rcon")),l(n,34,0,u.dataService.hasFeatureAccess("admin-server","structures-rcon"))},function(l,n){var u=n.component;l(n,8,0,u.currentOwner.Name),l(n,17,0,v._33(n,17,0,l(n,18,0,v._29(n.parent,0),u.currentOwner.AreaCount))),l(n,20,0,v._33(n,20,0,l(n,21,0,v._29(n.parent,0),u.currentOwner.StructureCount))),l(n,23,0,v._33(n,23,0,l(n,24,0,v._29(n.parent,0),u.currentOwner.CreatureCount)))})}function c(l){return v._24(0,[(l()(),v._25(0,null,null,16,null,null,null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),v._26(null,[" \n "])),(l()(),v._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.hideContextMenu()&&t}return t},null,null)),(l()(),v._26(null,["×"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,4,"div",[["class","w3-container w3-medium theme-l2"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"div",[["class","w3-section"]],null,null,null,null,null)),(l()(),v._26(null,["\n ","\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "]))],null,function(l,n){var u=n.component;l(n,8,0,u.modalInfo.Header),l(n,14,0,u.modalInfo.Message)})}function _(l){return v._24(0,[(l()(),v._25(0,null,null,3,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),v._25(0,null,null,2,"confirm-button",[["class","w3-right"]],null,[[null,"callback"]],function(l,n,u){var t=!0,e=l.component;if("callback"===n){t=!1!==e.saveWorld(u)&&t}return t},g.a,g.b)),v._27(57344,null,0,y.a,[],{width:[0,"width"]},{callback:"callback"}),(l()(),v._26(0,["Save World"]))],function(l,n){l(n,2,0,void 0)},null)}function p(l){return v._24(0,[(l()(),v._25(0,null,null,30,"tr",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,8,"td",[],null,null,null,null,null)),(l()(),v._25(0,null,null,6,"input",[["type","radio"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,e=l.component;if("input"===n){t=!1!==v._29(l,4)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==v._29(l,4).onTouched()&&t}if("compositionstart"===n){t=!1!==v._29(l,4)._compositionStart()&&t}if("compositionend"===n){t=!1!==v._29(l,4)._compositionEnd(u.target.value)&&t}if("change"===n){t=!1!==v._29(l,5).onChange()&&t}if("blur"===n){t=!1!==v._29(l,5).onTouched()&&t}if("ngModelChange"===n){t=!1!==(e.selectedOwner=u)&&t}if("change"===n){t=!1!==e.updateSelection()&&t}return t},null,null)),v._27(8192,null,0,S.d,[v.J,v.K,[2,S.e]],null,null),v._27(106496,null,0,S.f,[v.J,v.K,S.a,v.W],{value:[0,"value"]},null),v._37(512,null,S.g,function(l,n){return[l,n]},[S.d,S.f]),v._27(335872,null,0,S.h,[[8,null],[8,null],[8,null],[2,S.g]],{model:[0,"model"]},{update:"ngModelChange"}),v._37(1024,null,S.i,null,[S.h]),v._27(8192,null,0,S.j,[S.i],null,null),(l()(),v._26(null,[" ",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),v._26(null,["",""])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"button",[["class","w3-button theme-d1 w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.showOwnerModal(u,l.context.$implicit)&&t}return t},null,null)),(l()(),v._26(null,["Options"])),(l()(),v._26(null,["\n "]))],function(l,n){var u=n.component;l(n,5,0,n.context.$implicit),l(n,7,0,u.selectedOwner)},function(l,n){var u=n.component;l(n,3,0,v._29(n,9).ngClassUntouched,v._29(n,9).ngClassTouched,v._29(n,9).ngClassPristine,v._29(n,9).ngClassDirty,v._29(n,9).ngClassValid,v._29(n,9).ngClassInvalid,v._29(n,9).ngClassPending),l(n,10,0,n.context.$implicit.Name),l(n,13,0,n.context.$implicit.Type),l(n,16,0,n.context.$implicit.AreaCount),l(n,19,0,n.context.$implicit.StructureCount),l(n,22,0,n.context.$implicit.CreatureCount),l(n,25,0,u.dataService.toRelativeDate(n.context.$implicit.LastActiveTime))})}function d(l){return v._24(0,[(l()(),v._25(0,null,null,56,null,null,null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,15,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),v._26(null,["Player/Tribe Locations"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,8,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,5,"div",[["class","w3-clear"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"button",[["class","w3-button theme-d1 w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.reset(u)&&t}return t},null,null)),(l()(),v._26(null,["Reset"])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,36,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,33,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,24,"thead",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,21,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),v._26(null,["Name"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),v._26(null,["Type"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Location Count"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setOwnerSort("locations")&&t}return t},null,null)),(l()(),v._26(null,["A#"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Structure Count"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setOwnerSort("structures")&&t}return t},null,null)),(l()(),v._26(null,["S#"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[["title","Creature Count"]],null,null,null,null,null)),(l()(),v._26(null,["C#"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Last Active Time"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setOwnerSort("lastactive")&&t}return t},null,null)),(l()(),v._26(null,["Last Active"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,0,"th",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,p)),v._27(401408,null,0,b.n,[v.S,v._5,v.v],{ngForOf:[0,"ngForOf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n"]))],function(l,n){l(n,52,0,n.component.ownersSorted)},null)}function f(l){return v._24(0,[v._34(0,b.p,[v.t]),v._35(201326592,1,{mapContainer:0}),v._35(201326592,2,{contextMenu:0}),(l()(),v._26(null,["\n"])),(l()(),v._25(0,[[2,0],["contextMenu",1]],null,14,"div",[["class","contextMenu w3-modal"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,11,"div",[["class","w3-modal-content w3-card-4 w3-animate-zoom"],["style","font-size: 0;"]],null,[[null,"clickOutside"],["document","click"]],function(l,n,u){var t=!0,e=l.component;if("document:click"===n){t=!1!==v._29(l,7).onClick(u,u.target)&&t}if("clickOutside"===n){t=!1!==e.hideContextMenu()&&t}return t},null,null)),v._27(8192,null,0,k.a,[v.K],null,{clickOutside:"clickOutside"}),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,r)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,s)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,c)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n"])),(l()(),v._26(null,["\n\n"])),(l()(),v._25(0,null,null,9,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,3,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),v._25(0,null,null,0,"a",[["id","structures"]],null,null,null,null,null)),(l()(),v._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),v._26(null,["Structures"])),(l()(),v._26(null,["\n "])),(l()(),v._28(8388608,null,null,1,null,_)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null),(l()(),v._26(null,["\n"])),(l()(),v._26(null,["\n\n"])),(l()(),v._25(0,null,null,14,"div",[["class","wrapper"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,9,"div",[["class","buttons"]],null,null,null,null,null)),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"button",[["class","w3-button theme-d1"],["style","padding: 3px 6px;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.zoomIn()&&t}return t},null,null)),(l()(),v._25(0,null,null,1,"i",[["class","material-icons w3-xxlarge"]],null,null,null,null,null)),(l()(),v._26(null,["add"])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,null,null,2,"button",[["class","w3-button theme-d1"],["style","padding: 3px 6px;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.zoomOut()&&t}return t},null,null)),(l()(),v._25(0,null,null,1,"i",[["class","material-icons w3-xxlarge"]],null,null,null,null,null)),(l()(),v._26(null,["remove"])),(l()(),v._26(null,["\n "])),(l()(),v._26(null,["\n "])),(l()(),v._25(0,[[1,0],["map",1]],null,0,"div",[["class","map"]],null,null,null,null,null)),(l()(),v._26(null,["\n"])),(l()(),v._26(null,["\n\n"])),(l()(),v._28(8388608,null,null,1,null,d)),v._27(8192,null,0,b.l,[v.S,v._5],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,10,0,u.currentArea&&u.currentOwner),l(n,13,0,u.currentOwner&&!u.currentArea),l(n,16,0,u.modalInfo),l(n,28,0,u.dataService.hasFeatureAccess("admin-server","structures-rcon")),l(n,48,0,u.ownersSorted)},null)}function m(l){return v._24(0,[(l()(),v._25(0,null,null,1,"arkmap-structures",[],null,null,null,f,O)),v._27(385024,null,0,w.a,[C.a,I.a,v.e],null,null)],function(l,n){l(n,1,0)},null)}var h=u("Dn8Y"),v=u("3j3K"),g=u("r8sF"),y=u("7T2B"),b=u("2Je8"),S=u("NVOs"),w=u("lCrv"),k=u("8zLQ"),C=u("ATz5"),I=u("lHWG");u.d(n,"b",function(){return O}),n.a=f;var x=[h.a],O=v._23({encapsulation:2,styles:x,data:{}});v._30("arkmap-structures",w.a,m,{structures:"structures",serverKey:"serverKey",mapName:"mapName"},{},[])},Dn8Y:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=['.map canvas,.map svg{position:absolute;top:0;left:0;width:100%}rect.overlay{fill:transparent}.wrapper{position:relative}.wrapper:after{padding-top:100%;display:block;content:""}.wrapper .buttons{position:absolute;left:5px;top:5px;opacity:.75;z-index:2}']},Fnlp:function(l,n,u){"use strict";var t=u("ATz5"),e=u("3MNG"),r=u("+Lwu");u.d(n,"a",function(){return i});var i=function(){function l(l,n,u){this.dataService=l,this.messageService=n,this.notificationsService=u,this.menuOption=void 0,this.demoMode=!1}return l.prototype.ngOnInit=function(){var l=this;this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.showServerUpdateNotification(n)}),this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n}),this.demoMode="true"==localStorage.getItem("demoMode")},l.prototype.ngOnDestroy=function(){this.serverUpdatedSubscription.unsubscribe(),this.menuOptionSubscription.unsubscribe()},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.prototype.toggleDemoMode=function(){var l="true"!=localStorage.getItem("demoMode");this.demoMode=l,localStorage.setItem("demoMode",l+"")},l.ctorParameters=function(){return[{type:t.a},{type:r.a},{type:e.a}]},l}()},FxpQ:function(l,n,u){"use strict";var t=u("ATz5"),e=u("3MNG"),r=u("+Lwu");u.d(n,"a",function(){return i});var i=function(){function l(l,n,u){this.dataService=l,this.messageService=n,this.notificationsService=u,this.menuOption=void 0}return l.prototype.ngOnInit=function(){var l=this;this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.showServerUpdateNotification(n)}),this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n})},l.prototype.ngOnDestroy=function(){this.serverUpdatedSubscription.unsubscribe(),this.menuOptionSubscription.unsubscribe()},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.ctorParameters=function(){return[{type:t.a},{type:r.a},{type:e.a}]},l}()},I9JA:function(l,n,u){"use strict";function t(l){return r._24(0,[r._35(201326592,1,{canvasRef:0}),(l()(),r._25(0,[[1,0],["myCanvas",1]],null,0,"canvas",[["style","width: 100%;"]],[[8,"width",0],[8,"height",0]],null,null,null,null))],null,function(l,n){var u=n.component;l(n,1,0,u.width,u.height)})}function e(l){return r._24(0,[(l()(),r._25(0,null,null,1,"arkmap",[],null,null,null,t,o)),r._27(286720,null,0,i.a,[],null,null)],null,null)}var r=u("3j3K"),i=u("5305");u.d(n,"b",function(){return o}),n.a=t;var a=[],o=r._23({encapsulation:2,styles:a,data:{}});r._30("arkmap",i.a,e,{mapName:"mapName",points:"points"},{},[])},Iksp:function(l,n,u){"use strict";var t=u("KZxv"),e=u("RiXa"),r=u("qn86"),i=u("JLFQ"),a=u("e/mT"),o=u("+w0e"),s=u("JKTH"),c=u("7xIs"),_=u("08Wm"),p=u("+qYp"),d=u("FxpQ"),f=u("Fnlp");u.d(n,"a",function(){return m});var m=(o.a,t.a,e.a,o.a,r.a,c.a,o.a,a.a,_.a,o.a,i.a,s.a,f.a,p.a,d.a,function(){function l(){}return l}())},J8nT:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=function(){function l(){}return l}()},JKTH:function(l,n,u){"use strict";var t=u("ATz5");u.d(n,"a",function(){return e});var e=function(){function l(l){this.dataService=l}return l.prototype.ngOnInit=function(){this.menu.activate("overview")},l.ctorParameters=function(){return[{type:t.a}]},l}()},JLFQ:function(l,n,u){"use strict";var t=u("ATz5"),e=u("3MNG"),r=u("+Lwu");u.d(n,"a",function(){return i});var i=function(){function l(l,n,u){this.dataService=l,this.messageService=n,this.notificationsService=u,this.menuOption=void 0,this.serverCount=0,this.onlinePlayerCount=0}return l.prototype.ngOnInit=function(){var l=this;this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.showServerUpdateNotification(n)}),this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n}),this.serversUpdatedSubscription=this.dataService.ServersUpdated$.subscribe(function(n){l.updateData(n)}),this.serverUpdateInterval=window.setInterval(function(){l.dataService.updateServer(null)},6e4),this.updateData(this.dataService.Servers)},l.prototype.ngOnDestroy=function(){this.serverUpdatedSubscription.unsubscribe(),this.menuOptionSubscription.unsubscribe(),this.serversUpdatedSubscription.unsubscribe(),window.clearInterval(this.serverUpdateInterval)},l.prototype.updateData=function(l){var n=0,u=0;if(l&&l.Servers){n=l.Servers.length;for(var t=0,e=l.Servers;t0?u[0]:null);var t=Object.keys(n.Clusters);l.clusterKey&&void 0!=t.find(function(n){return n==l.clusterKey})||(l.clusterKey=t.length>0?t[0]:null),l.player=n,l.filterAndSort(),l.sortCluster(),l.filterCluster(),l.loaded=!0,l.ref.detectChanges()}).catch(function(n){l.player=null,l.filteredCreatures=null,l.imprintCreatures=null,l.filteredClusterCreatures=null,l.loaded=!0})},l.prototype.ngOnInit=function(){var l=this;this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){return l.menuOption=n}),this.steamId=this.route.snapshot.params.playerid,this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){return l.updateServer(n)}),this.getPlayer()},l.prototype.ngOnDestroy=function(){this.menuOptionSubscription.unsubscribe(),this.serverUpdatedSubscription.unsubscribe()},l.prototype.haveMatingCooldown=function(l){return null!=l.NextMating&&new Date(l.NextMating)>new Date},l.prototype.active=function(l){return this.serverKey==l},l.prototype.activate=function(l){this.serverKey=l,this.filterAndSort()},l.prototype.serverWidth=function(){return 100/Object.keys(this.player.Servers).length},l.prototype.activeCluster=function(l){return this.clusterKey==l},l.prototype.activateCluster=function(l){this.clusterKey=l,this.sortCluster(),this.filterCluster()},l.prototype.clusterWidth=function(){return 100/Object.keys(this.player.Clusters).length},l.prototype.sort=function(){var l=this,n="-"!=this.creaturesSortField[0],u=this.creaturesSortFunctions[this.creaturesSortField.replace(/^\-/,"")],t=this.creaturesAltSortFields.split(",").map(function(n){var u={};return u.asc="-"!=n[0],u.sortFunc=l.creaturesSortFunctions[n.replace(/^\-/,"")],u});this.filteredCreatures.sort(function(l,e){var r=u(l,e,n);if(0==r)for(var i=0,a=t;i=0||null!=n.Name&&n.Name.toLowerCase().indexOf(l)>=0})}var n=this.player.Servers[this.serverKey].Creatures.filter(function(l){return null!=l.BabyAge});n.sort(function(l,n){return new Date(l.BabyNextCuddle)new Date(n.BabyNextCuddle)?1:0}),this.imprintCreatures=n;for(var u=[],t=0,e=this.filteredCreatures;tn.Level?-1:l.Level=0||null!=n.Name&&n.Name.toLowerCase().indexOf(l)>=0})}},l.prototype.run=function(){if(null==this.steamId||""==this.steamId)return this.player=null,this.filteredCreatures=null,void(this.imprintCreatures=null);this.getPlayer()},l.prototype.openMap=function(l){this.showMap=!0,l.stopPropagation()},l.prototype.closeMap=function(l){this.showMap=!1},l.prototype.updateServer=function(l){this.getPlayer(),this.showServerUpdateNotification(l)},l.prototype.haveCluster=function(){return null!=this.player&&Object.keys(this.player.Clusters).length>0},l.prototype.sumKibbleAndEggs=function(){return void 0!=this.player.Servers[this.serverKey].KibblesAndEggs?this.player.Servers[this.serverKey].KibblesAndEggs.reduce(function(l,n){return l+n.KibbleCount+n.EggCount},0):0},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.prototype.getStateForCreature=function(l){if(l){var n=this.creatureStates[l.Id1+"_"+l.Id2];return n||(n={imprintNotifications:!0},this.creatureStates[l.Id1+"_"+l.Id2]=n),n}},l.prototype.toggleImprintNotificationForCreature=function(l){var n=this.getStateForCreature(l);n.imprintNotifications=!n.imprintNotifications},l.prototype.activeCreaturesMode=function(l){return l==this.creaturesMode},l.prototype.activateCreaturesMode=function(l){this.creaturesMode=l},l.prototype.setCreaturesSort=function(l){var n=this.creaturesSortField==l;this.creaturesSortField=n?"-"+l:l,this.creaturesAltSortFields="latitude"==l?n?"-longitude,name":"longitude,name":"longitude"==l?n?"-latitude,name":"latitude,name":"name",this.sort()},l.prototype.copyCreature=function(l){},l.prototype.getCurrentServer=function(){var l=this;if(this.dataService&&this.dataService.Servers&&this.dataService.Servers.Servers){return this.dataService.Servers.Servers.find(function(n){return n.Key==l.serverKey})}},l.prototype.numCreatureTabs=function(){var l=1;return this.dataService.hasFeatureAccess("player","creatures-basestats",this.steamId)&&(l+=1),this.dataService.hasFeatureAccess("player","creatures-ids",this.steamId)&&(l+=1),l},l.ctorParameters=function(){return[{type:e.v},{type:e.g},{type:o.a},{type:i.a},{type:a.a},{type:r.a},{type:t.O}]},l}()},Layn:function(l,n,u){"use strict";function t(l){return s._24(0,[(l()(),s._25(0,null,null,0,"div",[["class","icon"]],[[8,"innerHTML",1]],null,null,null,null))],null,function(l,n){l(n,0,0,n.component.safeSvg)})}function e(l){return s._24(0,[(l()(),s._25(0,null,null,11,"div",[],null,null,null,null,null)),(l()(),s._26(null,["\n "])),(l()(),s._25(0,null,null,1,"div",[["class","sn-title"]],null,null,null,null,null)),(l()(),s._26(null,["",""])),(l()(),s._26(null,["\n "])),(l()(),s._25(0,null,null,2,"div",[["class","sn-content"]],null,null,null,null,null)),(l()(),s._26(null,["",""])),s._32(2),(l()(),s._26(null,["\n\n "])),(l()(),s._28(8388608,null,null,1,null,t)),s._27(8192,null,0,c.l,[s.S,s._5],{ngIf:[0,"ngIf"]},null),(l()(),s._26(null,["\n "]))],function(l,n){l(n,10,0,"bare"!==n.component.item.icon)},function(l,n){var u=n.component;l(n,3,0,u.item.title),l(n,6,0,s._33(n,6,0,l(n,7,0,s._29(n.parent,0),u.item.content,u.maxLength)))})}function r(l){return s._24(0,[(l()(),s._25(0,null,null,0,"div",[],[[8,"innerHTML",1]],null,null,null,null))],null,function(l,n){l(n,0,0,n.component.item.html)})}function i(l){return s._24(0,[(l()(),s._25(0,null,null,5,"div",[["class","sn-progress-loader"]],null,null,null,null,null)),(l()(),s._26(null,["\n "])),(l()(),s._25(0,null,null,2,"span",[],null,null,null,null,null)),s._27(139264,null,0,c.o,[s.w,s.K,s.J],{ngStyle:[0,"ngStyle"]},null),s._31(["width"]),(l()(),s._26(null,["\n "]))],function(l,n){l(n,3,0,l(n,4,0,n.component.progressWidth+"%"))},null)}function a(l){return s._24(0,[s._34(0,_.a,[]),(l()(),s._26(null,["\n "])),(l()(),s._25(0,null,null,12,"div",[["class","simple-notification"]],[[24,"@enterLeave",0]],[[null,"click"],[null,"mouseenter"],[null,"mouseleave"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.onClick(u)&&t}if("mouseenter"===n){t=!1!==e.onEnter()&&t}if("mouseleave"===n){t=!1!==e.onLeave()&&t}return t},null,null)),s._27(139264,null,0,c.m,[s.v,s.w,s.K,s.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),s._31(["alert","error","warn","success","info","bare","rtl-mode"]),(l()(),s._26(null,["\n\n "])),(l()(),s._28(8388608,null,null,1,null,e)),s._27(8192,null,0,c.l,[s.S,s._5],{ngIf:[0,"ngIf"]},null),(l()(),s._26(null,["\n "])),(l()(),s._28(8388608,null,null,1,null,r)),s._27(8192,null,0,c.l,[s.S,s._5],{ngIf:[0,"ngIf"]},null),(l()(),s._26(null,["\n\n "])),(l()(),s._28(8388608,null,null,1,null,i)),s._27(8192,null,0,c.l,[s.S,s._5],{ngIf:[0,"ngIf"]},null),(l()(),s._26(null,["\n\n "])),(l()(),s._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,u.theClass,l(n,4,0,"alert"===u.item.type,"error"===u.item.type,"warn"===u.item.type,"success"===u.item.type,"info"===u.item.type,"bare"===u.item.type,u.rtl)),l(n,7,0,!u.item.html),l(n,10,0,u.item.html),l(n,13,0,u.showProgressBar)},function(l,n){l(n,2,0,n.component.item.state)})}function o(l){return s._24(0,[(l()(),s._25(0,null,null,1,"simple-notification",[],null,null,null,a,h)),s._27(122880,null,0,p.a,[d.a,f.q,s.e],null,null)],function(l,n){l(n,1,0)},null)}var s=u("3j3K"),c=u("2Je8"),_=u("g/xi"),p=u("Ev1B"),d=u("XLrO"),f=u("Qbdm");u.d(n,"b",function(){return h}),n.a=a;var m=["\n .simple-notification {\n width: 100%;\n padding: 10px 20px;\n box-sizing: border-box;\n position: relative;\n float: left;\n margin-bottom: 10px;\n color: #fff;\n cursor: pointer;\n transition: all 0.5s;\n }\n\n .simple-notification .sn-title {\n margin: 0;\n padding: 0 50px 0 0;\n line-height: 30px;\n font-size: 20px;\n }\n\n .simple-notification .sn-content {\n margin: 0;\n font-size: 16px;\n padding: 0 50px 0 0;\n line-height: 20px;\n }\n\n .simple-notification .icon {\n position: absolute;\n box-sizing: border-box;\n top: 0;\n right: 0;\n width: 70px;\n height: 70px;\n padding: 10px;\n }\n\n .simple-notification .icon svg {\n fill: #fff;\n width: 100%;\n height: 100%;\n }\n\n .simple-notification .icon svg g {\n fill: #fff;\n }\n\n .simple-notification.rtl-mode {\n direction: rtl;\n }\n\n .simple-notification.rtl-mode .sn-content {\n padding: 0 0 0 50px;\n }\n\n .simple-notification.rtl-mode svg {\n left: 0;\n right: auto;\n }\n\n .simple-notification.error { background: #F44336; }\n .simple-notification.success { background: #8BC34A; }\n .simple-notification.alert { background: #ffdb5b; }\n .simple-notification.info { background: #03A9F4; }\n .simple-notification.warn { background: #ffdb5b; }\n\n .simple-notification .sn-progress-loader {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 5px;\n }\n\n .simple-notification .sn-progress-loader span {\n float: left;\n height: 100%;\n }\n\n .simple-notification.success .sn-progress-loader span { background: #689F38; }\n .simple-notification.error .sn-progress-loader span { background: #D32F2F; }\n .simple-notification.alert .sn-progress-loader span { background: #edc242; }\n .simple-notification.info .sn-progress-loader span { background: #0288D1; }\n .simple-notification.warn .sn-progress-loader span { background: #edc242; }\n .simple-notification.bare .sn-progress-loader span { background: #ccc; }\n\n .simple-notification.warn div .sn-title { color: #444; }\n .simple-notification.warn div .sn-content { color: #444; }\n "],h=s._23({encapsulation:2,styles:m,data:{animation:[{name:"enterLeave",definitions:[{type:0,name:"fromRight",styles:{type:6,styles:{opacity:1,transform:"translateX(0)"}}},{type:1,expr:"* => fromRight",animation:[{type:6,styles:{opacity:0,transform:"translateX(5%)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"fromRightOut",styles:{type:6,styles:{opacity:0,transform:"translateX(-5%)"}}},{type:1,expr:"fromRight => fromRightOut",animation:[{type:6,styles:{opacity:1,transform:"translateX(0)"}},{type:4,styles:null,timings:"300ms ease-in-out"}]},{type:0,name:"fromLeft",styles:{type:6,styles:{opacity:1,transform:"translateX(0)"}}},{type:1,expr:"* => fromLeft",animation:[{type:6,styles:{opacity:0,transform:"translateX(-5%)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"fromLeftOut",styles:{type:6,styles:{opacity:0,transform:"translateX(5%)"}}},{type:1,expr:"fromLeft => fromLeftOut",animation:[{type:6,styles:{opacity:1,transform:"translateX(0)"}},{type:4,styles:null,timings:"300ms ease-in-out"}]},{type:0,name:"scale",styles:{type:6,styles:{opacity:1,transform:"scale(1)"}}},{type:1,expr:"* => scale",animation:[{type:6,styles:{opacity:0,transform:"scale(0)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"scaleOut",styles:{type:6,styles:{opacity:0,transform:"scale(0)"}}},{type:1,expr:"scale => scaleOut",animation:[{type:6,styles:{opacity:1,transform:"scale(1)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"rotate",styles:{type:6,styles:{opacity:1,transform:"rotate(0deg)"}}},{type:1,expr:"* => rotate",animation:[{type:6,styles:{opacity:0,transform:"rotate(5deg)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]},{type:0,name:"rotateOut",styles:{type:6,styles:{opacity:0,transform:"rotate(-5deg)"}}},{type:1,expr:"rotate => rotateOut",animation:[{type:6,styles:{opacity:1,transform:"rotate(0deg)"}},{type:4,styles:null,timings:"400ms ease-in-out"}]}]}]}});s._30("simple-notification",p.a,o,{timeOut:"timeOut",showProgressBar:"showProgressBar",pauseOnHover:"pauseOnHover",clickToClose:"clickToClose",maxLength:"maxLength",theClass:"theClass",rtl:"rtl",animate:"animate",position:"position",item:"item"},{},[])},Ni5f:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},OO5M:function(l,n,u){"use strict";function t(l){return i._24(0,[(l()(),i._25(0,null,null,10,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,7,"div",[["class","w3-panel w3-red"]],null,null,null,null,null)),(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),i._26(null,["Connection error"])),(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),i._26(null,["The application was unable to connect to the Web API. This could be due to a configuration error..."])),(l()(),i._26(null,["\n "])),(l()(),i._26(null,[" \n "]))],null,null)}function e(l){return i._24(0,[(l()(),i._25(0,null,null,1,"app-connection-error",[],null,null,null,t,p)),i._27(122880,null,0,a.a,[o.a,s.a,c.a],null,null)],function(l,n){l(n,1,0)},null)}var r=u("UYln"),i=u("3j3K"),a=u("FxpQ"),o=u("ATz5"),s=u("+Lwu"),c=u("XLrO");u.d(n,"a",function(){return d});var _=[r.a],p=i._23({encapsulation:0,styles:_,data:{}}),d=i._30("app-connection-error",a.a,e,{},{},[])},RWZN:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},RdYi:function(l,n,u){"use strict";function t(l){return o._24(0,[(l()(),o._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),o._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component._str)})}function e(l){return o._24(0,[(l()(),o._25(0,null,null,3,"button",[["class","w3-button w3-small"],["style","padding: 4px 8px;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.state._completed=!e.state._completed)&&t}return t},null,null)),o._27(139264,null,0,s.m,[o.v,o.w,o.K,o.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),o._31(["theme-d1","theme-l2","theme-hover"]),(l()(),o._26(null,["",""]))],function(l,n){var u=n.component;l(n,1,0,"w3-button w3-small",l(n,2,0,u.state._completed,!u.state._completed&&u._ready,!u.state._completed&&u._ready))},function(l,n){l(n,3,0,n.component.state._completed?"Completed":"Ready")})}function r(l){return o._24(0,[(l()(),o._28(8388608,null,null,1,null,t)),o._27(8192,null,0,s.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null),(l()(),o._28(8388608,null,null,1,null,e)),o._27(8192,null,0,s.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,1,0,!u._ready),l(n,3,0,u._ready)},null)}function i(l){return o._24(0,[(l()(),o._25(0,null,null,1,"timer",[],null,null,null,r,p)),o._27(122880,null,0,c.a,[],null,null)],function(l,n){l(n,1,0)},null)}var a=u("SWNH"),o=u("3j3K"),s=u("2Je8"),c=u("CzL3");u.d(n,"b",function(){return p}),n.a=r;var _=[a.a],p=o._23({encapsulation:0,styles:_,data:{}});o._30("timer",c.a,i,{state:"state",time:"time",notification:"notification"},{},[])},RiXa:function(l,n,u){"use strict";var t=u("5oXY"),e=u("ATz5");u.d(n,"a",function(){return r});var r=function(){function l(l,n){this.route=l,this.dataService=n}return l.prototype.ngOnInit=function(){this.steamId=this.route.snapshot.params.playerid,this.dataService.hasFeatureAccess("player","profile",this.steamId)?this.menu.activate("profile"):this.dataService.hasFeatureAccess("player","creatures",this.steamId)?this.menu.activate("creatures"):this.dataService.hasFeatureAccess("player","creatures-cloud",this.steamId)?this.menu.activate("creatures_cloud"):this.dataService.hasFeatureAccess("player","breeding",this.steamId)?this.menu.activate("breeding"):this.dataService.hasFeatureAccess("player","crops",this.steamId)?this.menu.activate("crop_plots"):this.dataService.hasFeatureAccess("player","generators",this.steamId)?this.menu.activate("electrical_generators"):this.dataService.hasFeatureAccess("player","kibbles-eggs",this.steamId)?this.menu.activate("kibbles_and_eggs"):this.dataService.hasFeatureAccess("player","tribelog",this.steamId)&&this.menu.activate("tribelog")},l.ctorParameters=function(){return[{type:t.v},{type:e.a}]},l}()},SQlA:function(l,n,u){"use strict";function t(l){return a._24(0,[(l()(),a._25(0,null,null,1,"i",[["class","material-icons"],["style","margin: -5px 5px -5px -5px; vertical-align: middle;"]],null,null,null,null,null)),(l()(),a._26(null,["check"]))],null,null)}function e(l){return a._24(0,[(l()(),a._25(0,null,null,8,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),a._26(null,["\n "])),(l()(),a._25(0,null,null,5,"button",[["class","w3-button"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.toggleDemoMode()&&t}return t},null,null)),a._27(139264,null,0,s.m,[a.v,a.w,a.K,a.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),a._31(["theme-d1","theme-l2","theme-hover"]),(l()(),a._28(8388608,null,null,1,null,t)),a._27(8192,null,0,s.l,[a.S,a._5],{ngIf:[0,"ngIf"]},null),(l()(),a._26(null,["",""])),(l()(),a._26(null,["\n"]))],function(l,n){var u=n.component;l(n,3,0,"w3-button",l(n,4,0,u.demoMode,!u.demoMode,!u.demoMode)),l(n,6,0,u.demoMode)},function(l,n){l(n,7,0,n.component.demoMode?"Demo Mode Enabled":"Enable Demo Mode")})}function r(l){return a._24(0,[(l()(),a._25(0,null,null,1,"app-developer",[],null,null,null,e,f)),a._27(122880,null,0,o.a,[c.a,_.a,p.a],null,null)],function(l,n){l(n,1,0)},null)}var i=u("7MbP"),a=u("3j3K"),o=u("Fnlp"),s=u("2Je8"),c=u("ATz5"),_=u("+Lwu"),p=u("XLrO");u.d(n,"a",function(){return m});var d=[i.a],f=a._23({encapsulation:0,styles:d,data:{}}),m=a._30("app-developer",o.a,r,{},{},[])},SWNH:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},SWoV:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},UYln:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},XhEa:function(l,n,u){"use strict";function t(l){return i._24(0,[(l()(),i._25(0,null,null,2,"simple-notification",[],null,null,null,a.a,a.b)),i._27(122880,null,0,o.a,[s.a,c.q,i.e],{timeOut:[0,"timeOut"],showProgressBar:[1,"showProgressBar"],pauseOnHover:[2,"pauseOnHover"],clickToClose:[3,"clickToClose"],maxLength:[4,"maxLength"],theClass:[5,"theClass"],rtl:[6,"rtl"],animate:[7,"animate"],position:[8,"position"],item:[9,"item"]},null),(l()(),i._26(null,["\n "]))],function(l,n){var u=n.component;l(n,1,0,u.timeOut,u.showProgressBar,u.pauseOnHover,u.clickToClose,u.maxLength,u.theClass,u.rtl,u.animate,n.context.index,n.context.$implicit)},null)}function e(l){return i._24(0,[(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,5,"div",[["class","simple-notification-wrapper"]],null,null,null,null,null)),i._27(139264,null,0,_.m,[i.v,i.w,i.K,i.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),(l()(),i._26(null,["\n "])),(l()(),i._28(8388608,null,null,1,null,t)),i._27(401408,null,0,_.n,[i.S,i._5,i.v],{ngForOf:[0,"ngForOf"]},null),(l()(),i._26(null,["\n "])),(l()(),i._26(null,["\n "]))],function(l,n){var u=n.component;l(n,2,0,"simple-notification-wrapper",u.position),l(n,5,0,u.notifications)},null)}function r(l){return i._24(0,[(l()(),i._25(0,null,null,1,"simple-notifications",[],null,null,null,e,f)),i._27(122880,null,0,p.a,[s.a],null,null)],function(l,n){l(n,1,0)},null)}var i=u("3j3K"),a=u("Layn"),o=u("Ev1B"),s=u("XLrO"),c=u("Qbdm"),_=u("2Je8"),p=u("B8cY");u.d(n,"b",function(){return f}),n.a=e;var d=["\n .simple-notification-wrapper {\n position: fixed;\n width: 300px;\n z-index: 1000;\n }\n \n .simple-notification-wrapper.left { left: 20px; }\n .simple-notification-wrapper.top { top: 20px; }\n .simple-notification-wrapper.right { right: 20px; }\n .simple-notification-wrapper.bottom { bottom: 20px; }\n \n @media (max-width: 340px) {\n .simple-notification-wrapper {\n width: auto;\n left: 20px;\n right: 20px;\n }\n }\n "],f=i._23({encapsulation:2,styles:d,data:{}});i._30("simple-notifications",p.a,r,{options:"options"},{onCreate:"onCreate",onDestroy:"onDestroy"},[])},YWx4:function(l,n,u){"use strict";var t=u("5oXY"),e=u("3MNG"),r=u("hHgl"),i=u("ATz5"),a=u("lHWG"),o=u("kZql");u.d(n,"a",function(){return s});var s=function(){function l(l,n,u,t,e){this.dataService=l,this.httpService=n,this.breadcrumbService=u,this.notificationsService=t,this.router=e,this.notificationOptions={position:["top","right"],timeOut:1e3,lastOnBottom:!1},this.showLogin=!1,this.currentUrl="/",this.serversUpdatedBefore=!1,this.loading=!0,u.addFriendlyNameForRoute("/accessdenied","Access Denied"),u.addFriendlyNameForRoute("/connectionerror","Connection error"),u.hideRoute("/player"),u.hideRoute("/servers"),u.hideRoute("/server"),u.hideRoute("/admin"),u.addCallbackForRouteRegex("^/player/.+$",this.getNameForPlayer)}return l.prototype.ngOnInit=function(){var l=this;this.routerEventsSubscription=this.router.events.subscribe(function(n){l.navigationInterceptor(n)}),this.currentUrl=window.location.href||"/",this.serversUpdatedSubscription=this.dataService.ServersUpdated$.subscribe(function(n){l.serversUpdatedBefore||!n||n.User&&n.User.SteamId||(l.showLogin=!0),l.serversUpdatedBefore=!0})},l.prototype.ngOnDestroy=function(){this.routerEventsSubscription.unsubscribe(),this.serversUpdatedSubscription.unsubscribe()},l.prototype.navigationInterceptor=function(l){l instanceof t.A?this.loading=!0:l instanceof t.y?this.loading=!1:l instanceof t.B?this.loading=!1:l instanceof t.C&&(this.loading=!1)},l.prototype.getNameForPlayer=function(l){return"Player"},l.prototype.getTheme=function(){return localStorage.getItem("theme")||"light"},l.prototype.setTheme=function(l){return localStorage.setItem("theme",l),!1},l.prototype.openLogin=function(l){this.showLogin=!0,l.stopPropagation(),l.preventDefault()},l.prototype.closeLogin=function(l){this.showLogin=!1},l.prototype.getLoginUrl=function(){return this.httpService.getApiBaseUrl()+"/authentication/login"},l.prototype.getLogoutUrl=function(){return o.a.demo?"":this.httpService.getApiBaseUrl()+"/authentication/logout?returnUrl="+this.currentUrl},l.ctorParameters=function(){return[{type:i.a},{type:a.a},{type:r.a},{type:e.a},{type:t.g}]},l}()},ZfYc:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},beiT:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=["tr th.orderBy{cursor:pointer}a.w3-button.disabled{color:#a9a9a9}a.w3-button.disabled:hover{color:#a9a9a9!important;background-color:transparent!important;opacity:1!important;cursor:default}"]},coiB:function(l,n,u){"use strict";function t(l){return i._24(0,[(l()(),i._25(0,null,null,11,"div",[["class","w3-sidebar theme-l2"],["id","menu"],["style","min-height: 52px;"]],null,null,null,null,null)),(l()(),i._26(null,[" \n "])),(l()(),i._25(0,null,null,1,"button",[["class","w3-button w3-xlarge w3-display-topright"],["id","menubtn"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.toggleMenu()&&t}return t},null,null)),(l()(),i._26(null,["☰"])),(l()(),i._26(null,["\n "])),(l()(),i._25(0,null,null,5,"section",[["class","w3-container"],["id","menucontent"]],null,null,null,null,null)),i._27(139264,null,0,o.m,[i.v,i.w,i.K,i.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),i._31(["hide"]),(l()(),i._26(null,["\n "])),i._36(null,0),(l()(),i._26(null,["\n "])),(l()(),i._26(null,["\n"]))],function(l,n){l(n,6,0,"w3-container",l(n,7,0,!n.component.menuVisible))},null)}function e(l){return i._24(0,[(l()(),i._25(0,null,null,1,"app-menu",[],null,null,null,t,_)),i._27(122880,null,0,a.a,[s.a],null,null)],function(l,n){l(n,1,0)},null)}var r=u("+SUW"),i=u("3j3K"),a=u("8kYA"),o=u("2Je8"),s=u("ATz5");u.d(n,"b",function(){return _}),n.a=t;var c=[r.a],_=i._23({encapsulation:0,styles:c,data:{}});i._30("app-menu",a.a,e,{},{},["*"])},"e/mT":function(l,n,u){"use strict";var t=u("5oXY"),e=u("3MNG"),r=u("ATz5"),i=u("+Lwu"),a=u("lHWG");u.d(n,"a",function(){return o});var o=function(){function l(l,n,u,t,e,r){this.route=l,this.router=n,this.httpService=u,this.dataService=t,this.messageService=e,this.notificationsService=r,this.menuOption=void 0,this.loaded=!1,this.loadedStructures=!1}return l.prototype.getServer=function(){var l=this;this.httpService.getAdminServer(this.serverKey).then(function(n){l.server=n,l.loaded=!0}).catch(function(n){l.server=null,l.loaded=!0})},l.prototype.getStructures=function(){var l=this;this.httpService.getStructures(this.serverKey).then(function(n){l.structures=n,l.loadedStructures=!0}).catch(function(n){l.structures=void 0,l.loadedStructures=!0})},l.prototype.ngOnInit=function(){var l=this;this.serverKey=this.route.snapshot.params.id,this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){l.menuOption=n,"structures"==l.menuOption&&l.getStructures()}),this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){l.serverKey==n&&(l.updateServer(),l.showServerUpdateNotification(n))}),this.getServer()},l.prototype.ngOnDestroy=function(){this.menuOptionSubscription.unsubscribe(),this.serverUpdatedSubscription.unsubscribe()},l.prototype.getTribeMember=function(l){return this.server.Players.find(function(n){return n.SteamId==l})},l.prototype.updateServer=function(){this.getServer()},l.prototype.showServerUpdateNotification=function(l){this.notificationsService.success("Server Update",l+" was updated; Reloading data...",{showProgressBar:!0,pauseOnHover:!0,clickToClose:!0})},l.prototype.isMenuActive=function(l){return this.menuOption==l},l.ctorParameters=function(){return[{type:t.v},{type:t.g},{type:a.a},{type:r.a},{type:i.a},{type:e.a}]},l}()},fYAd:function(l,n,u){"use strict";function t(l){return y._24(0,[(l()(),y._25(0,null,null,4,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCurrentMode(l.parent.context.$implicit.key)&&t}return t},null,null)),y._27(139264,null,0,b.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["theme-d1"]),y._34(65536,b.q,[y.O]),(l()(),y._26(null,["",""]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.isCurrentMode(n.parent.context.$implicit.key)))},function(l,n){var u=n.component;l(n,0,0,100/y._33(n,0,0,y._29(n,3).transform(u.numEnabledModes))),l(n,4,0,n.parent.context.$implicit.name)})}function e(l){return y._24(0,[(l()(),y._25(0,null,null,5,null,null,null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,2,null,t)),y._27(8192,null,0,b.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),y._34(65536,b.q,[y.O]),(l()(),y._26(null,["\n "]))],function(l,n){l(n,3,0,y._33(n,3,0,y._29(n,4).transform(n.context.$implicit.enabled)))},null)}function r(l){return y._24(0,[(l()(),y._25(0,null,null,4,"div",[["class","w3-bar theme-l2 w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,e)),y._27(401408,null,0,b.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(l()(),y._26(null,["\n"]))],function(l,n){var u=n.component;l(n,3,0,u._modes,u.trackByKey)},null)}function i(l){return y._24(0,[(l()(),y._26(null,["\n "]))],null,null)}function a(l){return y._24(0,[(l()(),y._28(8388608,null,null,1,null,i)),y._27(270336,null,0,b.s,[y.S],{ngTemplateOutlet:[0,"ngTemplateOutlet"]},null),(l()(),y._28(0,null,null,0))],function(l,n){l(n,1,0,n.parent.parent.context.$implicit.headerTemplate)},null)}function o(l){return y._24(0,[(l()(),y._25(0,null,null,6,"th",[],[[8,"title",0]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.orderBy(l.parent.context.$implicit.key,u)&&t}return t},null,null)),y._27(139264,null,0,b.m,[y.v,y.w,y.K,y.J],{ngClass:[0,"ngClass"]},null),y._31(["orderBy"]),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,a)),y._27(8192,null,0,b.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),(l()(),y._26(null,["\n "]))],function(l,n){l(n,1,0,l(n,2,0,n.parent.context.$implicit.orderBy)),l(n,5,0,n.parent.context.$implicit.headerTemplate)},function(l,n){l(n,0,0,y._38(1,"",n.parent.context.$implicit.title,""))})}function s(l){return y._24(0,[(l()(),y._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,o)),y._27(8192,null,0,b.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),(l()(),y._26(null,["\n "]))],function(l,n){l(n,3,0,n.component.showColumn(n.context.$implicit.key))},null)}function c(l){return y._24(0,[(l()(),y._26(null,["\n "]))],null,null)}function _(l){return y._24(0,[(l()(),y._28(8388608,null,null,2,null,c)),y._27(270336,null,0,b.s,[y.S],{ngTemplateOutletContext:[0,"ngTemplateOutletContext"],ngTemplateOutlet:[1,"ngTemplateOutlet"]},null),y._31(["$implicit"]),(l()(),y._28(0,null,null,0))],function(l,n){l(n,1,0,l(n,2,0,n.parent.parent.parent.context.$implicit),n.parent.parent.context.$implicit.cellTemplate)},null)}function p(l){return y._24(0,[(l()(),y._25(0,null,null,4,"td",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,_)),y._27(8192,null,0,b.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),(l()(),y._26(null,["\n "]))],function(l,n){l(n,3,0,n.parent.context.$implicit.cellTemplate)},null)}function d(l){return y._24(0,[(l()(),y._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,p)),y._27(8192,null,0,b.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),(l()(),y._26(null,["\n "]))],function(l,n){l(n,3,0,n.component.showColumn(n.context.$implicit.key))},null)}function f(l){return y._24(0,[(l()(),y._25(0,null,null,4,"tr",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,d)),y._27(401408,null,0,b.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(l()(),y._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,u._columnTemplates,u.trackByKey)},null)}function m(l){return y._24(0,[(l()(),y._25(0,null,null,3,"option",[],null,null,null,null,null)),y._27(73728,null,0,S.k,[y.K,y.J,[2,S.l]],{value:[0,"value"]},null),y._27(73728,null,0,S.m,[y.K,y.J,[8,null]],{value:[0,"value"]},null),(l()(),y._26(null,["",""]))],function(l,n){l(n,1,0,n.context.$implicit.value),l(n,2,0,n.context.$implicit.value)},function(l,n){l(n,3,0,n.context.$implicit.text)})}function h(l){return y._24(2,[(l()(),y._28(8388608,null,null,2,null,r)),y._27(8192,null,0,b.l,[y.S,y._5],{ngIf:[0,"ngIf"]},null),y._34(65536,b.q,[y.O]),(l()(),y._26(null,["\n"])),(l()(),y._25(0,null,null,21,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,18,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,7,"thead",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,4,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,s)),y._27(401408,null,0,b.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,6,"tbody",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,3,null,f)),y._27(401408,null,0,b.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"],ngForTrackBy:[1,"ngForTrackBy"]},null),y._34(65536,b.q,[y.O]),y._34(0,b.t,[]),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n"])),(l()(),y._26(null,["\n"])),(l()(),y._25(0,null,null,59,"div",[["class","w3-cell-row w3-margin-top"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,56,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,53,"table",[["class","w3-responsive w3-right w3-small"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,51,"tbody",[],null,null,null,null,null)),(l()(),y._25(0,null,null,49,"tr",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,32,"td",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,29,"div",[["class","w3-bar w3-border border-theme"]],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button w3-border-right border-theme"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setFirstPage()&&t}return t},null,null)),y._27(139264,null,0,b.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["«"])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button device-tiny-show"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setPrevPage()&&t}return t},null,null)),y._27(139264,null,0,b.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["❮"])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button w3-border-right border-theme device-tiny-hide"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setPrevPage()&&t}return t},null,null)),y._27(139264,null,0,b.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["❮"])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,1,"span",[["class","device-tiny-hide"]],null,null,null,null,null)),(l()(),y._26(null,[" "," - "," of "," "])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button w3-border-left border-theme w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setLastPage()&&t}return t},null,null)),y._27(139264,null,0,b.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["»"])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,3,"a",[["class","w3-button w3-border-left border-theme w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setNextPage()&&t}return t},null,null)),y._27(139264,null,0,b.m,[y.v,y.w,y.K,y.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),y._31(["disabled"]),(l()(),y._26(null,["❯"])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,12,"td",[],null,null,null,null,null)),(l()(),y._26(null,["\n "])),(l()(),y._25(0,null,null,9,"select",[["class","w3-select w3-border border-theme theme-l1"],["style","max-width: 200px; padding: 12px 5px;"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"change"],[null,"blur"]],function(l,n,u){var t=!0,e=l.component;if("change"===n){t=!1!==y._29(l,73).onChange(u.target.value)&&t}if("blur"===n){t=!1!==y._29(l,73).onTouched()&&t}if("ngModelChange"===n){t=!1!==e.setViewLimit(u)&&t}return t},null,null)),y._27(8192,null,0,S.l,[y.J,y.K],null,null),y._37(512,null,S.g,function(l){return[l]},[S.l]),y._27(335872,null,0,S.h,[[8,null],[8,null],[8,null],[2,S.g]],{model:[0,"model"]},{update:"ngModelChange"}),y._37(1024,null,S.i,null,[S.h]),y._27(8192,null,0,S.j,[S.i],null,null),(l()(),y._26(null,["\n "])),(l()(),y._28(8388608,null,null,1,null,m)),y._27(401408,null,0,b.n,[y.S,y._5,y.v],{ngForOf:[0,"ngForOf"]},null),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n "])),(l()(),y._26(null,["\n"]))],function(l,n){var u=n.component;l(n,1,0,y._33(n,1,0,y._29(n,2).transform(u.numEnabledModes))>1),l(n,13,0,u._columnTemplates,u.trackByKey),l(n,20,0,y._33(n,20,0,y._29(n,22).transform(y._33(n,20,0,y._29(n,21).transform(u._rows$)),u._fromRow,u._fromRow+u._numRows)),u.trackByRow),l(n,41,0,"w3-button w3-border-right border-theme",l(n,42,0,u.isFirstPage())),l(n,46,0,"w3-button device-tiny-show",l(n,47,0,u.isFirstPage())),l(n,51,0,"w3-button w3-border-right border-theme device-tiny-hide",l(n,52,0,u.isFirstPage())),l(n,59,0,"w3-button w3-border-left border-theme w3-right",l(n,60,0,u.isLastPage())),l(n,64,0,"w3-button w3-border-left border-theme w3-right",l(n,65,0,u.isLastPage())),l(n,75,0,u._numRows),l(n,80,0,u._viewOptions)},function(l,n){var u=n.component;l(n,56,0,u._fromRow,u.getLastRowOffset(),u._rows.length),l(n,72,0,y._29(n,77).ngClassUntouched,y._29(n,77).ngClassTouched,y._29(n,77).ngClassPristine,y._29(n,77).ngClassDirty,y._29(n,77).ngClassValid,y._29(n,77).ngClassInvalid,y._29(n,77).ngClassPending)})}function v(l){return y._24(0,[(l()(),y._25(0,null,null,3,"ark-data-table",[],null,null,null,h,C)),y._27(57344,null,2,w.a,[y.O],null,null),y._35(301989888,1,{modeTemplates:1}),y._35(301989888,2,{columnTemplates:1})],function(l,n){l(n,1,0)},null)}var g=u("beiT"),y=u("3j3K"),b=u("2Je8"),S=u("NVOs"),w=u("0jRk");u.d(n,"b",function(){return C}),n.a=h;var k=[g.a],C=y._23({encapsulation:2,styles:k,data:{}});y._30("ark-data-table",w.a,v,{rows:"rows",trackByProp:"trackByProp",sortFunctions:"sortFunctions",orderByColumn:"orderByColumn"},{},[])},h5ac:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},if6N:function(l,n,u){"use strict";function t(l){return c._24(0,[(l()(),c._25(0,null,null,1,"a",[["role","button"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.navigateTo("/")&&t}return t},null,null)),(l()(),c._26(null,["",""]))],null,function(l,n){l(n,1,0,n.parent.context.$implicit)})}function e(l){return c._24(0,[(l()(),c._25(0,null,null,1,"a",[["role","button"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.navigateTo(l.parent.context.$implicit)&&t}return t},null,null)),(l()(),c._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component.friendlyName(n.parent.context.$implicit))})}function r(l){return c._24(0,[(l()(),c._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),c._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component.friendlyName(n.parent.context.$implicit))})}function i(l){return c._24(0,[(l()(),c._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),c._26(null,["",""]))],null,function(l,n){l(n,1,0,n.component.friendlyName("/"))})}function a(l){return c._24(0,[(l()(),c._25(0,null,null,16,"li",[],null,null,null,null,null)),c._27(139264,null,0,_.m,[c.v,c.w,c.K,c.J],{ngClass:[0,"ngClass"]},null),c._31(["breadcrumb-item","active"]),(l()(),c._26(null,[" "])),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,t)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,e)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,r)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,i)),c._27(8192,null,0,_.l,[c.S,c._5],{ngIf:[0,"ngIf"]},null),(l()(),c._26(null,["\n "]))],function(l,n){var u=n.component;l(n,1,0,l(n,2,0,u.useBootstrap,n.context.last)),l(n,6,0,!n.context.last&&n.context.$implicit==u.prefix),l(n,9,0,!n.context.last&&n.context.$implicit!=u.prefix),l(n,12,0,n.context.last),l(n,15,0,n.context.last&&n.context.$implicit==u.prefix)},null)}function o(l){return c._24(0,[(l()(),c._26(null,["\n "])),(l()(),c._25(0,null,null,4,"ul",[],[[2,"breadcrumb",null]],null,null,null,null)),(l()(),c._26(null,["\n "])),(l()(),c._28(8388608,null,null,1,null,a)),c._27(401408,null,0,_.n,[c.S,c._5,c.v],{ngForOf:[0,"ngForOf"]},null),(l()(),c._26(null,["\n "])),(l()(),c._26(null,["\n "]))],function(l,n){l(n,4,0,n.component._urls)},function(l,n){l(n,1,0,n.component.useBootstrap)})}function s(l){return c._24(0,[(l()(),c._25(0,null,null,1,"breadcrumb",[],null,null,null,o,h)),c._27(385024,null,0,p.a,[d.g,f.a],null,null)],function(l,n){l(n,1,0)},null)}var c=u("3j3K"),_=u("2Je8"),p=u("v8ur"),d=u("5oXY"),f=u("aT6V");u.d(n,"b",function(){return h}),n.a=o;var m=[],h=c._23({encapsulation:2,styles:m,data:{}});c._30("breadcrumb",p.a,s,{useBootstrap:"useBootstrap",prefix:"prefix"},{},[])},jWPz:function(l,n,u){"use strict";var t=u("3j3K");u.d(n,"c",function(){return e}),u.d(n,"b",function(){return r}),u.d(n,"a",function(){return i});var e=function(){function l(l){this.template=l}return l.ctorParameters=function(){return[{type:t._5}]},l}(),r=function(){function l(l){this.template=l}return l.ctorParameters=function(){return[{type:t._5}]},l}(),i=function(){function l(){}return l}()},joX7:function(l,n,u){"use strict";var t=u("Gvdl");u.n(t);u.d(n,"a",function(){return e});var e=function(){function l(){this.enabled=t.Observable.of(!0)}return Object.defineProperty(l.prototype,"columnKeys",{set:function(l){this._columnKeys=l,this.ColumnKeys=this._columnKeys.split(",")},enumerable:!0,configurable:!0}),l}()},jxRA:function(l,n,u){"use strict";function t(l){return o._24(0,[(l()(),o._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==o._29(l.parent.parent,2).activate(l.context.$implicit.Key)&&t}return t},null,null)),o._27(139264,null,0,s.m,[o.v,o.w,o.K,o.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),o._31(["theme-d1"]),(l()(),o._26(null,["",""]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,o._29(n.parent.parent,2).active(n.context.$implicit.Key)))},function(l,n){l(n,3,0,n.context.$implicit.Key)})}function e(l){return o._24(0,[(l()(),o._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._28(8388608,null,null,1,null,t)),o._27(401408,null,0,s.n,[o.S,o._5,o.v],{ngForOf:[0,"ngForOf"]},null),(l()(),o._26(null,["\n "]))],function(l,n){l(n,3,0,n.component.dataService.Servers.Servers)},null)}function r(l){return o._24(0,[o._35(201326592,1,{menu:0}),(l()(),o._25(0,null,null,16,"app-menu",[],null,null,null,c.a,c.b)),o._27(122880,[[1,4],["menu",4]],0,_.a,[p.a],null,null),(l()(),o._26(0,["\n "])),(l()(),o._25(0,null,0,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),o._26(null,["Servers"])),(l()(),o._26(0,["\n "])),(l()(),o._25(0,null,0,9,"div",[["class","w3-cell-row theme-l2"]],null,null,null,null,null)),(l()(),o._26(null,["\n "])),(l()(),o._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==o._29(l,2).activate("overview")&&t}return t},null,null)),o._27(139264,null,0,s.m,[o.v,o.w,o.K,o.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),o._31(["theme-d1"]),(l()(),o._26(null,["Overview"])),(l()(),o._26(null,["\n "])),(l()(),o._28(8388608,null,null,1,null,e)),o._27(8192,null,0,s.l,[o.S,o._5],{ngIf:[0,"ngIf"]},null),(l()(),o._26(null,["\n "])),(l()(),o._26(0,["\n"]))],function(l,n){var u=n.component;l(n,2,0),l(n,10,0,"w3-button w3-cell w3-mobile",l(n,11,0,o._29(n,2).active("overview"))),l(n,15,0,void 0!=u.dataService.Servers&&u.dataService.hasFeatureAccess("home","serverdetails"))},null)}function i(l){return o._24(0,[(l()(),o._25(0,null,null,1,"app-server-list-menu",[],[[8,"className",0]],null,null,r,m)),o._27(57344,null,0,d.a,[p.a],null,null)],function(l,n){l(n,1,0)},function(l,n){l(n,0,0,o._29(n,1).menu.className)})}var a=u("mjI6"),o=u("3j3K"),s=u("2Je8"),c=u("coiB"),_=u("8kYA"),p=u("ATz5"),d=u("JKTH");u.d(n,"a",function(){return h});var f=[a.a],m=o._23({encapsulation:0,styles:f,data:{}}),h=o._30("app-server-list-menu",d.a,i,{},{},[])},kZql:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t={production:!0,demo:!1,demoDate:null,apiBaseUrl:"//:/api",signalrBaseUrl:"//:/signalr"}},kke6:function(l,n,u){"use strict";var t=u("3j3K"),e=u("Iksp"),r=u("5oXY"),i=u("2Je8"),a=u("ktkS"),o=u("Qbdm"),s=u("NVOs"),c=u("Fzro"),_=u("KN8t"),p=u("zsCj"),d=u("J8nT"),f=u("aT6V"),m=u("XLrO"),h=u("lHWG"),v=u("+Lwu"),g=u("ATz5"),y=u("AcJ7"),b=u("+w0e"),S=u("nuuw"),w=u("ofcV"),k=u("+T68"),C=u("1AkI"),I=u("+KJ1"),x=u("0VGx"),O=u("nMh6"),A=u("jxRA"),T=u("SQlA"),F=u("0ME9"),M=u("OO5M"),L=u("1A80"),P=u("KZxv"),N=u("RiXa"),B=u("qn86"),K=u("7xIs"),j=u("e/mT"),$=u("08Wm"),R=u("JLFQ"),D=u("JKTH"),E=u("Fnlp"),U=u("+qYp"),z=u("FxpQ"),J=u("1GJ2");u.d(n,"a",function(){return X});var G=this&&this.__extends||function(){var l=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(l,n){l.__proto__=n}||function(l,n){for(var u in n)n.hasOwnProperty(u)&&(l[u]=n[u])};return function(n,u){function t(){this.constructor=n}l(n,u),n.prototype=null===u?Object.create(u):(t.prototype=u.prototype,new t)}}(),H=function(l){function n(n){return l.call(this,n,[S.a,w.a,k.a,C.a,I.a,x.a,O.a,A.a,T.a,F.a,M.a,L.a],[L.a])||this}return G(n,l),Object.defineProperty(n.prototype,"_LOCALE_ID_29",{get:function(){return null==this.__LOCALE_ID_29&&(this.__LOCALE_ID_29="en-US"),this.__LOCALE_ID_29},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_NgLocalization_30",{get:function(){return null==this.__NgLocalization_30&&(this.__NgLocalization_30=new i.a(this._LOCALE_ID_29)),this.__NgLocalization_30},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_APP_ID_31",{get:function(){return null==this.__APP_ID_31&&(this.__APP_ID_31=t.b()),this.__APP_ID_31},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_IterableDiffers_32",{get:function(){return null==this.__IterableDiffers_32&&(this.__IterableDiffers_32=t.c()),this.__IterableDiffers_32},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_KeyValueDiffers_33",{get:function(){return null==this.__KeyValueDiffers_33&&(this.__KeyValueDiffers_33=t.d()),this.__KeyValueDiffers_33},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_DomSanitizer_34",{get:function(){return null==this.__DomSanitizer_34&&(this.__DomSanitizer_34=new o.b(this.parent.get(o.c))),this.__DomSanitizer_34},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Sanitizer_35",{get:function(){return null==this.__Sanitizer_35&&(this.__Sanitizer_35=this._DomSanitizer_34),this.__Sanitizer_35},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_HAMMER_GESTURE_CONFIG_36",{get:function(){return null==this.__HAMMER_GESTURE_CONFIG_36&&(this.__HAMMER_GESTURE_CONFIG_36=new o.d),this.__HAMMER_GESTURE_CONFIG_36},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_EVENT_MANAGER_PLUGINS_37",{get:function(){return null==this.__EVENT_MANAGER_PLUGINS_37&&(this.__EVENT_MANAGER_PLUGINS_37=[new o.e(this.parent.get(o.c)),new o.f(this.parent.get(o.c)),new o.g(this.parent.get(o.c),this._HAMMER_GESTURE_CONFIG_36)]),this.__EVENT_MANAGER_PLUGINS_37},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_EventManager_38",{get:function(){return null==this.__EventManager_38&&(this.__EventManager_38=new o.h(this._EVENT_MANAGER_PLUGINS_37,this.parent.get(t.e))),this.__EventManager_38},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵDomSharedStylesHost_39",{get:function(){return null==this.__ɵDomSharedStylesHost_39&&(this.__ɵDomSharedStylesHost_39=new o.i(this.parent.get(o.c))),this.__ɵDomSharedStylesHost_39},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵDomRendererFactory2_40",{get:function(){return null==this.__ɵDomRendererFactory2_40&&(this.__ɵDomRendererFactory2_40=new o.j(this._EventManager_38,this._ɵDomSharedStylesHost_39)),this.__ɵDomRendererFactory2_40},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_AnimationDriver_41",{get:function(){return null==this.__AnimationDriver_41&&(this.__AnimationDriver_41=_.a()),this.__AnimationDriver_41},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵAnimationStyleNormalizer_42",{get:function(){return null==this.__ɵAnimationStyleNormalizer_42&&(this.__ɵAnimationStyleNormalizer_42=_.b()),this.__ɵAnimationStyleNormalizer_42},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵAnimationEngine_43",{get:function(){return null==this.__ɵAnimationEngine_43&&(this.__ɵAnimationEngine_43=new _.c(this._AnimationDriver_41,this._ɵAnimationStyleNormalizer_42)),this.__ɵAnimationEngine_43},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_RendererFactory2_44",{get:function(){return null==this.__RendererFactory2_44&&(this.__RendererFactory2_44=_.d(this._ɵDomRendererFactory2_40,this._ɵAnimationEngine_43,this.parent.get(t.e))),this.__RendererFactory2_44},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵSharedStylesHost_45",{get:function(){return null==this.__ɵSharedStylesHost_45&&(this.__ɵSharedStylesHost_45=this._ɵDomSharedStylesHost_39),this.__ɵSharedStylesHost_45},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Testability_46",{get:function(){return null==this.__Testability_46&&(this.__Testability_46=new t.f(this.parent.get(t.e))),this.__Testability_46},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Meta_47",{get:function(){return null==this.__Meta_47&&(this.__Meta_47=new o.k(this.parent.get(o.c))),this.__Meta_47},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Title_48",{get:function(){return null==this.__Title_48&&(this.__Title_48=new o.l(this.parent.get(o.c))),this.__Title_48},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ɵi_49",{get:function(){return null==this.__ɵi_49&&(this.__ɵi_49=new s.a),this.__ɵi_49},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_BrowserXhr_50",{get:function(){return null==this.__BrowserXhr_50&&(this.__BrowserXhr_50=new c.a),this.__BrowserXhr_50},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ResponseOptions_51",{get:function(){return null==this.__ResponseOptions_51&&(this.__ResponseOptions_51=new c.b),this.__ResponseOptions_51},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_XSRFStrategy_52",{get:function(){return null==this.__XSRFStrategy_52&&(this.__XSRFStrategy_52=c.c()),this.__XSRFStrategy_52},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_XHRBackend_53",{get:function(){return null==this.__XHRBackend_53&&(this.__XHRBackend_53=new c.d(this._BrowserXhr_50,this._ResponseOptions_51,this._XSRFStrategy_52)),this.__XHRBackend_53},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_RequestOptions_54",{get:function(){return null==this.__RequestOptions_54&&(this.__RequestOptions_54=new c.e),this.__RequestOptions_54},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_Http_55",{get:function(){return null==this.__Http_55&&(this.__Http_55=c.f(this._XHRBackend_53,this._RequestOptions_54)),this.__Http_55},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ActivatedRoute_56",{get:function(){return null==this.__ActivatedRoute_56&&(this.__ActivatedRoute_56=r.a(this._Router_16)),this.__ActivatedRoute_56},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_NoPreloading_57",{get:function(){return null==this.__NoPreloading_57&&(this.__NoPreloading_57=new r.b),this.__NoPreloading_57},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_PreloadingStrategy_58",{get:function(){return null==this.__PreloadingStrategy_58&&(this.__PreloadingStrategy_58=this._NoPreloading_57),this.__PreloadingStrategy_58},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_RouterPreloader_59",{get:function(){return null==this.__RouterPreloader_59&&(this.__RouterPreloader_59=new r.c(this._Router_16,this._NgModuleFactoryLoader_14,this._Compiler_13,this,this._PreloadingStrategy_58)),this.__RouterPreloader_59},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_PreloadAllModules_60",{get:function(){return null==this.__PreloadAllModules_60&&(this.__PreloadAllModules_60=new r.d),this.__PreloadAllModules_60},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_ROUTER_INITIALIZER_61",{get:function(){return null==this.__ROUTER_INITIALIZER_61&&(this.__ROUTER_INITIALIZER_61=r.e(this._ɵg_3)),this.__ROUTER_INITIALIZER_61},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_APP_BOOTSTRAP_LISTENER_62",{get:function(){return null==this.__APP_BOOTSTRAP_LISTENER_62&&(this.__APP_BOOTSTRAP_LISTENER_62=[this._ROUTER_INITIALIZER_61]),this.__APP_BOOTSTRAP_LISTENER_62},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_BreadcrumbService_63",{get:function(){return null==this.__BreadcrumbService_63&&(this.__BreadcrumbService_63=new f.a),this.__BreadcrumbService_63},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_NotificationsService_64",{get:function(){return null==this.__NotificationsService_64&&(this.__NotificationsService_64=new m.a),this.__NotificationsService_64},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_HttpService_65",{get:function(){return null==this.__HttpService_65&&(this.__HttpService_65=new h.a(this._Http_55)),this.__HttpService_65},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_MessageService_66",{get:function(){return null==this.__MessageService_66&&(this.__MessageService_66=new v.a(this.parent.get(t.e))),this.__MessageService_66},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_DataService_67",{get:function(){return null==this.__DataService_67&&(this.__DataService_67=new g.a(this._HttpService_65,this._MessageService_66)),this.__DataService_67},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_DataServiceResolver_68",{get:function(){return null==this.__DataServiceResolver_68&&(this.__DataServiceResolver_68=new y.a(this._DataService_67,this._Router_16)),this.__DataServiceResolver_68},enumerable:!0,configurable:!0}),Object.defineProperty(n.prototype,"_AccessControlRouteGuardService_69",{get:function(){return null==this.__AccessControlRouteGuardService_69&&(this.__AccessControlRouteGuardService_69=new b.a(this._DataService_67,this._Router_16)),this.__AccessControlRouteGuardService_69},enumerable:!0,configurable:!0}),n.prototype.createInternal=function(){return this._ɵa_0=r.f(this.parent.get(r.g,null)),this._ErrorHandler_1=o.m(),this._NgProbeToken_2=[r.h()],this._ɵg_3=new r.i(this),this._APP_INITIALIZER_4=[t.g,o.n(this.parent.get(o.o,null),this._NgProbeToken_2),r.j(this._ɵg_3)],this._ApplicationInitStatus_5=new t.h(this._APP_INITIALIZER_4),this._ɵf_6=new t.i(this.parent.get(t.e),this.parent.get(t.j),this,this._ErrorHandler_1,this.componentFactoryResolver,this._ApplicationInitStatus_5),this._ApplicationRef_7=this._ɵf_6,this._UrlSerializer_8=new r.k,this._RouterOutletMap_9=new r.l,this._ROUTER_CONFIGURATION_10={},this._LocationStrategy_11=r.m(this.parent.get(i.b),this.parent.get(i.c,null),this._ROUTER_CONFIGURATION_10),this._Location_12=new i.d(this._LocationStrategy_11),this._Compiler_13=new t.k,this._NgModuleFactoryLoader_14=new t.l(this._Compiler_13,this.parent.get(t.m,null)),this._ROUTES_15=[[{path:"player/:playerid",canActivate:[b.a],data:{name:"player"},children:[{path:"",component:P.a},{path:"",component:N.a,outlet:"menu"}]},{path:"server/:id",canActivate:[b.a],data:{name:"server"},children:[{path:"",component:B.a},{path:"",component:K.a,outlet:"menu"}]},{path:"admin/:id",canActivate:[b.a],data:{name:"admin-server"},children:[{path:"",component:j.a},{path:"",component:$.a,outlet:"menu"}]},{path:"servers",canActivate:[b.a],data:{name:"home"},children:[{path:"",component:R.a},{path:"",component:D.a,outlet:"menu"}]},{path:"developer",component:E.a},{path:"accessdenied",component:U.a},{path:"connectionerror",component:z.a},{path:"",redirectTo:"/servers",pathMatch:"full"}]],this._Router_16=r.n(this._ApplicationRef_7,this._UrlSerializer_8,this._RouterOutletMap_9,this._Location_12,this,this._NgModuleFactoryLoader_14,this._Compiler_13,this._ROUTES_15,this._ROUTER_CONFIGURATION_10,this.parent.get(r.o,null),this.parent.get(r.p,null)),this._RouterModule_17=new r.q(this._ɵa_0,this._Router_16),this._CommonModule_18=new i.e,this._Ng2BreadcrumbModule_19=new a.a,this._ApplicationModule_20=new t.n(this._ApplicationRef_7),this._BrowserModule_21=new o.p(this.parent.get(o.p,null)),this._ɵba_22=new s.b,this._FormsModule_23=new s.c,this._HttpModule_24=new c.g,this._BrowserAnimationsModule_25=new _.e,this._SimpleNotificationsModule_26=new p.SimpleNotificationsModule,this._DataTableModule_27=new d.a,this._AppModule_28=new e.a,this._AppModule_28},n.prototype.getInternal=function(l,n){return l===r.r?this._ɵa_0:l===t.o?this._ErrorHandler_1:l===t.p?this._NgProbeToken_2:l===r.i?this._ɵg_3:l===t.q?this._APP_INITIALIZER_4:l===t.h?this._ApplicationInitStatus_5:l===t.i?this._ɵf_6:l===t.r?this._ApplicationRef_7:l===r.s?this._UrlSerializer_8:l===r.l?this._RouterOutletMap_9:l===r.t?this._ROUTER_CONFIGURATION_10:l===i.f?this._LocationStrategy_11:l===i.d?this._Location_12:l===t.k?this._Compiler_13:l===t.s?this._NgModuleFactoryLoader_14:l===r.u?this._ROUTES_15:l===r.g?this._Router_16:l===r.q?this._RouterModule_17:l===i.e?this._CommonModule_18:l===a.a?this._Ng2BreadcrumbModule_19:l===t.n?this._ApplicationModule_20:l===o.p?this._BrowserModule_21:l===s.b?this._ɵba_22:l===s.c?this._FormsModule_23:l===c.g?this._HttpModule_24:l===_.e?this._BrowserAnimationsModule_25:l===p.SimpleNotificationsModule?this._SimpleNotificationsModule_26:l===d.a?this._DataTableModule_27:l===e.a?this._AppModule_28:l===t.t?this._LOCALE_ID_29:l===i.g?this._NgLocalization_30:l===t.u?this._APP_ID_31:l===t.v?this._IterableDiffers_32:l===t.w?this._KeyValueDiffers_33:l===o.q?this._DomSanitizer_34:l===t.x?this._Sanitizer_35:l===o.r?this._HAMMER_GESTURE_CONFIG_36:l===o.s?this._EVENT_MANAGER_PLUGINS_37:l===o.h?this._EventManager_38:l===o.i?this._ɵDomSharedStylesHost_39:l===o.j?this._ɵDomRendererFactory2_40:l===J.a?this._AnimationDriver_41:l===J.b?this._ɵAnimationStyleNormalizer_42:l===J.c?this._ɵAnimationEngine_43:l===t.y?this._RendererFactory2_44:l===o.t?this._ɵSharedStylesHost_45:l===t.f?this._Testability_46:l===o.k?this._Meta_47:l===o.l?this._Title_48:l===s.a?this._ɵi_49:l===c.a?this._BrowserXhr_50:l===c.h?this._ResponseOptions_51:l===c.i?this._XSRFStrategy_52:l===c.d?this._XHRBackend_53:l===c.j?this._RequestOptions_54:l===c.k?this._Http_55:l===r.v?this._ActivatedRoute_56:l===r.b?this._NoPreloading_57:l===r.w?this._PreloadingStrategy_58:l===r.c?this._RouterPreloader_59:l===r.d?this._PreloadAllModules_60:l===r.x?this._ROUTER_INITIALIZER_61:l===t.z?this._APP_BOOTSTRAP_LISTENER_62:l===f.a?this._BreadcrumbService_63:l===m.a?this._NotificationsService_64:l===h.a?this._HttpService_65:l===v.a?this._MessageService_66:l===g.a?this._DataService_67:l===y.a?this._DataServiceResolver_68:l===b.a?this._AccessControlRouteGuardService_69:n},n.prototype.destroyInternal=function(){this._ɵf_6.ngOnDestroy(),this.__ɵDomSharedStylesHost_39&&this._ɵDomSharedStylesHost_39.ngOnDestroy(),this.__RouterPreloader_59&&this._RouterPreloader_59.ngOnDestroy()},n}(t.A),X=new t.B(H,e.a)},l3s9:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},lCrv:function(l,n,u){"use strict";var t=u("3j3K"),e=u("Gvdl"),r=(u.n(e),u("ATz5")),i=u("lHWG"),a=u("kZql"),o=u("f4AQ"),s=(u.n(o),u("PJh5"));u.n(s);u.d(n,"a",function(){return c});var c=function(){function l(l,n,u){this.dataService=l,this.httpService=n,this.zone=u,this._structures=new e.BehaviorSubject(void 0),this.keysGetter=Object.keys,this.ownerSortField="locations",this.ownerSortFunctions={locations:function(l,n){return l.AreaCount>n.AreaCount?-1:l.AreaCountn.StructureCount?-1:l.StructureCountn.StructureCount?-1:l.StructureCountn.LastActiveTime||void 0==n.LastActiveTime?1:0}},this.width=1024,this.height=1024,this.zoom=o.zoom().scaleExtent([1,8])}return Object.defineProperty(l.prototype,"structures",{get:function(){return this._structures.getValue()},set:function(l){this._structures.next(l)},enumerable:!0,configurable:!0}),l.prototype.ngOnInit=function(){var l=this;this._structuresSubscription=this._structures.subscribe(function(n){return l.update(n)});var n=this.mapContainer.nativeElement;this.map={},this.map.canvas=o.select(n).append("canvas").attr("width",1024).attr("height",1024).node().getContext("2d"),this.map.svg=o.select(n).append("svg").attr("viewBox","0 0 1024 1024").attr("preserveAspectRatio","xMidYMid").append("g").on("contextmenu",function(l,n){o.event.preventDefault()}),this.map.svg.append("rect").attr("class","overlay").attr("width",1024).attr("height",1024),this.map.x=o.scaleLinear().domain([0,1024]).range([0,1024]),this.map.y=o.scaleLinear().domain([0,1024]).range([0,1024]),o.select(n).call(this.zoom.on("zoom",function(){l.hideContextMenu(),l.redraw()})).on("wheel.zoom",null),this.structures&&this.updateMap()},l.prototype.ngOnDestroy=function(){this._structuresSubscription.unsubscribe()},l.prototype.zoomIn=function(){this.zoom.scaleBy(o.select(this.mapContainer.nativeElement),1.2)},l.prototype.zoomOut=function(){this.zoom.scaleBy(o.select(this.mapContainer.nativeElement),.8)},l.prototype.updateSelection=function(){var l=this;this.map.svg.circle.attr("display",function(n){var u=l.structures.Owners[n.OwnerId];return n.Removed||u.Removed||l.selectedOwner&&(!l.selectedOwner||l.selectedOwner.Id!=n.OwnerId)?"none":"block"}),this.redraw()},l.prototype.update=function(l){this.sortOwners(l),this.map&&this.updateMap()},l.prototype.sortOwners=function(l){var n=this.ownerSortFunctions[this.ownerSortField];if(l){var u=l.Owners.slice();u.sort(n),this.ownersSorted=u}else this.ownersSorted=void 0},l.prototype.updateMap=function(){var l=this;this.map.svg.nodes=this.structures.Areas,this.map.svg.draw=function(){l.map.svg.circle=l.map.svg.selectAll("circle").data(l.map.svg.nodes).enter().append("circle").attr("r",function(l){return l.RadiusPx<2?2:l.RadiusPx}).attr("fill","transparent").attr("stroke",function(n){var u=l.structures.Owners[n.OwnerId];return!!u.LastActiveTime&&s(new Date(u.LastActiveTime)).isSameOrAfter(s().subtract(28,"day"))&&(n.StructureCount>=100||n.TrashQuota<.5&&n.StructureCount>=10)?"magenta":"red"}).attr("stroke-width",function(n){var u=l.structures.Owners[n.OwnerId];return!!u.LastActiveTime&&s(new Date(u.LastActiveTime)).isSameOrAfter(s().subtract(28,"day"))&&(n.StructureCount>=100||n.TrashQuota<.5&&n.StructureCount>=10)?3:2}).attr("transform",l.map.svg.transform),l.map.svg.circle.on("click",function(n){o.event.preventDefault();var u={};u.x=o.event.pageX,u.y=o.event.pageY,l.showAreaModal(n,u)}),l.map.svg.circle.append("svg:title").text(function(n){var u=l.structures.Owners[n.OwnerId],t=u.LastActiveTime?s(new Date(u.LastActiveTime)).fromNow():null;return u.Name+": "+n.StructureCount+" structures\nCoords: "+n.Latitude+", "+n.Longitude+"\n"+(t?"Last active: "+t+"\n":"")+"---\n"+n.Structures.map(function(n){var u=l.structures.Types[n.t];return n.c+": "+(u?u.Name:n.t)}).join("\n")})},this.map.svg.draw(),this.map.svg.transform=function(n){return"translate("+l.map.x(n.TopoMapX)+","+l.map.y(n.TopoMapY)+")"},this.map.svg.circle.attr("transform",this.map.svg.transform)},l.prototype.imageLoaded=function(l){var n=this;this.img=l,this.width=l?l.naturalWidth:1024,this.height=l?l.naturalHeight:1024,window.setTimeout(function(){n.resize(),n.redraw()},100)},l.prototype.resize=function(){},l.prototype.redraw=function(){var l=this,n=o.zoomTransform(this.mapContainer.nativeElement);this.map.svg.attr("transform","translate("+n.x+","+n.y+") scale("+n.k+")"),n.k!=this.prevTransformK&&this.map.svg.circle.attr("stroke-width",function(u){var t=l.structures.Owners[u.OwnerId];return(!!t.LastActiveTime&&s(new Date(t.LastActiveTime)).isSameOrAfter(s().subtract(28,"day"))&&(u.StructureCount>=100||u.TrashQuota<.5&&u.StructureCount>=10)?3:2)/n.k});var u=this.map.canvas;u.setTransform(1,0,0,1,0,0),u.clearRect(0,0,1024,1024),u.translate(n.x,n.y),u.scale(n.k,n.k),this.img&&u.drawImage(this.img,0,0),this.prevTransformK=n.k},l.prototype.ngOnChanges=function(l){var n=this;if(null!=this.mapName){var u=new Image;u.onload=function(){return n.imageLoaded(u)},u.onerror=function(){return n.imageLoaded(void 0)},u.src=a.a.demo?"assets/demo/Ragnarok.jpg":this.getApiBaseUrl()+"/map/"+this.mapName,u.complete&&(u.onload=null,u.onerror=null,this.imageLoaded(u))}},l.prototype.getApiBaseUrl=function(){return a.a.apiBaseUrl.replace(/\/gi,window.location.protocol).replace(/\/gi,window.location.hostname).replace(/\/gi,void 0!=config?config.webapi.port:"")},l.prototype.reset=function(){this.selectedOwner=void 0,this.updateSelection()},l.prototype.setSelectedOwner=function(l){this.selectedOwner=l,this.updateSelection()},l.prototype.setOwnerSort=function(l){this.ownerSortField=l,this.sortOwners(this.structures)},l.prototype.showAreaModal=function(l,n){this.currentArea=l,this.currentOwner=this.structures.Owners[l.OwnerId],o.select(this.contextMenu.nativeElement).style("display","block"),o.event&&o.event.stopPropagation()},l.prototype.showOwnerModal=function(l,n){this.currentOwner=n,o.select(this.contextMenu.nativeElement).style("display","block"),l.stopPropagation()},l.prototype.showInfoModal=function(l,n){var u={};u.Header=l,u.Message=n,this.modalInfo=u,o.select(this.contextMenu.nativeElement).style("display","block"),o.event&&o.event.stopPropagation()},l.prototype.hideContextMenu=function(){o.select(this.contextMenu.nativeElement).style("display","none"),this.currentArea=void 0,this.currentOwner=void 0,this.modalInfo=void 0},l.prototype.destroyCurrentArea=function(l){var n=this;this.httpService.adminDestroyStructuresForTeamIdAtPosition(this.serverKey,this.currentOwner.OwnerId,this.currentArea.X,this.currentArea.Y,+this.currentArea.RadiusUu+1e3,1).then(function(l){n.currentArea.Removed=!0,n.currentOwner.AreaCount-=1,n.currentOwner.StructureCount-=n.currentArea.StructureCount,n.hideContextMenu(),n.showInfoModal("Action Successfull!",l.Message),n.updateSelection()}).catch(function(l){n.hideContextMenu();var u=l&&l._body?JSON.parse(l._body):void 0;n.showInfoModal("Action Failed...",u?u.Message:l.statusText)})},l.prototype.destroyAllStructuresForTeam=function(l){var n=this;this.httpService.adminDestroyAllStructuresForTeamId(this.serverKey,this.currentOwner.OwnerId).then(function(l){n.currentOwner.Removed=!0,n.currentOwner.AreaCount=0,n.currentOwner.StructureCount=0,n.hideContextMenu(),n.showInfoModal("Action Successfull!",l.Message),n.updateSelection()}).catch(function(l){n.hideContextMenu();var u=l&&l._body?JSON.parse(l._body):void 0;n.showInfoModal("Action Failed...",u?u.Message:l.statusText)})},l.prototype.destroyDinosForTeam=function(l){var n=this;this.httpService.adminDestroyDinosForTeamId(this.serverKey,this.currentOwner.OwnerId).then(function(l){n.currentOwner.CreatureCount=0,n.hideContextMenu(),n.showInfoModal("Action Successfull!",l.Message),n.updateSelection()}).catch(function(l){n.hideContextMenu();var u=l&&l._body?JSON.parse(l._body):void 0;n.showInfoModal("Action Failed...",u?u.Message:l.statusText)})},l.prototype.saveWorld=function(l){var n=this;this.httpService.adminSaveWorld(this.serverKey).then(function(l){n.hideContextMenu(),n.showInfoModal("Action Successfull!",l.Message)}).catch(function(l){n.hideContextMenu();var u=l&&l._body?JSON.parse(l._body):void 0;n.showInfoModal("Action Failed...",u?u.Message:l.statusText)})},l.ctorParameters=function(){return[{type:r.a},{type:i.a},{type:t.e}]},l}()},lHWG:function(l,n,u){"use strict";var t=u("Fzro"),e=u("eErF"),r=(u.n(e),u("kZql"));u.d(n,"a",function(){return i});var i=function(){function l(l){this.http=l,this.headers=new t.l({"Content-Type":"application/json"}),this.serversUrl="/servers",this.serverUrl="/server",this.wildCreaturesUrl="/wildcreatures",this.structuresUrl="/structures",this.adminServerUrl="/adminserver",this.administerUrl="/administer",this.playerUrl="/player"}return l.prototype.getOptions=function(){var l="true"==localStorage.getItem("demoMode"),n=new t.j({withCredentials:!0});return l&&(n.headers||(n.headers=new t.l),n.headers.append("demoMode","true")),n},l.prototype.getServers=function(){return this.http.get(""+this.getApiBaseUrl()+this.serversUrl+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getServer=function(l){return this.http.get(""+this.getApiBaseUrl()+this.serverUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getWildCreatures=function(l){return this.http.get(""+this.getApiBaseUrl()+this.wildCreaturesUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getStructures=function(l){return this.http.get(""+this.getApiBaseUrl()+this.structuresUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getPlayer=function(l){return this.http.get(""+this.getApiBaseUrl()+this.playerUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getAdminServer=function(l){return this.http.get(""+this.getApiBaseUrl()+this.adminServerUrl+"/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.adminDestroyAllStructuresForTeamId=function(l,n){return this.http.get(""+this.getApiBaseUrl()+this.administerUrl+"/DestroyAllStructuresForTeamId/"+l+"?teamId="+n+"&t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.adminDestroyStructuresForTeamIdAtPosition=function(l,n,u,t,e,r){return this.http.get(""+this.getApiBaseUrl()+this.administerUrl+"/DestroyStructuresForTeamIdAtPosition/"+l+"?teamId="+n+"&x="+u+"&y="+t+"&radius="+e+"&rafts="+r+"&t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.adminDestroyDinosForTeamId=function(l,n){return this.http.get(""+this.getApiBaseUrl()+this.administerUrl+"/DestroyDinosForTeamId/"+l+"?teamId="+n+"&t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.adminSaveWorld=function(l){return this.http.get(""+this.getApiBaseUrl()+this.administerUrl+"/SaveWorld/"+l+"?t="+ +new Date,this.getOptions()).toPromise().then(function(l){return l.json()}).catch(this.handleError)},l.prototype.getApiBaseUrl=function(){return r.a.apiBaseUrl.replace(/\/gi,window.location.protocol).replace(/\/gi,window.location.hostname).replace(/\/gi,void 0!=config?config.webapi.port:"")},l.prototype.handleError=function(l){return Promise.reject(l.message||l)},l.ctorParameters=function(){return[{type:t.k}]},l}()},mjI6:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},nJHW:function(l,n,u){"use strict";u.d(n,"a",function(){return t});var t=[""]},nMh6:function(l,n,u){"use strict";function t(l){return F._24(0,[(l()(),F._25(0,null,null,24,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["My Profile"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,18,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,4,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),F._26(null,["Hello, ",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,9,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),F._26(null,["\n Find your tames, view base stats and keep track of their food status. Get notified of pending imprints, the amount of fertilizer and gasoline remaining in your crops and generators. This and much more is available in your profile.\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,3,"p",[],null,null,null,null,null)),(l()(),F._25(0,null,null,2,"a",[["class",""],["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==F._29(l,20).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),F._27(335872,null,0,M.D,[M.g,M.v,L.f],{routerLink:[0,"routerLink"]},null),(l()(),F._26(null,["View my profile ❯"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n"]))],function(l,n){l(n,20,0,"/player/"+n.component.dataService.UserSteamId)},function(l,n){l(n,10,0,n.component.dataService.Servers.User.Name),l(n,19,0,F._29(n,20).target,F._29(n,20).href)})}function e(l){return F._24(0,[(l()(),F._25(0,null,null,1,null,null,null,null,null,null,null)),(l()(),F._26(null,[""," - "]))],null,function(l,n){l(n,1,0,n.parent.parent.context.$implicit.MapName)})}function r(l){return F._24(0,[(l()(),F._25(0,null,null,4,"a",[["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==F._29(l,1).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),F._27(335872,null,0,M.D,[M.g,M.v,L.f],{routerLink:[0,"routerLink"]},null),(l()(),F._28(8388608,null,null,1,null,e)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["",""]))],function(l,n){l(n,1,0,"/server/"+n.parent.context.$implicit.Key),l(n,3,0,n.parent.context.$implicit.MapName)},function(l,n){l(n,0,0,F._29(n,1).target,F._29(n,1).href),l(n,4,0,n.parent.context.$implicit.Key)})}function i(l){return F._24(0,[(l()(),F._25(0,null,null,1,null,null,null,null,null,null,null)),(l()(),F._26(null,[""," - "]))],null,function(l,n){l(n,1,0,n.parent.parent.context.$implicit.MapName)})}function a(l){return F._24(0,[(l()(),F._28(8388608,null,null,1,null,i)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["",""]))],function(l,n){l(n,1,0,n.parent.context.$implicit.MapName)},function(l,n){l(n,2,0,n.parent.context.$implicit.Key)})}function o(l){return F._24(0,[(l()(),F._25(0,null,null,3,"p",[],null,null,null,null,null)),(l()(),F._25(0,null,null,2,"a",[["class",""],["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==F._29(l,2).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),F._27(335872,null,0,M.D,[M.g,M.v,L.f],{routerLink:[0,"routerLink"]},null),(l()(),F._26(null,["View server ❯"]))],function(l,n){l(n,2,0,"/server/"+n.parent.context.$implicit.Key)},function(l,n){l(n,1,0,F._29(n,2).target,F._29(n,2).href)})}function s(l){return F._24(0,[(l()(),F._25(0,null,null,3,"p",[],null,null,null,null,null)),(l()(),F._25(0,null,null,2,"a",[["class",""],["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==F._29(l,2).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),F._27(335872,null,0,M.D,[M.g,M.v,L.f],{routerLink:[0,"routerLink"]},null),(l()(),F._26(null,["Admin ❯"]))],function(l,n){l(n,2,0,"/admin/"+n.parent.context.$implicit.Key)},function(l,n){l(n,1,0,F._29(n,2).target,F._29(n,2).href)})}function c(l){return F._24(0,[(l()(),F._25(0,null,null,21,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,6,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,3,"h3",[],null,null,null,null,null)),(l()(),F._28(8388608,null,null,1,null,r)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),F._28(0,[["server_no_link",2]],null,0,null,a)),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,10,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"p",[["class","w3-small"]],null,null,null,null,null)),(l()(),F._26(null,["\n Last Update ",", Next Update ","\n "])),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,o)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,s)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "]))],function(l,n){var u=n.component;l(n,6,0,u.dataService.hasFeatureAccess("pages","server"),F._29(n,7)),l(n,16,0,u.dataService.hasFeatureAccess("pages","server")),l(n,19,0,u.dataService.hasFeatureAccess("pages","admin-server"))},function(l,n){l(n,13,0,n.context.$implicit.LastUpdate,n.context.$implicit.NextUpdate||"-")})}function _(l){return F._24(0,[(l()(),F._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Servers"])),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,c)),F._27(401408,null,0,L.n,[F.S,F._5,F.v],{ngForOf:[0,"ngForOf"]},null),(l()(),F._26(null,["\n"]))],function(l,n){l(n,6,0,n.component.dataService.Servers.Servers)},null)}function p(l){return F._24(0,[(l()(),F._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),F._26(null,["There are no players online..."]))],null,null)}function d(l){return F._24(0,[(l()(),F._25(0,null,null,19,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.SteamName),l(n,6,0,n.context.$implicit.CharacterName),l(n,9,0,n.context.$implicit.TribeName),l(n,12,0,n.context.$implicit.DiscordName),l(n,15,0,n.parent.context.$implicit.Key),l(n,18,0,n.context.$implicit.TimeOnline)})}function f(l){return F._24(0,[(l()(),F._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,d)),F._27(401408,null,0,L.n,[F.S,F._5,F.v],{ngForOf:[0,"ngForOf"]},null),(l()(),F._26(null,["\n "]))],function(l,n){l(n,3,0,n.context.$implicit.OnlinePlayers)},null)}function m(l){return F._24(0,[(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,29,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,26,"table",[["class","w3-table w3-striped w3-bordered border-theme"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,24,"tbody",[],null,null,null,null,null)),(l()(),F._25(0,null,null,19,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Steam Name"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Character Name"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Tribe Name"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Discord Tag"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Server"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Time Online"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,f)),F._27(401408,null,0,L.n,[F.S,F._5,F.v],{ngForOf:[0,"ngForOf"]},null),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "]))],function(l,n){l(n,28,0,n.component.dataService.Servers.Servers)},null)}function h(l){return F._24(0,[(l()(),F._25(0,null,null,11,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,3,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Online "])),(l()(),F._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,p)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),F._26(null,["\n "])),(l()(),F._28(0,[["online_players_list",2]],null,0,null,m)),(l()(),F._26(null,["\n"]))],function(l,n){l(n,8,0,0==n.component.onlinePlayerCount,F._29(n,10))},function(l,n){l(n,5,0,n.component.onlinePlayerCount)})}function v(l){return F._24(0,[(l()(),F._25(0,null,null,2,"a",[["style","text-decoration: none;"]],[[1,"target",0],[8,"href",4]],[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==F._29(l,1).onClick(u.button,u.ctrlKey,u.metaKey)&&t}return t},null,null)),F._27(335872,null,0,M.D,[M.g,M.v,L.f],{routerLink:[0,"routerLink"]},null),(l()(),F._26(null,["",""]))],function(l,n){l(n,1,0,"/server/"+n.parent.parent.context.$implicit.Key)},function(l,n){l(n,0,0,F._29(n,1).target,F._29(n,1).href),l(n,2,0,n.parent.parent.context.$implicit.Name)})}function g(l){return F._24(0,[(l()(),F._26(null,["",""]))],null,function(l,n){l(n,0,0,n.parent.parent.context.$implicit.Name)})}function y(l){return F._24(0,[(l()(),F._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),F._26(null,["There are no players online..."]))],null,null)}function b(l){return F._24(0,[(l()(),F._25(0,null,null,16,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.SteamName),l(n,6,0,n.context.$implicit.CharacterName),l(n,9,0,n.context.$implicit.TribeName),l(n,12,0,n.context.$implicit.DiscordName),l(n,15,0,n.context.$implicit.TimeOnline)})}function S(l){return F._24(0,[(l()(),F._25(0,null,null,23,"table",[["class","w3-table w3-striped w3-bordered border-theme"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,21,"tbody",[],null,null,null,null,null)),(l()(),F._25(0,null,null,16,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Steam Name"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Character Name"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Tribe Name"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Discord Tag"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),F._26(null,["Time Online"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,b)),F._27(401408,null,0,L.n,[F.S,F._5,F.v],{ngForOf:[0,"ngForOf"]},null),(l()(),F._26(null,["\n "]))],function(l,n){l(n,22,0,n.parent.parent.parent.parent.context.$implicit.OnlinePlayers)},null)}function w(l){return F._24(0,[(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,4,"div",[["class","w3-card-4 w3-responsive w3-margin-bottom"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,S)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "]))],function(l,n){l(n,4,0,n.component.isMenuActive(n.parent.parent.parent.context.$implicit.Key))},null)}function k(l){return F._24(0,[(l()(),F._25(0,null,null,11,null,null,null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,3,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Online "])),(l()(),F._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,y)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),F._26(null,["\n "])),(l()(),F._28(0,[["server_online_players_list",2]],null,0,null,w)),(l()(),F._26(null,["\n "]))],function(l,n){l(n,8,0,0==n.parent.parent.context.$implicit.OnlinePlayerCount,F._29(n,10))},function(l,n){l(n,5,0,n.parent.parent.context.$implicit.OnlinePlayerCount)})}function C(l){return F._24(0,[(l()(),F._25(0,null,null,155,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,148,"div",[["class","w3-card-4 w3-responsive w3-margin-bottom"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,6,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,3,"h3",[],null,null,null,null,null)),(l()(),F._28(8388608,null,null,1,null,v)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"],ngIfElse:[1,"ngIfElse"]},null),(l()(),F._28(0,[["serverdetails_no_link",2]],null,0,null,g)),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,137,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,134,"table",[["class","w3-table w3-bordered w3-small border-theme serverdetails"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,132,"tbody",[],null,null,null,null,null)),(l()(),F._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Address"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[["style","width: max-content;"]],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Version"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Player Slots"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Map"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["In-Game Day"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Tamed Creatures"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),F._32(1),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Cloud Creatures"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),F._32(1),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Wild Creatures"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),F._32(1),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Structures"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),F._32(1),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Players"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),F._32(1),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,8,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Tribes"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),F._32(1),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Last Update"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,7,"tr",[],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Next Update"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,7,"tr",[["style","border-bottom: none;"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"th",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["Uptime"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),F._26(null,["",""])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n\n "])),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,k)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["\n "]))],function(l,n){var u=n.component;l(n,8,0,u.dataService.hasFeatureAccess("pages","server"),F._29(n,9)),l(n,154,0,u.dataService.hasFeatureAccess("home","online"))},function(l,n){var u=n.component;l(n,23,0,n.parent.context.$implicit.Address),l(n,32,0,n.parent.context.$implicit.Version),l(n,41,0,n.parent.context.$implicit.OnlinePlayerMax),l(n,50,0,n.parent.context.$implicit.MapName),l(n,59,0,n.parent.context.$implicit.InGameTime),l(n,68,0,F._33(n,68,0,l(n,69,0,F._29(n.parent.parent,0),n.parent.context.$implicit.TamedCreatureCount))),l(n,78,0,F._33(n,78,0,l(n,79,0,F._29(n.parent.parent,0),n.parent.context.$implicit.CloudCreatureCount))),l(n,88,0,F._33(n,88,0,l(n,89,0,F._29(n.parent.parent,0),n.parent.context.$implicit.WildCreatureCount))),l(n,98,0,F._33(n,98,0,l(n,99,0,F._29(n.parent.parent,0),n.parent.context.$implicit.StructureCount))),l(n,108,0,F._33(n,108,0,l(n,109,0,F._29(n.parent.parent,0),n.parent.context.$implicit.PlayerCount))),l(n,118,0,F._33(n,118,0,l(n,119,0,F._29(n.parent.parent,0),n.parent.context.$implicit.TribeCount))),l(n,128,0,n.parent.context.$implicit.LastUpdate),l(n,137,0,n.parent.context.$implicit.NextUpdate),l(n,146,0,n.parent.context.$implicit.ServerStarted?u.dataService.toRelativeDate(n.parent.context.$implicit.ServerStarted):"-")})}function I(l){return F._24(0,[(l()(),F._25(0,null,null,4,null,null,null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._28(8388608,null,null,1,null,C)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["\n"]))],function(l,n){var u=n.component;l(n,3,0,u.isMenuActive(n.context.$implicit.Key)&&void 0!=u.dataService.Servers&&u.dataService.hasFeatureAccess("home","serverdetails"))},null)}function x(l){return F._24(0,[(l()(),F._25(0,null,null,59,"section",[["class","w3-container margin-top"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"h3",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),F._26(null,["External Resources"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,14,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,4,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),F._26(null,["Wiki"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,5,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"p",[],null,null,null,null,null)),(l()(),F._25(0,null,null,1,"a",[["href","http://ark.gamepedia.com/"],["style","text-decoration: none;"]],null,null,null,null,null)),(l()(),F._26(null,["Official ARK Survival Evolved Wiki ❯"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,21,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,4,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),F._26(null,["Taming Calculators"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,12,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,9,"ul",[["class","w3-ul"],["style","margin: 7px 0px;"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"li",[["style","padding-left: 0px;"]],null,null,null,null,null)),(l()(),F._25(0,null,null,1,"a",[["href","http://www.survive-ark.com/taming-calculator/"],["style","text-decoration: none;"]],null,null,null,null,null)),(l()(),F._26(null,["Survive ARK: Taming Calculator ❯"])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"li",[["style","padding-left: 0px;"]],null,null,null,null,null)),(l()(),F._25(0,null,null,1,"a",[["href","http://www.dododex.com/"],["style","text-decoration: none;"]],null,null,null,null,null)),(l()(),F._26(null,["Dododex: Taming Calculator ❯"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,14,"div",[["class","w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,4,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),F._26(null,["Creature Library and Breeding Suggestions"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,5,"div",[["class","w3-container theme-l1"]],null,null,null,null,null)),(l()(),F._26(null,["\n "])),(l()(),F._25(0,null,null,2,"p",[],null,null,null,null,null)),(l()(),F._25(0,null,null,1,"a",[["href","https://github.com/cadon/ARKStatsExtractor"],["style","text-decoration: none;"]],null,null,null,null,null)),(l()(),F._26(null,["ARK Smart Breeding ❯"])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n "])),(l()(),F._26(null,["\n"]))],null,null)}function O(l){return F._24(0,[F._34(0,L.p,[F.t]),(l()(),F._28(8388608,null,null,1,null,t)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["\n"])),(l()(),F._28(8388608,null,null,1,null,_)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["\n"])),(l()(),F._28(8388608,null,null,1,null,h)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null),(l()(),F._26(null,["\n"])),(l()(),F._28(8388608,null,null,1,null,I)),F._27(401408,null,0,L.n,[F.S,F._5,F.v],{ngForOf:[0,"ngForOf"]},null),(l()(),F._26(null,["\n"])),(l()(),F._28(8388608,null,null,1,null,x)),F._27(8192,null,0,L.l,[F.S,F._5],{ngIf:[0,"ngIf"]},null)],function(l,n){var u=n.component;l(n,2,0,u.isMenuActive("overview")&&void 0!=u.dataService.UserSteamId&&u.dataService.hasFeatureAccess("home","myprofile")&&u.dataService.hasFeatureAccess("pages","player",u.dataService.UserSteamId)),l(n,5,0,u.isMenuActive("overview")&&void 0!=u.dataService.Servers&&u.serverCount>0&&u.dataService.hasFeatureAccess("home","serverlist")),l(n,8,0,u.isMenuActive("overview")&&void 0!=u.dataService.Servers&&u.dataService.hasFeatureAccess("home","online")),l(n,11,0,null==u.dataService.Servers?null:u.dataService.Servers.Servers),l(n,14,0,u.isMenuActive("overview")&&u.dataService.hasFeatureAccess("home","externalresources"))},null)}function A(l){return F._24(0,[(l()(),F._25(0,null,null,1,"app-server-list",[],null,null,null,O,$)),F._27(122880,null,0,P.a,[N.a,B.a,K.a],null,null)],function(l,n){l(n,1,0)},null)}var T=u("BYL0"),F=u("3j3K"),M=u("5oXY"),L=u("2Je8"),P=u("JLFQ"),N=u("ATz5"),B=u("+Lwu"),K=u("XLrO");u.d(n,"a",function(){return R});var j=[T.a],$=F._23({encapsulation:0,styles:j,data:{}}),R=F._30("app-server-list",P.a,A,{},{},[])},nuuw:function(l,n,u){"use strict";function t(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"div",[["class","w3-panel theme-l2"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h3",[["class","theme-text-l1-light"]],null,null,null,null,null)),(l()(),wl._26(null,["Loading..."])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,[" \n"]))],null,null)}function e(l){return wl._24(0,[(l()(),wl._25(0,null,null,10,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"div",[["class","w3-panel w3-red"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h3",[],null,null,null,null,null)),(l()(),wl._26(null,["Error!"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"p",[],null,null,null,null,null)),(l()(),wl._26(null,["No data could be loaded for the given steam id."])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,[" \n"]))],null,null)}function r(l){return wl._24(0,[(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activate(l.context.$implicit)&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["",""]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.active(n.context.$implicit)))},function(l,n){l(n,0,0,n.component.serverWidth()),l(n,3,0,n.context.$implicit)})}function i(l){return wl._24(0,[(l()(),wl._25(0,null,null,4,"div",[["class","w3-bar theme-l2 w3-card-4"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,r)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,u.keysGetter(null==u.player?null:u.player.Servers))},null)}function a(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["Servers"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,i)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,6,0,null==u.player?null:u.player.Servers)},null)}function o(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Gender"]))],null,null)}function s(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Level"]))],null,null)}function c(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Engram Points"]))],null,null)}function _(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lat"]))],null,null)}function p(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lng"]))],null,null)}function d(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""]))],null,function(l,n){var u=n.component;l(n,1,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].Gender)})}function f(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""]))],null,function(l,n){var u=n.component;l(n,1,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].Level)})}function m(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(1)],null,function(l,n){var u=n.component;l(n,1,0,wl._33(n,1,0,l(n,2,0,wl._29(n.parent.parent,0),null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].EngramPoints)))})}function h(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2)],null,function(l,n){var u=n.component;l(n,1,0,wl._33(n,1,0,l(n,2,0,wl._29(n.parent.parent,0),null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].Latitude,"1.1-1")))})}function v(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2)],null,function(l,n){var u=n.component;l(n,1,0,wl._33(n,1,0,l(n,2,0,wl._29(n.parent.parent,0),null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].Longitude,"1.1-1")))})}function g(l){return wl._24(0,[(l()(),wl._25(0,null,null,83,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,0,"a",[["id","player"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["Player"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,76,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,73,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,34,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,31,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Character Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,o)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Tribe Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Steam Id"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Tribe Id"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,s)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,c)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,_)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,p)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Saved At"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,34,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,31,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,d)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,f)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,m)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,h)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,v)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,18,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,30,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,33,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,36,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,39,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,54,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,66,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,69,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,72,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId)),l(n,75,0,u.dataService.hasFeatureAccess("player","profile-detailed",u.steamId))},function(l,n){var u=n.component;l(n,51,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].CharacterName),l(n,57,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].TribeName),l(n,60,0,(null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].FakeSteamId)||(null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].SteamId)),l(n,63,0,null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].TribeId),l(n,78,0,u.dataService.toDate(null==u.player?null:null==u.player.Servers[u.serverKey]?null:u.player.Servers[u.serverKey].SavedAt))})}function y(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no creatures..."]))],null,null)}function b(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"i",[["class","material-icons"],["style","cursor: pointer;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){e.creaturesFilter="";t=!1!==e.filterAndSort()&&t}return t},null,null)),(l()(),wl._26(null,["close"]))],null,null)}function S(l){return wl._24(0,[(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("stats")&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["Base Stats"]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCreaturesMode("stats")))},function(l,n){l(n,0,0,100/n.component.numCreatureTabs())})}function w(l){return wl._24(0,[(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("ids")&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["IDs"]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCreaturesMode("ids")))},function(l,n){l(n,0,0,100/n.component.numCreatureTabs())})}function k(l){return wl._24(0,[(l()(),wl._25(0,null,null,12,"div",[["class","w3-bar theme-l2 w3-card-4 w3-margin-bottom"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCreaturesMode("status")&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["Overview / Status"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,S)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,w)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,"w3-bar-item w3-button w3-mobile",l(n,4,0,u.activeCreaturesMode("status"))),l(n,8,0,u.dataService.hasFeatureAccess("player","creatures-basestats",u.steamId)),l(n,11,0,u.dataService.hasFeatureAccess("player","creatures-ids",u.steamId))},function(l,n){l(n,2,0,100/n.component.numCreatureTabs())})}function C(l){return wl._24(0,[(l()(),wl._25(0,null,null,22,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Level"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("level")&&t}return t},null,null)),(l()(),wl._26(null,["Level"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Imprint"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("imprint")&&t}return t},null,null)),(l()(),wl._26(null,["Imprint"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Food"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("food")&&t}return t},null,null)),(l()(),wl._26(null,["Food"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Latitude"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("latitude")&&t}return t},null,null)),(l()(),wl._26(null,["Lat"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Longitude"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("longitude")&&t}return t},null,null)),(l()(),wl._26(null,["Lng"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Status"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Owner"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("owner")&&t}return t},null,null)),(l()(),wl._26(null,["Owner"])),(l()(),wl._26(null,["\n "]))],null,null)}function I(l){return wl._24(0,[(l()(),wl._25(0,null,null,23,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Health"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_health")&&t}return t},null,null)),(l()(),wl._26(null,["HP"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Stamina"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_stamina")&&t}return t},null,null)),(l()(),wl._26(null,["ST"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Oxygen"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_oxygen")&&t}return t},null,null)),(l()(),wl._26(null,["OX"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Food"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_food")&&t}return t},null,null)),(l()(),wl._26(null,["FO"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Weight"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_weight")&&t}return t},null,null)),(l()(),wl._26(null,["WE"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Melee"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_melee")&&t}return t},null,null)),(l()(),wl._26(null,["ME"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Speed"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("stat_speed")&&t}return t},null,null)),(l()(),wl._26(null,["SP"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],null,null)}function x(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by ID1"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("id1")&&t}return t},null,null)),(l()(),wl._26(null,["ID1"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by ID2"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("id2")&&t}return t},null,null)),(l()(),wl._26(null,["ID2"])),(l()(),wl._26(null,["\n "]))],null,null)}function O(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"tr",[],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"td",[],[[8,"colSpan",0]],null,null,null,null)),(l()(),wl._26(null,["No matching creatures..."]))],null,function(l,n){l(n,1,0,n.component.activeCreaturesMode("ids")?6:11)})}function A(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),wl._26(null,["",""]))],null,function(l,n){l(n,1,0,n.parent.parent.context.$implicit.Level)})}function T(l){return wl._24(0,[(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 6em; position: relative;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,wl._33(n,3,0,l(n,4,0,wl._29(n.parent.parent.parent.parent.parent,1),n.parent.parent.context.$implicit.FoodStatus,"1.0-0"))),l(n,6,0,100*n.parent.parent.context.$implicit.FoodStatus)})}function F(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"span",[],null,null,null,null,null)),(l()(),wl._26(null,["Next mating ",""]))],null,function(l,n){l(n,1,0,n.component.dataService.toRelativeDate(n.parent.parent.context.$implicit.NextMating))})}function M(l){return wl._24(0,[(l()(),wl._25(0,null,null,23,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,20,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),wl._26(null,["Baby"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,11,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 4em; position: relative; margin: 0em 0.5em;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._26(null,["cuddle ",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],null,function(l,n){var u=n.component;l(n,12,0,wl._33(n,12,0,l(n,13,0,wl._29(n.parent.parent.parent.parent.parent,1),n.parent.parent.context.$implicit.BabyAge,"1.0-0"))),l(n,15,0,100*n.parent.parent.context.$implicit.BabyAge),l(n,21,0,u.dataService.toRelativeDate(n.parent.parent.context.$implicit.BabyNextCuddle))})}function L(l){return wl._24(0,[(l()(),wl._25(0,null,null,35,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._28(8388608,null,null,1,null,A)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,T)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,F)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,M)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,4,0,n.parent.context.$implicit.BaseLevel!=n.parent.context.$implicit.Level),l(n,13,0,null!=n.parent.context.$implicit.FoodStatus),l(n,27,0,u.haveMatingCooldown(n.parent.context.$implicit)),l(n,30,0,null!=n.parent.context.$implicit.BabyAge)},function(l,n){l(n,7,0,wl._33(n,7,0,l(n,8,0,wl._29(n.parent.parent.parent.parent,1),n.parent.context.$implicit.Imprint,"1.0-0"))),l(n,17,0,wl._33(n,17,0,l(n,18,0,wl._29(n.parent.parent.parent.parent,0),n.parent.context.$implicit.Latitude,"1.1-1"))),l(n,21,0,wl._33(n,21,0,l(n,22,0,wl._29(n.parent.parent.parent.parent,0),n.parent.context.$implicit.Longitude,"1.1-1"))),l(n,34,0,n.parent.context.$implicit.OwnerType)})}function P(l){return wl._24(0,[(l()(),wl._25(0,null,null,23,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Health),l(n,6,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Stamina),l(n,9,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Oxygen),l(n,12,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Food),l(n,15,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Weight),l(n,18,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.Melee),l(n,21,0,null==n.parent.context.$implicit.BaseStats?null:n.parent.context.$implicit.BaseStats.MovementSpeed)})}function N(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.parent.context.$implicit.Id1),l(n,6,0,n.parent.context.$implicit.Id2)})}function B(l){return wl._24(0,[(l()(),wl._25(0,null,null,24,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,L)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,P)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,N)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,17,0,u.activeCreaturesMode("status")),l(n,20,0,u.activeCreaturesMode("stats")),l(n,23,0,u.activeCreaturesMode("ids"))},function(l,n){l(n,3,0,n.context.$implicit.Name),l(n,7,0,n.context.$implicit.Species),l(n,11,0,n.context.$implicit.Gender),l(n,14,0,n.context.$implicit.BaseLevel)})}function K(l){return wl._24(0,[(l()(),wl._25(0,null,null,61,null,null,null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,11,"div",[["class","inner-addon right-addon"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,b)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"input",[["class","w3-input w3-border w3-round-xlarge w3-large w3-margin-bottom border-theme theme-l1"],["placeholder","Filter"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,e=l.component;if("input"===n){t=!1!==wl._29(l,8)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==wl._29(l,8).onTouched()&&t}if("compositionstart"===n){t=!1!==wl._29(l,8)._compositionStart()&&t}if("compositionend"===n){t=!1!==wl._29(l,8)._compositionEnd(u.target.value)&&t}if("ngModelChange"===n){e.creaturesFilter=u;t=!1!==e.filterAndSort()&&t}return t},null,null)),wl._27(8192,null,0,Cl.d,[wl.J,wl.K,[2,Cl.e]],null,null),wl._37(512,null,Cl.g,function(l){return[l]},[Cl.d]),wl._27(335872,null,0,Cl.h,[[8,null],[8,null],[8,null],[2,Cl.g]],{model:[0,"model"]},{update:"ngModelChange"}),wl._37(1024,null,Cl.i,null,[Cl.h]),wl._27(8192,null,0,Cl.j,[Cl.i],null,null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,k)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,42,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,39,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,27,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,24,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Name"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("name")&&t}return t},null,null)),(l()(),wl._26(null,["Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Species"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("species")&&t}return t},null,null)),(l()(),wl._26(null,["Species"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Gender"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("gender")&&t}return t},null,null)),(l()(),wl._26(null,["Gender"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[["style","cursor: pointer;"],["title","Sort by Base Level"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.setCreaturesSort("base_level")&&t}return t},null,null)),(l()(),wl._26(null,["Base Level"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,C)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,I)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,x)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,O)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,B)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,5,0,null!=u.creaturesFilter&&""!=u.creaturesFilter),l(n,10,0,u.creaturesFilter),l(n,16,0,u.numCreatureTabs()>1),l(n,41,0,u.activeCreaturesMode("status")),l(n,44,0,u.activeCreaturesMode("stats")),l(n,47,0,u.activeCreaturesMode("ids")),l(n,54,0,!((null==u.filteredCreatures?null:u.filteredCreatures.length)>0)),l(n,57,0,u.filteredCreatures)},function(l,n){l(n,7,0,wl._29(n,12).ngClassUntouched,wl._29(n,12).ngClassTouched,wl._29(n,12).ngClassPristine,wl._29(n,12).ngClassDirty,wl._29(n,12).ngClassValid,wl._29(n,12).ngClassInvalid,wl._29(n,12).ngClassPending)})}function j(l){return wl._24(0,[(l()(),wl._25(0,null,null,21,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,12,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","creatures"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,3,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Creatures "])),(l()(),wl._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"button",[["class","w3-button theme-d1 w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.openMap(u)&&t}return t},null,null)),(l()(),wl._26(null,["Show Map"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,y)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,K)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,17,0,!((null==u.player.Servers[u.serverKey]?null:null==u.player.Servers[u.serverKey].Creatures?null:u.player.Servers[u.serverKey].Creatures.length)>0)),l(n,20,0,(null==u.player.Servers[u.serverKey]?null:null==u.player.Servers[u.serverKey].Creatures?null:u.player.Servers[u.serverKey].Creatures.length)>0)},function(l,n){l(n,9,0,n.component.filteredCreatures.length)})}function $(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"i",[["class","material-icons"],["style","margin: -5px 5px -5px -5px; vertical-align: middle;"]],null,null,null,null,null)),(l()(),wl._26(null,["check"]))],null,null)}function R(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no baby creatures..."]))],null,null)}function D(l){return wl._24(0,[(l()(),wl._25(0,null,null,0,"th",[],null,null,null,null,null))],null,null)}function E(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"input",[["class","w3-check w3-right"],["style","top: 0;"],["type","checkbox"]],[[8,"checked",0]],[[null,"change"]],function(l,n,u){var t=!0,e=l.component;if("change"===n){t=!1!==e.toggleImprintNotificationForCreature(l.parent.context.$implicit)&&t}return t},null,null))],null,function(l,n){l(n,1,0,n.component.getStateForCreature(n.parent.context.$implicit).imprintNotifications)})}function U(l){return wl._24(0,[(l()(),wl._25(0,null,null,42,"tr",[],null,null,null,null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{ngClass:[0,"ngClass"]},null),wl._31(["odd"]),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,11,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 6em; position: relative;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"timer",[],null,null,null,Il.a,Il.b)),wl._27(122880,null,0,xl.a,[],{state:[0,"state"],time:[1,"time"],notification:[2,"notification"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,E)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,1,0,l(n,2,0,n.context.index%2==1)),l(n,38,0,u.getStateForCreature(n.context.$implicit),n.context.$implicit.BabyNextCuddle,u.imprintNotifications),l(n,41,0,u.imprintNotifications)},function(l,n){var u=n.component;l(n,5,0,n.context.$implicit.Name),l(n,8,0,n.context.$implicit.Species),l(n,11,0,n.context.$implicit.Gender),l(n,14,0,n.context.$implicit.BaseLevel),l(n,17,0,wl._33(n,17,0,l(n,18,0,wl._29(n.parent.parent.parent,1),n.context.$implicit.Imprint,"1.0-0"))),l(n,25,0,wl._33(n,25,0,l(n,26,0,wl._29(n.parent.parent.parent,1),n.context.$implicit.BabyAge,"1.0-0"))),l(n,28,0,100*n.context.$implicit.BabyAge),l(n,34,0,u.dataService.toDate(n.context.$implicit.BabyFullyGrown))})}function z(l){return wl._24(0,[(l()(),wl._25(0,null,null,43,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,40,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,31,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,28,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Species"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Gender"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Base Level"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Imprint"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Progress"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Fully Grown At"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Next Imprint"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,D)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,U)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,33,0,u.imprintNotifications),l(n,40,0,u.imprintCreatures)},null)}function J(l){return wl._24(0,[(l()(),wl._25(0,null,null,26,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,16,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","imprint_timers"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,3,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Breeding "])),(l()(),wl._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell w3-cell-middle"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,5,"button",[["class","w3-button w3-right"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.imprintNotifications=!e.imprintNotifications)&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1","theme-l2","theme-hover"]),(l()(),wl._28(8388608,null,null,1,null,$)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,R)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,z)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,13,0,"w3-button w3-right",l(n,14,0,u.imprintNotifications,!u.imprintNotifications,!u.imprintNotifications)),l(n,16,0,u.imprintNotifications),l(n,21,0,!((null==u.imprintCreatures?null:u.imprintCreatures.length)>0)),l(n,24,0,(null==u.imprintCreatures?null:u.imprintCreatures.length)>0)},function(l,n){var u=n.component;l(n,9,0,u.imprintCreatures.length),l(n,17,0,u.imprintNotifications?"Notifications Enabled":"Enable Notifications")})}function G(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no kibbles or eggs..."]))],null,null)}function H(l){return wl._24(0,[(l()(),wl._25(0,null,null,13,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.Name),l(n,6,0,n.context.$implicit.KibbleCount),l(n,9,0,n.context.$implicit.EggCount),l(n,12,0,n.context.$implicit.KibbleCount+n.context.$implicit.EggCount)})}function X(l){return wl._24(0,[(l()(),wl._25(0,null,null,28,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,25,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,16,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,13,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Kibbles"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Eggs"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Total"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,H)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,25,0,u.player.Servers[u.serverKey].KibblesAndEggs)},null)}function W(l){return wl._24(0,[(l()(),wl._25(0,null,null,18,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,9,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","kibblesandeggs"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,4,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Kibbles and Eggs "])),(l()(),wl._25(0,null,null,2,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,G)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,X)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,14,0,!((null==u.player.Servers[u.serverKey].KibblesAndEggs?null:u.player.Servers[u.serverKey].KibblesAndEggs.length)>0)),l(n,17,0,(null==u.player.Servers[u.serverKey].KibblesAndEggs?null:u.player.Servers[u.serverKey].KibblesAndEggs.length)>0)},function(l,n){var u=n.component;l(n,9,0,wl._33(n,9,0,l(n,10,0,wl._29(n.parent,0),u.sumKibbleAndEggs(),0)))})}function V(l){return wl._24(0,[(l()(),wl._25(0,null,null,3,"button",[["class","w3-bar-item w3-button w3-mobile"],["href","#"]],[[4,"width","%"]],[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!==e.activateCluster(l.context.$implicit)&&t}return t},null,null)),wl._27(139264,null,0,kl.m,[wl.v,wl.w,wl.K,wl.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),wl._31(["theme-d1"]),(l()(),wl._26(null,["",""]))],function(l,n){l(n,1,0,"w3-bar-item w3-button w3-mobile",l(n,2,0,n.component.activeCluster(n.context.$implicit)))},function(l,n){l(n,0,0,n.component.clusterWidth()),l(n,3,0,n.context.$implicit)})}function Y(l){return wl._24(0,[(l()(),wl._25(0,null,null,4,"div",[["class","w3-bar theme-l2 w3-card-4"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,V)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,u.keysGetter(null==u.player?null:u.player.Clusters))},null)}function q(l){return wl._24(0,[(l()(),wl._25(0,null,null,7,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["Clusters"])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,Y)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,6,0,null==u.player?null:u.player.Clusters)},null)}function Q(l){return wl._24(0,[(l()(),wl._25(0,null,null,11,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Creatures"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no creatures in the cloud..."])),(l()(),wl._26(null,["\n"]))],null,null)}function Z(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no creatures in the cloud..."]))],null,null)}function ll(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"i",[["class","material-icons"],["style","cursor: pointer;"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){e.creaturesClusterFilter="";t=!1!==e.filterCluster()&&t}return t},null,null)),(l()(),wl._26(null,["close"]))],null,null)}function nl(l){return wl._24(0,[(l()(),wl._25(0,null,null,11,"div",[["class","inner-addon right-addon"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,ll)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,5,"input",[["class","w3-input w3-border w3-round-xlarge w3-large w3-margin-bottom border-theme theme-l1"],["placeholder","Filter"]],[[2,"ng-untouched",null],[2,"ng-touched",null],[2,"ng-pristine",null],[2,"ng-dirty",null],[2,"ng-valid",null],[2,"ng-invalid",null],[2,"ng-pending",null]],[[null,"ngModelChange"],[null,"input"],[null,"blur"],[null,"compositionstart"],[null,"compositionend"]],function(l,n,u){var t=!0,e=l.component;if("input"===n){t=!1!==wl._29(l,6)._handleInput(u.target.value)&&t}if("blur"===n){t=!1!==wl._29(l,6).onTouched()&&t}if("compositionstart"===n){t=!1!==wl._29(l,6)._compositionStart()&&t}if("compositionend"===n){t=!1!==wl._29(l,6)._compositionEnd(u.target.value)&&t}if("ngModelChange"===n){e.creaturesClusterFilter=u;t=!1!==e.filterCluster()&&t}return t},null,null)),wl._27(8192,null,0,Cl.d,[wl.J,wl.K,[2,Cl.e]],null,null),wl._37(512,null,Cl.g,function(l){return[l]},[Cl.d]),wl._27(335872,null,0,Cl.h,[[8,null],[8,null],[8,null],[2,Cl.g]],{model:[0,"model"]},{update:"ngModelChange"}),wl._37(1024,null,Cl.i,null,[Cl.h]),wl._27(8192,null,0,Cl.j,[Cl.i],null,null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,3,0,null!=u.creaturesClusterFilter&&""!=u.creaturesClusterFilter),l(n,8,0,u.creaturesClusterFilter)},function(l,n){l(n,5,0,wl._29(n,10).ngClassUntouched,wl._29(n,10).ngClassTouched,wl._29(n,10).ngClassPristine,wl._29(n,10).ngClassDirty,wl._29(n,10).ngClassValid,wl._29(n,10).ngClassInvalid,wl._29(n,10).ngClassPending)})}function ul(l){return wl._24(0,[(l()(),wl._25(0,null,null,2,"tr",[],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"td",[["colspan","3"]],null,null,null,null,null)),(l()(),wl._26(null,["No matching creatures..."]))],null,null)}function tl(l){return wl._24(0,[(l()(),wl._25(0,null,null,10,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.Name),l(n,6,0,n.context.$implicit.Species),l(n,9,0,n.context.$implicit.Level)})}function el(l){return wl._24(0,[(l()(),wl._25(0,null,null,28,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,25,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,13,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,10,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Name"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Species"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Level"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,ul)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,tl)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,22,0,!((null==u.filteredClusterCreatures?null:u.filteredClusterCreatures.length)>0)),l(n,25,0,u.filteredClusterCreatures)},null)}function rl(l){return wl._24(0,[(l()(),wl._25(0,null,null,19,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,3,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Creatures "])),(l()(),wl._25(0,null,null,1,"span",[["class","w3-tag w3-large theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,Z)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,nl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,el)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,12,0,!((null==u.player.Clusters[u.clusterKey]?null:null==u.player.Clusters[u.clusterKey].Creatures?null:u.player.Clusters[u.clusterKey].Creatures.length)>0)),l(n,15,0,(null==u.player.Clusters[u.clusterKey]?null:null==u.player.Clusters[u.clusterKey].Creatures?null:u.player.Clusters[u.clusterKey].Creatures.length)>0),l(n,18,0,(null==u.player.Clusters[u.clusterKey]?null:null==u.player.Clusters[u.clusterKey].Creatures?null:u.player.Clusters[u.clusterKey].Creatures.length)>0)},function(l,n){l(n,8,0,n.component.filteredClusterCreatures.length)})}function il(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no crops..."]))],null,null)}function al(l){return wl._24(0,[(l()(),wl._25(0,null,null,36,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,11,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 6em; position: relative;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(1),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.PlantedCropName||n.context.$implicit.PlantedCropClassName),l(n,6,0,n.context.$implicit.Size),l(n,13,0,wl._33(n,13,0,l(n,14,0,wl._29(n.parent.parent.parent,1),n.context.$implicit.FertilizerQuantity/n.context.$implicit.FertilizerMax,"1.0-0"))),l(n,16,0,n.context.$implicit.FertilizerQuantity/n.context.$implicit.FertilizerMax*100),l(n,22,0,wl._33(n,22,0,l(n,23,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.FertilizerQuantity))),l(n,26,0,wl._33(n,26,0,l(n,27,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.WaterAmount,"1.0-0"))),l(n,30,0,wl._33(n,30,0,l(n,31,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.Latitude,"1.1-1"))),l(n,34,0,wl._33(n,34,0,l(n,35,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.Longitude,"1.1-1")))})}function ol(l){return wl._24(0,[(l()(),wl._25(0,null,null,37,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,34,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,25,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,22,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Crop"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Size"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Fertilizer %"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Fertilizer Units"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Water"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lat"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lng"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,al)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,34,0,u.player.Servers[u.serverKey].CropPlots)},null)}function sl(l){return wl._24(0,[(l()(),wl._25(0,null,null,15,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,3,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","cropplots"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Crops"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,il)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,ol)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,11,0,!((null==u.player.Servers[u.serverKey].CropPlots?null:u.player.Servers[u.serverKey].CropPlots.length)>0)),l(n,14,0,(null==u.player.Servers[u.serverKey].CropPlots?null:u.player.Servers[u.serverKey].CropPlots.length)>0)},null)}function cl(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no electrical generators..."]))],null,null)}function _l(l){return wl._24(0,[(l()(),wl._25(0,null,null,8,"div",[["class","app-green-light w3-round"],["style","width: 6em; position: relative;"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"div",[["style","position: absolute; left: 50%; transform: translate(-50%, 0%); color: white;"]],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"div",[["class","theme-c1 w3-round"]],[[4,"width","%"]],null,null,null,null)),(l()(),wl._26(null,[" "])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,wl._33(n,3,0,l(n,4,0,wl._29(n.parent.parent.parent.parent,1),n.parent.context.$implicit.GasolineQuantity/800,"1.0-0"))),l(n,6,0,n.parent.context.$implicit.GasolineQuantity/800*100)})}function pl(l){return wl._24(0,[(l()(),wl._25(0,null,null,22,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,_l)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(1),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,2,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),wl._32(2),(l()(),wl._26(null,["\n "]))],function(l,n){l(n,5,0,1==n.context.$implicit.Activated)},function(l,n){l(n,9,0,wl._33(n,9,0,l(n,10,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.GasolineQuantity))),l(n,13,0,1==n.context.$implicit.Activated?"Yes":"No"),l(n,16,0,wl._33(n,16,0,l(n,17,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.Latitude,"1.1-1"))),l(n,20,0,wl._33(n,20,0,l(n,21,0,wl._29(n.parent.parent.parent,0),n.context.$implicit.Longitude,"1.1-1")))})}function dl(l){return wl._24(0,[(l()(),wl._25(0,null,null,31,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,28,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,19,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,16,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Gasoline %"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Gasoline Quantity"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Activated"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lat"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Lng"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,pl)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,28,0,u.player.Servers[u.serverKey].ElectricalGenerators)},null)}function fl(l){return wl._24(0,[(l()(),wl._25(0,null,null,15,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,3,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","electricalgenerators"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Electrical Generators"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,cl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,dl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,11,0,!((null==u.player.Servers[u.serverKey].ElectricalGenerators?null:u.player.Servers[u.serverKey].ElectricalGenerators.length)>0)),l(n,14,0,(null==u.player.Servers[u.serverKey].ElectricalGenerators?null:u.player.Servers[u.serverKey].ElectricalGenerators.length)>0)},null)}function ml(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"div",[],null,null,null,null,null)),(l()(),wl._26(null,["There are no tribe logs..."]))],null,null)}function hl(l){return wl._24(0,[(l()(),wl._25(0,null,null,10,"tr",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"td",[],null,null,null,null,null)),(l()(),wl._26(null,["",""])),(l()(),wl._26(null,["\n "]))],null,function(l,n){l(n,3,0,n.context.$implicit.Day),l(n,6,0,n.context.$implicit.Time),l(n,9,0,n.context.$implicit.Message)})}function vl(l){return wl._24(0,[(l()(),wl._25(0,null,null,25,"div",[["class","w3-card-4 w3-responsive"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,22,"table",[["class","w3-table-all border-theme"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,13,"thead",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,10,"tr",[["class","theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Day"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Time"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"th",[],null,null,null,null,null)),(l()(),wl._26(null,["Message"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,4,"tbody",[],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,hl)),wl._27(401408,null,0,kl.n,[wl.S,wl._5,wl.v],{ngForOf:[0,"ngForOf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,22,0,u.player.Servers[u.serverKey].TribeLog)},null)}function gl(l){return wl._24(0,[(l()(),wl._25(0,null,null,15,"section",[["class","w3-container"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,6,"div",[["class","w3-cell-row"]],null,null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,3,"div",[["class","w3-cell"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,0,"a",[["id","tribelog"]],null,null,null,null,null)),(l()(),wl._25(0,null,null,1,"h2",[["class","theme-text-d1 w3-left"]],null,null,null,null,null)),(l()(),wl._26(null,["Tribe Log"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,ml)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._28(8388608,null,null,1,null,vl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n "]))],function(l,n){var u=n.component;l(n,11,0,!((null==u.player.Servers[u.serverKey].TribeLog?null:u.player.Servers[u.serverKey].TribeLog.length)>0)),l(n,14,0,(null==u.player.Servers[u.serverKey].TribeLog?null:u.player.Servers[u.serverKey].TribeLog.length)>0)},null)}function yl(l){return wl._24(0,[wl._34(0,kl.p,[wl.t]),wl._34(0,kl.r,[wl.t]),(l()(),wl._28(8388608,null,null,1,null,t)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,e)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,a)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,g)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,j)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,J)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,W)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,q)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,Q)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,rl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,sl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,fl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._28(8388608,null,null,1,null,gl)),wl._27(8192,null,0,kl.l,[wl.S,wl._5],{ngIf:[0,"ngIf"]},null),(l()(),wl._26(null,["\n"])),(l()(),wl._25(0,null,null,17,"div",[["class","w3-modal"],["id","modal_map"]],[[4,"display",null]],null,null,null,null)),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,14,"div",[["class","w3-modal-content w3-card-4 w3-animate-zoom"],["style","font-size: 0;"]],null,[[null,"clickOutside"],["document","click"]],function(l,n,u){var t=!0,e=l.component;if("document:click"===n){t=!1!==wl._29(l,44).onClick(u,u.target)&&t}if("clickOutside"===n){t=!1!==e.closeMap(u)&&t}return t},null,null)),wl._27(8192,null,0,Al.a,[wl.K],null,{clickOutside:"clickOutside"}),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,7,"header",[["class","w3-container theme-d1"]],null,null,null,null,null)),(l()(),wl._26(null,[" \n "])),(l()(),wl._25(0,null,null,1,"span",[["class","w3-button theme-d1 w3-xlarge w3-display-topright"]],null,[[null,"click"]],function(l,n,u){var t=!0,e=l.component;if("click"===n){t=!1!=(e.showMap=!1)&&t}return t},null,null)),(l()(),wl._26(null,["×"])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"h2",[],null,null,null,null,null)),(l()(),wl._26(null,["Map"])),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n "])),(l()(),wl._25(0,null,null,1,"arkmap",[],null,null,null,Tl.a,Tl.b)),wl._27(286720,null,0,Fl.a,[],{mapName:[0,"mapName"],points:[1,"points"]},null),(l()(),wl._26(null,["\n "])),(l()(),wl._26(null,["\n"]))],function(l,n){var u=n.component;l(n,3,0,0==u.loaded),l(n,6,0,1==u.loaded&&null==u.player),l(n,9,0,!u.isMenuActive("creatures_cloud")&&void 0!=u.player),l(n,12,0,u.isMenuActive("profile")&&void 0!=u.player&&u.dataService.hasFeatureAccess("player","profile",u.steamId)),l(n,15,0,u.isMenuActive("creatures")&&void 0!=u.player&&u.dataService.hasFeatureAccess("player","creatures",u.steamId)),l(n,18,0,u.isMenuActive("breeding")&&void 0!=u.player&&u.dataService.hasFeatureAccess("player","breeding",u.steamId)),l(n,21,0,u.isMenuActive("kibbles_and_eggs")&&(null==u.player?null:u.player.Servers[u.serverKey])&&u.dataService.hasFeatureAccess("player","kibbles-eggs",u.steamId)),l(n,24,0,u.isMenuActive("creatures_cloud")&&u.haveCluster()),l(n,27,0,u.isMenuActive("creatures_cloud")&&!u.haveCluster()&&u.dataService.hasFeatureAccess("player","creatures-cloud",u.steamId)),l(n,30,0,u.isMenuActive("creatures_cloud")&&u.haveCluster()&&u.dataService.hasFeatureAccess("player","creatures-cloud",u.steamId)),l(n,33,0,u.isMenuActive("crop_plots")&&(null==u.player?null:u.player.Servers[u.serverKey])&&u.dataService.hasFeatureAccess("player","crops",u.steamId)),l(n,36,0,u.isMenuActive("electrical_generators")&&(null==u.player?null:u.player.Servers[u.serverKey])&&u.dataService.hasFeatureAccess("player","generators",u.steamId)),l(n,39,0,u.isMenuActive("tribelog")&&(null==u.player?null:u.player.Servers[u.serverKey])&&u.dataService.hasFeatureAccess("player","tribelog",u.steamId)),l(n,56,0,null==u.player?null:u.player.MapNames[u.serverKey],u.points)},function(l,n){l(n,41,0,n.component.showMap?"block":"none")})}function bl(l){return wl._24(0,[(l()(),wl._25(0,null,null,1,"app-player",[],null,null,null,yl,jl)),wl._27(122880,null,0,Ol.a,[Ml.v,Ml.g,Ll.a,Pl.a,Nl.a,Bl.a,wl.O],null,null)],function(l,n){l(n,1,0)},null)}var Sl=u("SWoV"),wl=u("3j3K"),kl=u("2Je8"),Cl=u("NVOs"),Il=u("RdYi"),xl=u("CzL3"),Ol=u("KZxv"),Al=u("8zLQ"),Tl=u("I9JA"),Fl=u("5305"),Ml=u("5oXY"),Ll=u("lHWG"),Pl=u("ATz5"),Nl=u("+Lwu"),Bl=u("XLrO");u.d(n,"a",function(){return $l});var Kl=[Sl.a],jl=wl._23({encapsulation:0,styles:Kl,data:{}}),$l=wl._30("app-player",Ol.a,bl,{},{},[])},ofcV:function(l,n,u){"use strict";function t(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("profile")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Profile"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("profile")))},null)}function e(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("creatures")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Creatures"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("creatures")))},null)}function r(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("creatures_cloud")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Creatures (Cloud)"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("creatures_cloud")))},null)}function i(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("breeding")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Breeding"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("breeding")))},null)}function a(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("crop_plots")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Crops"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("crop_plots")))},null)}function o(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("electrical_generators")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Electrical Generators"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("electrical_generators")))},null)}function s(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("kibbles_and_eggs")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Kibbles and Eggs"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("kibbles_and_eggs")))},null)}function c(l){return f._24(0,[(l()(),f._25(0,null,null,3,"div",[["class","w3-button w3-cell w3-mobile"]],null,[[null,"click"]],function(l,n,u){var t=!0;if("click"===n){t=!1!==f._29(l.parent,2).activate("tribelog")&&t}return t},null,null)),f._27(139264,null,0,m.m,[f.v,f.w,f.K,f.J],{klass:[0,"klass"],ngClass:[1,"ngClass"]},null),f._31(["theme-d1"]),(l()(),f._26(null,["Tribe Log"]))],function(l,n){l(n,1,0,"w3-button w3-cell w3-mobile",l(n,2,0,f._29(n.parent,2).active("tribelog")))},null)}function _(l){return f._24(0,[f._35(201326592,1,{menu:0}),(l()(),f._25(0,null,null,32,"app-menu",[],null,null,null,h.a,h.b)),f._27(122880,[[1,4],["menu",4]],0,v.a,[g.a],null,null),(l()(),f._26(0,["\n "])),(l()(),f._25(0,null,0,1,"h2",[["class","theme-text-d1"]],null,null,null,null,null)),(l()(),f._26(null,["Player"])),(l()(),f._26(0,["\n "])),(l()(),f._25(0,null,0,25,"div",[["class","w3-cell-row theme-l2"]],null,null,null,null,null)),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,t)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,e)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,r)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,i)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,a)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,o)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,s)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._28(8388608,null,null,1,null,c)),f._27(8192,null,0,m.l,[f.S,f._5],{ngIf:[0,"ngIf"]},null),(l()(),f._26(null,["\n "])),(l()(),f._26(0,["\n"]))],function(l,n){var u=n.component;l(n,2,0),l(n,10,0,u.dataService.hasFeatureAccess("player","profile",u.steamId)),l(n,13,0,u.dataService.hasFeatureAccess("player","creatures",u.steamId)),l(n,16,0,u.dataService.hasFeatureAccess("player","creatures-cloud",u.steamId)),l(n,19,0,u.dataService.hasFeatureAccess("player","breeding",u.steamId)),l(n,22,0,u.dataService.hasFeatureAccess("player","crops",u.steamId)),l(n,25,0,u.dataService.hasFeatureAccess("player","generators",u.steamId)),l(n,28,0,u.dataService.hasFeatureAccess("player","kibbles-eggs",u.steamId)),l(n,31,0,u.dataService.hasFeatureAccess("player","tribelog",u.steamId))},null)}function p(l){return f._24(0,[(l()(),f._25(0,null,null,1,"app-player-menu",[],[[8,"className",0]],null,null,_,w)),f._27(57344,null,0,y.a,[b.v,g.a],null,null)],function(l,n){l(n,1,0)},function(l,n){l(n,0,0,f._29(n,1).menu.className)})}var d=u("l3s9"),f=u("3j3K"),m=u("2Je8"),h=u("coiB"),v=u("8kYA"),g=u("ATz5"),y=u("RiXa"),b=u("5oXY");u.d(n,"a",function(){return k});var S=[d.a],w=f._23({encapsulation:0,styles:S,data:{}}),k=f._30("app-player-menu",y.a,p,{},{},[])},qn86:function(l,n,u){"use strict";var t=u("3j3K"),e=u("5oXY"),r=u("3MNG"),i=u("PJh5"),a=(u.n(i),u("ATz5")),o=u("+Lwu"),s=u("lHWG"),c=u("+rAa");u.d(n,"a",function(){return _});var _=function(){function l(l,n,t,e,r,i,a){this.route=l,this.router=n,this.httpService=t,this.dataService=e,this.messageService=r,this.notificationsService=i,this.ref=a,this.menuOption=void 0,this.loaded=!1,this.creaturesLoaded=!1,this.keysGetter=Object.keys,this.showMap=!1,this.creaturesMode="status",this.creaturesSortField="base_level",this.creaturesAltSortFields="base_level,gender",this.creaturesSortFunctions={gender:function(l,n,t){return u.i(c.a)(l.Gender,n.Gender,t)},base_level:function(l,n,t){return u.i(c.b)(l.BaseLevel,n.BaseLevel,!t)},tameable:function(l,n,t){return u.i(c.b)(l.IsTameable,n.IsTameable,!t)},latitude:function(l,n,t){return u.i(c.c)(l.Latitude,n.Latitude,t,1)},longitude:function(l,n,t){return u.i(c.c)(l.Longitude,n.Longitude,t,1)},x:function(l,n,t){return u.i(c.c)(l.X,n.X,t,0)},y:function(l,n,t){return u.i(c.c)(l.Y,n.Y,t,0)},z:function(l,n,t){return u.i(c.c)(l.Z,n.Z,t,0)},stat_health:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Health:null,void 0!=n.BaseStats?n.BaseStats.Health:null,!t)},stat_stamina:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Stamina:null,void 0!=n.BaseStats?n.BaseStats.Stamina:null,!t)},stat_oxygen:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Oxygen:null,void 0!=n.BaseStats?n.BaseStats.Oxygen:null,!t)},stat_food:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Food:null,void 0!=n.BaseStats?n.BaseStats.Food:null,!t)},stat_weight:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Weight:null,void 0!=n.BaseStats?n.BaseStats.Weight:null,!t)},stat_melee:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.Melee:null,void 0!=n.BaseStats?n.BaseStats.Melee:null,!t)},stat_speed:function(l,n,t){return u.i(c.b)(void 0!=l.BaseStats?l.BaseStats.MovementSpeed:null,void 0!=n.BaseStats?n.BaseStats.MovementSpeed:null,!t)},id1:function(l,n,t){return u.i(c.b)(l.Id1,n.Id1,t)},id2:function(l,n,t){return u.i(c.b)(l.Id1,n.Id1,t)}},this.playerSortFunctions={character_name:function(l,n,t){return u.i(c.a)(l.CharacterName,n.CharacterName,t)},tribe_name:function(l,n,t){return u.i(c.a)(l.TribeName,n.TribeName,t)},last_active:function(l,n,t){return u.i(c.b)(l.LastActiveTime,n.LastActiveTime,!t)}},this.tribeSortFunctions={tribe_name:function(l,n,t){return u.i(c.a)(l.Name,n.Name,t)},last_active:function(l,n,t){return u.i(c.b)(l.LastActiveTime,n.LastActiveTime,!t)}},this.wildStatisticsSortFunctions={species:function(l,n,t){return u.i(c.a)(l.Name,n.Name,t)},class_name:function(l,n,t){return u.i(c.a)(l.ClassName,n.ClassName,t)},count:function(l,n,t){return u.i(c.b)(l.Count,n.Count,!t)},fraction:function(l,n,t){return u.i(c.c)(l.Fraction,n.Fraction,!t,4)}}}return l.prototype.getServer=function(){var l=this;this.httpService.getServer(this.serverKey).then(function(n){l.server=n,l.filter(),l.loaded=!0}).catch(function(n){l.server=null,l.filteredPlayers=null,l.filteredTribes=null,l.loaded=!0})},l.prototype.getWildCreatures=function(){var l=this;this.httpService.getWildCreatures(this.serverKey).then(function(n){l.wild=n,l.species=Object.keys(l.wild.Species).sort(function(n,t){return u.i(c.a)(l.wild.Species[n].Name||n,l.wild.Species[t].Name||t,!0)}),l.selectedSpecies&&void 0!=l.species.find(function(n){return n==l.selectedSpecies})||(l.selectedSpecies=l.species.length>0?l.species[0]:null),l.filterAndSortWild(),l.creaturesLoaded=!0,l.ref.detectChanges()}).catch(function(n){l.wild=null,l.species=null,l.filteredCreatures=null,l.creaturesLoaded=!0})},l.prototype.ngOnInit=function(){var l=this;this.accessControl_pages_player=this.dataService.hasFeatureAccessObservable("pages","player"),this.serverKey=this.route.snapshot.params.id,this.menuOptionSubscription=this.dataService.MenuOption.subscribe(function(n){l.menuOption=n,0!=l.creaturesLoaded||"wildcreatures"!=l.menuOption&&"wildcreatures-statistics"!=l.menuOption||l.getWildCreatures()}),this.serverUpdatedSubscription=this.messageService.serverUpdated$.subscribe(function(n){l.serverKey==n&&(l.updateServer(),l.showServerUpdateNotification(n))}),this.getServer()},l.prototype.ngOnDestroy=function(){this.menuOptionSubscription.unsubscribe(),this.serverUpdatedSubscription.unsubscribe()},l.prototype.filter=function(){this.filteredPlayers=this.server.Players.filter(function(l){return i(new Date(l.LastActiveTime)).isSameOrAfter(i().subtract(90,"day"))}),this.filteredTribes=this.server.Tribes.filter(function(l){return i(new Date(l.LastActiveTime)).isSameOrAfter(i().subtract(90,"day"))})},l.prototype.sortWild=function(){var l=this,n="-"!=this.creaturesSortField[0],u=this.creaturesSortFunctions[this.creaturesSortField.replace(/^\-/,"")],t=this.creaturesAltSortFields.split(",").map(function(n){var u={};return u.asc="-"!=n[0],u.sortFunc=l.creaturesSortFunctions[n.replace(/^\-/,"")],u});void 0!=this.filteredCreatures&&this.filteredCreatures.sort(function(l,e){var r=u(l,e,n);if(0==r)for(var i=0,a=t;i/gi, window.location.protocol).replace(/\/gi, window.location.hostname); + return environment.apiBaseUrl + .replace(/\/gi, window.location.protocol) + .replace(/\/gi, window.location.hostname) + .replace(/\/gi, config != undefined ? config.webapi.port : ""); } reset() { diff --git a/ArkBot/WebApp/src/app/arkmap.component.ts b/ArkBot/WebApp/src/app/arkmap.component.ts index 9201fdb..8db4857 100644 --- a/ArkBot/WebApp/src/app/arkmap.component.ts +++ b/ArkBot/WebApp/src/app/arkmap.component.ts @@ -3,6 +3,8 @@ import { Component, Input, ViewChild, OnChanges, SimpleChanges, ElementRef, Host import { environment } from '../environments/environment'; import * as d3 from "d3"; +declare var config: any; + @Component({ selector: 'arkmap', template: `` @@ -82,6 +84,9 @@ export class ArkMapComponent implements OnChanges { } getApiBaseUrl(): string { - return environment.apiBaseUrl.replace(/\/gi, window.location.protocol).replace(/\/gi, window.location.hostname); + return environment.apiBaseUrl + .replace(/\/gi, window.location.protocol) + .replace(/\/gi, window.location.hostname) + .replace(/\/gi, config != undefined ? config.webapi.port : ""); } } \ No newline at end of file diff --git a/ArkBot/WebApp/src/app/http.service.ts b/ArkBot/WebApp/src/app/http.service.ts index 0af3b51..80eda63 100644 --- a/ArkBot/WebApp/src/app/http.service.ts +++ b/ArkBot/WebApp/src/app/http.service.ts @@ -7,6 +7,8 @@ import { environment } from '../environments/environment'; import { Servers } from './servers'; import { Player } from './player'; +declare var config: any; + @Injectable() export class HttpService { @@ -104,7 +106,10 @@ export class HttpService { } getApiBaseUrl(): string { - return environment.apiBaseUrl.replace(/\/gi, window.location.protocol).replace(/\/gi, window.location.hostname); + return environment.apiBaseUrl + .replace(/\/gi, window.location.protocol) + .replace(/\/gi, window.location.hostname) + .replace(/\/gi, config != undefined ? config.webapi.port : ""); } protected handleError(error: any): Promise { diff --git a/ArkBot/WebApp/src/app/message.service.ts b/ArkBot/WebApp/src/app/message.service.ts index 06acd20..bb63da5 100644 --- a/ArkBot/WebApp/src/app/message.service.ts +++ b/ArkBot/WebApp/src/app/message.service.ts @@ -4,6 +4,7 @@ import { environment } from '../environments/environment'; //import 'ms-signalr-client'; //problem: does not appear to work with typescript //import {SignalR} from 'signalr'; //problem: 'signalr' is not a module declare var $: any; +declare var config: any; @Injectable() export class MessageService { @@ -32,6 +33,9 @@ export class MessageService { } getSignalRBaseUrl(): string { - return environment.signalrBaseUrl.replace(/\/gi, window.location.protocol).replace(/\/gi, window.location.hostname); + return environment.signalrBaseUrl + .replace(/\/gi, window.location.protocol) + .replace(/\/gi, window.location.hostname) + .replace(/\/gi, config != undefined ? config.webapi.port : ""); } } \ No newline at end of file diff --git a/ArkBot/WebApp/src/app/server-list/server-list.component.html b/ArkBot/WebApp/src/app/server-list/server-list.component.html index d6ee569..df7f1f0 100644 --- a/ArkBot/WebApp/src/app/server-list/server-list.component.html +++ b/ArkBot/WebApp/src/app/server-list/server-list.component.html @@ -16,7 +16,7 @@

Hello, {{dataService.Servers.User.Name}}

Servers

-

{{server.MapName}} - {{server.Key}}{{server.MapName}} - {{server.Key}}

+

{{server.MapName}} - {{server.Key}}{{server.MapName}} - {{server.Key}}

diff --git a/ArkBot/WebApp/src/environments/environment.prod.ts b/ArkBot/WebApp/src/environments/environment.prod.ts index 3c68ef7..c367599 100644 --- a/ArkBot/WebApp/src/environments/environment.prod.ts +++ b/ArkBot/WebApp/src/environments/environment.prod.ts @@ -2,6 +2,6 @@ export const environment = { production: true, demo: false, demoDate: null, - apiBaseUrl: "//:60001/api", - signalrBaseUrl: "//:60001/signalr" + apiBaseUrl: "//:/api", + signalrBaseUrl: "//:/signalr" }; diff --git a/ArkBot/WebApp/src/index.html b/ArkBot/WebApp/src/index.html index 6262b3b..c7c8bc3 100644 --- a/ArkBot/WebApp/src/index.html +++ b/ArkBot/WebApp/src/index.html @@ -9,6 +9,7 @@ + diff --git a/ArkBot/aliases.json b/ArkBot/aliases.json index bbfbcc0..c3656d2 100644 --- a/ArkBot/aliases.json +++ b/ArkBot/aliases.json @@ -1087,6 +1087,16 @@ "Xenomorph_Character_BP_Female_C", "Xenomorph Female" ], + [ + "Reaper King", + "Xenomorph_Character_BP_Male_Tamed_C", + "Xenomorph Male" + ], + [ + "Reaper King (Wild)", + "Xenomorph_Character_BP_Male_C", + "Xenomorph Male (Wild)" + ], [ "Surface Reaper King", "Xenomorph_Character_BP_Male_Surface_C", diff --git a/ArkBot/defaultconfig.json b/ArkBot/defaultconfig.json index b9b214e..c9b7c74 100644 --- a/ArkBot/defaultconfig.json +++ b/ArkBot/defaultconfig.json @@ -2,12 +2,12 @@ "botName": "ARK Bot", "botUrl": "", "appUrl": "", - "tempFileOutputDirPath": "C:\\ArkBot\\temp", - "googleApiKey": "", - "steamApiKey": "", + "tempFileOutputDirPath": "", + "googleApiKey": "", + "steamApiKey": "", "discord": { "discordBotEnabled": true, - "botToken": "", + "botToken": "", "enabledChannels": [ "bot-commands" ], "infoTopicChannel": "bot-commands", "announcementChannel": "bot-notifications", @@ -33,11 +33,15 @@ } }, "steamOpenIdRelyingServiceListenPrefix": "http://+:60002/openid/", - "steamOpenIdRedirectUri": "http://:60002/openid/" - }, - "userRoles": { - "admin": [] + "steamOpenIdRedirectUri": "" }, + "userRoles": [ + { + "role": "admin", + "steamIds": [ + ] + } + ], "accessControl": { "pages": { "home": [ "guest" ], @@ -82,7 +86,7 @@ }, "backups": { "backupsEnabled": false, - "backupsDirectoryPath": "C:\\ARK Servers\\Backups" + "backupsDirectoryPath": "" }, "webApiListenPrefix": "http://+:60001/", "webAppListenPrefix": "http://+:80/", @@ -94,10 +98,9 @@ "enabled": false, "challengeListenPrefix": "http://+:80/", "name": "ark-bot-ssl", - "password": "secret123", - "email": "youremail@yourdomain.com", + "password": "", + "email": "", "domains": [ - "app.yourdomain.com" ], "ports": [ 443, 60001 ], "useCompatibilityNonSNIBindings": true @@ -113,41 +116,47 @@ "servers": [ { "key": "server1", - "cluster": "cluster1", - "saveFilePath": "C:\\ARK Servers\\server1\\ShooterGame\\Saved\\SavedArks\\TheIsland.ark", - "displayAddress": "myarkserver.domain.com:27015", + "clusterKey": "cluster1", + "saveFilePath": "", + "displayAddress": "", "ip": "127.0.0.1", "queryPort": 27015, "rconPort": 27020, - "rconPassword": "password", - "serverExecutablePath": "C:\\ARK Servers\\server1\\ShooterGame\\Binaries\\Win64\\ShooterGameServer.exe", - "serverExecutableArguments": "TheIsland?listen?Port=7777?QueryPort=27015?RCONPort=27020?RCONEnabled=True?SessionName=Server1?ServerPassword=?ServerAdminPassword=password?SpectatorPassword=password?MaxPlayers=5 -culture=en -nosteamclient -clusterid=cluster1 -ClusterDirOverride=\"C:\\ARK Servers\\cluster1\" -serverkey=server1", - "steamCmdExecutablePath": "C:\\SteamCmd\\steamcmd.exe", - "serverInstallDirPath": "C:\\ARK Servers\\server1", - "usePowershellOutputRedirect": false, - "disableChatNotificationOnGlobalCountdown": false + "rconPassword": "", + "serverManagement": { + "enabled": true, + "serverExecutablePath": "", + "serverExecutableArguments": "", + "steamCmdExecutablePath": "", + "serverInstallDirPath": "", + "usePowershellOutputRedirect": false + }, + "disableChatNotifications": false }, { "key": "server2", - "cluster": "cluster1", - "saveFilePath": "C:\\ARK Servers\\server2\\ShooterGame\\Saved\\SavedArks\\TheIsland.ark", - "displayAddress": "myarkserver.domain.com:27016", + "clusterKey": "cluster1", + "saveFilePath": "", + "displayAddress": "", "ip": "127.0.0.1", "queryPort": 27016, "rconPort": 27021, - "rconPassword": "password", - "serverExecutablePath": "C:\\ARK Servers\\server2\\ShooterGame\\Binaries\\Win64\\ShooterGameServer.exe", - "serverExecutableArguments": "TheIsland?listen?Port=7779?QueryPort=27016?RCONPort=27021?RCONEnabled=True?SessionName=Server2?ServerPassword=?ServerAdminPassword=password?SpectatorPassword=password?MaxPlayers=5 -culture=en -nosteamclient -clusterid=cluster1 -ClusterDirOverride=\"C:\\ARK Servers\\cluster1\" -serverkey=server2", - "steamCmdExecutablePath": "C:\\SteamCmd\\steamcmd.exe", - "serverInstallDirPath": "C:\\ARK Servers\\server2", - "usePowershellOutputRedirect": false, - "disableChatNotificationOnGlobalCountdown": false + "rconPassword": "", + "serverManagement": { + "enabled": true, + "serverExecutablePath": "", + "serverExecutableArguments": "", + "steamCmdExecutablePath": "", + "serverInstallDirPath": "", + "usePowershellOutputRedirect": false + }, + "disableChatNotifications": false } ], "clusters": [ { "key": "cluster1", - "savePath": "C:\\ARK Servers\\cluster1" + "savePath": "" } ] } \ No newline at end of file diff --git a/ArkBot/packages.config b/ArkBot/packages.config index 2314334..31f4443 100644 --- a/ArkBot/packages.config +++ b/ArkBot/packages.config @@ -10,6 +10,10 @@ + + + + @@ -32,6 +36,7 @@ + @@ -61,6 +66,7 @@ + From 88e9a01b5def73f6cac117804d4ba3a37e755a40 Mon Sep 17 00:00:00 2001 From: Tobias Sebring Date: Thu, 31 May 2018 09:38:11 +0200 Subject: [PATCH 04/15] Update README.md Update README.md Added a note on project status Replaced resource --- ArkBot/WebApp/src/assets/Alarm01.mp3 | Bin 92177 -> 13799 bytes README.md | 16 +++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/ArkBot/WebApp/src/assets/Alarm01.mp3 b/ArkBot/WebApp/src/assets/Alarm01.mp3 index f4ab5f6f18f04f3c46503ddd3a240a521ab4be18..d96764b1373ed60b3af2e4ef7cfa92ae7c727af2 100644 GIT binary patch literal 13799 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%0D*+QH6fKsQUwX9((}4pn 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 literal 92177 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 M|E1;bf2rmF03_%nWdHyG diff --git a/README.md b/README.md index 7cd237c..213df60 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ +# Project status + +#### Development +This project is not currently being actively developed. It is still minimally maintained by me as the primary developer of the project. There are currently no other developers contributing code to the project. + +#### Support +Users are encouraged to support each other with issues and requests for help. Personal support request directed my way are no longer answered due to lack of time. + +Read the [wiki](https://github.com/tsebring/ArkBot/wiki) for help getting started. + +#### Suggestions/improvments/bugs +If you think something is wrong with the project - help improve it. If you find a bug - help fix it. Don't know how to program? Start learning. This is the way of open source! + +--- + ![Web-app Interface](https://user-images.githubusercontent.com/408350/31540442-f0cb204c-b00b-11e7-8d40-f15b445cdcd2.png) ![Discord Bot Commands](https://user-images.githubusercontent.com/408350/31518648-405ee5f6-afa0-11e7-9c50-3dfd60ecdd7a.png) @@ -28,7 +43,6 @@ Open as zip-archive or change extension to .zip, binaries are located under tool https://www.myget.org/F/tsebring/api/v2/package/ArkDiscordBot ## Installation -**For questions/problems: open a GitHub issue or contact me on Discord (Tobias#5051).** * Download the latest pre-built binaries (see above). * Copy defaultconfig.json and name it config.json. From d28f0ee582639eb2c934e7e01f0b8e70eaed3e3b Mon Sep 17 00:00:00 2001 From: Tobias Sebring Date: Thu, 31 May 2018 09:48:44 +0200 Subject: [PATCH 05/15] Update for patch 278 (#46) Added Aberrant Gigantopithecus and Aberrant Dire Bear. Fix for tamed Reaper King --- ArkBot/aliases.json | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/ArkBot/aliases.json b/ArkBot/aliases.json index c3656d2..ac5200d 100644 --- a/ArkBot/aliases.json +++ b/ArkBot/aliases.json @@ -1111,12 +1111,26 @@ "Xenomorph_Character_BP_Male_Chupa_C" ], [ - "Nameless Queen", + "Reaper", "Xenomorph_Character_BP_C" ], + [ + "Reaper King", + "Xenomorph_Character_BP_Male_Tamed_C" + ], [ "Rockwell", "Rockwell_Character_BP_C" + ], + [ + "Aberrant Gigantopithecus", + "Bigfoot_Character_BP_Aberrant_C" + ], + [ + "Aberrant Direbear", + "Direbear_Character_BP_Aberrant_C", + "Aberrant Dire Bear", + "Aberrant Bear" ] ] } From 562c354761d11f2fec74f768181f7c519b9552da Mon Sep 17 00:00:00 2001 From: Me_Goes_RAWR Date: Fri, 1 Jun 2018 04:26:01 -0400 Subject: [PATCH 06/15] Update BarebonesSteamOpenId.cs (#56) --- ArkBot/OpenID/BarebonesSteamOpenId.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ArkBot/OpenID/BarebonesSteamOpenId.cs b/ArkBot/OpenID/BarebonesSteamOpenId.cs index ef4cf78..2131834 100644 --- a/ArkBot/OpenID/BarebonesSteamOpenId.cs +++ b/ArkBot/OpenID/BarebonesSteamOpenId.cs @@ -16,7 +16,7 @@ namespace ArkBot.OpenID { public class BarebonesSteamOpenId : IBarebonesSteamOpenId { - private const string _authority = @"http://steamcommunity.com/openid"; + private const string _authority = @"https://steamcommunity.com/openid"; private AsyncLazy _endpoint = new AsyncLazy(async () => await Discovery()); private HttpListener _listener; private CancellationTokenSource _cts; From d4f990286b2d5ba2797661f95624bf396e01ecdf Mon Sep 17 00:00:00 2001 From: Tobias Sebring Date: Fri, 1 Jun 2018 21:27:18 +0200 Subject: [PATCH 07/15] Updated .nuspec --- ArkBot/ArkBot.nuspec | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ArkBot/ArkBot.nuspec b/ArkBot/ArkBot.nuspec index e1a805b..acf09dc 100644 --- a/ArkBot/ArkBot.nuspec +++ b/ArkBot/ArkBot.nuspec @@ -1,17 +1,17 @@  - ArkDiscordBot + ArkBot $version$ - ARK Survival Evolved Discord Bot + ARK Bot tsebring https://raw.githubusercontent.com/tsebring/ArkBot/master/LICENSE.txt https://github.com/tsebring/ArkBot/ true - A Discord bot for ARK Survival Evolved utilizing https://github.com/arktools to extract data from savegame-files on your server. - arksurvivalevolved discord-bot + ARK Survival Evolved application that monitors and extracts data from local ARK servers and exposes this data through a Web App, Web API and Discord Bot. + arksurvivalevolved ark game-ark game webapi discord-bot community server-management administration web-app - + \ No newline at end of file From ab9951b33956cdb759f80e4f7ca2ffb85264633d Mon Sep 17 00:00:00 2001 From: Kyle Allen Date: Tue, 19 Jun 2018 13:49:08 +0100 Subject: [PATCH 08/15] urlshorten updated --- ArkBot/Configuration/Model/Config.cs | 4 +-- ArkBot/Configuration/Model/IConfig.cs | 2 +- ArkBot/Services/UrlShortenerService.cs | 38 ++++++++++++++++++-------- ArkBot/ViewModel/Workspace.cs | 6 ++-- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/ArkBot/Configuration/Model/Config.cs b/ArkBot/Configuration/Model/Config.cs index 04b5c57..e02f653 100644 --- a/ArkBot/Configuration/Model/Config.cs +++ b/ArkBot/Configuration/Model/Config.cs @@ -44,7 +44,7 @@ public Config() // Required - [JsonProperty(PropertyName = "googleApiKey")] + [JsonProperty(PropertyName = "bitlyApiKey")] [Display(Name = "Google API Key", Description = "API Key from Google used for url-shortening services")] [ConfigurationHelp(instructions: new[] { @"1. Go to [Googe APIs & Services](https://console.developers.google.com/apis/credentials) and create a credential of type ""API Key"".", @@ -54,7 +54,7 @@ public Config() [PropertyOrder(0)] [MinLength(1, ErrorMessage = "{0} is not set")] //todo: validate google api key with google - public string GoogleApiKey { get; set; } + public string BitlyApiKey { get; set; } [JsonProperty(PropertyName = "steamApiKey")] [Display(Name = "Steam API Key", Description = "API Key from Steam used for fetching server and user details from the Steam API")] diff --git a/ArkBot/Configuration/Model/IConfig.cs b/ArkBot/Configuration/Model/IConfig.cs index e83c1b7..7b46bc9 100644 --- a/ArkBot/Configuration/Model/IConfig.cs +++ b/ArkBot/Configuration/Model/IConfig.cs @@ -10,7 +10,7 @@ public interface IConfig string BotName { get; set; } string BotUrl { get; set; } string AppUrl { get; set; } - string GoogleApiKey { get; set; } + string BitlyApiKey { get; set; } string SteamApiKey { get; set; } string TempFileOutputDirPath { get; set; } DiscordConfigSection Discord { get; set; } diff --git a/ArkBot/Services/UrlShortenerService.cs b/ArkBot/Services/UrlShortenerService.cs index 15f599e..3219820 100644 --- a/ArkBot/Services/UrlShortenerService.cs +++ b/ArkBot/Services/UrlShortenerService.cs @@ -1,7 +1,9 @@ using ArkBot.Configuration.Model; +using Nancy.Helpers; +using Newtonsoft.Json.Linq; using System; -using System.Collections.Generic; -using System.Linq; +using System.IO; +using System.Net; using System.Text; using System.Threading.Tasks; @@ -9,26 +11,38 @@ namespace ArkBot.Services { public class UrlShortenerService : IUrlShortenerService { - private Google.Apis.Urlshortener.v1.UrlshortenerService _urlShortenerService; private IConfig _config; public UrlShortenerService(IConfig config) { _config = config; - _urlShortenerService = new Google.Apis.Urlshortener.v1.UrlshortenerService(new Google.Apis.Services.BaseClientService.Initializer() - { - ApiKey = _config.GoogleApiKey, - ApplicationName = _config.BotName, - }); } public async Task ShortenUrl(string longUrl) { - var url = new Google.Apis.Urlshortener.v1.Data.Url + var url = string.Format("https://api-ssl.bitly.com/v3/shorten?access_token={0}&longUrl={1}", _config.BitlyApiKey, HttpUtility.UrlEncode(longUrl)); + var request = (HttpWebRequest)WebRequest.Create(url); + + try + { + var response = await request.GetResponseAsync(); + using (var responseStream = response.GetResponseStream()) + { + var reader = new StreamReader(responseStream, Encoding.UTF8); + var jsonResponse = JObject.Parse(await reader.ReadToEndAsync()); + var statusCode = jsonResponse["status_code"].Value(); + if (statusCode == (int)HttpStatusCode.OK) + return jsonResponse["data"]["url"].Value(); + + Logging.Log(String.Join("Bitly request returned error code {0}, status text '{1}' on longUrl = {2}", statusCode, jsonResponse["status_txt"].Value(), longUrl), GetType()); + return longUrl; + } + } + catch (WebException ex) { - LongUrl = longUrl - }; - return (await _urlShortenerService.Url.Insert(url).ExecuteAsync())?.Id; + Logging.LogException("Bitly Url Service", ex, GetType()); + return longUrl; + } } } } diff --git a/ArkBot/ViewModel/Workspace.cs b/ArkBot/ViewModel/Workspace.cs index bae3108..890cac0 100644 --- a/ArkBot/ViewModel/Workspace.cs +++ b/ArkBot/ViewModel/Workspace.cs @@ -723,10 +723,10 @@ private string ValidateConfig() sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.TempFileOutputDirPath))}"); sb.AppendLine(); } - if (string.IsNullOrWhiteSpace(_config.GoogleApiKey)) + if (string.IsNullOrWhiteSpace(_config.BitlyApiKey)) { - sb.AppendLine($@"Error: {nameof(_config.GoogleApiKey)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.GoogleApiKey))}"); + sb.AppendLine($@"Error: {nameof(_config.BitlyApiKey)} is not set."); + sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BitlyApiKey))}"); sb.AppendLine(); } if (string.IsNullOrWhiteSpace(_config.SteamApiKey)) From 4097bbe35852fff71661441b9b8e0ce810a718ea Mon Sep 17 00:00:00 2001 From: Kyle Allen Date: Tue, 19 Jun 2018 18:59:38 +0100 Subject: [PATCH 09/15] removed urlshortener --- ArkBot/Commands/LinkSteamCommand.cs | 17 +++++---- ArkBot/Configuration/Model/Config.cs | 12 ------- ArkBot/Configuration/Model/IConfig.cs | 1 - ArkBot/Services/IUrlShortenerService.cs | 9 ----- ArkBot/Services/UrlShortenerService.cs | 48 ------------------------- ArkBot/ViewModel/Workspace.cs | 7 ---- 6 files changed, 10 insertions(+), 84 deletions(-) delete mode 100644 ArkBot/Services/IUrlShortenerService.cs delete mode 100644 ArkBot/Services/UrlShortenerService.cs diff --git a/ArkBot/Commands/LinkSteamCommand.cs b/ArkBot/Commands/LinkSteamCommand.cs index 39573c2..133bc0c 100644 --- a/ArkBot/Commands/LinkSteamCommand.cs +++ b/ArkBot/Commands/LinkSteamCommand.cs @@ -16,15 +16,13 @@ public class LinkSteamCommand : ModuleBase { private IConstants _constants; private IBarebonesSteamOpenId _openId; - private IUrlShortenerService _urlShortenerService; private EfDatabaseContextFactory _databaseContextFactory; public LinkSteamCommand(IConstants constants, IBarebonesSteamOpenId openId, - IUrlShortenerService urlShortenerService, EfDatabaseContextFactory databaseContextFactory) + EfDatabaseContextFactory databaseContextFactory) { _constants = constants; _openId = openId; - _urlShortenerService = urlShortenerService; _databaseContextFactory = databaseContextFactory; } @@ -54,12 +52,17 @@ await Context.Channel.SendMessageAsync( return; } - var sb = new StringBuilder(); - sb.AppendLine($"**Proceed to link your Discord user with your Steam account by following this link:**"); - sb.AppendLine($"{(await _urlShortenerService?.ShortenUrl(state.StartUrl)) ?? state.StartUrl}"); + EmbedBuilder builder = new EmbedBuilder() + { + Title = "Steam Account Link", + Description = $"Proceed to link your Discord user with your Steam account by [Logging into Steam]({state.StartUrl})", + Url = state.StartUrl, + Color = Color.Green + + }; var channel = await Context.User.GetOrCreateDMChannelAsync(); - var msg = await channel.SendMessageAsync(sb.ToString().Trim('\r', '\n')); + var msg = await channel.SendMessageAsync("", false, builder.Build()); if (Context.IsPrivate) return; diff --git a/ArkBot/Configuration/Model/Config.cs b/ArkBot/Configuration/Model/Config.cs index e02f653..167a770 100644 --- a/ArkBot/Configuration/Model/Config.cs +++ b/ArkBot/Configuration/Model/Config.cs @@ -44,18 +44,6 @@ public Config() // Required - [JsonProperty(PropertyName = "bitlyApiKey")] - [Display(Name = "Google API Key", Description = "API Key from Google used for url-shortening services")] - [ConfigurationHelp(instructions: new[] { - @"1. Go to [Googe APIs & Services](https://console.developers.google.com/apis/credentials) and create a credential of type ""API Key"".", - @"2. Go to [URL Shortener API](https://console.developers.google.com/apis/api/urlshortener.googleapis.com) and enable it." }, - Example = "`AIzaSyBukSL8pbCjkyR__f6kvL0XW_2OcP5Mrfo`")] - [Category(ConfigurationCategory.Required)] - [PropertyOrder(0)] - [MinLength(1, ErrorMessage = "{0} is not set")] - //todo: validate google api key with google - public string BitlyApiKey { get; set; } - [JsonProperty(PropertyName = "steamApiKey")] [Display(Name = "Steam API Key", Description = "API Key from Steam used for fetching server and user details from the Steam API")] [ConfigurationHelp(instructions: new[] { diff --git a/ArkBot/Configuration/Model/IConfig.cs b/ArkBot/Configuration/Model/IConfig.cs index 7b46bc9..04f4999 100644 --- a/ArkBot/Configuration/Model/IConfig.cs +++ b/ArkBot/Configuration/Model/IConfig.cs @@ -10,7 +10,6 @@ public interface IConfig string BotName { get; set; } string BotUrl { get; set; } string AppUrl { get; set; } - string BitlyApiKey { get; set; } string SteamApiKey { get; set; } string TempFileOutputDirPath { get; set; } DiscordConfigSection Discord { get; set; } diff --git a/ArkBot/Services/IUrlShortenerService.cs b/ArkBot/Services/IUrlShortenerService.cs deleted file mode 100644 index 5f64db4..0000000 --- a/ArkBot/Services/IUrlShortenerService.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace ArkBot.Services -{ - public interface IUrlShortenerService - { - Task ShortenUrl(string longUrl); - } -} \ No newline at end of file diff --git a/ArkBot/Services/UrlShortenerService.cs b/ArkBot/Services/UrlShortenerService.cs deleted file mode 100644 index 3219820..0000000 --- a/ArkBot/Services/UrlShortenerService.cs +++ /dev/null @@ -1,48 +0,0 @@ -using ArkBot.Configuration.Model; -using Nancy.Helpers; -using Newtonsoft.Json.Linq; -using System; -using System.IO; -using System.Net; -using System.Text; -using System.Threading.Tasks; - -namespace ArkBot.Services -{ - public class UrlShortenerService : IUrlShortenerService - { - private IConfig _config; - - public UrlShortenerService(IConfig config) - { - _config = config; - } - - public async Task ShortenUrl(string longUrl) - { - var url = string.Format("https://api-ssl.bitly.com/v3/shorten?access_token={0}&longUrl={1}", _config.BitlyApiKey, HttpUtility.UrlEncode(longUrl)); - var request = (HttpWebRequest)WebRequest.Create(url); - - try - { - var response = await request.GetResponseAsync(); - using (var responseStream = response.GetResponseStream()) - { - var reader = new StreamReader(responseStream, Encoding.UTF8); - var jsonResponse = JObject.Parse(await reader.ReadToEndAsync()); - var statusCode = jsonResponse["status_code"].Value(); - if (statusCode == (int)HttpStatusCode.OK) - return jsonResponse["data"]["url"].Value(); - - Logging.Log(String.Join("Bitly request returned error code {0}, status text '{1}' on longUrl = {2}", statusCode, jsonResponse["status_txt"].Value(), longUrl), GetType()); - return longUrl; - } - } - catch (WebException ex) - { - Logging.LogException("Bitly Url Service", ex, GetType()); - return longUrl; - } - } - } -} diff --git a/ArkBot/ViewModel/Workspace.cs b/ArkBot/ViewModel/Workspace.cs index 890cac0..a5d78b1 100644 --- a/ArkBot/ViewModel/Workspace.cs +++ b/ArkBot/ViewModel/Workspace.cs @@ -377,7 +377,6 @@ internal async Task Init() builder.RegisterInstance(discordCommands).AsSelf(); builder.RegisterType().As().SingleInstance(); builder.RegisterType(); - builder.RegisterType().As().SingleInstance(); builder.RegisterType().AsSelf(); builder.RegisterInstance(constants).As(); builder.RegisterInstance(_savedstate).As(); @@ -723,12 +722,6 @@ private string ValidateConfig() sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.TempFileOutputDirPath))}"); sb.AppendLine(); } - if (string.IsNullOrWhiteSpace(_config.BitlyApiKey)) - { - sb.AppendLine($@"Error: {nameof(_config.BitlyApiKey)} is not set."); - sb.AppendLine($@"Expected value: {ValidationHelper.GetDescriptionForMember(_config, nameof(_config.BitlyApiKey))}"); - sb.AppendLine(); - } if (string.IsNullOrWhiteSpace(_config.SteamApiKey)) { sb.AppendLine($@"Error: {nameof(_config.SteamApiKey)} is not set."); From e76c034ca7f0537272f6a9a61c4eb53cfe9f25c3 Mon Sep 17 00:00:00 2001 From: Kyle Allen Date: Tue, 19 Jun 2018 19:27:26 +0100 Subject: [PATCH 10/15] cleanup --- ArkBot/ArkBot.csproj | 26 -------------------------- ArkBot/Discord/ArkDiscordBot.cs | 2 -- ArkBot/aliases.json | 4 ---- ArkBot/defaultconfig.json | 1 - ArkBot/packages.config | 4 ---- 5 files changed, 37 deletions(-) diff --git a/ArkBot/ArkBot.csproj b/ArkBot/ArkBot.csproj index a6037b4..1237f3f 100644 --- a/ArkBot/ArkBot.csproj +++ b/ArkBot/ArkBot.csproj @@ -175,30 +175,6 @@ ..\packages\FSharp.Core.4.1.12\lib\net45\FSharp.Core.dll True - - ..\packages\Google.Apis.1.20.0\lib\net45\Google.Apis.dll - True - - - ..\packages\Google.Apis.Auth.1.20.0\lib\net45\Google.Apis.Auth.dll - True - - - ..\packages\Google.Apis.Auth.1.20.0\lib\net45\Google.Apis.Auth.PlatformServices.dll - True - - - ..\packages\Google.Apis.Core.1.20.0\lib\net45\Google.Apis.Core.dll - True - - - ..\packages\Google.Apis.1.20.0\lib\net45\Google.Apis.PlatformServices.dll - True - - - ..\packages\Google.Apis.Urlshortener.v1.1.20.0.138\lib\net45\Google.Apis.Urlshortener.v1.dll - True - ..\packages\HtmlAgilityPack.1.4.9\lib\Net45\HtmlAgilityPack.dll True @@ -747,10 +723,8 @@ - - diff --git a/ArkBot/Discord/ArkDiscordBot.cs b/ArkBot/Discord/ArkDiscordBot.cs index 7f21d22..df91315 100644 --- a/ArkBot/Discord/ArkDiscordBot.cs +++ b/ArkBot/Discord/ArkDiscordBot.cs @@ -6,7 +6,6 @@ using Discord; using Discord.WebSocket; using Discord.Commands; -using Google.Apis.Urlshortener.v1; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -26,7 +25,6 @@ using ArkBot.Ark; using ArkBot.Discord.Command; using ArkBot.Voting; -using Discord.WebSocket; using RazorEngine.Compilation.ImpromptuInterface; using VDS.Common.Collections.Enumerations; using ArkBot.Configuration.Model; diff --git a/ArkBot/aliases.json b/ArkBot/aliases.json index ac5200d..7f9bebf 100644 --- a/ArkBot/aliases.json +++ b/ArkBot/aliases.json @@ -1114,10 +1114,6 @@ "Reaper", "Xenomorph_Character_BP_C" ], - [ - "Reaper King", - "Xenomorph_Character_BP_Male_Tamed_C" - ], [ "Rockwell", "Rockwell_Character_BP_C" diff --git a/ArkBot/defaultconfig.json b/ArkBot/defaultconfig.json index c9b7c74..60e045d 100644 --- a/ArkBot/defaultconfig.json +++ b/ArkBot/defaultconfig.json @@ -3,7 +3,6 @@ "botUrl": "", "appUrl": "", "tempFileOutputDirPath": "", - "googleApiKey": "", "steamApiKey": "", "discord": { "discordBotEnabled": true, diff --git a/ArkBot/packages.config b/ArkBot/packages.config index 31f4443..8078528 100644 --- a/ArkBot/packages.config +++ b/ArkBot/packages.config @@ -30,10 +30,6 @@ - - - - From 80ede649aea33032556b6e422cbc4f12098dc0ee Mon Sep 17 00:00:00 2001 From: Lewimaron Date: Sat, 25 Aug 2018 17:00:25 +0100 Subject: [PATCH 11/15] Updated Aliases Added Crystal Isles, The Volcano, and Valguero custom creatures as well as updated vanilla ones. --- ArkBot/aliases.json | 1948 ++++++++++++++++++++++++++++--------------- 1 file changed, 1278 insertions(+), 670 deletions(-) diff --git a/ArkBot/aliases.json b/ArkBot/aliases.json index ac5200d..f743c6d 100644 --- a/ArkBot/aliases.json +++ b/ArkBot/aliases.json @@ -1,1136 +1,1744 @@ { "Aliases": [ [ - "Achatina", - "Achatina_Character_BP_C", - "Snail", - "Acha" + "Alpha Basilisk", + "MegaBasilisk_Character_BP_C" ], [ - "Allosaurus", - "Allo_Character_BP_C", - "Allo" + "Alpha Karkinos", + "MegaCrab_Character_BP_C", + "Alpha Crab" ], [ - "Alpha Carno", - "MegaCarno_Character_BP_C" + "Alpha Reaper King (Surface)", + "MegaXenomorph_Character_BP_Male_Surface_C" ], [ - "Alpha Deathworm", - "MegaDeathworm_Character_BP_C" + "Aberrant Dodo", + "Dodo_Character_BP_Aberrant_C" ], [ - "Alpha Fire Wyvern", - "MegaWyvern_Character_BP_Fire_C" + "Featherlight", + "LanternBird_Character_BP_C" ], [ - "Alpha Leedsichthys", - "Alpha_Leedsichthys_Character_BP_C", - "Alpha Leeds" + "Edmund Rockwell (Base)", + "Rockwell_Character_BP_C", + "Rockwell (Base)" ], [ - "Alpha Megalodon", - "MegaMegalodon_Character_BP_C" + "Edmund Rockwell (Alpha)", + "Rockwell_Character_BP_Hard_C", + "Rockwell (Alpha)" ], [ - "Alpha Mosasaurus", - "Mosa_Character_BP_Mega_C" + "Edmund Rockwell (Beta)", + "Rockwell_Character_BP_Medium_C", + "Rockwell (Beta)" ], [ - "Alpha Raptor", - "MegaRaptor_Character_BP_C" + "Edmund Rockwell (Gamma)", + "Rockwell_Character_BP_Easy_C", + "Rockwell (Gamma)" ], [ - "Alpha Rex", - "MegaRex_Character_BP_C" + "Rockwell Tentacle (Base)", + "RockwellTentacle_Character_BP_C", + "Tentacle (Base)" ], [ - "Alpha Tusoteuthis", - "Mega_Tusoteuthis_Character_BP_C" + "Rockwell Tentacle (Alpha)", + "RockwellTentacle_Character_BP_Alpha_C", + "Tentacle (Alpha)" ], [ - "Ammonite", - "Ammonite_Character_C" + "Rockwell Tentacle (Beta)", + "RockwellTentacle_Character_BP_Beta_C", + "Tentacle (Beta)" ], [ - "Angler", - "Angler_Character_BP_C", - "Anglerfish" + "Rockwell Tentacle (Gamma)", + "RockwellTentacle_Character_BP_Gamma_C", + "Tentacle (Gamma)" ], [ - "Ankylosaurus", - "Ankylo_Character_BP_C", - "Ankylo", - "Anky" + "Aberrant Ankylosaurus", + "Ankylo_Character_BP_Aberrant_C", + "Aberrant Ankylo" ], [ - "Araneo", - "SpiderS_Character_BP_C", - "Spider" + "Aberrant Baryonyx", + "Baryonyx_Character_BP_Aberrant_C" ], [ - "Archaeopteryx", - "Archa_Character_BP_C", - "Archa" + "Aberrant Carno", + "Carno_Character_BP_Aberrant_C" ], [ - "Argentavis", - "Argent_Character_BP_C", - "Argent", - "Argi" + "Aberrant Dimorphodon", + "Dimorph_Character_BP_Aberrant_C" ], [ - "Arthropluera", - "Arthro_Character_BP_C", - "Arthro", - "Centipede" + "Aberrant Diplodocus", + "Diplodocus_Character_BP_Aberrant_C", + "Aberrant Diplo" ], [ - "Baryonyx", - "Baryonyx_Character_BP_C", - "Bary" + "Aberrant Iguanodon", + "Iguanodon_Character_BP_Aberrant_C" ], [ - "Basilosaurus", - "Basilosaurus_Character_BP_C", - "Basilo" + "Aberrant Megalosaurus", + "Megalosaurus_Character_BP_Aberrant_C" ], [ - "Beelzebufo", - "Toad_Character_BP_C", - "Toad" + "Aberrant Parasaurolophus", + "Para_Character_BP_Aberrant_C", + "Aberrant Parasaur" ], [ - "Bone Fire Wyvern", - "Bone_MegaWyvern_Character_BP_Fire_C" + "Aberrant Raptor", + "Raptor_Character_BP_Aberrant_C" ], [ - "Brontosaurus", - "Sauropod_Character_BP_C", - "Bronto" + "Aberrant Spinosaurus", + "Spino_Character_BP_Aberrant_C", + "Aberrant Spino" ], [ - "Broodmother Lysrix", - "SpiderL_Character_BP_C" + "Aberrant Stegosaurus", + "Stego_Character_BP_Aberrant_C", + "Aberrant Stego" ], [ - "BunnyDodo", - "Dodo_Character_BP_Bunny", - "Bunny Dodo" + "Aberrant Triceratops", + "Trike_Character_BP_Aberrant_C", + "Aberrant Trike" ], [ - "BunnyOviraptor", - "BunnyOviRaptor_Character_BP", - "Bunny Oviraptor" + "Elemental Reaper King", + "Xenomorph_Character_BP_Male_Minion_C" ], [ - "Carbonemys", - "Turtle_Character_BP_C", - "Turtle" + "Nameless", + "ChupaCabra_Character_BP_C" ], [ - "Carnotaurus", - "Carno_Character_BP_C", - "Carno" + "Nameless (Minion)", + "ChupaCabra_Character_BP_Minion_C" ], [ - "Castoroides", - "Beaver_Character_BP_C", - "Beaver" + "Nameless (Surface)", + "ChupaCabra_Character_BP_Surface_C" ], [ - "Chalicotherium", - "Chalico_Character_BP_C", - "Chalico", - "Cow" + "Reaper King", + "Xenomorph_Character_BP_Male_Tamed_C" ], [ - "Cnidaria", - "Cnidaria_Character_BP_C" + "Reaper Queen", + "Xenomorph_Character_BP_Female_C" ], [ - "Coelacanth", - "Coel_Character_BP_C", - "Coel" + "Subterranian Reaper King", + "Xenomorph_Character_BP_Male_Chupa_C" ], [ - "Ocean Coelacanth", - "Coel_Character_BP_Ocean_C", - "Ocean Coel" + "Surface Reaper King", + "Xenomorph_Character_BP_Male_Surface_C" ], [ - "Compsognathus", - "Compy_Character_BP_C", - "Compy" + "Aberrant Angler", + "Angler_Character_BP_Aberrant_C" ], [ - "Daeodon", - "Daeodon_Character_BP_C", - "Hell Pig" + "Aberrant Coelacanth", + "Coel_Character_BP_Aberrant_C", + "Aberrant Coel" ], [ - "Deathworm", - "Deathworm_Character_BP_C" + "Aberrant Electrophorus", + "Eel_Character_BP_Aberrant_C", + "Aberrant Eel" ], [ - "Dilophosaur", - "Dilo_Character_BP_C", - "Dilo" + "Lamprey", + "Lamprey_Character_C" ], [ - "Dimetrodon", - "Dimetro_Character_BP_C", - "Dimetro" + "Aberrant Manta", + "Manta_Character_BP_Aberrant_C" ], [ - "Dimorphodon", - "Dimorph_Character_BP_C", - "Dimorph", - "Dimo" + "Aberrant Piranha", + "Piranha_Character_BP_Aberrant_C" ], [ - "Diplocaulus", - "Diplocaulus_Character_BP_C", - "Newt" + "Aberrant Sabertooth Salmon", + "Salmon_Character_Aberrant_C", + "Aberrant Salmon" ], [ - "Diplodocus", - "Diplodocus_Character_BP_C" + "Aberrant Achatina", + "Achatina_Character_BP_Aberrant_C", + "Aberrant Snail" ], [ - "Direbear", - "Direbear_Character_BP_C", - "Dire Bear", - "Bear" + "Aberrant Araneo", + "SpiderS_Character_BP_Aberrant_C", + "Aberrant Spider" ], [ - "Dire Polar Bear", - "Direbear_Character_Polar_C", - "Direbear Polar", - "Dire Bear Polar" + "Aberrant Arthropluera", + "Arthro_Character_BP_Aberrant_C" ], [ - "Direwolf", - "Direwolf_Character_BP_C", - "Dire Wolf", - "Wolf" + "Aberrant Cnidaria", + "Cnidaria_Character_BP_Aberrant_C", + "Aberrant Jellyfish" ], [ - "Dodo", - "Dodo_Character_BP_C", - "Chicken" + "Aberrant Dung Beetle", + "DungBeetle_Character_BP_Aberrant_C" ], [ - "Dodo Wyvern", - "DodoWyvern_Character_BP_C" + "Glowbug", + "Lightbug_Character_BaseBP_C" ], [ - "DodoRex", - "DodoRex_Character_BP_C", - "Dodo Rex" + "Karkinos", + "Crab_Character_BP_C", + "Crab" ], [ - "Doedicurus", - "Doed_Character_BP_C", - "Doed" + "Aberrant Meganeura", + "Dragonfly_Character_BP_Aberrant_C", + "Aberrant Dragonfly" ], [ - "Dragon", - "Dragon_Character_BP_Boss_C" + "Aberrant Pulminoscorpius", + "Scorpion_Character_BP_Aberrant_C", + "Aberrant Scorpion" ], [ - "Dragonfly", - "Dragonfly_Character_BP_C" + "Aberrant Trillobyte", + "Trilobite_Character_Aberrant_C" ], [ - "Dung Beetle", - "DungBeetle_Character_BP_C", - "Beetle" + "Bulbdog", + "LanternPug_Character_BP_C" ], [ - "Dunkleosteus", - "Dunkle_Character_BP_C", - "Dunkle" + "Aberrant Direbear", + "Direbear_Character_BP_Aberrant_C" ], [ - "Electrophorus", - "Eel_Character_BP_C", - "Eel", - "Electro" + "Aberrant Doedicurus", + "Doed_Character_BP_Aberrant_C" ], [ - "Equus", - "Equus_Character_BP_C", - "Horse" + "Aberrant Equus", + "Equus_Character_BP_Aberrant_C", + "Aberrant Horse" ], [ - "Unicorn", - "Equus_Character_BP_Unicorn_C" + "Aberrant Gigantopithecus", + "Bigfoot_Character_BP_Aberrant_C", + "Aberrant Bigfoot" ], [ - "Eurypterid", - "Euryp_Character_C", - "Euryp" + "Aberrant Otter", + "Otter_Character_BP_Aberrant_C" ], [ - "Gallimimus", - "Galli_Character_BP_C", - "Galli" + "Aberrant Ovis", + "Sheep_Character_BP_Aberrant_C", + "Aberrant Sheep" ], [ - "Giant Bee", - "Bee_Queen_Character_BP_C", - "Bee Queen", - "Bee" + "Aberrant Paracer", + "Paracer_Character_BP_Aberrant_C" ], [ - "Giganotosaurus", - "Gigant_Character_BP_C", - "Giga" + "Aberrant Purlovia", + "Purlovia_Character_BP_Aberrant_C" ], [ - "Gigantopithecus", - "Bigfoot_Character_BP_C" + "Ravager", + "CaveWolf_Character_BP_C" ], [ - "Griffin", - "Griffin_Character_BP_C", - "Gryphon" + "Roll Rat", + "MoleRat_Character_BP_C", + "Mole" ], [ - "Hesperornis", - "Hesperornis_Character_BP_C", - "Duck" + "Shinehorn", + "LanternGoat_Character_BP_C" ], [ - "Human" + "Basilisk", + "Basilisk_Character_BP_C" ], [ - "Hyaenodon", - "Hyaenodon_Character_BP_C", - "Hyena" + "Aberrant Beelzebufo", + "Toad_Character_BP_Aberrant_C", + "Aberrant Frog" ], [ - "Ice Worm Queen", - "Iceworm_Queen_Character_BP_C" + "Aberrant Carbonemys", + "Turtle_Character_BP_Aberrant_C", + "Aberrant Turtle" ], [ - "Ice Worm", - "Iceworm_Character_Minion_BP_Smaller_C" + "Aberrant Dimetrodon", + "Dimetro_Character_BP_Aberrant_C" ], [ - "Ichthy", - "Dolphin_Character_BP_C", - "Ichthyosaurus", - "Dolphin" + "Aberrant Diplocaulus", + "Diplocaulus_Character_BP_Aberrant_C" ], [ - "Ichthyornis", - "Ichthyornis_Character_BP_C", - "Seagull" + "Glowtail", + "LanternLizard_Character_BP_C" ], [ - "Iguanodon", - "Iguanodon_Character_BP_C", - "Iguan" + "Aberrant Lystrosaurus", + "Lystro_Character_BP_Aberrant_C", + "Aberrant Lystro" ], [ - "Jerboa", - "Jerboa_Character_BP_C" + "Aberrant Megalania", + "Megalania_Character_BP_Aberrant_C" ], [ - "Jug Bug", - "Jugbug_Character_BaseBP_C", - "Jugbug_Oil_Character_BP_C", - "Jugbug_Water_Character_BP_C" + "Aberrant Moschops", + "Moschops_Character_BP_Aberrant_C" ], [ - "Kairuku", - "Kairuku_Character_BP_C", - "Penguin" + "Rock Drake", + "RockDrake_Character_BP_C" ], [ - "Kaprosuchus", - "Kaprosuchus_Character_BP_C", - "Kapro", - "Gator", - "Jumping Crocodile" + "Aberrant Sarcosuchus", + "Sarco_Character_BP_Aberrant_C", + "Aberrant Sarco" ], [ - "Kentrosaurus", - "Kentro_Character_BP_C", - "Kentro" + "Seeker", + "Pteroteuthis_Char_BP_C" ], [ - "Leech", - "Leech_Character_C" + "Seeker (Surface)", + "Pteroteuthis_Char_BP_Surface_C" ], [ - "Leech Diseased", - "Leech_Character_Diseased_C", - "Diseased Leech" + "Aberrant Titanoboa", + "BoaFrill_Character_BP_Aberrant_C" ], [ - "Leedsichthys", - "Leedsichthys_Character_BP_C", - "Leeds" + "Albino Leedsichthys", + "Alpha_Leedsichthys_Character_BP_C" ], [ - "Liopleurodon", - "Liopleurodon_Character_BP_C", - "Lio" + "Alpha Carnotaurus", + "MegaCarno_Character_BP_C", + "Alpha Carno" ], [ - "Lymantria", - "Moth_Character_BP_C", - "Moth", - "Desert Moth" + "Alpha Megalodon", + "MegaMegalodon_Character_BP_C" ], [ - "Lystrosaurus", - "Lystro_Character_BP_C", - "Lystro" + "Alpha Mosasaur", + "Mosa_Character_BP_Mega_C", + "Alpha Mosa" ], [ - "Mammoth", - "Mammoth_Character_BP_C" + "Alpha Mosasaur (Cave)", + "Mosa_Character_BP_Mega_Cave_C", + "Alpha Mosa (Cave)" ], [ - "Manta", - "Manta_Character_BP_C" + "Alpha Raptor", + "MegaRaptor_Character_BP_C" ], [ - "Manticore", - "Manticore_Character_BP_C" + "Alpha Rex", + "MegaRex_Character_BP_C" ], [ - "Mantis", - "Mantis_Character_BP_C" + "Alpha Tusoteuthis", + "Mega_Tusoteuthis_Character_BP_C", + "Alpha Squid" ], [ - "Megalania", - "Megalania_Character_BP_C" + "Giganotosaurus (Base)", + "Gigant_Character_BP_Base_C", + "Giga (Base)" ], [ - "Megaloceros", - "Stag_Character_BP_C", - "Megaloc", - "Stag", - "Deer" + "Tusoteuthis (Cave Base)", + "Tusoteuthis_Character_BP_CaveBase_C", + "Squid (Cave Base)" ], [ - "Megalodon", - "Megalodon_Character_BP_C", - "Shark" + "Archaeopterix", + "Archa_Character_BP_C" ], [ - "Megalosaurus", - "Megalosaurus_Character_BP_C", - "Megalos", - "Sleeping Raptor" + "Argentavis", + "Argent_Character_BP_C" + ], + [ + "Dodo", + "Dodo_Character_BP_C" + ], + [ + "Hesperornis", + "Hesperornis_Character_BP_C" + ], + [ + "Ichthyornis", + "Ichthyornis_Character_BP_C", + "Seagull" + ], + [ + "Kairuku", + "Kairuku_Character_BP_C", + "Penguin" + ], + [ + "Pelagornis", + "Pela_Character_BP_C" + ], + [ + "Terror Bird", + "TerrorBird_Character_BP_C" + ], + [ + "Araneo (Boss Minion) (Alpha)", + "SpiderS_Character_BP_Aggressive_Hard_C", + "Spider (Boss Minion) (Alpha)" + ], + [ + "Araneo (Boss Minion) (Beta)", + "SpiderS_Character_BP_Aggressive_Med_C", + "Spider (Boss Minion) (Beta)" + ], + [ + "Araneo (Boss Minion) (Gamma)", + "SpiderS_Character_BP_Aggressive_C", + "Spider (Boss Minion) (Gamma)" + ], + [ + "Broodmother (Alpha)", + "SpiderL_Character_BP_Hard_C" + ], + [ + "Broodmother (Alpha) (The Center)", + "SpiderL_Character_BP_TheCenterHard_C" + ], + [ + "Broodmother (Beta)", + "SpiderL_Character_BP_Medium_C" + ], + [ + "Broodmother (Beta) (The Center)", + "SpiderL_Character_BP_TheCenterMedium_C" + ], + [ + "Broodmother (Gamma)", + "SpiderL_Character_BP_Easy_C" + ], + [ + "Broodmother (Gamma) (The Center)", + "SpiderL_Character_BP_TheCenter_C" + ], + [ + "Broodmother (Base)", + "SpiderL_Character_BP_C" + ], + [ + "Dimorphodon (Boss Minion) (Alpha)", + "Dimorph_Character_BP_Aggressive_DragonBoss_Hard_C" + ], + [ + "Dimorphodon (Boss Minion) (Bets)", + "Dimorph_Character_BP_Aggressive_DragonBoss_Med_C" + ], + [ + "Dimorphodon (Boss Minion) (Gamma)", + "Dimorph_Character_BP_Aggressive_DragonBoss_C" + ], + [ + "Dimorphodon (Boss Minion) (Base)", + "Dimorph_Character_BP_Aggressive_C" + ], + [ + "Dragon (Alpha)", + "Dragon_Character_BP_Boss_Hard_C" + ], + [ + "Dragon (Beta)", + "Dragon_Character_BP_Boss_Medium_C" + ], + [ + "Dragon (Gamma)", + "Dragon_Character_BP_Boss_Easy_C" + ], + [ + "Dragon (Base)", + "Dragon_Character_BP_Boss_C" + ], + [ + "Dragon (Old)", + "Dragon_Character_BP_C" + ], + [ + "End Boss Drone (Alpha)", + "EndDrone_Character_BP_Hard_C" + ], + [ + "End Boss Drone (Beta)", + "EndDrone_Character_BP_Med_C" + ], + [ + "End Boss Drone (Gamma)", + "EndDrone_Character_BP_C" + ], + [ + "End Boss Tank (Alpha)", + "EndTank_Character_BP_Hard_C" + ], + [ + "End Boss Tank (Beta)", + "EndTank_Character_BP_Med_C" + ], + [ + "End Boss Tank (Gamma)", + "EndTank_Character_BP_C" + ], + [ + "Gigantopithecus (Boss Minion) (Alpha)", + "Bigfoot_Character_BP_Aggressive_Hard_C", + "Bigfoot (Boss Minion) (Alpha)" + ], + [ + "Gigantopithecus (Boss Minion) (Beta)", + "Bigfoot_Character_BP_Aggressive_Med_C", + "Bigfoot (Boss Minion) (Beta)" + ], + [ + "Gigantopithecus (Boss Minion) (Gamma)", + "Bigfoot_Character_BP_Aggressive_C", + "Bigfoot (Boss Minion) (Gamma)" + ], + [ + "Megapithecus (Alpha)", + "Gorilla_Character_BP_Hard_C" + ], + [ + "Megapithecus (Alpha) (The Center)", + "Gorilla_Character_BP_TheCenter_Hard_C" + ], + [ + "Megapithecus (Beta)", + "Gorilla_Character_BP_Medium_C" + ], + [ + "Megapithecus (Beta) (The Center)", + "Gorilla_Character_BP_TheCenter_Medium_C" + ], + [ + "Megapithecus (Gamma)", + "Gorilla_Character_BP_Easy_C" + ], + [ + "Megapithecus (Gamma) (The Center)", + "Gorilla_Character_BP_TheCenter_C" + ], + [ + "Megapithecus (Base)", + "Gorila_Character_BP_C" + ], + [ + "Mesopithecus (Boss Minion) (Alpha)", + "Monkey_Character_BP_Aggressive_Hard_C", + "Monkey (Boss Minion) (Alpha)" + ], + [ + "Mesopithecus (Boss Minion) (Beta)", + "Monkey_Character_BP_Aggressive_Med_C", + "Monkey (Boss Minion) (Beta)" + ], + [ + "Mesopithecus (Boss Minion) (Gamma)", + "Monkey_Character_BP_Aggressive_C", + "Monkey (Boss Minion) (Gamma)" + ], + [ + "Overseer (Base)", + "EndBoss_Character_C" + ], + [ + "Overseer (Alpha)", + "EndBoss_Character_Hard_C" + ], + [ + "Overseer (Beta)", + "EndBoss_Character_Medium_C" + ], + [ + "Overseer (Gamma)", + "EndBoss_Character_Easy_C" + ], + [ + "Overseer (Gorilla Form) (Base)", + "EndBossGorilla_Character_BP_C" + ], + [ + "Overseer (Gorilla Form) (Alpha)", + "EndBossGorilla_Character_BP_Hard_C" + ], + [ + "Overseer (Gorilla Form) (Beta)", + "EndBossGorilla_Character_BP_Medium_C" + ], + [ + "Overseer (Gorilla Form) (Gamma)", + "EndBossGorilla_Character_BP_Easy_C" + ], + [ + "Overseer (Dragon Form) (Base)", + "EndBossDragon_Character_BP_C" + ], + [ + "Overseer (Dragon Form) (Alpha)", + "EndBossDragon_Character_BP_Hard_C" + ], + [ + "Overseer (Dragon Form) (Beta)", + "EndBossDragon_Character_BP_Medium_C" + ], + [ + "Overseer (Dragon Form) (Gamma)", + "EndBossDragon_Character_BP_Easy_C" + ], + [ + "Overseer (Spider Form) (Base)", + "EndBossSpiderL_Character_BP_C" + ], + [ + "Overseer (Spider Form) (Alpha)", + "EndBossSpiderL_Character_BP_Hard_C" + ], + [ + "Overseer (Spider Form) (Beta)", + "EndBossSpiderL_Character_BP_Medium_C" + ], + [ + "Overseer (Spider Form) (Gamma)", + "EndBossSpiderL_Character_BP_Easy_C" + ], + [ + "Pteranodon (Boss Minion) (Alpha)", + "Ptero_Minion_Character_Hard_C" + ], + [ + "Pteranodon (Boss Minion) (Beta)", + "Ptero_Minion_Character_Med_C" + ], + [ + "Pteranodon (Boss Minion) (Gamma)", + "Ptero_Minion_Character_BP_C" + ], + [ + "Allosaurus", + "Allo_Character_BP_C", + "Allo" + ], + [ + "Ankylosaurus", + "Ankylo_Character_BP_C", + "Ankylo" + ], + [ + "Baryonyx", + "Baryonyx_Character_BP_C" + ], + [ + "Brontosaurus", + "Sauropod_Character_BP_C", + "Bronto" + ], + [ + "Carnotaurus", + "Carno_Character_BP_C", + "Carno" + ], + [ + "Compsognathus", + "Compy_Character_BP_C", + "Compy" + ], + [ + "Dilophosaurus", + "Dilo_Character_BP_C", + "Dilo" + ], + [ + "Dimorphodon", + "Dimorph_Character_BP_C" + ], + [ + "Diplodocus", + "Diplodocus_Character_BP_C", + "Diplo" + ], + [ + "Gallimimus", + "Galli_Character_BP_C" + ], + [ + "Megalania", + "Megalania_Character_BP_C" + ], + [ + "Giganotosaurus", + "Gigant_Character_BP_C", + "Giga" + ], + [ + "Giganotosaurus (Tek Cave)", + "Gigant_Character_BP_TekCave_C", + "Giga (Tek Cave)" + ], + [ + "Iguanodon", + "Iguanodon_Character_BP_C" + ], + [ + "Kentrosaurus", + "Kentro_Character_BP_C", + "Kentro" + ], + [ + "Megalosaurus", + "Megalosaurus_Character_BP_C" + ], + [ + "Megalosaurus (Tek Cave)", + "Megalosaurus_Character_BP_TekCave_C" + ], + [ + "Microraptor", + "Microraptor_Character_BP_C" + ], + [ + "Oviraptor", + "OviRaptor_Character_BP_C" + ], + [ + "Pachycephalosaurus", + "Pachy_Character_BP_C", + "Pachy" + ], + [ + "Pachyrhinosaurus", + "Pachyrhino_Character_BP_C", + "Pachy Rhino" + ], + [ + "Motorboat", + "MotorRaft_BP_C" + ], + [ + "Parasaurolophus", + "Para_Character_BP_C", + "Parasaur" + ], + [ + "Raptor", + "Raptor_Character_BP_C" + ], + [ + "Rex", + "Rex_Character_BP_C" + ], + [ + "Spinosaurus", + "Spino_Character_BP_C", + "Spino" + ], + [ + "Stegosaurus", + "Stego_Character_BP_C", + "Stego" + ], + [ + "Therizinosaurus", + "Therizino_Character_BP_C", + "Therizino" + ], + [ + "Titanosaur", + "Titanosaur_Character_BP_C", + "Titan" + ], + [ + "Triceratops", + "Trike_Character_BP_C", + "Trike" + ], + [ + "Troodon", + "Troodon_Character_BP_C" + ], + [ + "Yutyrannus", + "Yutyrannus_Character_BP_C", + "Yuty" + ], + [ + "Tek Rex", + "BionicRex_Character_BP_C" + ], + [ + "Zombie Dodo", + "ZombieDodo_Character_BP_C" + ], + [ + "Unicorn", + "Equus_Character_BP_Unicorn_C" + ], + [ + "Yeti", + "Yeti_Character_BP_C" + ], + [ + "Angler", + "Angler_Character_BP_C" + ], + [ + "Coelacanth", + "Coel_Character_BP_C", + "Coel" + ], + [ + "Coelacanth (Deep Sea)", + "Coel_Character_BP_Ocean_C", + "Coel (Deep Sea)" + ], + [ + "Dunkleosteus", + "Dunkle_Character_BP_C", + "Dunkleo" + ], + [ + "Electrophorus", + "Eel_Character_BP_C", + "Eel" + ], + [ + "Leedsichthys", + "Leedsichthys_Character_BP_C" + ], + [ + "Manta", + "Manta_Character_BP_C" + ], + [ + "Raft", + "Raft_BP_C" + ], + [ + "Megalodon", + "Megalodon_Character_BP_C" + ], + [ + "Piranha", + "Piranha_Character_BP_C" + ], + [ + "Sabertooth Salmon", + "Salmon_Character_BP_C" + ], + [ + "Achatina", + "Achatina_Character_BP_C", + "Snail" + ], + [ + "Ammonite", + "Ammonite_Character_C" + ], + [ + "Araneo", + "SpiderS_Character_BP_C", + "Spider" + ], + [ + "Arthropluera", + "Arthro_Character_BP_C" + ], + [ + "Cnidaria", + "Cnidaria_Character_BP_C", + "Jellyfish" + ], + [ + "Diseased Leech", + "Leech_Character_Diseased_C" + ], + [ + "Dung Beetle", + "DungBeetle_Character_BP_C" + ], + [ + "Eurypterid", + "Euryp_Character_C", + "Sea Scorpion" + ], + [ + "Giant Bee Drone", + "Bee_Character_BP_C" + ], + [ + "Giant Bee Queen", + "Bee_Queen_Character_BP_C" + ], + [ + "Leech", + "Leech_Character_C" + ], + [ + "Skeletal Rex", + "Bone_MegaRex_Character_BP_C", + "Skele Rex" + ], + [ + "Meganeura", + "Dragonfly_Character_BP_C", + "Dragonfly" + ], + [ + "Pulminoscorpius", + "Scorpion_Character_BP_C", + "Scorpion" + ], + [ + "Titanomyrma", + "Ant_Character_BP_C", + "Ant" + ], + [ + "Titanomyrma (Flying)", + "FlyingAnt_Character_BP_C", + "Flying Ant" + ], + [ + "Trilobyte", + "Trilobite_Character_C" + ], + [ + "Tusoteuthis", + "Tusoteuthis_Character_BP_C", + "Squid" + ], + [ + "Tusoteuthis (Cave)", + "Tusoteuthis_Character_BP_Caves_C", + "Squid (Cave)" + ], + [ + "Basilosaurus", + "Basilosaurus_Character_BP_C", + "Basilo" + ], + [ + "Castroides", + "Beaver_Character_BP_C", + "Giant Beaver" + ], + [ + "Chalicotherium", + "Chalico_Character_BP_C", + "Chalico" + ], + [ + "Daeodon", + "Daeodon_Character_BP_C" + ], + [ + "Direbear", + "Direbear_Character_BP_C" + ], + [ + "Direwolf", + "Direwolf_Character_BP_C" + ], + [ + "Doedicurus", + "Doed_Character_BP_C", + "Doedic" + ], + [ + "Equus", + "Equus_Character_BP_C", + "Horse" + ], + [ + "Gigantopithecus", + "BigFoot_Character_BP_C", + "Bigfoot" + ], + [ + "Hyaenodon", + "Hyaenodon_Character_BP_C" + ], + [ + "Mammoth", + "Mammoth_Character_BP_C" + ], + [ + "Megaloceros", + "Stag_Character_BP_C", + "Deer" + ], + [ + "Megatherium", + "Megatherium_Character_BP_C", + "Sloth" + ], + [ + "Mesopithecus", + "Monkey_Character_BP_C", + "Monkey" + ], + [ + "Onychonycteris", + "Bat_Character_BP_C", + "Onyc", + "Bat" + ], + [ + "Otter", + "Otter_Character_BP_C" + ], + [ + "Ovis", + "Sheep_Character_BP_C", + "Sheep" + ], + [ + "Paracer", + "Paracer_Character_BP_C" + ], + [ + "Phiomia", + "Phiomia_Character_BP_C" + ], + [ + "Polar Bear (Island)", + "Direbear_Character_Polar_C" + ], + [ + "Procoptodon", + "Procoptodon_Character_BP_C", + "Kangaroo" + ], + [ + "Purlovia", + "Purlovia_Character_BP_C" + ], + [ + "Purlovia (Polar)", + "Purlovia_Character_BP_Polar_C" + ], + [ + "Sabertooth", + "Saber_Character_BP_C" + ], + [ + "Thylacoleo", + "Thylacoleo_Character_BP_C", + "Thyla" + ], + [ + "Wooly Rhino", + "Rhino_Character_BP_C" + ], + [ + "Beelzebufo", + "Toad_Character_BP_C", + "Frog" + ], + [ + "Carbonemys", + "Turtle_Character_BP_C", + "Turtle" + ], + [ + "Dimetrodon", + "Dimetro_Character_BP_C" + ], + [ + "Diplocaulus", + "Diplocaulus_Character_BP_C" + ], + [ + "Ichthyosaurus", + "Dolphin_Character_BP_C" + ], + [ + "Kaprosuchus", + "Kaprosuchus_Character_BP_C" + ], + [ + "Liopleurodon", + "Liopleurodon_Character_BP_C" + ], + [ + "Lystrosaurus", + "Lystro_Character_BP_C", + "Lystro" + ], + [ + "Mosasaurus (Cave)", + "Mosa_Character_BP_Cave_C", + "Mosa (Cave)" + ], + [ + "Mosasaurus", + "Mosa_Character_BP_C", + "Mosa" + ], + [ + "Moschops", + "Moschops_Character_BP_C" + ], + [ + "Pegomastax", + "Pegomastax_Character_BP_C", + "Pego" ], [ - "Megapithecus", - "Gorilla_Character_BP_C" + "Plesiosaur", + "Plesiosaur_Character_BP_C", + "Plesio" ], [ - "Megatherium", - "Megatherium_Character_BP_C" + "Pteranodon", + "Ptero_Character_BP_C", + "Ptera" ], [ - "Mesopithecus", - "Monkey_Character_BP_C", - "Monkey" + "Quetzalcoatlus", + "Quetz_Character_BP_C", + "Quetz" ], [ - "Microraptor", - "Microraptor_Character_BP_C" + "Sarcosuchus", + "Sarco_Character_BP_C", + "Sarco" ], [ - "Morellatops", - "camelsaurus_Character_BP_C", - "Camelsaurus" + "Tapejara", + "Tapejara_Character_BP_C" ], [ - "Mosasaurus", - "Mosa_Character_BP_C", - "Mosa" + "Titanoboa", + "BoaFrill_Character_BP_C" ], [ - "Moschops", - "Moschops_Character_BP_C" + "Tek ATV", + "VH_Buggy_C" ], [ - "Motorboat", - "MotorRaft_BP_C" + "Dragon (Alpha) (Ragnarok)", + "Dragon_Character_BP_Boss_Hard_Ragnarok_C" ], [ - "Onyc", - "Bat_Character_BP_C", - "Bat" + "Dragon (Beta) (Ragnarok)", + "Dragon_Character_BP_Boss_Medium_Ragnarok_C" ], [ - "Otter", - "Otter_Character_BP_C" + "Dragon (Gamma) (Ragnarok)", + "Dragon_Character_BP_Boss_Easy_Ragnarok_C" ], [ - "Oviraptor", - "Oviraptor_Character_BP_C" + "Griffin (Boss Minion)", + "Griffin_Character_Minion_BP_C" ], [ - "Ovis", - "Sheep_Character_BP_C", - "Sheep" + "Ice Worm Queen", + "Iceworm_Queen_Character_BP_C" ], [ - "Pachycephalosaurus", - "Pachy_Character_BP_C", - "Pachy" + "Lava Elemental", + "LavaGolem_Character_BP_C" ], [ - "Pachyrhinosaurus", - "Pachyrhino_Character_BP_C", - "Pachyrhino" + "Manticore (Alpha) (Ragnarok)", + "Manticore_Character_BP_Hard_Ragnarok_C" ], [ - "Paracer", - "Paracer_Character_BP_C", - "Paraceratherium" + "Manticore (Beta) (Ragnarok)", + "Manticore_Character_BP_Medium_Ragnarok_C" ], [ - "Parasaur", - "Para_Character_BP_C", - "Para" + "Manticore (Gamma) (Ragnarok)", + "Manticore_Character_BP_Easy_Ragnarok_C" ], [ - "Pegomastax", - "Pegomastax_Character_BP_C", - "Pego", - "Thief" + "Direbear (Lifes Labyrinth)", + "Direbear_LL_Character_BP_C" ], [ - "Pelagornis", - "Pela_Character_BP_C", - "Pela", - "Stork", - "Pelican" + "Direwolf (Lifes Labyrinth)", + "Direwolf_LL_Character_BP_C" ], [ - "Phiomia", - "Phiomia_Character_BP_C", - "Pig" + "Griffin", + "Griffin_Character_BP_C" ], [ - "Phoenix", - "Phoenix_Character_BP_C", - "Firebird" + "Iceworm Male", + "Iceworm_Character_Minion_BP_smaller_C" ], [ - "Polar Bear", - "Polar_Bear_C" + "Megaloceros (Lifes Labyrinth)", + "Stag_LL_Character_BP_C", + "Deer (Lifes Labyrinth)" ], [ - "Piranha", - "Piranha_Character_BP_C", - "Megapiranha" + "Fire Wyvern (Ragnarok)", + "Ragnarok_Wyvern_Override_C" ], [ - "Plesiosaur", - "Plesiosaur_Character_BP_C", - "Plesi" + "Ice Wyvern", + "Ragnarok_Wyvern_Override_Ice_C" ], [ - "Procoptodon", - "Procoptodon_Character_BP_C" + "Dire Polar Bear (Ragnarok)", + "Polar_Bear_C" ], [ - "Pteranodon", - "Ptero_Character_BP_C", - "Ptero", - "Ptera" + "Alpha Deathworm", + "MegaDeathworm_Character_BP_C" ], [ - "Pulmonoscorpius", - "Scorpion_Character_BP_C", - "Scorpion", - "Scorpius", - "Pulmono", - "Scorp", - "Pulminoscorpius" + "Alpha Wyvern", + "MegaWyvern_Character_BP_Fire_C" ], [ - "Purlovia", - "Purlovia_Character_BP_C" + "Wyvern (Base)", + "Wyvern_Character_BP_Base_C" ], [ - "Purlovia Polar", - "Purlovia_Character_BP_Polar_C" + "Zombie Wyvern (Base)", + "Wyvern_Character_BP_ZombieBase" ], [ - "Quetzalcoatl", - "Quetz_Character_BP_C", - "Quetzal", - "Quetz" + "Vulture", + "Vulture_Character_BP_C" ], [ - "Raft", - "Raft_BP_C" + "Deathworm (Boss Minion)", + "Deathworm_Character_Minion_BP_C" ], [ - "Raptor", - "Raptor_Character_BP_C" + "Manticore (Alpha)", + "Manticore_Character_BP_Hard_C" ], [ - "Tyrannosaurus", - "Rex_Character_BP_C", - "Rex" + "Manticore (Beta)", + "Manticore_Character_BP_Medium_C" ], [ - "Rock Elemental", - "RockGolem_Character_BP_C", - "Rock Golem", - "Golem" + "Manticore (Gamma)", + "Manticore_Character_BP_Easy_C" ], [ - "Rubble Golem", - "RubbleGolem_Character_BP_C" + "Manticore (Base)", + "Manticore_Character_BP_C" ], [ - "Lava Elemental", - "LavaGolem_Character_BP_C", - "Lava Golem" + "Rock Golem (Boss Minion)", + "RockGolem_Character_Minion_BP_C" ], [ - "Sabertooth", - "Saber_Character_BP_C", - "Saber" + "Morellatops", + "Camelsaurus_Character_BP_C" ], [ - "Sabertooth Salmon", - "Salmon_Character_BP_C", - "Salmon" + "Zombie Wyvern (Fire)", + "Wyvern_Character_BP_ZombieFire_c" + ], [ - "Sarcosuchus", - "Sarco_Character_BP_C", - "Sarco", - "Crocodile" + "Zombie Wyvern (Lightning)", + "Wyvern_Character_BP_ZombieLightning_c" ], [ - "Skeletal Bronto", - "Bone_Sauropod_Character_BP_C", - "Skele Bronto" + "Zombie Wyvern (Poison)", + "Wyvern_Character_BP_ZombiePoison_C" ], [ - "Skeletal Carnotaurus", - "Bone_MegaCarno_Character_BP_C", - "Skele Carno" + "Deathworm", + "Deathworm_Character_BP_C" ], [ - "Skeletal Giganotosaurus", - "Bone_Gigant_Character_BP_C", - "Skele Giga" + "Phoenix", + "Phoenix_Character_BP_C" ], [ - "Skeletal Jerboa", - "Bone_Jerboa_Character_BP_C", - "Skele Jerboa" + "Rock Golem", + "RockGolem_Character_BP_C" ], [ - "Skeletal Quetzal", - "Bone_Quetz_Character_BP_C", - "Skeletal Quetz", - "Skele Quetzal", - "Skele Quetz" + "Rubble Golem", + "RubbleGolem_Character_BP_C" ], [ - "Skeletal Raptor", - "Bone_MegaRaptor_Character_BP_C", - "Skele Raptor" + "Fire Wyvern", + "Wyvern_Character_BP_Fire_C" ], [ - "Skeletal Rex", - "Bone_MegaRex_Character_BP_C", - "Skele Rex" + "Lightning Wyvern", + "Wyvern_Character_BP_Lightning_C" ], [ - "Skeletal Stego", - "Bone_Stego_Character_BP_C", - "Skele Stego" + "Poison Wyvern", + "Wyvern_Character_BP_Poison_C" ], [ - "Skeletal Trike", - "Bone_Trike_Character_BP_C", - "Skele Trike" + "Jugbug", + "JugBug_Character_BaseBP_C" ], [ - "Spinosaur", - "Spino_Character_BP_C", - "Spinosaurus", - "Spino" + "Jugbug (Oil)", + "Jugbug_Oil_Character_BP_C" ], [ - "Stegosaurus", - "Stego_Character_BP_C", - "Stego" + "Jugbug (Water)", + "Jugbug_Water_Character_BP_C" ], [ - "Tapejara", - "Tapejara_Character_BP_C" + "Lymantria", + "Moth_Character_BP_C", + "Moth" ], [ - "Terror Bird", - "TerrorBird_Character_BP_C", - "Terrorbird" + "Mantis", + "Mantis_Character_BP_C" ], [ - "Therizinosaur", - "Therizino_Character_BP_C", - "Therizinosaurus", - "Therizino", - "Theriz" + "Jerboa", + "Jerboa_Character_BP_C" ], [ "Thorny Dragon", - "SpineyLizard_Character_BP_C", - "Spiney Lizard" + "SpineyLizard_Character_BP_C" ], [ - "Thylacoleo", - "Thylacoleo_Character_BP_C", - "Thyla" + "Tek Stegosaurus", + "BionicStego_Character_BP_C", + "Tek Stego" ], [ - "Titanoboa", - "BoaFrill_Character_BP_C", - "Boa", - "Snake" + "Tek Raptor", + "BionicRaptor_Character_BP_C" ], [ - "Flying Titanomyrma", - "FlyingAnt_Character_BP_C", - "Flying Giant Ant", - "Flying Ant" + "Giant Worker Bee", + "HoneyBee_Character_BP_C" ], [ - "Titanomyrma", - "Ant_Character_BP_C", - "Giant Ant", - "Ant" + "Zombie Wyvern (Base) (Crystal Isles)", + "ZombieWyvern_Character_BP_Base_C" ], [ - "Titanosaur", - "Titanosaur_Character_BP", - "Titan" + "Zombie Wyvern (Base Zombie) (Crystal Isles)", + "ZombieWyvern_Character_BP_BaseZombie_C" ], [ - "Triceratops", - "Trike_Character_BP_C", - "Trike" + "Zombie Wyvern (Fire) (Crystal Isles)", + "ZombieWyvern_Character_BP_Fire_C" ], [ - "Trilobite", - "Trilobite_Character_C" + "Zombie Wyvern (Lightning) (Crystal Isles)", + "ZombieWyvern_Character_BP_Lightning_C" ], [ - "Troodon", - "Troodon_Character_BP_C" + "Zombie Wyvern (Poison) (Crystal Isles)", + "ZombieWyvern_Character_BP_Poison_C" ], [ - "Turkey", - "Turkey_Character_BP_C" + "Tusoteuthis (Tiny)", + "TinyTuso_Character_BP_C", + "Tuso (Tiny)" ], [ - "Tusoteuthis", - "Tusoteuthis_Character_BP_C", - "Giant Squid", - "Squid" + "Liquefied Brontosaurus", + "LiquefiedBronto_Sauropod_Character_BP_C", + "Liquefied Bronto" ], [ - "Vulture", - "Vulture_Character_BP_C" + "Liquefied Giganotosaurus", + "Liquefied_Gigant_Character_BP_C", + "Liquefied Giga" ], [ - "Woolly Rhino", - "Rhino_Character_BP_C", - "Woolly Rhinoceros", - "Rhino" + "Liquefied Jerboa", + "LiquefiedJerboa_Character_BP_C" ], [ - "Fire Wyvern", - "Wyvern_Character_BP_Fire_C" + "Liquefied Quetzalcoatlus", + "LiquefiedQuetz_Character_BP_C", + "Liquefied Quetz" ], [ - "Lightning Wyvern", - "Wyvern_Character_BP_Lightning_C" + "Liquefied Raptor", + "LiquefiedRaptor_Character_BP_C" ], [ - "Poison Wyvern", - "Wyvern_Character_BP_Poison_C" + "Liquefied Rex", + "LiquefiedRex_Character_BP_C" ], [ - "Ice Wyvern", - "Ragnarok_Wyvern_Override_Ice_C" + "Liquefied Stegosaurus", + "LiquefiedStego_Character_BP_C", + "Liquefied Stego" ], [ - "Yeti", - "Yeti_Character_BP_C" + "Liquefied Triceratops", + "LiquefiedTrike_Character_BP_C", + "Liquefied Trike" ], [ - "Yutyrannus", - "Yutyrannus_Character_BP_C" + "Liquefied Wyvern", + "LiquefiedWyvern_Character_BP_C" ], [ - "Zombie Fire Wyvern", - "Wyvern_Character_BP_ZombieFire_C" + "Alpha Liquefied Wyvern", + "LiquefiedMegaWyvern_Character_BP_C" ], [ - "Zombie Lightning Wyvern", - "Wyvern_Character_BP_ZombieLightning_C" + "Grand Embertross", + "GrandEmbertross_Character_BP_C" ], [ - "Zombie Poison Wyvern", - "Wyvern_Character_BP_ZombiePoison_C" + "Crystal Griffin", + "CrystalGriffin_Character_BP_C" ], [ - "Zomdodo", - "ZombieDodo_Character_BP_C", - "Zombie Dodo", - "Zombiedodo" + "Blood Crystal Wyvern", + "CrystalWyvern_Character_BP_Blood_C" ], [ - "Aberrant Achatina", - "Achatina_Character_BP_Aberrant_C", - "Aberrant Snail", - "Aberrant Acha" + "Ember Crystal Wyvern", + "CrystalWyvern_Character_BP_Ember_C" ], [ - "Aberrant Angler", - "Angler_Character_BP_Aberrant_C", - "Aberrant Anglerfish" + "Tropical Crystal Wyvern", + "CrystalWyvern_Character_BP_WS_C" ], [ - "Aberrant Ankylosaurus", - "Ankylo_Character_BP_Aberrant_C", - "Aberrant Ankylo", - "Aberrant Anky" + "Alpha Fire Wyvern (Crystal Isles)", + "MegaCrystalWyvern_Character_BP_C" ], [ - "Aberrant Arthropluera", - "Arthro_Character_BP_Aberrant_C", - "Aberrant Arthro", - "Aberrant Centipede" + "Crystal Wyvern (Base)", + "CrystalWyvern_Character_BP_Base_C" ], [ - "Aberrant Baryonyx", - "Baryonyx_Character_BP_Aberrant_C", - "Aberrant Bary" + "Female Argentavis", + "Female_Argent_Character_BP_C" ], [ - "Basilisk", - "Basilisk_Character_BP_C" + "Baby Ankylosaurus", + "Ankylo_Character_BP_Child_C", + "Baby Anky" ], [ - "Aberrant Titanoboa", - "BoaFrill_Character_BP_Aberrant_C", - "Aberrant Boa", - "Aberrant Snake" + "Alpha Ovis", + "AlphaSheep_Character_BP_C", + "Alpha Sheep" ], [ - "Aberrant Carnotaurus", - "Carno_Character_BP_Aberrant_C", - "Aberrant Carno" + "Baby Allosaurus", + "Allo_Character_BP_Child_C", + "Baby Allo" ], [ - "Ravager", - "CaveWolf_Character_BP_C", - "Cave Wolf" + "Baby Carbonemys", + "Turtle_Character_BP_Child_C", + "Baby Turtle" ], [ - "Nameless", - "ChupaCabra_Character_BP_C", - "Chupa Cabra" + "Baby Triceratops", + "Trike_Character_BP_Child_C", + "Baby Trike" ], [ - "Nameless Surface", - "ChupaCabra_Character_BP_Surface_C", - "Chupa Cabra Surface" + "Baby Thylacoleo", + "Thylacoleo_Character_BP_Child_C" ], [ - "Aberrant Cnidaria", - "Cnidaria_Character_BP_Aberrant_C" + "Baby Therizinosaurus", + "Therizino_Character_BP_Child_C", + "Baby Therizino" ], [ - "Aberrant Coelacanth", - "Coel_Character_BP_Aberrant_C", - "Aberrant Coel" + "Baby Terror Bird", + "TerrorBird_Character_BP_Child_C" ], [ - "Karkinos", - "Crab_Character_BP_C", - "Crab" + "Baby Tapejara", + "Tapejara_Character_BP_Child_C" ], [ - "Aberrant Dimetrodon", - "Dimetro_Character_BP_Aberrant_C", - "Aberrant Dimetro" + "Baby Stegosaurus", + "Stego_Character_BP_Child_C", + "Baby Stego" ], [ - "Aberrant Diplocaulus", - "Diplocaulus_Character_BP_Aberrant_C", - "Aberrant Newt" + "Baby Megaloceros", + "Stag_Character_BP_Child_C", + "Baby Deer" ], [ - "Aberrant Diplodocus", - "Diplodocus_Character_BP_Aberrant_C" + "Baby Thorny Dragon", + "SpineyLizard_Character_BP_Child_C" ], [ - "Aberrant Dodo", - "Dodo_Character_BP_Aberrant_C", - "Aberrant Chicken" + "Snow Rock Golem", + "SnowRockGolem_Character_BP_C" ], [ - "Aberrant Doedicurus", - "Doed_Character_BP_Aberrant_C", - "Aberrant Doed" + "Baby Brontosaurus", + "Sauropod_Character_BP_Child_C", + "Baby Bronto" ], [ - "Aberrant Dragonfly", - "Dragonfly_Character_BP_Aberrant_C" + "Baby Sarcosuchus", + "Sarco_Character_BP_Child_C", + "Baby Sarco" ], [ - "Aberrant Dung Beetle", - "DungBeetle_Character_BP_Aberrant_C", - "Aberrant Beetle" + "Baby Sabertooth", + "Saber_Character_BP_Child_C" ], [ - "Aberrant Electrophorus", - "Eel_Character_BP_Aberrant_C", - "Aberrant Eel", - "Aberrant Electro" + "Baby Wooly Rhino", + "Rhino_Character_BP_Child_C" ], [ - "Aberrant Equus", - "Equus_Character_BP_Aberrant_C", - "Aberrant Horse" + "Baby Rex", + "Rex_Character_BP_Child_C" ], [ - "Aberrant Iguanodon", - "Iguanodon_Character_BP_Aberrant_C", - "Aberrant Iguan" + "Redwood Rock Golem", + "RedwoodRockGolem_Character_BP_C" ], [ - "Lamprey", - "Lamprey_Character_C" + "Baby Raptor", + "Raptor_Character_BP_Child_C" ], [ - "Featherlight", - "LanternBird_Character_BP_C", - "Lantern Bird" + "Baby Purlovia", + "Purlovia_Character_BP_Child_C" ], [ - "Shinehorn", - "LanternGoat_Character_BP_C", - "Lantern Goat" + "Baby Pteranodon", + "Ptero_Character_BP_Child_C" ], [ - "Glowtail", - "LanternLizard_Character_BP_C", - "Lantern Lizard" + "Baby Procoptodon", + "Procoptodon_Character_BP_Child_C", + "Baby Kangaroo" ], [ - "Bulbdog", - "LanternPug_Character_BP_C", - "Lantern Pug" + "Baby Plesiosaur", + "Plesiosaur_Character_BP_Child_C", + "Baby Plesio" ], [ - "Glowbug", - "Lightbug_Character_BaseBP_C", - "Lightbug" + "Baby Phiomia", + "Phiomia_Character_BP_Child_C" ], [ - "Aberrant Lystrosaurus", - "Lystro_Character_BP_Aberrant_C", - "Aberrant Lystro" + "Baby Pegomastax", + "Pegomastax_Character_BP_Child_C", + "Baby Pego" ], [ - "Aberrant Manta", - "Manta_Character_BP_Aberrant_C" + "Baby Parasaurolophus", + "Para_Character_BP_Child_C", + "Baby Parasaur" ], [ - "Alpha Basilisk", - "MegaBasilisk_Character_BP_C" + "Baby Paracer", + "Paracer_Character_BP_Child_C" ], [ - "Alpha Karkinos", - "MegaCrab_Character_BP_C", - "Mega Crab" + "Baby Pachycephalosaurus", + "Pachy_Character_BP_Child_C", + "Baby Pachy" ], [ - "Aberrant Megalosaurus", - "Megalosaurus_Character_BP_Aberrant_C", - "Aberrant Megalos", - "Aberrant Sleeping Raptor" + "Baby Pachyrhinosaurus", + "Pachyrhino_Character_BP_Child_C", + "Baby Pachyrhino" ], [ - "Alpha Surface Reaper King", - "MegaXenomorph_Character_BP_Male_Surface_C", - "Mega Xenomorph Male" + "Baby Oviraptor", + "Oviraptor_Character_BP_Child_C" ], [ - "Roll Rat", - "MoleRat_Character_BP_C", - "Mole Rat" + "Baby Moschops", + "Moschops_Character_BP_Child_C" ], [ - "Aberrant Moschops", - "Moschops_Character_BP_Aberrant_C" + "Baby Mosasaurus", + "Mosa_Character_BP_Child_C", + "Baby Mosa" ], [ - "Aberrant Otter", - "Otter_Character_BP_Aberrant_C" + "Baby Mesopithecus", + "Monkey_Character_BP_Child_C", + "Baby Monkey" ], [ - "Aberrant Parasaur", - "Para_Character_BP_Aberrant_C", - "Aberrant Para" + "Baby Megalodon", + "Megalodon_Character_BP_Child_C" ], [ - "Aberrant Paracer", - "Paracer_Character_BP_Aberrant_C", - "Aberrant Paraceratherium" + "Baby Manta", + "Manta_Character_BP_Child_C" ], [ - "Aberrant Piranha", - "Piranha_Character_BP_Aberrant_C", - "Aberrant Megapiranha" + "Baby Mammoth", + "Mammoth_Character_BP_Child_C" ], [ - "Seeker", - "Pteroteuthis_Char_BP_C", - "Pteroteuthis" + "Baby Lystrosaurus", + "Lystro_Character_BP_Child_C", + "Baby Lystro" ], [ - "Seeker Surface", - "Pteroteuthis_Char_BP_Surface_C", - "Pteroteuthis Surface" + "Lava Rock Golem", + "LavaRockGolem_Character_BP_C" ], [ - "Aberrant Purlovia", - "Purlovia_Character_BP_Aberrant_C" + "Baby Kentrosaurus", + "Kentro_Character_BP_Child_C", + "Baby Kentro" ], [ - "Aberrant Raptor", - "Raptor_Character_BP_Aberrant_C" + "Baby Kaprosuchus", + "Kaprosuchus_Character_BP_Child_C", + "Baby Kapro" ], [ - "Rock Drake", - "RockDrake_Character_BP_C" + "Jungle Rock Golem", + "JungleRockGolem_Character_BP_C" ], [ - "Aberrant Sabertooth Salmon", - "Salmon_Character_Aberrant_C", - "Aberrant Salmon" + "Baby Iguanodon", + "Iguanodon_Character_BP_Child_C" ], [ - "Aberrant Sarcosuchus", - "Sarco_Character_BP_Aberrant_C", - "Aberrant Sarco", - "Aberrant Crocodile" + "Baby Ichthyornis", + "Ichthyornis_Character_BP_Child_C", + "Baby Seagull" ], [ - "Aberrant Pulmonoscorpius", - "Scorpion_Character_BP_Aberrant_C", - "Aberrant Scorpion", - "Aberrant Scorpius", - "Aberrant Pulmono", - "Aberrant Scorp", - "Aberrant Pulminoscorpius" + "Ice Wyvern (The Volcano)", + "Wyvern_Character_BP_Ice_C" ], [ - "Aberrant Ovis", - "Sheep_Character_BP_Aberrant_C", - "Aberrant Sheep" + "Baby Gallimimus", + "Galli_Character_BP_Child_C", + "Baby Galli" ], [ - "Aberrant Spinosaur", - "Spino_Character_BP_Aberrant_C", - "Aberrant Spinosaurus", - "Aberrant Spino" + "Baby Equus", + "Equus_Character_BP_Child_C", + "Baby Horse" ], [ - "Aberrant Stegosaurus", - "Stego_Character_BP_Aberrant_C", - "Aberrant Stego" + "Baby Ichthyosaurus", + "Dolphin_Character_BP_Child_C", + "Baby Dolphin" ], [ - "Aberrant Beelzebufo", - "Toad_Character_BP_Aberrant_C", - "Aberrant Toad" + "Baby Doedicurus", + "Doed_Character_BP_Child_C", + "Baby Doed" ], [ - "Aberrant Triceratops", - "Trike_Character_BP_Aberrant_C", - "Aberrant Trike" + "Baby Dodo", + "Dodo_Character_BP_Child_C" ], [ - "Aberrant Trilobite", - "Trilobite_Character_Aberrant_C" + "Baby Direwolf", + "Direwolf_Character_BP_Child_C" ], [ - "Aberrant Carbonemys", - "Turtle_Character_BP_Aberrant_C", - "Aberrant Turtle" + "Baby Direbear", + "Direbear_Character_BP_Child_C" ], [ - "Reaper Queen", - "Xenomorph_Character_BP_Female_C", - "Xenomorph Female" + "Baby Diplodocus", + "Diplodocus_Character_BP_Child_C", + "Baby Diplo" ], [ - "Reaper King", - "Xenomorph_Character_BP_Male_Tamed_C", - "Xenomorph Male" + "Baby Dilophosaurus", + "Dilo_Character_BP_Child_C", + "Baby Dilo" ], [ - "Reaper King (Wild)", - "Xenomorph_Character_BP_Male_C", - "Xenomorph Male (Wild)" + "Desert Rock Golem", + "DesertRockGolem_Character_BP_C" ], [ - "Surface Reaper King", - "Xenomorph_Character_BP_Male_Surface_C", - "Xenomorph Male Surface" + "Baby Daeodon", + "Daeodon_Character_BP_Child_C" ], [ - "Elemental Reaper King", - "Xenomorph_Character_BP_Male_Minion_C" + "Baby Compsognathus", + "Compy_Character_BP_Child_C", + "Baby Compy" ], [ - "Subterranean Reaper King", - "Xenomorph_Character_BP_Male_Chupa_C" + "Baby Chalicotherium", + "Chalico_Character_BP_Child_C", + "Baby Chalico" ], [ - "Reaper", - "Xenomorph_Character_BP_C" + "Baby Carnotaurus", + "Carno_Character_BP_Child_C", + "Baby Carno" ], [ - "Reaper King", - "Xenomorph_Character_BP_Male_Tamed_C" + "Baby Morallatops", + "camelsaurus_Character_BP_Child_C" ], [ - "Rockwell", - "Rockwell_Character_BP_C" + "Baby Basilosaurus", + "Basilosaurus_Character_BP_Child_C" ], [ - "Aberrant Gigantopithecus", - "Bigfoot_Character_BP_Aberrant_C" + "Baby Baryonyx", + "Baryonyx_Character_BP_Child_C" ], [ - "Aberrant Direbear", - "Direbear_Character_BP_Aberrant_C", - "Aberrant Dire Bear", - "Aberrant Bear" + "Baby Argentavis", + "Argent_Character_BP_Child_C" ] ] -} +} \ No newline at end of file From ac80495c8f09f76f6e1beb3de2b7f8a0c6c10e6a Mon Sep 17 00:00:00 2001 From: Lewimaron Date: Sun, 26 Aug 2018 12:38:38 +0100 Subject: [PATCH 12/15] Added S+ and Jamon Stacks Support Added support for S+ Crop plots and generators aswell as support for my stackmod. --- ArkBot/WebApi/Controllers/PlayerController.cs | 2 +- ArkBot/WebApi/Model/CropPlotViewModel.cs | 24 ++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/ArkBot/WebApi/Controllers/PlayerController.cs b/ArkBot/WebApi/Controllers/PlayerController.cs index b26d36a..5bdbb04 100644 --- a/ArkBot/WebApi/Controllers/PlayerController.cs +++ b/ArkBot/WebApi/Controllers/PlayerController.cs @@ -434,7 +434,7 @@ internal static List BuildElectricalGeneratorViewM return new ElectricalGeneratorViewModel(x.Location) { Activated = x.Activated, - //FuelTime = x.FuelTime, + //FuelTime = x.FuelTime, PrimalItemResource_Gasoline_C , PrimalItemResource_Gasoline_JStacks_C GasolineQuantity = (int)(x.Inventory?.Where(y => y.ClassName.Equals("PrimalItemResource_Gasoline_C", StringComparison.Ordinal)).Sum(y => y.Quantity) ?? 0) }; }).OrderBy(x => x.Latitude).ThenBy(x => x.Longitude).ToList(); diff --git a/ArkBot/WebApi/Model/CropPlotViewModel.cs b/ArkBot/WebApi/Model/CropPlotViewModel.cs index fef94aa..81a50b5 100644 --- a/ArkBot/WebApi/Model/CropPlotViewModel.cs +++ b/ArkBot/WebApi/Model/CropPlotViewModel.cs @@ -21,14 +21,32 @@ public class CropPlotViewModel : StructureBase { "PrimalItemConsumable_Seed_Tintoberry_C", "Tintoberry" }, { "PrimalItemConsumable_Seed_Mejoberry_C", "Mejoberry" }, { "PrimalItemConsumable_Seed_Stimberry_C", "Stimberry" }, - { "PrimalItemConsumable_Seed_Narcoberry_C", "Narcoberry" } + { "PrimalItemConsumable_Seed_Narcoberry_C", "Narcoberry" }, + { "PrimalItemConsumable_Seed_PlantSpeciesZ_C", "Plant Species Z" }, + { "PrimalItemConsumable_Seed_Amarberry_JStacks_C", "Amarberry" }, + { "PrimalItemConsumable_Seed_Azulberry_JStacks_C", "Azulberry" }, + { "PrimalItemConsumable_Seed_Citronal_JStacks_C", "Citronal" }, + { "PrimalItemConsumable_Seed_DefensePlant_JStacks_C", "Plant Species X" }, + { "PrimalItemConsumable_Seed_Longrass_JStacks_C", "Longrass" }, + { "PrimalItemConsumable_Seed_Mejoberry_JStacks_C", "Mejoberry" }, + { "PrimalItemConsumable_Seed_Narcoberry_JStacks_C", "Narcoberry" }, + { "PrimalItemConsumable_Seed_Rockarrot_JStacks_C", "Rockarrot" }, + { "PrimalItemConsumable_Seed_Savoroot_JStacks_C", "Savoroot" }, + { "PrimalItemConsumable_Seed_Stimberry_JStacks_C", "Stimberry" }, + { "PrimalItemConsumable_Seed_Tintoberry_JStacks_C", "Tintoberry" }, + { "PrimalItemConsumable_Seed_PlantSpeciesY_JStacks_C", "Plant Species Y" }, + { "PrimalItemConsumable_Seed_PlantSpeciesZ_JStacks_C", "Plant Species Z" } + }; static readonly private Dictionary _sizes = new Dictionary { { "CropPlotSmall_SM_C", "Small" }, { "CropPlotMedium_SM_C", "Medium" }, - { "CropPlotLarge_SM_C", "Large" } + { "CropPlotLarge_SM_C", "Large" }, + { "BP_CropPlot_Small_C", "Small" }, + { "BP_CropPlot_Medium_C", "Medium" }, + { "BP_CropPlot_Large_C", "Large" } }; public CropPlotViewModel(ArkSavegameToolkitNet.Domain.ArkLocation location) : base(location) @@ -38,7 +56,7 @@ public CropPlotViewModel(ArkSavegameToolkitNet.Domain.ArkLocation location) : ba public string ClassName { get; set; } //public float FertilizerAmount { get; set; } public int FertilizerQuantity { get; set; } - public int FertilizerMax => 54000 * 10; + public int FertilizerMax => 54000 * 30; public float WaterAmount { get; set; } public string PlantedCropClassName { get; set; } public string PlantedCropName From 166028f935f340a8094add6fa17d45bccf4614f2 Mon Sep 17 00:00:00 2001 From: jefferson-1 Date: Thu, 13 Sep 2018 07:44:59 -0500 Subject: [PATCH 13/15] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3528e8f..e949194 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Project status #### Development -This project is not currently being actively developed. It is still minimally maintained by me as the primary developer of the project. There are currently no other developers contributing code to the project. +This project is not currently being actively developed. It is still minimally maintained by me as the primary developer of the project. Jefferson-1 has taken over maintenance of the project with Tsebring's permission. Contributors are welcome. The active development branch is currently [beta](https://github.com/tsebring/ArkBot/tree/beta). From 4ceb13b6629680a9606eb4b11d7876b99a4de496 Mon Sep 17 00:00:00 2001 From: jefferson-1 Date: Thu, 13 Sep 2018 07:49:24 -0500 Subject: [PATCH 14/15] Version.txt Version Indicator --- Version.txt | 1 + 1 file changed, 1 insertion(+) create mode 100644 Version.txt diff --git a/Version.txt b/Version.txt new file mode 100644 index 0000000..1cfb741 --- /dev/null +++ b/Version.txt @@ -0,0 +1 @@ +This is Version 1.83 From c7dda51ee74cb5a81241476645836f7dcc457168 Mon Sep 17 00:00:00 2001 From: jefferson-1 Date: Thu, 13 Sep 2018 08:03:43 -0500 Subject: [PATCH 15/15] Update aliases.json --- ArkBot/aliases.json | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ArkBot/aliases.json b/ArkBot/aliases.json index 3bab86c..c7e23e1 100644 --- a/ArkBot/aliases.json +++ b/ArkBot/aliases.json @@ -1724,6 +1724,14 @@ "Carno_Character_BP_Child_C", "Baby Carno" ], + [ + "Baby Morallatops", + "camelsaurus_Character_BP_Child_C" + ], + [ + "Baby Basilosaurus", + "Basilosaurus_Character_BP_Child_C" + ], [ "Baby Baryonyx", "Baryonyx_Character_BP_Child_C" @@ -1733,4 +1741,4 @@ "Argent_Character_BP_Child_C" ] ] -} \ No newline at end of file +}