diff --git a/MediaTekDocuments/App.config b/MediaTekDocuments/App.config
index f59bb87..a3d24b4 100644
--- a/MediaTekDocuments/App.config
+++ b/MediaTekDocuments/App.config
@@ -1,16 +1,38 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MediaTekDocuments/MediaTekDocuments.csproj b/MediaTekDocuments/MediaTekDocuments.csproj
index c2d4120..1cc65e2 100644
--- a/MediaTekDocuments/MediaTekDocuments.csproj
+++ b/MediaTekDocuments/MediaTekDocuments.csproj
@@ -12,6 +12,8 @@
512
true
true
+
+
AnyCPU
@@ -33,20 +35,94 @@
4
-
-
-
-
+
+ ..\packages\BouncyCastle.1.8.5\lib\BouncyCastle.Crypto.dll
+
+
+ ..\packages\BouncyCastle.Cryptography.2.6.2\lib\net461\BouncyCastle.Cryptography.dll
+
+
+ ..\packages\Google.Protobuf.3.34.1\lib\net45\Google.Protobuf.dll
+
+
+ ..\packages\K4os.Compression.LZ4.1.3.8\lib\net462\K4os.Compression.LZ4.dll
+
+
+ ..\packages\K4os.Compression.LZ4.Streams.1.3.8\lib\net462\K4os.Compression.LZ4.Streams.dll
+
+
+ ..\packages\K4os.Hash.xxHash.1.0.8\lib\net462\K4os.Hash.xxHash.dll
+
+
+ ..\packages\Microsoft.Bcl.AsyncInterfaces.5.0.0\lib\net461\Microsoft.Bcl.AsyncInterfaces.dll
+
+
+ ..\packages\MySql.Data.8.0.29\lib\net452\MySql.Data.dll
+
..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll
+
+ ..\packages\Serilog.4.3.1\lib\net471\Serilog.dll
+
+
+ ..\packages\Serilog.Sinks.File.7.0.0\lib\net471\Serilog.Sinks.File.dll
+
+
+ ..\packages\System.Buffers.4.5.1\lib\net461\System.Buffers.dll
+
+
+
+
+ ..\packages\System.Configuration.ConfigurationManager.8.0.0\lib\net462\System.Configuration.ConfigurationManager.dll
+
+
+ ..\packages\System.Diagnostics.DiagnosticSource.8.0.1\lib\net462\System.Diagnostics.DiagnosticSource.dll
+
+
+ ..\packages\System.IO.Pipelines.5.0.2\lib\net461\System.IO.Pipelines.dll
+
-
-
+
+ ..\packages\System.Memory.4.5.5\lib\net461\System.Memory.dll
+
+
+
+ ..\packages\System.Net.Http.2.0.20126.16343\lib\net40\System.Net.Http.dll
+ True
+ True
+
+
+ ..\packages\System.Net.Http.Formatting.Extension.5.2.3.0\lib\System.Net.Http.Extensions.dll
+
+
+ ..\packages\System.Net.Http.Formatting.Extension.5.2.3.0\lib\System.Net.Http.Formatting.dll
+
+
+ ..\packages\System.Net.Http.Formatting.Extension.5.2.3.0\lib\System.Net.Http.Primitives.dll
+
+
+ ..\packages\System.Net.Http.2.0.20126.16343\lib\net40\System.Net.Http.WebRequest.dll
+ True
+ True
+
+
+
+ ..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
+
+
+ ..\packages\System.Runtime.CompilerServices.Unsafe.6.0.0\lib\net461\System.Runtime.CompilerServices.Unsafe.dll
+
+
+ ..\packages\System.Threading.Channels.8.0.0\lib\net462\System.Threading.Channels.dll
+
+
+ ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll
+
@@ -54,11 +130,17 @@
-
-
-
+
+ ..\packages\MySql.Data.8.0.29\lib\net452\Ubiety.Dns.Core.dll
+
+
+ ..\packages\MySql.Data.8.0.29\lib\net452\ZstdNet.dll
+
+
+ ..\packages\ZstdSharp.Port.0.8.6\lib\net462\ZstdSharp.dll
+
@@ -124,4 +206,13 @@
+
+
+
+ Ce projet fait référence à des packages NuGet qui sont manquants sur cet ordinateur. Utilisez l'option de restauration des packages NuGet pour les télécharger. Pour plus d'informations, consultez http://go.microsoft.com/fwlink/?LinkID=322105. Le fichier manquant est : {0}.
+
+
+
+
+
\ No newline at end of file
diff --git a/MediaTekDocuments/Program.cs b/MediaTekDocuments/Program.cs
index 975e4a1..3ce3912 100644
--- a/MediaTekDocuments/Program.cs
+++ b/MediaTekDocuments/Program.cs
@@ -15,7 +15,6 @@ namespace MediaTekDocuments
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
- //Application.Run(new FrmAuth());
FrmAuth auth = new FrmAuth();
if (auth.ShowDialog() == DialogResult.OK)
diff --git a/MediaTekDocuments/dal/Access.cs b/MediaTekDocuments/dal/Access.cs
index db35f21..00c41c9 100644
--- a/MediaTekDocuments/dal/Access.cs
+++ b/MediaTekDocuments/dal/Access.cs
@@ -7,6 +7,7 @@ using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Linq;
using System.Configuration;
using System.Linq;
+using Serilog;
namespace MediaTekDocuments.dal
{
@@ -15,10 +16,6 @@ namespace MediaTekDocuments.dal
///
public class Access
{
- ///
- /// adresse de l'API
- ///
- private static readonly string uriApi = "http://localhost/rest_mediatekdocuments/";
///
/// instance unique de la classe
///
@@ -48,29 +45,34 @@ namespace MediaTekDocuments.dal
/// Méthode privée pour créer un singleton
/// initialise l'accès à l'API
///
+ // Le constructeur redevient sans paramètre pour le Singleton
private Access()
{
- String authenticationString;
+ string authenticationString;
+ string uriApi;
+
+ Log.Logger = new LoggerConfiguration().MinimumLevel.Debug().WriteTo.File("logs/log.txt", rollingInterval: RollingInterval.Day).CreateLogger();
+
try
{
- authenticationString = "admin:adminpwd";
+ uriApi = ConfigurationManager.AppSettings["ApiUri"];
+ authenticationString = ConfigurationManager.AppSettings["ApiAuthentication"];
api = ApiRest.GetInstance(uriApi, authenticationString);
+
+ Log.Information("Log de : {NomMethode} : {Message}", nameof(Access), "Api instanciée");
}
catch (Exception e)
{
- Console.WriteLine(e.Message);
+ Log.Fatal(e, "Erreur fatale lors de l'initialisation de l'accès API");
Environment.Exit(0);
}
}
- ///
- /// Création et retour de l'instance unique de la classe
- ///
- /// instance unique de la classe
public static Access GetInstance()
{
- if(instance == null)
+ if (instance == null)
{
+ // On appelle le constructeur sans argument
instance = new Access();
}
return instance;
@@ -165,6 +167,7 @@ namespace MediaTekDocuments.dal
catch (Exception ex)
{
Console.WriteLine(ex.Message);
+ Log.Error(ex, "Erreur dans {NomMethode} : {Message}", nameof(CreerExemplaire), ex.Message);
}
return false;
}
@@ -188,21 +191,21 @@ namespace MediaTekDocuments.dal
String code = (String)retour["code"];
if (code.Equals("200"))
{
- // dans le cas du GET (select), récupération de la liste d'objets
if (methode.Equals(GET))
{
String resultString = JsonConvert.SerializeObject(retour["result"]);
- // construction de la liste d'objets à partir du retour de l'api
liste = JsonConvert.DeserializeObject>(resultString, new CustomBooleanJsonConverter());
}
}
else
{
Console.WriteLine("code erreur = " + code + " message = " + (String)retour["message"]);
+ Log.Warning("API Retourne une erreur - Code: {Code}, Message: {Message}", code, (string)retour["message"]);
}
}catch(Exception e)
{
Console.WriteLine("Erreur lors de l'accès à l'API : "+e.Message);
+ Log.Error(e, "Erreur lors de l'accès à l'API via TraitementRecup");
Environment.Exit(0);
}
return liste;
@@ -274,7 +277,7 @@ namespace MediaTekDocuments.dal
}
catch (Exception ex)
{
- Console.WriteLine("Erreur lors de la suppression : " + ex.Message);
+ Log.Error(ex, "Erreur dans {NomMethode} : {Message}", nameof(DeleteCommande), ex.Message);
return false;
}
}
@@ -295,7 +298,7 @@ namespace MediaTekDocuments.dal
}
catch (Exception ex)
{
- Console.WriteLine(ex.Message);
+ Log.Error(ex, "Erreur lors de la création de commande");
}
return false;
}
@@ -303,12 +306,18 @@ namespace MediaTekDocuments.dal
public string GetNextCommandeId()
{
List result = TraitementRecup(GET, "maxcommande", null);
-
- if (result != null && result.Count > 0 && result[0].maxId != null)
+ if (result != null && result.Count > 0)
{
- string lastId = result[0].maxId.ToString();
- int nextIdVal = int.Parse(lastId.Substring(1)) + 1;
- return "" + nextIdVal.ToString("D4");
+ var firstResult = result[0];
+ if (firstResult != null && firstResult.maxId != null)
+ {
+ string lastId = firstResult.maxId.ToString();
+ if (lastId.Length > 1)
+ {
+ int nextIdVal = int.Parse(lastId.Substring(1)) + 1;
+ return nextIdVal.ToString("D4");
+ }
+ }
}
return "0001";
}
@@ -323,7 +332,7 @@ namespace MediaTekDocuments.dal
}
catch (Exception ex)
{
- Console.WriteLine("Erreur mise à jour suivi : " + ex.Message);
+ Log.Error(ex, "Erreur dans {NomMethode} : {Message}", nameof(UpdateSuiviCommande), ex.Message);
return false;
}
}
@@ -345,7 +354,7 @@ namespace MediaTekDocuments.dal
}
catch (Exception ex)
{
- Console.WriteLine("Erreur lors de l'accès à l'API : " + ex.Message);
+ Log.Error(ex, "Erreur dans {NomMethode} : {Message}", nameof(GetAbonnements), ex.Message);
return false;
}
}
@@ -358,7 +367,10 @@ namespace MediaTekDocuments.dal
JObject retour = api.RecupDistant(DELETE, "abonnement/" + jsonId, null);
return retour["code"].ToString().Equals("200");
}
- catch { return false; }
+ catch(Exception ex) {
+ Log.Error(ex, "Erreur dans {NomMethode} : {Message}", nameof(SupprimerAbonnement), ex.Message);
+ return false;
+ }
}
public Utilisateur GetConnection(string login, string pwd)
@@ -376,6 +388,7 @@ namespace MediaTekDocuments.dal
{
return lesUtilisateurs[0];
}
+ Log.Warning("Tentative de connexion échouée pour le login : {Login}", login);
return null;
}
}
diff --git a/MediaTekDocuments/packages.config b/MediaTekDocuments/packages.config
index 5eaa239..bc2c1f9 100644
--- a/MediaTekDocuments/packages.config
+++ b/MediaTekDocuments/packages.config
@@ -1,4 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/MediaTekDocuments/view/FrmAuth.cs b/MediaTekDocuments/view/FrmAuth.cs
index 2e77a55..e31ff7c 100644
--- a/MediaTekDocuments/view/FrmAuth.cs
+++ b/MediaTekDocuments/view/FrmAuth.cs
@@ -23,7 +23,8 @@ namespace MediaTekDocuments.view
private void FrmAuth_Load(object sender, EventArgs e)
{
- //
+ // Méthode laissée vide intentionnellement.
+ // Aucun traitement spécifique n'est requis au chargement du formulaire d'authentification.
}
private void btnLogin_Click(object sender, EventArgs e)
@@ -31,9 +32,9 @@ namespace MediaTekDocuments.view
string identifiant = txtIdentifiant.Text;
string password = txtPassword.Text;
- Utilisateur user = controller.GetConnection(identifiant, password);
+ Utilisateur utilisateur = controller.GetConnection(identifiant, password);
- if(user == null)
+ if(utilisateur == null)
{
txtIdentifiant.Text = "";
txtPassword.Text = "";
@@ -41,7 +42,7 @@ namespace MediaTekDocuments.view
return;
}
- if(user.LibelleService == "Culture")
+ if(utilisateur.LibelleService == "Culture")
{
MessageBox.Show("Vous n'êtes pas autorisé à accéder à cette application !", "Accès refusé", MessageBoxButtons.OK, MessageBoxIcon.Warning);
this.DialogResult = DialogResult.Abort;
@@ -49,7 +50,7 @@ namespace MediaTekDocuments.view
return;
}
- this.user = user;
+ this.user = utilisateur;
this.DialogResult = DialogResult.OK;
this.Close();
}
diff --git a/MediaTekDocuments/view/FrmMediatek.cs b/MediaTekDocuments/view/FrmMediatek.cs
index 9ec3b17..0e7b8a7 100644
--- a/MediaTekDocuments/view/FrmMediatek.cs
+++ b/MediaTekDocuments/view/FrmMediatek.cs
@@ -1,4 +1,5 @@
using System;
+using System.Text;
using System.Windows.Forms;
using MediaTekDocuments.model;
using MediaTekDocuments.controller;
@@ -33,7 +34,7 @@ namespace MediaTekDocuments.view
InitializeComponent();
this.controller = new FrmMediatekController();
this.user = user;
- this.Text += " - " + user.Prenom + " " + user.Nom;
+ this.Text += " - " + this.user.Prenom + " " + user.Nom;
RemplirComboSuivi(controller.GetAllSuivis(), bdgSuivis, cboSuivi);
RemplirComboSuivi(controller.GetAllSuivis(), bdgSuivis, cboSuiviDvd);
@@ -115,7 +116,7 @@ namespace MediaTekDocuments.view
if (tabOngletsApplication.TabPages.Contains(tabCommandeLivres))
{
dgvListeLivre2.DataSource = null;
- dgvListeLivre2.DataSource = bdgLivresListe;
+ dgvListeLivre2.DataSource = livres;
if (dgvListeLivre2.Columns.Count > 0 && dgvListeLivre2.Columns.Contains("isbn"))
{
@@ -454,7 +455,7 @@ namespace MediaTekDocuments.view
if (tabOngletsApplication.TabPages.Contains(tabCommandeDvd))
{
dgvDvd.DataSource = null;
- dgvDvd.DataSource = bdgDvdListe;
+ dgvDvd.DataSource = dvds;
if (dgvDvd.Columns.Count > 0 && dgvDvd.Columns.Contains("idRayon"))
{
@@ -1398,11 +1399,14 @@ namespace MediaTekDocuments.view
dgvCommandes.DataSource = null;
dgvCommandes.Columns.Clear();
dgvCommandes.DataSource = lesCommandes;
- string[] toHide = { "id", "idLivreDvd", "idSuivi" };
- foreach (string col in toHide)
- if (dgvCommandes.Columns.Contains(col)) dgvCommandes.Columns[col].Visible = false;
- dgvCommandes.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
+ string[] toHide = { "id", "idLivreDvd", "idSuivi" };
+ dgvCommandes.Columns.Cast()
+ .Where(col => toHide.Contains(col.Name))
+ .ToList()
+ .ForEach(col => col.Visible = false);
+
+ dgvCommandes.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
dgvCommandes.ClearSelection();
dgvCommandes.CurrentCell = null;
ViderZonesSaisieCommande();
@@ -1441,10 +1445,10 @@ namespace MediaTekDocuments.view
if (dgvCommandes.CurrentRow.Cells["Montant"].Value != null)
{
- CommandeDocument commandeDocument = (CommandeDocument)dgvCommandes.CurrentRow.DataBoundItem;
updownMontant.Value = Convert.ToDecimal(dgvCommandes.CurrentRow.Cells["Montant"].Value);
updownNbExemplaire.Value = Convert.ToDecimal(dgvCommandes.CurrentRow.Cells["NbExemplaire"].Value);
- string etape = commandeDocument.LibelleSuivi;
+
+ string etape = commande.LibelleSuivi;
cboSuivi.SelectedIndex = cboSuivi.FindStringExact(etape);
grpNewCommande.Text = "Modifier commande";
@@ -1452,8 +1456,6 @@ namespace MediaTekDocuments.view
dateTimeCommande.Enabled = false;
updownMontant.Enabled = false;
updownNbExemplaire.Enabled = false;
-
-
}
}
else
@@ -1466,8 +1468,6 @@ namespace MediaTekDocuments.view
{
if (dgvListeLivre2.CurrentCell != null && dgvCommandes.CurrentCell != null)
{
- string id = dgvListeLivre2.CurrentRow.Cells["Id"].Value.ToString();
- string commandeId = dgvCommandes.CurrentRow.Cells["id"].Value.ToString();
CommandeDocument commande = (CommandeDocument)dgvCommandes.CurrentRow.DataBoundItem;
btnDeleteCommande.Enabled = false;
@@ -1647,9 +1647,12 @@ namespace MediaTekDocuments.view
{
dgvCommandesDvd.DataSource = null;
dgvCommandesDvd.DataSource = lesCommandes;
+
string[] toHide = { "id", "idLivreDvd", "idSuivi" };
- foreach (string col in toHide)
- if (dgvCommandesDvd.Columns.Contains(col)) dgvCommandesDvd.Columns[col].Visible = false;
+ dgvCommandesDvd.Columns.Cast()
+ .Where(col => toHide.Contains(col.Name))
+ .ToList()
+ .ForEach(col => col.Visible = false);
dgvCommandesDvd.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
}
@@ -1768,10 +1771,8 @@ namespace MediaTekDocuments.view
private void btnDeleteCommandeDvd_Click(object sender, EventArgs e)
{
- if (dgvCommandesDvd.CurrentCell != null && dgvCommandesDvd.CurrentCell != null)
+ if (dgvCommandesDvd.CurrentCell != null)
{
- string id = dgvCommandesDvd.CurrentRow.Cells["Id"].Value.ToString();
- string commandeId = dgvCommandesDvd.CurrentRow.Cells["id"].Value.ToString();
CommandeDocument commande = (CommandeDocument)dgvCommandesDvd.CurrentRow.DataBoundItem;
btnDeleteCommandeDvd.Enabled = false;
@@ -1816,40 +1817,31 @@ namespace MediaTekDocuments.view
private void AlerteAbonnementsExpirants()
{
List toutesLesRevues = controller.GetAllRevues();
- string message = "Abonnements se terminant sous 30 jours :\n";
+ StringBuilder stp = new StringBuilder("Abonnements se terminant sous 30 jours :\n");
bool alerte = false;
foreach (Revue revue in toutesLesRevues)
{
List abos = controller.GetAbonnements(revue.Id);
- // On prend le dernier abonnement (le plus récent)
Abonnement dernierAbo = abos.OrderByDescending(a => a.DateFinAbonnement).FirstOrDefault();
if (dernierAbo != null && (dernierAbo.DateFinAbonnement - DateTime.Now).TotalDays <= 30
&& (dernierAbo.DateFinAbonnement - DateTime.Now).TotalDays > 0)
{
- message += $"- {revue.Titre} : finit le {dernierAbo.DateFinAbonnement:dd/MM/yyyy}\n";
+ stp.Append($"- {revue.Titre} : finit le {dernierAbo.DateFinAbonnement:dd/MM/yyyy}\n");
alerte = true;
}
}
-
if (alerte)
{
- MessageBox.Show(message, "Alerte Abonnements", MessageBoxButtons.OK, MessageBoxIcon.Warning);
+ MessageBox.Show(stp.ToString(), "Alerte Abonnements", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private bool PeutSupprimerAbonnement(Abonnement abonnement)
{
List exemplaires = controller.GetExemplairesRevue(abonnement.IdRevue);
- foreach (Exemplaire ex in exemplaires)
- {
- if (ParutionDansAbonnement(abonnement.DateCommande, abonnement.DateFinAbonnement, ex.DateAchat))
- {
- return false;
- }
- }
- return true;
+ return !exemplaires.Exists(ex => ParutionDansAbonnement(abonnement.DateCommande,abonnement.DateFinAbonnement, ex.DateAchat));
}
public bool ParutionDansAbonnement(DateTime dateCommande, DateTime dateFinAbonnement, DateTime dateParution)
@@ -1920,7 +1912,7 @@ namespace MediaTekDocuments.view
private void btnAbonnementAjouter_Click(object sender, EventArgs e)
{
string idRevue = txbRevuesCommandesNumRecherche.Text;
- if (idRevue.Equals(""))
+ if (string.IsNullOrEmpty(idRevue))
{
MessageBox.Show("Veuillez d'abord sélectionner une revue.", "Information");
return;
diff --git a/Mediatek.Tests/Mediatek.Tests.csproj b/Mediatek.Tests/Mediatek.Tests.csproj
index 3ac5e17..23ff553 100644
--- a/Mediatek.Tests/Mediatek.Tests.csproj
+++ b/Mediatek.Tests/Mediatek.Tests.csproj
@@ -54,6 +54,7 @@
+
diff --git a/Mediatek.Tests/UnitTest1.cs b/Mediatek.Tests/UnitTest1.cs
index bdbf341..76ec402 100644
--- a/Mediatek.Tests/UnitTest1.cs
+++ b/Mediatek.Tests/UnitTest1.cs
@@ -14,22 +14,23 @@ namespace Mediatek.Tests
Utilisateur user = new Utilisateur("1", "admin", "philippe", "erwann", 1, "administration");
FrmMediatek frm = new FrmMediatek(user);
- DateTime debut = new DateTime(2024, 01, 01);
- DateTime fin = new DateTime(2024, 12, 31);
+ // Ajout de DateTimeKind.Local à chaque création d'objet DateTime
+ DateTime debut = new DateTime(2024, 01, 01, 0, 0, 0, DateTimeKind.Local);
+ DateTime fin = new DateTime(2024, 12, 31, 0, 0, 0, DateTimeKind.Local);
- DateTime parutionDebut = new DateTime(2024, 01, 01);
+ DateTime parutionDebut = new DateTime(2024, 01, 01, 0, 0, 0, DateTimeKind.Local);
Assert.IsTrue(frm.ParutionDansAbonnement(debut, fin, parutionDebut), "La date de début devrait être incluse.");
- DateTime parutionFin = new DateTime(2024, 12, 31);
+ DateTime parutionFin = new DateTime(2024, 12, 31, 0, 0, 0, DateTimeKind.Local);
Assert.IsTrue(frm.ParutionDansAbonnement(debut, fin, parutionFin), "La date de fin devrait être incluse.");
- DateTime parutionMilieu = new DateTime(2024, 06, 15);
+ DateTime parutionMilieu = new DateTime(2024, 06, 15, 0, 0, 0, DateTimeKind.Local);
Assert.IsTrue(frm.ParutionDansAbonnement(debut, fin, parutionMilieu), "Une date en milieu d'abonnement doit être vraie.");
- DateTime parutionAvant = new DateTime(2023, 12, 31);
+ DateTime parutionAvant = new DateTime(2023, 12, 31, 0, 0, 0, DateTimeKind.Local);
Assert.IsFalse(frm.ParutionDansAbonnement(debut, fin, parutionAvant), "Une date avant le début doit être fausse.");
- DateTime parutionApres = new DateTime(2025, 01, 01);
+ DateTime parutionApres = new DateTime(2025, 01, 01, 0, 0, 0, DateTimeKind.Local);
Assert.IsFalse(frm.ParutionDansAbonnement(debut, fin, parutionApres), "Une date après la fin doit être fausse.");
}
}
diff --git a/Mediatek.Tests/app.config b/Mediatek.Tests/app.config
new file mode 100644
index 0000000..6b5675c
--- /dev/null
+++ b/Mediatek.Tests/app.config
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file