package dev.crucifixbeta.core.impl;

import dev.crucifixbeta.CrucifixBeta;
import dev.crucifixbeta.api.events.impl.Render2DEvent;
import dev.crucifixbeta.api.events.impl.Render3DEvent;
import dev.crucifixbeta.api.utils.Wrapper;
import dev.crucifixbeta.api.utils.path.BaritoneUtil;
import dev.crucifixbeta.api.utils.render.Render2DUtil;
import dev.crucifixbeta.api.utils.render.TextUtil;
import dev.crucifixbeta.mod.Mod;
import dev.crucifixbeta.mod.gui.clickgui.ClickGuiScreen;
import dev.crucifixbeta.mod.modules.HudModule;
import dev.crucifixbeta.mod.modules.Module;
import dev.crucifixbeta.mod.modules.impl.client.AntiCheat;
import dev.crucifixbeta.mod.modules.impl.client.BaritoneModule;
import dev.crucifixbeta.mod.modules.impl.client.ClickGui;
import dev.crucifixbeta.mod.modules.impl.client.ClientSetting;
import dev.crucifixbeta.mod.modules.impl.client.ColorsModule;
import dev.crucifixbeta.mod.modules.impl.client.Fonts;
import dev.crucifixbeta.mod.modules.impl.client.Language;
import dev.crucifixbeta.mod.modules.impl.client.Sounds;
import dev.crucifixbeta.mod.modules.impl.client.hud.ArrayListHudModule;
import dev.crucifixbeta.mod.modules.impl.client.hud.GUICharacter;
import dev.crucifixbeta.mod.modules.impl.client.hud.HudSetting;
import dev.crucifixbeta.mod.modules.impl.client.hud.InfoHudModule;
import dev.crucifixbeta.mod.modules.impl.client.hud.ItemCounterHudModule;
import dev.crucifixbeta.mod.modules.impl.client.hud.LavenderHudModules;
import dev.crucifixbeta.mod.modules.impl.client.hud.PlayerModule;
import dev.crucifixbeta.mod.modules.impl.client.hud.TextRadar;
import dev.crucifixbeta.mod.modules.impl.client.hud.WaterMarkHudModule;
import dev.crucifixbeta.mod.modules.impl.combat.AntiBurrow;
import dev.crucifixbeta.mod.modules.impl.combat.AntiCrawl;
import dev.crucifixbeta.mod.modules.impl.combat.AntiPhase;
import dev.crucifixbeta.mod.modules.impl.combat.AntiPiston;
import dev.crucifixbeta.mod.modules.impl.combat.AntiRegear;
import dev.crucifixbeta.mod.modules.impl.combat.AntiStand;
import dev.crucifixbeta.mod.modules.impl.combat.AntiWeak;
import dev.crucifixbeta.mod.modules.impl.combat.Aura;
import dev.crucifixbeta.mod.modules.impl.combat.AutoAnchor;
import dev.crucifixbeta.mod.modules.impl.combat.AutoCrystal;
import dev.crucifixbeta.mod.modules.impl.combat.AutoPush;
import dev.crucifixbeta.mod.modules.impl.combat.AutoRegear;
import dev.crucifixbeta.mod.modules.impl.combat.AutoSpear;
import dev.crucifixbeta.mod.modules.impl.combat.AutoTrap;
import dev.crucifixbeta.mod.modules.impl.combat.AutoWeb;
import dev.crucifixbeta.mod.modules.impl.combat.AutoXP;
import dev.crucifixbeta.mod.modules.impl.combat.Blocker;
import dev.crucifixbeta.mod.modules.impl.combat.Breaker;
import dev.crucifixbeta.mod.modules.impl.combat.Burrow;
import dev.crucifixbeta.mod.modules.impl.combat.Criticals;
import dev.crucifixbeta.mod.modules.impl.combat.HoleFiller;
import dev.crucifixbeta.mod.modules.impl.combat.MainHand;
import dev.crucifixbeta.mod.modules.impl.combat.Offhand;
import dev.crucifixbeta.mod.modules.impl.combat.PistonCrystal;
import dev.crucifixbeta.mod.modules.impl.combat.Quiver;
import dev.crucifixbeta.mod.modules.impl.combat.SelfTrap;
import dev.crucifixbeta.mod.modules.impl.combat.Surround;
import dev.crucifixbeta.mod.modules.impl.exploit.AntiPacket;
import dev.crucifixbeta.mod.modules.impl.exploit.Blink;
import dev.crucifixbeta.mod.modules.impl.exploit.BowBomb;
import dev.crucifixbeta.mod.modules.impl.exploit.ChorusControl;
import dev.crucifixbeta.mod.modules.impl.exploit.ChunkESP;
import dev.crucifixbeta.mod.modules.impl.exploit.InfiniteTrident;
import dev.crucifixbeta.mod.modules.impl.exploit.MaceSpoof;
import dev.crucifixbeta.mod.modules.impl.exploit.NoResourcePack;
import dev.crucifixbeta.mod.modules.impl.exploit.PacketControl;
import dev.crucifixbeta.mod.modules.impl.exploit.Phase;
import dev.crucifixbeta.mod.modules.impl.exploit.PingSpoof;
import dev.crucifixbeta.mod.modules.impl.exploit.RocketExtend;
import dev.crucifixbeta.mod.modules.impl.exploit.ServerLagger;
import dev.crucifixbeta.mod.modules.impl.exploit.SkinFlicker;
import dev.crucifixbeta.mod.modules.impl.exploit.WindChargeHighJump;
import dev.crucifixbeta.mod.modules.impl.exploit.XCarry;
import dev.crucifixbeta.mod.modules.impl.misc.AddFriend;
import dev.crucifixbeta.mod.modules.impl.misc.AutoEZ;
import dev.crucifixbeta.mod.modules.impl.misc.AutoKit;
import dev.crucifixbeta.mod.modules.impl.misc.AutoKouZi;
import dev.crucifixbeta.mod.modules.impl.misc.AutoLog;
import dev.crucifixbeta.mod.modules.impl.misc.AutoReconnect;
import dev.crucifixbeta.mod.modules.impl.misc.AutoSanZiJing;
import dev.crucifixbeta.mod.modules.impl.misc.BaseFinderXin;
import dev.crucifixbeta.mod.modules.impl.misc.BedCrafter;
import dev.crucifixbeta.mod.modules.impl.misc.ChatAppend;
import dev.crucifixbeta.mod.modules.impl.misc.ChestStealer;
import dev.crucifixbeta.mod.modules.impl.misc.ChestStealerPlus;
import dev.crucifixbeta.mod.modules.impl.misc.ExtraTab;
import dev.crucifixbeta.mod.modules.impl.misc.FakePlayer;
import dev.crucifixbeta.mod.modules.impl.misc.KillEffect;
import dev.crucifixbeta.mod.modules.impl.misc.LowArmorAlert;
import dev.crucifixbeta.mod.modules.impl.misc.LowHealthAlert;
import dev.crucifixbeta.mod.modules.impl.misc.NoSound;
import dev.crucifixbeta.mod.modules.impl.misc.NoTerrainScreen;
import dev.crucifixbeta.mod.modules.impl.misc.Nuker;
import dev.crucifixbeta.mod.modules.impl.misc.PacketLogger;
import dev.crucifixbeta.mod.modules.impl.misc.ShulkerViewer;
import dev.crucifixbeta.mod.modules.impl.misc.Spammer;
import dev.crucifixbeta.mod.modules.impl.misc.Tips;
import dev.crucifixbeta.mod.modules.impl.movement.AntiBounce;
import dev.crucifixbeta.mod.modules.impl.movement.AntiSlowFalling;
import dev.crucifixbeta.mod.modules.impl.movement.AntiVoid;
import dev.crucifixbeta.mod.modules.impl.movement.ElytraFly;
import dev.crucifixbeta.mod.modules.impl.movement.FastFall;
import dev.crucifixbeta.mod.modules.impl.movement.FastWeb;
import dev.crucifixbeta.mod.modules.impl.movement.Flatten;
import dev.crucifixbeta.mod.modules.impl.movement.Fly;
import dev.crucifixbeta.mod.modules.impl.movement.HighJump;
import dev.crucifixbeta.mod.modules.impl.movement.HoleSnap;
import dev.crucifixbeta.mod.modules.impl.movement.MovementSync;
import dev.crucifixbeta.mod.modules.impl.movement.NoJumpDelay;
import dev.crucifixbeta.mod.modules.impl.movement.NoSlow;
import dev.crucifixbeta.mod.modules.impl.movement.SafeWalk;
import dev.crucifixbeta.mod.modules.impl.movement.Scaffold;
import dev.crucifixbeta.mod.modules.impl.movement.Speed;
import dev.crucifixbeta.mod.modules.impl.movement.Sprint;
import dev.crucifixbeta.mod.modules.impl.movement.Step;
import dev.crucifixbeta.mod.modules.impl.movement.Strafe;
import dev.crucifixbeta.mod.modules.impl.movement.TargetFollow;
import dev.crucifixbeta.mod.modules.impl.movement.VClip;
import dev.crucifixbeta.mod.modules.impl.movement.Velocity;
import dev.crucifixbeta.mod.modules.impl.player.AirPlace;
import dev.crucifixbeta.mod.modules.impl.player.AntiEffects;
import dev.crucifixbeta.mod.modules.impl.player.AutoArmor;
import dev.crucifixbeta.mod.modules.impl.player.AutoPearl;
import dev.crucifixbeta.mod.modules.impl.player.AutoPot;
import dev.crucifixbeta.mod.modules.impl.player.AutoTool;
import dev.crucifixbeta.mod.modules.impl.player.FreeLook;
import dev.crucifixbeta.mod.modules.impl.player.Freecam;
import dev.crucifixbeta.mod.modules.impl.player.InteractTweaks;
import dev.crucifixbeta.mod.modules.impl.player.NoFall;
import dev.crucifixbeta.mod.modules.impl.player.PacketEat;
import dev.crucifixbeta.mod.modules.impl.player.PacketMine;
import dev.crucifixbeta.mod.modules.impl.player.Replenish;
import dev.crucifixbeta.mod.modules.impl.player.Sorter;
import dev.crucifixbeta.mod.modules.impl.player.SpeedMineGrimV3;
import dev.crucifixbeta.mod.modules.impl.player.TimerModule;
import dev.crucifixbeta.mod.modules.impl.player.Yaw;
import dev.crucifixbeta.mod.modules.impl.render.Ambience;
import dev.crucifixbeta.mod.modules.impl.render.AnimationsModule;
import dev.crucifixbeta.mod.modules.impl.render.AspectRatio;
import dev.crucifixbeta.mod.modules.impl.render.BreakESP;
import dev.crucifixbeta.mod.modules.impl.render.CameraClip;
import dev.crucifixbeta.mod.modules.impl.render.CapeChanger;
import dev.crucifixbeta.mod.modules.impl.render.Chams;
import dev.crucifixbeta.mod.modules.impl.render.Crosshair;
import dev.crucifixbeta.mod.modules.impl.render.ESP;
import dev.crucifixbeta.mod.modules.impl.render.Fov;
import dev.crucifixbeta.mod.modules.impl.render.HighLight;
import dev.crucifixbeta.mod.modules.impl.render.LogoutSpots;
import dev.crucifixbeta.mod.modules.impl.render.MaceEffect;
import dev.crucifixbeta.mod.modules.impl.render.MotionCamera;
import dev.crucifixbeta.mod.modules.impl.render.NameTags;
import dev.crucifixbeta.mod.modules.impl.render.NoRender;
import dev.crucifixbeta.mod.modules.impl.render.PhaseESP;
import dev.crucifixbeta.mod.modules.impl.render.PlaceRender;
import dev.crucifixbeta.mod.modules.impl.render.ShaderModule;
import dev.crucifixbeta.mod.modules.impl.render.Tracers;
import dev.crucifixbeta.mod.modules.impl.render.Trajectories;
import dev.crucifixbeta.mod.modules.impl.render.ViewModel;
import dev.crucifixbeta.mod.modules.impl.render.Xray;
import dev.crucifixbeta.mod.modules.impl.render.Zoom;
import dev.crucifixbeta.mod.modules.settings.Setting;
import dev.crucifixbeta.mod.modules.settings.impl.BindSetting;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Comparator;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.gui.DrawContext;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.entity.effect.StatusEffectInstance;
import org.lwjgl.opengl.GL11;

@Environment(EnvType.CLIENT)
public class ModuleManager implements Wrapper {
   private final ArrayList<Module> modules = new ArrayList<>();
   private final ArrayList<ModuleManager.ToggleBanner> toggleBanners = new ArrayList<>();

   public ArrayList<Module> getModules() {
      return this.modules;
   }

   public ModuleManager() {
      this.init();
   }

   public void init() {
      if (BaritoneUtil.loaded) {
         this.addModule(new BaritoneModule());
      }

      this.addModule(new AutoKit());
      this.addModule(new Fonts());
      this.addModule(new AutoCrystal());
      this.addModule(new Ambience());
      this.addModule(new AnimationsModule());
      this.addModule(new AntiVoid());
      this.addModule(new HighJump());
      this.addModule(new VClip());
      this.addModule(new ExtraTab());
      this.addModule(new AntiWeak());
      this.addModule(new AddFriend());
      this.addModule(new AspectRatio());
      this.addModule(new ChunkESP());
      this.addModule(new Aura());
      this.addModule(new PistonCrystal());
      this.addModule(new AutoAnchor());
      this.addModule(new PhaseESP());
      this.addModule(new AutoArmor());
      this.addModule(new Breaker());
      this.addModule(new AutoLog());
      this.addModule(new AutoEZ());
      this.addModule(new ChestStealer());
      this.addModule(new ChestStealerPlus());
      this.addModule(new SelfTrap());
      this.addModule(new Sorter());
      this.addModule(new AutoXP());
      this.addModule(new AutoPot());
      this.addModule(new AutoPush());
      this.addModule(new MainHand());
      this.addModule(new Offhand());
      this.addModule(new Nuker());
      this.addModule(new AutoTrap());
      this.addModule(new AutoWeb());
      this.addModule(new Blink());
      this.addModule(new ChorusControl());
      this.addModule(new Blocker());
      this.addModule(new Quiver());
      this.addModule(new BowBomb());
      this.addModule(new BreakESP());
      this.addModule(new Burrow());
      this.addModule(new MaceSpoof());
      this.addModule(new CameraClip());
      this.addModule(new ChatAppend());
      this.addModule(new ColorsModule());
      this.addModule(new ClickGui());
      this.addModule(new InfiniteTrident());
      this.addModule(new AutoRegear());
      this.addModule(new AntiPhase());
      this.addModule(new AntiCheat());
      this.addModule(new ItemCounterHudModule("Items", "\u7269\u54c1", 100, 100));
      this.addModule(new Fov());
      this.addModule(new Criticals());
      this.addModule(new Crosshair());
      this.addModule(new Chams());
      this.addModule(new AntiPacket());
      this.addModule(new AutoReconnect());
      this.addModule(new ESP());
      this.addModule(new Tracers());
      this.addModule(new MovementSync());
      this.addModule(new ElytraFly());
      this.addModule(new PacketLogger());
      this.addModule(new SkinFlicker());
      this.addModule(new TargetFollow());
      this.addModule(new NameTags());
      this.addModule(new ShulkerViewer());
      this.addModule(new PingSpoof());
      this.addModule(new FakePlayer());
      this.addModule(new Spammer());
      this.addModule(new MotionCamera());
      this.addModule(new HighLight());
      this.addModule(new FastFall());
      this.addModule(new FastWeb());
      this.addModule(new Flatten());
      this.addModule(new Fly());
      this.addModule(new Yaw());
      this.addModule(new Freecam());
      this.addModule(new FreeLook());
      this.addModule(new TimerModule());
      this.addModule(new Tips());
      this.addModule(new ClientSetting());
      this.addModule(new Language());
      this.addModule(new Sounds());
      this.addModule(new HudSetting());
      this.addModule(new TextRadar());
      this.addModule(new GUICharacter());
      this.addModule(new PlayerModule());
      this.addModule(new LavenderHudModules.ArmorHud());
      this.addModule(new WaterMarkHudModule());
      this.addModule(new LavenderHudModules.PotionHud());
      this.addModule(new LavenderHudModules.InventoryHud());
      this.addModule(new LavenderHudModules.PlayerListHud());
      this.addModule(new LavenderHudModules.TargetInfoHud());
      this.addModule(new LavenderHudModules.KeyBindsHud());
      this.addModule(new LavenderHudModules.KeyStrokesHud());
      this.addModule(new ArrayListHudModule());
      this.addModule(new InfoHudModule());
      this.addModule(new RocketExtend());
      this.addModule(new HoleFiller());
      this.addModule(new HoleSnap());
      this.addModule(new LogoutSpots());
      this.addModule(new AutoTool());
      this.addModule(new Trajectories());
      this.addModule(new KillEffect());
      this.addModule(new AutoPearl());
      this.addModule(new AntiEffects());
      this.addModule(new NoFall());
      this.addModule(new NoRender());
      this.addModule(new NoSlow());
      this.addModule(new NoSound());
      this.addModule(new AirPlace());
      this.addModule(new Xray());
      this.addModule(new PacketEat());
      this.addModule(new PacketMine());
      this.addModule(new PacketControl());
      this.addModule(new Phase());
      this.addModule(new PlaceRender());
      this.addModule(new InteractTweaks());
      this.addModule(new Replenish());
      this.addModule(new ServerLagger());
      this.addModule(new Scaffold());
      this.addModule(new ShaderModule());
      this.addModule(new AntiCrawl());
      this.addModule(new AntiRegear());
      this.addModule(new SafeWalk());
      this.addModule(new NoJumpDelay());
      this.addModule(new Speed());
      this.addModule(new Sprint());
      this.addModule(new Strafe());
      this.addModule(new Step());
      this.addModule(new Surround());
      this.addModule(new Velocity());
      this.addModule(new ViewModel());
      this.addModule(new XCarry());
      this.addModule(new Zoom());
      this.addModule(new AntiBurrow());
      this.addModule(new AntiPiston());
      this.addModule(new AntiStand());
      this.addModule(new AutoSpear());
      this.addModule(new AntiBounce());
      this.addModule(new AntiSlowFalling());
      this.addModule(new AutoKouZi());
      this.addModule(new AutoSanZiJing());
      this.addModule(new BaseFinderXin());
      this.addModule(new BedCrafter());
      this.addModule(new LowArmorAlert());
      this.addModule(new LowHealthAlert());
      this.addModule(new NoTerrainScreen());
      this.addModule(new SpeedMineGrimV3());
      this.addModule(new CapeChanger());
      this.addModule(new MaceEffect());
      this.addModule(new NoResourcePack());
      this.addModule(new WindChargeHighJump());
      this.modules.sort(Comparator.comparing(Mod::getName));
   }

   public void onKeyReleased(int eventKey) {
      if (eventKey != -1 && eventKey != 0) {
         this.handleKeyEvent(eventKey, false);
      }
   }

   public void onKeyPressed(int eventKey) {
      if (eventKey != -1 && eventKey != 0) {
         this.handleKeyEvent(eventKey, true);
      }
   }

   private void handleKeyEvent(int key, boolean isPressed) {
      for (Module var4 : this.modules) {
         BindSetting var5 = var4.getBindSetting();
         if (var5.getValue() == key) {
            if (isPressed && mc.currentScreen == null) {
               var4.toggle();
               var5.holding = true;
            } else if (!isPressed && var5.isHoldEnable() && var5.holding) {
               var4.toggle();
               var5.holding = false;
            }
         }

         for (Setting var7 : var4.getSettings()) {
            BindSetting var8;
            if (var7 instanceof BindSetting && (var8 = (BindSetting)var7).getValue() == key) {
               var8.setPressed(isPressed);
            }
         }
      }
   }

   public void onLogin() {
      for (Module var2 : this.modules) {
         if (var2.isOn()) {
            var2.onLogin();
         }
      }
   }

   public void onLogout() {
      for (Module var2 : this.modules) {
         if (var2.isOn()) {
            var2.onLogout();
         }
      }
   }

   public void onRender2D(DrawContext drawContext) {
      boolean var2 = false;
      if (mc.currentScreen instanceof ClickGuiScreen) {
         var2 = ((ClickGuiScreen)mc.currentScreen).getPage() == ClickGuiScreen.Page.Hud;
      }

      for (Module var4 : this.modules) {
         if (var4.isOn() && (!var2 || !(var4 instanceof HudModule))) {
            try {
               float var5 = mc.getRenderTickCounter().getTickDelta(true);
               if (var4 instanceof HudModule var6) {
                  var6.renderBackground(drawContext);
                  var6.beginScaledRender(drawContext);

                  try {
                     var4.onRender2D(drawContext, var5);
                  } finally {
                     var6.endScaledRender(drawContext);
                  }
               } else {
                  var4.onRender2D(drawContext, var5);
               }
            } catch (Exception var13) {
               var13.printStackTrace();
               if (ClientSetting.INSTANCE.debug.getValue()) {
                  CommandManager.sendMessage("§4An error has occurred (" + var4.getName() + " [onRender2D]) Message: [" + var13.getMessage() + "]");
               }
            }
         }
      }

      try {
         CrucifixBeta.EVENT_BUS.post(Render2DEvent.get(drawContext, mc.getRenderTickCounter().getTickDelta(true)));
      } catch (Exception var12) {
         var12.printStackTrace();
         if (ClientSetting.INSTANCE.debug.getValue()) {
            CommandManager.sendMessage("§4An error has occurred (Render3DEvent) Message: [" + var12.getMessage() + "]");
         }
      }

      this.renderToggleBanners(drawContext);
   }

   public void render3D(MatrixStack matrices) {
      GL11.glEnable(2848);

      for (Module var3 : this.modules) {
         if (var3.isOn()) {
            try {
               var3.onRender3D(matrices);
            } catch (Exception var6) {
               var6.printStackTrace();
               if (ClientSetting.INSTANCE.debug.getValue()) {
                  CommandManager.sendMessage("§4An error has occurred (" + var3.getName() + " [onRender3D]) Message: [" + var6.getMessage() + "]");
               }
            }
         }
      }

      try {
         CrucifixBeta.EVENT_BUS.post(Render3DEvent.get(matrices, mc.getRenderTickCounter().getTickDelta(true)));
      } catch (Exception var5) {
         var5.printStackTrace();
         if (ClientSetting.INSTANCE.debug.getValue()) {
            CommandManager.sendMessage("§4An error has occurred (Render3DEvent) Message: [" + var5.getMessage() + "]");
         }
      }

      GL11.glDisable(2848);
   }

   public void showToggleBanner(Module module, boolean enabled) {
   }

   private void renderToggleBanners(DrawContext ctx) {
      this.toggleBanners.clear();
   }

   private void renderPotionListLegacy(DrawContext ctx) {
      if (mc.player != null) {
         byte var2 = 14;
         int var3 = var2 + 2;
         int var4 = var2 + 92;
         byte var5 = 14;
         byte var6 = 6;
         int var7 = 0;

         for (StatusEffectInstance var9 : mc.player.getStatusEffects()) {
            String var10 = var9.getEffectType().value().getName().getString();
            int var11 = var9.getDuration();
            int var12 = Math.max(0, var11 / 20);
            int var13 = var12 / 60;
            int var14 = var12 % 60;
            String var15 = String.format("%d:%02d", var13, var14);
            String var16 = var10 + " " + var15;
            boolean var17 = FontManager.isCustomFontEnabled();
            int var18 = var17 ? (int)FontManager.ui.getWidth(var16) : (int)TextUtil.getWidth(var16);
            int var19 = var18 + var6 * 2;
            int var21 = var4 + var7 * (var5 + 4);
            short var22 = 180;
            Render2DUtil.drawRoundedRect(ctx.getMatrices(), (float)var3, (float)var21, (float)var19, (float)var5, 4.0F, new Color(255, 255, 255, var22));
            Render2DUtil.drawRoundedStroke(ctx.getMatrices(), (float)var3, (float)var21, (float)var19, (float)var5, 4.0F, new Color(220, 224, 230, 160), 48);
            int var23 = var3 + var6;
            double var24 = (double)var21 + (double)((float)var5 - (var17 ? FontManager.ui.getFontHeight() : TextUtil.getHeight())) / 2.0;
            TextUtil.drawString(ctx, var16, (double)var23, var24, new Color(30, 30, 30).getRGB(), var17);
            if (++var7 >= 5) {
               break;
            }
         }
      }
   }

   public void addModule(Module module) {
      this.modules.add(module);
   }

   public Module getModuleByName(String string) {
      for (Module var3 : this.modules) {
         if (var3.getName().equalsIgnoreCase(string)) {
            return var3;
         }
      }

      return null;
   }
@Environment(EnvType.CLIENT)
   private static class ToggleBanner {
      public final String name;
      public final boolean enabled;
      public final long start;

      public ToggleBanner(String name, boolean enabled, long start) {
         this.name = name;
         this.enabled = enabled;
         this.start = start;
      }
   }
}
