Commit 8f509b48 authored by kruger's avatar kruger

premiere modif des fichier

parent b08f027d
......@@ -50,9 +50,11 @@ extern int nMINIMISE,nELITE;
extern bool bELITISM, bVERBOSE;
extern bool bBALDWINISM;
extern bool bPRINT_STATS, bPLOT_STATS, bGENERATE_CSV_FILE, bGENERATE_GNUPLOT_SCRIPT, bGENERATE_R_SCRIPT;
extern bool bSAVE_POPULATION, bSTART_FROM_FILE;
extern char* nGENOME_NAME;
extern int nPOP_SIZE, nNB_GEN, nNB_OPT_IT, nOFF_SIZE, nPROBLEM_DIM, nTIME_LIMIT;
extern float fMUT_PROB, fXOVER_PROB, fSURV_PAR_SIZE, fSURV_OFF_SIZE;
extern bool bREMOTE_ISLAND_MODEL;
extern int nWARNINGS, nERRORS;
extern int TARGET, OPERATING_SYSTEM;
......
This diff is collapsed.
......@@ -680,15 +680,6 @@ exponent ([Ee][+-]?[0-9]+)
<TEMPLATE_ANALYSIS>"\\GENOME_SERIAL" {
CListItem<CSymbol*> *pSym;
if (bVERBOSE) printf ("Inserting default genome serializer.\n");
pGENOME->pSymbolList->reset();
while (pSym=pGENOME->pSymbolList->walkToNextItem()){
//DEBUG_PRT_PRT("found new symbol %s",pSym->Object->sName);
fprintf(fpOutputFile," ar & %s;\n",pSym->Object->sName);
}
}
<TEMPLATE_ANALYSIS>"\\INSERT_GENOME" {
if (pGENOME->sString) {
......@@ -761,6 +752,23 @@ exponent ([Ee][+-]?[0-9]+)
}
}
<TEMPLATE_ANALYSIS>"\\GENOME_SERIAL" {
CListItem<CSymbol*> *pSym;
if (bVERBOSE) printf ("Inserting default genome serializer.\n");
fprintf (fpOutputFile,"// Memberwise serialization\n");
pGENOME->pSymbolList->reset();
pGENOME->serializeIndividual(fpOutputFile, "this");
//fprintf(fpOutputFile,"\tEASEA_Line << endl;\n");
}
<TEMPLATE_ANALYSIS>"\\GENOME_DESERIAL" {
CListItem<CSymbol*> *pSym;
if (bVERBOSE) printf ("Inserting default genome deserializer.\n");
fprintf (fpOutputFile,"// Memberwise deserialization\n");
pGENOME->pSymbolList->reset();
pGENOME->deserializeIndividual(fpOutputFile, "this");
}
<TEMPLATE_ANALYSIS>"\\COPY_CUDA_CTOR" {
CListItem<CSymbol*> *pSym;
if (bVERBOSE) printf ("Creating default copy constructor.\n");
......@@ -1094,15 +1102,21 @@ if(OPERATING_SYSTEM=WINDOWS)
<TEMPLATE_ANALYSIS>"\\XOVER_PROB" {fprintf(fpOutputFile,"%f",fXOVER_PROB);}
<TEMPLATE_ANALYSIS>"\\MINIMAXI" {fprintf(fpOutputFile,"%s",(nMINIMISE? "true" : "false")); }
<TEMPLATE_ANALYSIS>"\\ELITISM" {fprintf(fpOutputFile,"%d",bELITISM);}
<TEMPLATE_ANALYSIS>"\\NB_OPT_IT" {fprintf(fpOutputFile,"%d",nNB_OPT_IT);}
<TEMPLATE_ANALYSIS>"\\BALDWINISM" {fprintf(fpOutputFile,"%d",bBALDWINISM);}
<TEMPLATE_ANALYSIS>"\\REMOTE_ISLAND_MODEL" {fprintf(fpOutputFile,"%d",bREMOTE_ISLAND_MODEL);}
<TEMPLATE_ANALYSIS>"\\PRINT_STATS" {fprintf(fpOutputFile,"%d",bPRINT_STATS);}
<TEMPLATE_ANALYSIS>"\\PLOT_STATS" {fprintf(fpOutputFile,"%d",bPLOT_STATS);}
<TEMPLATE_ANALYSIS>"\\GENERATE_CSV_FILE" {fprintf(fpOutputFile,"%d",bGENERATE_CSV_FILE);}
<TEMPLATE_ANALYSIS>"\\GENERATE_GNUPLOT_SCRIPT" {fprintf(fpOutputFile,"%d",bGENERATE_GNUPLOT_SCRIPT);}
<TEMPLATE_ANALYSIS>"\\GENERATE_R_SCRIPT" {fprintf(fpOutputFile,"%d",bGENERATE_R_SCRIPT);}
<TEMPLATE_ANALYSIS>"\\SAVE_POPULATION" {fprintf(fpOutputFile,"%d",bSAVE_POPULATION);}
<TEMPLATE_ANALYSIS>"\\START_FROM_FILE" {fprintf(fpOutputFile,"%d",bSTART_FROM_FILE);}
<TEMPLATE_ANALYSIS>"\\START_CUDA_GENOME_H_TPL" {
char sFileName[1000];
fclose(fpOutputFile);
......@@ -1528,7 +1542,7 @@ if(OPERATING_SYSTEM=WINDOWS)
fprintf(fpOutputFile,"template <class fitT> %s %sGenome<fitT>::",yytext,sPROJECT_NAME);}
<COPY>"GenomeClass::" {fprintf(fpOutputFile,"template <class fitT> %sGenome<fitT>::",sPROJECT_NAME);}
<COPY>"GenomeClass" {
if( TARGET==CUDA || TARGET==STD) fprintf(fpOutputFile,"Individual");
if( TARGET==CUDA || TARGET==STD) fprintf(fpOutputFile,"IndividualImpl");
else fprintf(fpOutputFile,"%sGenome",sPROJECT_NAME);} // local name
<COPY>"pPopulation[" {
if(bFinalizationFunction){
......@@ -1602,7 +1616,7 @@ if(OPERATING_SYSTEM=WINDOWS)
// keywords
<GENOME_ANALYSIS>"bool" {
yylval.pSymbol = pSymbolTable->find("boolean");
yylval.pSymbol = pSymbolTable->find("bool");
return BOOL;}
<GENOME_ANALYSIS>"boolean" {
yylval.pSymbol = new CSymbol(yytext);
......@@ -2053,12 +2067,15 @@ if(OPERATING_SYSTEM=WINDOWS)
<GET_PARAMETERS>"Crossover"[ \t\n]+"probability"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf ("\tXov Prob...\n");return XOVER_PROB;}
<GET_PARAMETERS>"Offspring"[ \t\n]+"size"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf ("\tOff Size...\n");return OFFSPRING;}
<GET_PARAMETERS>"Print"[ \t\n]+"stats"[ \t\n]*":"[\t\n]* {if (bVERBOSE) printf("\tPrint Stats...\n");return PRINT_STATS;}
<GET_PARAMETERS>"Plot"[ \t\n]+"stats"[ \t\n]*":"[\t\n]* {if (bVERBOSE) printf("\tPlot Stats with gnuplot...\n");return PLOT_STATS;}
<GET_PARAMETERS>"Print"[ \t\n]+"stats"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf("\tPrint Stats...\n");return PRINT_STATS;}
<GET_PARAMETERS>"Plot"[ \t\n]+"stats"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf("\tPlot Stats with gnuplot...\n");return PLOT_STATS;}
<GET_PARAMETERS>"Generate"[ \t\n]+"csv"[ \t\n]+"stats"[ \t\n]+"file"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf("\tPrint Stats to csv File...\n");return GENERATE_CSV_FILE;}
<GET_PARAMETERS>"Generate"[ \t\n]+"gnuplot"[ \t\n]+"script"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf("\tGenerate Gnuplot Script...\n");return GENERATE_GNUPLOT_SCRIPT;}
<GET_PARAMETERS>"Generate"[ \t\n]+"R"[ \t\n]+"script"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf("\tGenerate R Script...\n");return GENERATE_R_SCRIPT;}
<GET_PARAMETERS>"Save"[ \t\n]+"population"[ \t\n]*":"[ \t\n]* {if(bVERBOSE) printf("\tSave population...\n"); return SAVE_POPULATION;}
<GET_PARAMETERS>"Start"[ \t\n]+"from"[ \t\n]+"file"[ \t\n]*":"[ \t\n]* {if(bVERBOSE) printf("\tStart from file...\n"); return START_FROM_FILE;}
<GET_PARAMETERS>"Reduce"[ \t\n]+"parents"[ \t\n]+"operator"[ \t\n]*":"[ \t\n]* {
if (bVERBOSE) printf ("\tReduce Parents Operator...\n");
bIsParentReduce = true;
......@@ -2079,6 +2096,9 @@ if(OPERATING_SYSTEM=WINDOWS)
<GET_PARAMETERS>"Evaluator"[ \t\n]+"goal"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf ("\tMinMax...\n");return MINIMAXI;}
<GET_PARAMETERS>"Number"[ \t\n]+"of"[ \t\n]+"optimisation"[ \t\n]+"iterations"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf ("\tNb of Optimisation It...\n");return NB_OPT_IT;}
<GET_PARAMETERS>"Baldwinism"[ \t\n]*":"[ \t\n]* {if (bVERBOSE) printf ("\tBaldwinism...\n");return BALDWINISM;}
<GET_PARAMETERS>"Remote"[ \t\n]+"island"[ \t\n]+"model"[ \t\n]*":"[ \t\n]* {if(bVERBOSE) printf ("\tRemote Island Model...\n"); return REMOTE_ISLAND_MODEL;}
// number
<GET_PARAMETERS>[0-9]+"."[0-9]*{exponent}? |
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
#include <cyacc.h>
#line 65 "EaseaParse.y"
#line 67 "EaseaParse.y"
// forward references
class CSymbol;
......@@ -11,7 +11,7 @@ class CSymbol;
#line 12 "EaseaParse.h"
#ifndef YYSTYPE
union tagYYSTYPE {
#line 71 "EaseaParse.y"
#line 73 "EaseaParse.y"
CSymbol* pSymbol;
double dValue;
......@@ -65,26 +65,29 @@ union tagYYSTYPE {
#define MINIMAXI 294
#define ELITISM 295
#define ELITE 296
#define PRINT_STATS 297
#define PLOT_STATS 298
#define GENERATE_CSV_FILE 299
#define GENERATE_GNUPLOT_SCRIPT 300
#define GENERATE_R_SCRIPT 301
#define TIME_LIMIT 302
#define MAX_INIT_TREE_D 303
#define MIN_INIT_TREE_D 304
#define MAX_XOVER_DEPTH 305
#define MAX_MUTAT_DEPTH 306
#define MAX_TREE_D 307
#define NB_GPU 308
#define PRG_BUF_SIZE 309
#define NO_FITNESS_CASES 310
#line 150 "EaseaParse.y"
#define REMOTE_ISLAND_MODEL 297
#define PRINT_STATS 298
#define PLOT_STATS 299
#define GENERATE_CSV_FILE 300
#define GENERATE_GNUPLOT_SCRIPT 301
#define GENERATE_R_SCRIPT 302
#define SAVE_POPULATION 303
#define START_FROM_FILE 304
#define TIME_LIMIT 305
#define MAX_INIT_TREE_D 306
#define MIN_INIT_TREE_D 307
#define MAX_XOVER_DEPTH 308
#define MAX_MUTAT_DEPTH 309
#define MAX_TREE_D 310
#define NB_GPU 311
#define PRG_BUF_SIZE 312
#define NO_FITNESS_CASES 313
#line 155 "EaseaParse.y"
#include "EaseaSym.h"
#include "EaseaLex.h"
#line 88 "EaseaParse.h"
#line 91 "EaseaParse.h"
/////////////////////////////////////////////////////////////////////////////
// CEASEAParser
......@@ -105,7 +108,7 @@ protected:
#endif
public:
#line 157 "EaseaParse.y"
#line 162 "EaseaParse.y"
protected:
CEASEALexer EASEALexer; // the lexical analyser
......@@ -119,7 +122,7 @@ public:
double divide(double dDividend, double dDivisor);
CSymbol* insert() const;
#line 123 "EaseaParse.h"
#line 126 "EaseaParse.h"
};
#ifndef YYPARSENAME
......
......@@ -46,7 +46,9 @@ bool bLINE_NUM_EZ_FILE=1;
bool bPRINT_STATS=1;
bool bPLOT_STATS=0;
bool bGENERATE_CSV_FILE=0, bGENERATE_R_SCRIPT=0, bGENERATE_GNUPLOT_SCRIPT=0;
bool bSAVE_POPULATION=0, bSTART_FROM_FILE=0;
bool bBALDWINISM=0;
bool bREMOTE_ISLAND_MODEL=0;
int nPOP_SIZE, nOFF_SIZE;
float fSURV_PAR_SIZE=-1.0, fSURV_OFF_SIZE=-1.0;
char *nGENOME_NAME;
......@@ -132,11 +134,14 @@ class CSymbol;
%token MINIMAXI
%token ELITISM
%token ELITE
%token REMOTE_ISLAND_MODEL //island model
%token PRINT_STATS
%token PLOT_STATS
%token GENERATE_CSV_FILE
%token GENERATE_GNUPLOT_SCRIPT
%token GENERATE_R_SCRIPT
%token SAVE_POPULATION
%token START_FROM_FILE
%token TIME_LIMIT
%token MAX_INIT_TREE_D
%token MIN_INIT_TREE_D
......@@ -610,6 +615,14 @@ Parameter
fprintf(stderr,"\n%s - Warning line %d: Baldwinism must be \"True\" or \"False\".\nDefault value \"True\" inserted.\n.",sEZ_FILE_NAME,EASEALexer.yylineno);nWARNINGS++;
bBALDWINISM=1;
}}
| REMOTE_ISLAND_MODEL IDENTIFIER2{
if (!mystricmp($2->sName,"False")) bREMOTE_ISLAND_MODEL=0;
else if (!mystricmp($2->sName,"True")) bREMOTE_ISLAND_MODEL=1;
else {
fprintf(stderr,"\n%s - Warning line %d: remote island model must be \"True\" or \"False\".\nDefault value \"False\" inserted.\n",sEZ_FILE_NAME,EASEALexer.yylineno);nWARNINGS++;
bREMOTE_ISLAND_MODEL=0;
}}
| PRINT_STATS NUMBER2{
if((int)$2>=1)
......@@ -641,6 +654,20 @@ Parameter
else
bGENERATE_R_SCRIPT=0;
}
| SAVE_POPULATION IDENTIFIER2{
if (!mystricmp($2->sName,"False")) bSAVE_POPULATION=0;
else if (!mystricmp($2->sName,"True")) bSAVE_POPULATION=1;
else {
fprintf(stderr,"\n%s - Warning line %d: SavePopulation must be \"True\" or \"False\".\nDefault value \"False\" inserted.\n.",sEZ_FILE_NAME,EASEALexer.yylineno);nWARNINGS++;
bSAVE_POPULATION=0;
}}
| START_FROM_FILE IDENTIFIER2{
if (!mystricmp($2->sName,"False")) bSTART_FROM_FILE=0;
else if (!mystricmp($2->sName,"True")) bSTART_FROM_FILE=1;
else {
fprintf(stderr,"\n%s - Warning line %d: StartFromFile must be \"True\" or \"False\".\nDefault value \"False\" inserted.\n.",sEZ_FILE_NAME,EASEALexer.yylineno);nWARNINGS++;
bSTART_FROM_FILE=0;
}}
| MAX_INIT_TREE_D NUMBER2 {iMAX_INIT_TREE_D = (unsigned)$2;}
| MIN_INIT_TREE_D NUMBER2 {iMIN_INIT_TREE_D = (unsigned)$2;}
| MAX_TREE_D NUMBER2 {iMAX_TREE_D = (unsigned)$2;}
......
......@@ -185,9 +185,59 @@ void CSymbol::print(FILE *fp){
fprintf(fp," if( %s[EASEA_Ndx] ) delete %s[EASEA_Ndx];\n",pSym->Object->sName,pSym->Object->sName);
}
}
fprintf(fp," }\n"); // destructor
fprintf(fp," string serializer() { // serialize\n"); // serializer
fprintf(fp," \tostringstream EASEA_Line(ios_base::app);\n");
pSymbolList->reset();
while (pSym=pSymbolList->walkToNextItem()){
if((pSym->Object->pType->ObjectType==oUserClass)){
fprintf(fpOutputFile,"\tif(this->%s != NULL){\n",pSym->Object->sName);
fprintf(fpOutputFile,"\t\tEASEA_Line << \"\\a \";\n");
fprintf(fpOutputFile,"\t\tEASEA_Line << this->%s->serializer() << \" \";\n",pSym->Object->sName);
fprintf(fpOutputFile,"}\n");
fprintf(fpOutputFile,"\telse\n");
fprintf(fpOutputFile,"\t\tEASEA_Line << \"NULL\" << \" \";\n");
}
else{
if (pSym->Object->ObjectType==oObject){
fprintf(fpOutputFile,"\tEASEA_Line << this->%s << \" \";\n",pSym->Object->sName);
}
if(pSym->Object->ObjectType==oArray){
fprintf(fpOutputFile,"\tfor(int EASEA_Ndx=0; EASEA_Ndx<%d; EASEA_Ndx++)\n",pSym->Object->nSize/pSym->Object->pType->nSize);
fprintf(fpOutputFile,"\t\tEASEA_Line << this->%s[EASEA_Ndx] <<\" \";\n", pSym->Object->sName);
}
}
}
fprintf(fp," \treturn EASEA_Line.str();\n");
fprintf(fp," }\n"); // serializer
fprintf(fp," void deserializer(istringstream* EASEA_Line) { // deserialize\n"); // deserializer
fprintf(fp," \tstring line;\n");
pSymbolList->reset();
while (pSym=pSymbolList->walkToNextItem()){
if((pSym->Object->pType->ObjectType==oUserClass)){
fprintf(fpOutputFile,"\t(*EASEA_Line) >> line;\n");
fprintf(fpOutputFile,"\tif(strcmp(line.c_str(),\"NULL\")==0)\n");
fprintf(fpOutputFile,"\t\tthis->%s = NULL;\n",pSym->Object->sName);
fprintf(fpOutputFile,"\telse{\n");
fprintf(fpOutputFile,"\t\tthis->%s = new %s;\n",pSym->Object->sName, sName);
fprintf(fpOutputFile,"\t\tthis->%s->deserializer(EASEA_Line);\n",pSym->Object->sName);
fprintf(fpOutputFile,"\t}");
}
else{
if (pSym->Object->ObjectType==oObject){
fprintf(fpOutputFile,"\t(*EASEA_Line) >> this->%s;\n",pSym->Object->sName);
}
if(pSym->Object->ObjectType==oArray){
fprintf(fpOutputFile,"\tfor(int EASEA_Ndx=0; EASEA_Ndx<%d; EASEA_Ndx++)\n",pSym->Object->nSize/pSym->Object->pType->nSize);
fprintf(fpOutputFile,"\t\t(*EASEA_Line) >> this->%s[EASEA_Ndx];\n", pSym->Object->sName);
}
}
}
fprintf(fp," }\n"); // deserializer
fprintf(fp," %s& operator=(const %s &EASEA_Var) { // Operator=\n",sName,sName); // operator=
fprintf(fp," if (&EASEA_Var == this) return *this;\n");
pSymbolList->reset();
......@@ -325,6 +375,57 @@ void CSymbol::printUserClasses(FILE *fp){
}
}
void CSymbol::serializeIndividual(FILE *fp, char* sCompleteName){
CListItem<CSymbol*> *pSym;
pSymbolList->reset();
char sNewCompleteName[1000];
strcpy(sNewCompleteName, sCompleteName);
while(pSym=pSymbolList->walkToNextItem()){
if((pSym->Object->pType->ObjectType==oUserClass)){
fprintf(fpOutputFile,"\tif(this->%s != NULL){\n",pSym->Object->sName);
fprintf(fpOutputFile,"\t\tEASEA_Line << \"\\a \";\n");
fprintf(fpOutputFile,"\t\tEASEA_Line << this->%s->serializer() << \" \";\n",pSym->Object->sName);
fprintf(fpOutputFile,"\t}\n");
fprintf(fpOutputFile,"\telse\n");
fprintf(fpOutputFile,"\t\tEASEA_Line << \"NULL\" << \" \";\n");
}
else{
if (pSym->Object->ObjectType==oObject){
fprintf(fpOutputFile,"\tEASEA_Line << this->%s << \" \";\n",pSym->Object->sName);
}
if(pSym->Object->ObjectType==oArray){
fprintf(fpOutputFile,"\tfor(int EASEA_Ndx=0; EASEA_Ndx<%d; EASEA_Ndx++)\n",pSym->Object->nSize/pSym->Object->pType->nSize);
fprintf(fpOutputFile,"\t\tEASEA_Line << this->%s[EASEA_Ndx] <<\" \";\n", pSym->Object->sName);
}
}
}
}
void CSymbol::deserializeIndividual(FILE *fp, char* sCompleteName){
CListItem<CSymbol*> *pSym;
pSymbolList->reset();
while (pSym=pSymbolList->walkToNextItem()){
if((pSym->Object->pType->ObjectType==oUserClass)){
fprintf(fpOutputFile,"\tEASEA_Line >> line;\n");
fprintf(fpOutputFile,"\tif(strcmp(line.c_str(),\"NULL\")==0)\n");
fprintf(fpOutputFile,"\t\tthis->%s = NULL;\n",pSym->Object->sName);
fprintf(fpOutputFile,"\telse{\n");
fprintf(fpOutputFile,"\t\tthis->%s = new %s;\n",pSym->Object->sName, pSym->Object->pType->sName);
fprintf(fpOutputFile,"\t\tthis->%s->deserializer(&EASEA_Line);\n",pSym->Object->sName);
fprintf(fpOutputFile,"\t}");
}
else{
if (pSym->Object->ObjectType==oObject){
fprintf(fpOutputFile,"\tEASEA_Line >> this->%s;\n",pSym->Object->sName);
}
if(pSym->Object->ObjectType==oArray){
fprintf(fpOutputFile,"\tfor(int EASEA_Ndx=0; EASEA_Ndx<%d; EASEA_Ndx++)\n",pSym->Object->nSize/pSym->Object->pType->nSize);
fprintf(fpOutputFile,"\t\tEASEA_Line >> this->%s[EASEA_Ndx];\n", pSym->Object->sName);
}
}
}
}
void CSymbol::printAllSymbols(FILE *fp, char *sCompleteName, EObjectType FatherType, CListItem<CSymbol *> *pSym){
char sNewCompleteName[1000], s[20];
......
......@@ -91,6 +91,8 @@ public:
void printAllSymbols(FILE *f, char *, EObjectType, CListItem<CSymbol *> *pSym);
void printUserClasses(FILE* fp);
void printUC(FILE* fp);
void serializeIndividual(FILE *fp, char* sCompleteName);
void deserializeIndividual(FILE *fp, char* sCompleteName);
};
......
......@@ -516,17 +516,17 @@
\GenomeClass::crossover:
int locusC = random(0,child1.Size-1);
int locusC = random(0,child.Size-1);
int locusP2 = random(0,parent2.Size-1);
Element * elt1=chercheNoeud(child1.arbre,locusC);
Element * elt1=chercheNoeud(child.arbre,locusC);
Element * eltParent2=chercheNoeud(parent2.arbre,locusP2);
Element *elt11 = copierSousArbreRec(eltParent2, elt1->profondeur,profondeurMax1);
remplace(child1.arbre,elt11,locusC);
regenSize(child1.arbre);
child1.Size=SIZE;
remplace(child.arbre,elt11,locusC);
regenSize(child.arbre);
child.Size=SIZE;
\end
......@@ -643,6 +643,8 @@
Surviving offspring: 96
Final reduce operator: Tournament 2
Elitism: Weak
Save population:true
\end
......@@ -183,7 +183,7 @@ void MaxTournament::initialize(CIndividual** population, float selectionPressure
}
float MaxTournament::getExtremum(){
return FLT_MAX;
return -FLT_MAX;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment