summaryrefslogtreecommitdiff
path: root/Decompiler/Gestor.Application.Helpers/LicenseHelper.cs
diff options
context:
space:
mode:
authorLucas Faria Mendes <lucas.fariamo08@gmail.com>2026-03-30 15:29:41 +0000
committerLucas Faria Mendes <lucas.fariamo08@gmail.com>2026-03-30 15:29:41 +0000
commit225aa1499e37faf9d38257caabbadc68d78b427e (patch)
tree102bb7a40c58595348ae9d3c7076201759fe0720 /Decompiler/Gestor.Application.Helpers/LicenseHelper.cs
parent1f4e14b2e973ee7de337fd4866d9a5ceff5cb6d1 (diff)
downloadgestor-225aa1499e37faf9d38257caabbadc68d78b427e.tar.gz
gestor-225aa1499e37faf9d38257caabbadc68d78b427e.zip
decompiler.com
Diffstat (limited to 'Decompiler/Gestor.Application.Helpers/LicenseHelper.cs')
-rw-r--r--Decompiler/Gestor.Application.Helpers/LicenseHelper.cs455
1 files changed, 455 insertions, 0 deletions
diff --git a/Decompiler/Gestor.Application.Helpers/LicenseHelper.cs b/Decompiler/Gestor.Application.Helpers/LicenseHelper.cs
new file mode 100644
index 0000000..65b9dee
--- /dev/null
+++ b/Decompiler/Gestor.Application.Helpers/LicenseHelper.cs
@@ -0,0 +1,455 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.NetworkInformation;
+using System.Net.Sockets;
+using System.Threading.Tasks;
+using Agger.Registro;
+using Gestor.Common.Helpers;
+using Gestor.Common.Validation;
+using Gestor.Model.API;
+using Gestor.Model.Domain.Generic;
+using Gestor.Model.License;
+using Microsoft.Win32;
+using Newtonsoft.Json;
+
+namespace Gestor.Application.Helpers;
+
+public class LicenseHelper
+{
+ public static int? DiasRestantes { get; set; }
+
+ public static StatusLicenca Status { get; set; } = (StatusLicenca)1;
+
+
+ public static List<Licenca> Produtos { get; set; }
+
+ public static Instalacao Instalacao { get; set; }
+
+ public static DateTime DataAtual { get; private set; }
+
+ private string _guid { get; set; }
+
+ public async Task<bool> VerificarRegistro()
+ {
+ return await Task.Run(delegate
+ {
+ //IL_0005: Unknown result type (might be due to invalid IL or missing references)
+ //IL_000b: Expected O, but got Unknown
+ RegistryHelper val = new RegistryHelper(ApplicationHelper.Subkey);
+ if (string.IsNullOrEmpty(val.Read("NS", true)))
+ {
+ return false;
+ }
+ string s = EncryptionHelper.Decrypt(val.Read("CUSTOMER", true));
+ if (!long.TryParse(s, out var _))
+ {
+ ApplicationHelper.IdFornecedor = long.Parse(Connection.Get<string>("Configuration/Customer").Result);
+ val.Write<string>("CUSTOMER", EncryptionHelper.Encrypt(ApplicationHelper.IdFornecedor.ToString()), true);
+ }
+ else
+ {
+ ApplicationHelper.IdFornecedor = long.Parse(s);
+ }
+ string text = Connection.Get<string>("Installation/Time", autorizar: false).Result ?? Funcoes.GetNetworkTime().ToString("d");
+ DataAtual = DateTime.Parse(text);
+ val.Write<string>("CURRENTDATE", EncryptionHelper.Encrypt(text), true);
+ val.Write<string>("DATE", text, true);
+ ApplicationHelper.Beta = Connection.Get<List<object>>($"Configuration/Customer/{ApplicationHelper.IdFornecedor}").Result?.Any((object x) => x.ToString().Contains("\"Tipo\": 45")) ?? false;
+ Address.Beta = ApplicationHelper.Beta;
+ return true;
+ });
+ }
+
+ public async Task<Tuple<bool, string>> VerificarAcesso()
+ {
+ return await Task.Run(delegate
+ {
+ //IL_000b: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0011: Expected O, but got Unknown
+ //IL_053f: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0545: Invalid comparison between Unknown and I4
+ //IL_0547: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0555: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02d4: Unknown result type (might be due to invalid IL or missing references)
+ //IL_035e: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0363: Unknown result type (might be due to invalid IL or missing references)
+ //IL_036f: Expected O, but got Unknown
+ //IL_03b1: Unknown result type (might be due to invalid IL or missing references)
+ //IL_040b: Unknown result type (might be due to invalid IL or missing references)
+ //IL_03d7: Unknown result type (might be due to invalid IL or missing references)
+ //IL_03dc: Unknown result type (might be due to invalid IL or missing references)
+ //IL_03e3: Unknown result type (might be due to invalid IL or missing references)
+ //IL_03ef: Unknown result type (might be due to invalid IL or missing references)
+ //IL_03f7: Unknown result type (might be due to invalid IL or missing references)
+ //IL_03fe: Unknown result type (might be due to invalid IL or missing references)
+ //IL_040a: Expected O, but got Unknown
+ RegistryHelper val = new RegistryHelper(ApplicationHelper.Subkey);
+ DateTime now = Funcoes.GetNetworkTime();
+ DateTime today = now.Date;
+ if (ApplicationHelper.Conectado)
+ {
+ List<Access> result = Connection.Get<List<Access>>($"Access/Customer/{ApplicationHelper.IdFornecedor}").Result;
+ List<long> liberados = new List<long> { 2L, 3L, 4L, 5L, 24L, 10024L };
+ Produtos = (from x in result
+ group x by new { x.ProductId, x.Status }).Select(x =>
+ {
+ //IL_0014: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0019: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0038: Unknown result type (might be due to invalid IL or missing references)
+ //IL_00b0: Unknown result type (might be due to invalid IL or missing references)
+ //IL_00cd: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0102: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0127: Expected O, but got Unknown
+ Licenca val2 = new Licenca
+ {
+ Produto = (Produto)x.Key.ProductId.GetValueOrDefault()
+ };
+ AccessControl? obj2 = (from l in x.SelectMany((Access c) => c.Control)
+ orderby l.Expiration descending
+ select l).FirstOrDefault();
+ val2.Liberacao = ((obj2 != null) ? obj2.Expiration : now.AddDays(-1.0));
+ val2.AcessoLiberado = x.All(delegate(Access l)
+ {
+ if (!l.AgreementId.HasValue || !liberados.Contains(l.AgreementId.Value))
+ {
+ AccessControl? obj3 = (from d in x.SelectMany((Access c) => c.Control)
+ orderby d.Expiration descending
+ select d).FirstOrDefault();
+ if (obj3 == null)
+ {
+ return false;
+ }
+ return obj3.Expiration >= today;
+ }
+ return true;
+ });
+ val2.Quantidade = (int)x.Sum((Access l) => l.Ammount.GetValueOrDefault());
+ val2.Status = int.Parse(x.Key.Status ?? "1");
+ return val2;
+ }).ToList();
+ if (Produtos == null || Produtos.Count == 0 || Produtos.All((Licenca x) => x.Status == 3))
+ {
+ val.Write<string>("EXPIRATION", EncryptionHelper.Encrypt(now.AddDays(-1.0).ToString("d")), true);
+ val.Write<string>("BLOCK", EncryptionHelper.Encrypt("TRUE"), true);
+ Status = (StatusLicenca)3;
+ return new Tuple<bool, string>(item1: false, "");
+ }
+ Licenca? obj = ((IEnumerable<Licenca>)Produtos.OrderBy((Licenca x) => x.Liberacao)).FirstOrDefault((Func<Licenca, bool>)((Licenca x) => !x.AcessoLiberado && x.Status == 1));
+ DateTime dateTime = ((obj != null) ? obj.Liberacao : now);
+ DiasRestantes = (int)(dateTime - today).TotalDays;
+ val.Write<string>("EXPIRATION", EncryptionHelper.Encrypt(dateTime.ToString("d")), true);
+ val.Write<string>("BLOCK", (dateTime >= today) ? EncryptionHelper.Encrypt("FALSE") : EncryptionHelper.Encrypt("TRUE"), true);
+ bool flag = Produtos.Any((Licenca x) => (int)x.Produto == 1 && x.Status == 4);
+ val.Write<string>("CONSULTA", EncryptionHelper.Encrypt(flag.ToString().ToUpper()), true);
+ if (flag)
+ {
+ Status = (StatusLicenca)2;
+ }
+ Status = (StatusLicenca)((dateTime < today) ? 1 : 0);
+ if (Produtos.Any((Licenca x) => (int)x.Produto == 1) && (int)Status == 0)
+ {
+ val.Write<string>("P1", EncryptionHelper.Encrypt("1$P1#" + ApplicationHelper.NumeroSerial), true);
+ val.Write<string>("P5", EncryptionHelper.Encrypt("1$P1#" + ApplicationHelper.NumeroSerial), true);
+ val.Write<string>("M1", EncryptionHelper.Encrypt("TRUE"), true);
+ }
+ string text = JsonConvert.SerializeObject((object)Produtos.Where((Licenca x) => x.Status == 1), (Formatting)1, new JsonSerializerSettings
+ {
+ ReferenceLoopHandling = (ReferenceLoopHandling)1
+ });
+ val.Write<string>("PRODUTOS", EncryptionHelper.Encrypt(text), true);
+ if (Produtos.Find((Licenca p) => (int)p.Produto == 86) != null)
+ {
+ return new Tuple<bool, string>(item1: true, EnumHelper.GetDescription<StatusLicenca>(Status));
+ }
+ if (ValidationHelper.IsNotNullOrEmpty(AssinadorHelper.Key().Result))
+ {
+ Produtos.Add(new Licenca
+ {
+ AcessoLiberado = true,
+ Liberacao = today,
+ Produto = (Produto)86,
+ Quantidade = 0,
+ Status = 1
+ });
+ }
+ return new Tuple<bool, string>(item1: true, EnumHelper.GetDescription<StatusLicenca>(Status));
+ }
+ if ((today - DataAtual).TotalDays > 2.0)
+ {
+ return new Tuple<bool, string>(item1: true, "DATA INVÁLIDA");
+ }
+ DiasRestantes = (int)(DateTime.Parse(EncryptionHelper.Decrypt(val.Read("EXPIRATION", true))).AddDays(5.0) - DataAtual).TotalDays;
+ if (DiasRestantes < 1)
+ {
+ return new Tuple<bool, string>(item1: true, "SISTEMA BLOQUEADO");
+ }
+ if (EncryptionHelper.Decrypt(val.Read("BLOCK", true)) == "TRUE")
+ {
+ return new Tuple<bool, string>(item1: true, "SISTEMA BLOQUEADO");
+ }
+ if (EncryptionHelper.Decrypt(val.Read("CONSULTA", true)) == "TRUE")
+ {
+ Status = (StatusLicenca)2;
+ }
+ string text2 = EncryptionHelper.Decrypt(val.Read("PRODUTOS", true));
+ if (string.IsNullOrEmpty(text2))
+ {
+ Status = (StatusLicenca)3;
+ return new Tuple<bool, string>(item1: false, "SISTEMA CANCELADO");
+ }
+ Produtos = JsonConvert.DeserializeObject<List<Licenca>>(text2);
+ Status = (StatusLicenca)(((int)Status == 2) ? ((int)Status) : 0);
+ return new Tuple<bool, string>(item1: true, EnumHelper.GetDescription<StatusLicenca>(Status));
+ });
+ }
+
+ public async Task<bool> VerificarMaquina()
+ {
+ return await Task.Run(delegate
+ {
+ //IL_0005: Unknown result type (might be due to invalid IL or missing references)
+ //IL_000b: Expected O, but got Unknown
+ //IL_029d: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02a2: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02ad: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02b8: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02c0: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02cb: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02d6: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02e6: Unknown result type (might be due to invalid IL or missing references)
+ //IL_02f6: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0301: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0346: Expected O, but got Unknown
+ RegistryHelper val = new RegistryHelper(ApplicationHelper.Subkey);
+ string macAddress = GetMacAddress();
+ string value = val.Read("MACHINEID", false);
+ if (string.IsNullOrEmpty(value))
+ {
+ value = GetMachineSerial();
+ val.Write<string>("MACHINEID", EncryptionHelper.Encrypt(macAddress + " " + value), false);
+ }
+ string[] array = EncryptionHelper.Decrypt(val.Read("MACHINEID", false)).Split(new char[1] { ' ' });
+ string text = ((array.Length > 1) ? array[1] : array[0]);
+ if (ApplicationHelper.Conectado)
+ {
+ List<Instalacao> result = Connection.Get<List<Instalacao>>("Installation/Machine/" + text + "/GerenciadorList").Result;
+ if (!Guid.TryParse(text, out var _))
+ {
+ text = GetMachineSerial();
+ }
+ _guid = text;
+ Instalacao = result?.FirstOrDefault((Func<Instalacao, bool>)((Instalacao x) => x.IdFornecedor == ApplicationHelper.IdFornecedor));
+ if (Instalacao != null && Instalacao.IdFornecedor != ApplicationHelper.IdFornecedor)
+ {
+ Instalacao = null;
+ }
+ if (Instalacao != null)
+ {
+ Instalacao.Gerenciador = text;
+ Instalacao.UsuarioId = ((DomainBase)Recursos.Usuario).Id;
+ Instalacao.UsuarioSistema = Recursos.Usuario.Nome;
+ Instalacao.Ip = Recursos.Host.AddressList.FirstOrDefault((IPAddress ip) => ip.AddressFamily == AddressFamily.InterNetwork)?.ToString();
+ Instalacao.UltimoAcesso = DateTime.Now;
+ Instalacao.OSInfo = string.Format("P={0};V={1};x64={2};N={3}", (Environment.OSVersion.Platform == PlatformID.Win32NT) ? "W" : "O", Environment.OSVersion.Version, Environment.Is64BitOperatingSystem ? "1" : "0", GetFrameworkVersion());
+ Instalacao = Connection.Put<Instalacao>("Installation/Machine", Instalacao).Result;
+ val.Write<string>("MACHINEID", EncryptionHelper.Encrypt(macAddress + " " + Instalacao.Gerenciador), false);
+ }
+ val.Write<string>("ACCESS", (Instalacao != null || RegistrarMaquina().Result) ? EncryptionHelper.Encrypt("TRUE") : EncryptionHelper.Encrypt("FALSE"), false);
+ }
+ else if (EncryptionHelper.Decrypt(val.Read("ACCESS", false)) == "TRUE")
+ {
+ Instalacao = new Instalacao
+ {
+ IdFornecedor = ApplicationHelper.IdFornecedor,
+ Data = DataAtual,
+ Gerenciador = text,
+ NomeMaquina = Environment.MachineName,
+ UsuarioMaquina = Environment.UserName,
+ UsuarioId = ((DomainBase)Recursos.Usuario).Id,
+ UsuarioSistema = Recursos.Usuario.Nome,
+ UltimoAcesso = DateTime.Now,
+ Ip = Recursos.Host.AddressList.FirstOrDefault((IPAddress ip) => ip.AddressFamily == AddressFamily.InterNetwork)?.ToString()
+ };
+ }
+ return Produtos.Any((Licenca x) => (int)x.Produto == 1) && (Instalacao != null || RegistrarMaquina().Result);
+ });
+ }
+
+ public async Task<string> Registrar(string chave)
+ {
+ return await Task.Run(delegate
+ {
+ //IL_001f: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0029: Expected O, but got Unknown
+ if (string.IsNullOrEmpty(chave))
+ {
+ return "false";
+ }
+ RegistryHelper helper = new RegistryHelper("");
+ string[] array = EncryptionHelper.Decrypt(chave).Split(new char[1] { ' ' });
+ if (array.Length < 2)
+ {
+ return "false";
+ }
+ string text = helper.Verificar(array[0], EncryptionHelper.Encrypt(array[0]));
+ if (text != "false")
+ {
+ if (text == "root")
+ {
+ return "root";
+ }
+ ApplicationHelper.NumeroSerial = array[0];
+ ApplicationHelper.IdFornecedor = long.Parse(Connection.Get<string>("Maintenance/Customer").Result);
+ Instancia.Conexao = null;
+ ApplicationHelper.Subkey = array[0];
+ return "true";
+ }
+ DateTime networkTime = Funcoes.GetNetworkTime();
+ string text2 = Connection.Get<string>("Installation/Time", autorizar: false, verificarConexao: true).Result ?? networkTime.ToString("d");
+ if (!ApplicationHelper.Conectado)
+ {
+ return "false";
+ }
+ DataAtual = DateTime.Parse($"{text2} {networkTime.Hour}:{networkTime.Minute}:{networkTime.Second}");
+ DateTime dateTime = DateTime.Parse(array[1]);
+ if (Math.Abs((DataAtual - dateTime).TotalDays) > 1.0)
+ {
+ return "false";
+ }
+ string text3 = EncryptionHelper.Decrypt(helper.Read("NS", true));
+ string text4 = helper.Read("SERIALS", false);
+ if (string.IsNullOrWhiteSpace(text4) && !string.IsNullOrWhiteSpace(text3))
+ {
+ helper.Write<string>("SERIALS", EncryptionHelper.Encrypt(text3), false);
+ text4 = helper.Read("SERIALS", false);
+ }
+ List<string> source = ((text4 != null) ? EncryptionHelper.Decrypt(text4).Split(new char[1] { ':' }).ToList() : new List<string>());
+ List<string> seriais = new List<string>();
+ source.Distinct().ToList().ForEach(delegate(string x)
+ {
+ if (!(helper.Verificar(x, EncryptionHelper.Encrypt(x)) == "false"))
+ {
+ seriais.Add(x);
+ }
+ });
+ seriais.Add(array[0]);
+ helper.Write<string>("SERIALS", EncryptionHelper.Encrypt(string.Join(":", seriais.Distinct())), false);
+ helper.Serial = ((seriais.Count > 1) ? ("\\" + array[0]) : "");
+ ApplicationHelper.Subkey = ((seriais.Count > 1) ? array[0] : "");
+ ApplicationHelper.NumeroSerial = array[0];
+ string result = Connection.Get<string>("Customer/Name/" + array[0]).Result;
+ helper.Write<string>("PERFIL", result, true);
+ helper.Write<string>("CURRENTDATE", EncryptionHelper.Encrypt(text2), true);
+ helper.Write<string>("DATE", text2, true);
+ helper.Write<string>("NS", EncryptionHelper.Encrypt(array[0]), true);
+ helper.Write<string>("INSTALL", EncryptionHelper.Encrypt(array[0]), true);
+ ApplicationHelper.IdFornecedor = long.Parse(Connection.Get<string>("Maintenance/Customer").Result);
+ helper.Write<string>("CUSTOMER", EncryptionHelper.Encrypt(ApplicationHelper.IdFornecedor.ToString()), true);
+ Instancia.Conexao = null;
+ return "true";
+ });
+ }
+
+ public async Task<List<Instalacao>> GetInstalacoes()
+ {
+ return await Connection.Get<List<Instalacao>>($"Installation/Machine/{ApplicationHelper.IdFornecedor}");
+ }
+
+ private string GetMachineSerial()
+ {
+ if (string.IsNullOrEmpty(_guid))
+ {
+ _guid = Guid.NewGuid().ToString();
+ }
+ return _guid;
+ }
+
+ public async Task<bool> RegistrarMaquina()
+ {
+ return await Task.Run(delegate
+ {
+ //IL_007e: Unknown result type (might be due to invalid IL or missing references)
+ //IL_0084: Expected O, but got Unknown
+ //IL_00ac: Unknown result type (might be due to invalid IL or missing references)
+ //IL_00b3: Expected O, but got Unknown
+ if (!ApplicationHelper.Conectado)
+ {
+ return false;
+ }
+ List<Instalacao> result = GetInstalacoes().Result;
+ Licenca? obj = ((IEnumerable<Licenca>)Produtos).FirstOrDefault((Func<Licenca, bool>)((Licenca x) => (int)x.Produto == 1));
+ if (((obj != null) ? obj.Quantidade : 0) <= result.Count((Instalacao x) => x.Gerenciador != null))
+ {
+ return false;
+ }
+ string text = "";
+ RegistryHelper val = new RegistryHelper("");
+ if (Instalacao == null)
+ {
+ string machineSerial = GetMachineSerial();
+ text = EncryptionHelper.Encrypt(GetMacAddress() + " " + machineSerial);
+ Instalacao val2 = new Instalacao();
+ val2.IdFornecedor = ApplicationHelper.IdFornecedor;
+ val2.Data = DataAtual;
+ val2.Gerenciador = machineSerial;
+ val2.NomeMaquina = Environment.MachineName;
+ val2.UsuarioMaquina = Environment.UserName;
+ val2.UsuarioId = ((DomainBase)Recursos.Usuario).Id;
+ val2.UsuarioSistema = Recursos.Usuario.Nome;
+ val2.UltimoAcesso = DateTime.Now;
+ val2.Ip = Recursos.Host.AddressList.FirstOrDefault((IPAddress ip) => ip.AddressFamily == AddressFamily.InterNetwork)?.ToString();
+ val2.OSInfo = string.Format("P={0};V={1};x64={2};N={3}", (Environment.OSVersion.Platform == PlatformID.Win32NT) ? "W" : "O", Environment.OSVersion.Version, Environment.Is64BitOperatingSystem ? "1" : "0", GetFrameworkVersion());
+ Instalacao = val2;
+ }
+ val.Write<string>("MACHINEID", text, false);
+ Instalacao = Connection.Put<Instalacao>("Installation/Machine", Instalacao).Result;
+ return true;
+ });
+ }
+
+ public string GetMacAddress()
+ {
+ IEnumerable<string> values = from ni in NetworkInterface.GetAllNetworkInterfaces()
+ where ni.NetworkInterfaceType == NetworkInterfaceType.Ethernet || ni.NetworkInterfaceType == NetworkInterfaceType.Wireless80211
+ orderby ni.Id descending
+ select ni into x
+ select x.GetPhysicalAddress().ToString();
+ return string.Join("", values);
+ }
+
+ public NetworkInterface FindMacAddress(string macToSearch)
+ {
+ string[] macList = macToSearch.Split(new char[1] { '|' });
+ return NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault((NetworkInterface ni) => macList.Contains(ni.GetPhysicalAddress().ToString()));
+ }
+
+ public async Task<Tuple<bool, string>> VerificarVersao()
+ {
+ return new Tuple<bool, string>(bool.Parse(await Connection.Get<string>($"Installation/Version/{ApplicationHelper.IdFornecedor}")), "VERSÃO INDISPONÍVEL");
+ }
+
+ public async Task<string> FindKey()
+ {
+ string text = EncryptionHelper.Decrypt(new RegistryHelper(ApplicationHelper.Subkey).ForceRead("MACHINEID", false));
+ string text2 = (string.IsNullOrEmpty(text) ? (GetMacAddress() + GetMachineSerial()) : text);
+ return await Connection.Get<string>("Installation/Serial/" + text2, autorizar: false);
+ }
+
+ private string GetFrameworkVersion()
+ {
+ try
+ {
+ using RegistryKey registryKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey("SOFTWARE\\Microsoft\\NET Framework Setup\\NDP\\v4\\Full\\");
+ if (registryKey != null && registryKey.GetValue("Version") != null)
+ {
+ return registryKey.GetValue("Version").ToString();
+ }
+ }
+ catch
+ {
+ }
+ return "<4.5";
+ }
+}