improved y axis tick generation and labeling.
This commit is contained in:
@@ -29,13 +29,13 @@
|
|||||||
<inlines>
|
<inlines>
|
||||||
<inline loc="end" access="public">
|
<inline loc="end" access="public">
|
||||||
<content>
|
<content>
|
||||||
$(api) void $(struct_prefix)_AddNewTick($(struct_type) *st, const char *label, double v, int lvl, uint32_t flags);
|
$(api) void $(struct_prefix)_AddNewTick($(struct_type) *st, const char *label, double v, int lvl, uint32_t flags, double dist);
|
||||||
</content>
|
</content>
|
||||||
</inline>
|
</inline>
|
||||||
|
|
||||||
<inline loc="code">
|
<inline loc="code">
|
||||||
<content>
|
<content>
|
||||||
void $(struct_prefix)_AddNewTick($(struct_type) *st, const char *label, double v, int lvl, uint32_t flags) \n
|
void $(struct_prefix)_AddNewTick($(struct_type) *st, const char *label, double v, int lvl, uint32_t flags, double dist) \n
|
||||||
{ \n
|
{ \n
|
||||||
AQDG_GRAPH_TICK *tick; \n
|
AQDG_GRAPH_TICK *tick; \n
|
||||||
\n
|
\n
|
||||||
@@ -44,6 +44,7 @@
|
|||||||
AQDG_Graph_Tick_SetValue(tick, v); \n
|
AQDG_Graph_Tick_SetValue(tick, v); \n
|
||||||
AQDG_Graph_Tick_SetLevel(tick, lvl); \n
|
AQDG_Graph_Tick_SetLevel(tick, lvl); \n
|
||||||
AQDG_Graph_Tick_SetFlags(tick, flags); \n
|
AQDG_Graph_Tick_SetFlags(tick, flags); \n
|
||||||
|
AQDG_Graph_Tick_SetLevelDist(tick, dist); \n
|
||||||
if (st->tickList==NULL) \n
|
if (st->tickList==NULL) \n
|
||||||
st->tickList=AQDG_Graph_Tick_List_new(); \n
|
st->tickList=AQDG_Graph_Tick_List_new(); \n
|
||||||
AQDG_Graph_Tick_List_Add(tick, st->tickList); \n
|
AQDG_Graph_Tick_List_Add(tick, st->tickList); \n
|
||||||
@@ -82,53 +83,49 @@
|
|||||||
if ((st->minValue)<startValue) \n
|
if ((st->minValue)<startValue) \n
|
||||||
startValue=-startValue; \n
|
startValue=-startValue; \n
|
||||||
\n
|
\n
|
||||||
|
while(v>=0.0) { \n
|
||||||
|
DBG_ERROR(NULL, "Handling level %d (%.2f)", nextLevel, v); \n
|
||||||
|
if (nextLevel>=2) \n
|
||||||
|
break; \n
|
||||||
vRun=startValue; \n
|
vRun=startValue; \n
|
||||||
DBG_ERROR(NULL, "vRun=%.2f, v=%.2f, vMin=%.2f, vMax=%.2f", vRun, v, st->minValue, st->maxValue); \n
|
|
||||||
while(vRun<=(st->maxValue)) { \n
|
while(vRun<=(st->maxValue)) { \n
|
||||||
if (vRun>=(st->minValue)) { \n
|
if (vRun>=(st->minValue)) { \n
|
||||||
if (!$(struct_prefix)_HasTickValue(st, vRun)) { \n
|
if (!$(struct_prefix)_HasTickValue(st, vRun)) { \n
|
||||||
GWEN_Buffer_AppendArgs(dbuf, "%.*f", st->precision, vRun); \n
|
GWEN_Buffer_AppendArgs(dbuf, "%.*f", st->precision, vRun); \n
|
||||||
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), vRun, nextLevel, 0); \n
|
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), vRun, nextLevel, 0, v); \n
|
||||||
|
DBG_ERROR(NULL, "Adding tick %d: %s", nextLevel, GWEN_Buffer_GetStart(dbuf)); \n
|
||||||
GWEN_Buffer_Reset(dbuf); \n
|
GWEN_Buffer_Reset(dbuf); \n
|
||||||
} \n
|
} \n
|
||||||
} \n
|
} \n
|
||||||
vRun+=v; \n
|
vRun+=v; \n
|
||||||
} \n
|
} \n
|
||||||
if ($(struct_prefix)_HasLevelTicks(st, nextLevel)) \n
|
|
||||||
nextLevel++; \n
|
|
||||||
\n
|
|
||||||
vRun=startValue; \n
|
|
||||||
v/=2.0; \n
|
v/=2.0; \n
|
||||||
DBG_ERROR(NULL, "vRun=%.2f, v=%.2f, vMin=%.2f, vMax=%.2f", vRun, v, st->minValue, st->maxValue); \n
|
if ($(struct_prefix)_HasAtLeastNLevelTicks(st, nextLevel, nextLevel?1:2)) \n
|
||||||
while(vRun<=(st->maxValue)) { \n
|
|
||||||
if (vRun>=(st->minValue)) { \n
|
|
||||||
if (!$(struct_prefix)_HasTickValue(st, vRun)) { \n
|
|
||||||
GWEN_Buffer_AppendArgs(dbuf, "%.*f", st->precision, vRun); \n
|
|
||||||
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), vRun, nextLevel, 0); \n
|
|
||||||
GWEN_Buffer_Reset(dbuf); \n
|
|
||||||
} \n
|
|
||||||
} \n
|
|
||||||
vRun+=v; \n
|
|
||||||
} \n
|
|
||||||
if ($(struct_prefix)_HasLevelTicks(st, nextLevel)) \n
|
|
||||||
nextLevel++; \n
|
nextLevel++; \n
|
||||||
|
else \n
|
||||||
|
$(struct_prefix)_RemoveLevelTicks(st, nextLevel); \n
|
||||||
\n
|
\n
|
||||||
|
DBG_ERROR(NULL, "Handling level %d (%.2f)", nextLevel, v); \n
|
||||||
|
if (nextLevel>=2) \n
|
||||||
|
break; \n
|
||||||
vRun=startValue; \n
|
vRun=startValue; \n
|
||||||
v/=5.0; \n
|
|
||||||
DBG_ERROR(NULL, "vRun=%.2f, v=%.2f, vMin=%.2f, vMax=%.2f", vRun, v, st->minValue, st->maxValue); \n
|
|
||||||
while(vRun<=(st->maxValue)) { \n
|
while(vRun<=(st->maxValue)) { \n
|
||||||
if (vRun>=(st->minValue)) { \n
|
if (vRun>=(st->minValue)) { \n
|
||||||
if (!$(struct_prefix)_HasTickValue(st, vRun)) { \n
|
if (!$(struct_prefix)_HasTickValue(st, vRun)) { \n
|
||||||
GWEN_Buffer_AppendArgs(dbuf, "%.*f", st->precision, vRun); \n
|
GWEN_Buffer_AppendArgs(dbuf, "%.*f", st->precision, vRun); \n
|
||||||
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), vRun, nextLevel, 0); \n
|
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), vRun, nextLevel, 0, v); \n
|
||||||
|
DBG_ERROR(NULL, "Adding tick %d: %s", nextLevel, GWEN_Buffer_GetStart(dbuf)); \n
|
||||||
GWEN_Buffer_Reset(dbuf); \n
|
GWEN_Buffer_Reset(dbuf); \n
|
||||||
} \n
|
} \n
|
||||||
} \n
|
} \n
|
||||||
vRun+=v; \n
|
vRun+=v; \n
|
||||||
} \n
|
} \n
|
||||||
if ($(struct_prefix)_HasLevelTicks(st, nextLevel)) \n
|
v/=5.0; \n
|
||||||
|
if ($(struct_prefix)_HasAtLeastNLevelTicks(st, nextLevel, nextLevel?1:2)) \n
|
||||||
nextLevel++; \n
|
nextLevel++; \n
|
||||||
\n
|
else \n
|
||||||
|
$(struct_prefix)_RemoveLevelTicks(st, nextLevel); \n
|
||||||
|
} /* while */ \n
|
||||||
GWEN_Buffer_free(dbuf); \n
|
GWEN_Buffer_free(dbuf); \n
|
||||||
} \n
|
} \n
|
||||||
</content>
|
</content>
|
||||||
@@ -161,20 +158,24 @@
|
|||||||
|
|
||||||
<inline loc="end" access="public">
|
<inline loc="end" access="public">
|
||||||
<content>
|
<content>
|
||||||
$(api) int $(struct_prefix)_HasLevelTicks(const $(struct_type) *st, int level);
|
$(api) int $(struct_prefix)_HasAtLeastNLevelTicks(const $(struct_type) *st, int level, int min);
|
||||||
</content>
|
</content>
|
||||||
</inline>
|
</inline>
|
||||||
|
|
||||||
<inline loc="code">
|
<inline loc="code">
|
||||||
<content>
|
<content>
|
||||||
int $(struct_prefix)_HasLevelTicks(const $(struct_type) *st, int level) \n
|
int $(struct_prefix)_HasAtLeastNLevelTicks(const $(struct_type) *st, int level, int min) \n
|
||||||
{ \n
|
{ \n
|
||||||
const AQDG_GRAPH_TICK *tick; \n
|
const AQDG_GRAPH_TICK *tick; \n
|
||||||
|
int cnt=0; \n
|
||||||
\n
|
\n
|
||||||
tick=AQDG_Graph_Tick_List_First(st->tickList); \n
|
tick=AQDG_Graph_Tick_List_First(st->tickList); \n
|
||||||
while(tick) { \n
|
while(tick) { \n
|
||||||
if (AQDG_Graph_Tick_GetLevel(tick)==level) \n
|
if (AQDG_Graph_Tick_GetLevel(tick)==level) { \n
|
||||||
|
cnt++; \n
|
||||||
|
if (cnt>=min) \n
|
||||||
return 1; \n
|
return 1; \n
|
||||||
|
}
|
||||||
tick=AQDG_Graph_Tick_List_Next(tick); \n
|
tick=AQDG_Graph_Tick_List_Next(tick); \n
|
||||||
} \n
|
} \n
|
||||||
return 0; \n
|
return 0; \n
|
||||||
@@ -183,6 +184,35 @@
|
|||||||
</inline>
|
</inline>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<inline loc="end" access="public">
|
||||||
|
<content>
|
||||||
|
$(api) void $(struct_prefix)_RemoveLevelTicks($(struct_type) *st, int level);
|
||||||
|
</content>
|
||||||
|
</inline>
|
||||||
|
|
||||||
|
<inline loc="code">
|
||||||
|
<content>
|
||||||
|
void $(struct_prefix)_RemoveLevelTicks($(struct_type) *st, int level) \n
|
||||||
|
{ \n
|
||||||
|
AQDG_GRAPH_TICK *tick; \n
|
||||||
|
\n
|
||||||
|
tick=AQDG_Graph_Tick_List_First(st->tickList); \n
|
||||||
|
while(tick) { \n
|
||||||
|
AQDG_GRAPH_TICK *nextTick; \n
|
||||||
|
\n
|
||||||
|
nextTick=AQDG_Graph_Tick_List_Next(tick); \n
|
||||||
|
if (AQDG_Graph_Tick_GetLevel(tick)==level) { \n
|
||||||
|
AQDG_Graph_Tick_List_Del(tick); \n
|
||||||
|
AQDG_Graph_Tick_free(tick); \n
|
||||||
|
} \n
|
||||||
|
tick=nextTick; \n
|
||||||
|
} \n
|
||||||
|
} \n
|
||||||
|
</content>
|
||||||
|
</inline>
|
||||||
|
|
||||||
|
|
||||||
<inline loc="end" access="public">
|
<inline loc="end" access="public">
|
||||||
<content>
|
<content>
|
||||||
$(api) void $(struct_prefix)_GenHourTicks($(struct_type) *st, int lvl, int hours);
|
$(api) void $(struct_prefix)_GenHourTicks($(struct_type) *st, int lvl, int hours);
|
||||||
@@ -198,7 +228,9 @@
|
|||||||
GWEN_BUFFER *dbuf; \n
|
GWEN_BUFFER *dbuf; \n
|
||||||
GWEN_TIMESTAMP *ts; \n
|
GWEN_TIMESTAMP *ts; \n
|
||||||
int h; \n
|
int h; \n
|
||||||
|
int addSecs; \n
|
||||||
\n
|
\n
|
||||||
|
addSecs=hours*60*60; \n
|
||||||
maxValue=st->maxValue; \n
|
maxValue=st->maxValue; \n
|
||||||
minValue=st->minValue; \n
|
minValue=st->minValue; \n
|
||||||
ts=GWEN_Timestamp_fromLocalTime(minValue); \n
|
ts=GWEN_Timestamp_fromLocalTime(minValue); \n
|
||||||
@@ -216,10 +248,10 @@
|
|||||||
GWEN_Timestamp_GetHour(ts), \n
|
GWEN_Timestamp_GetHour(ts), \n
|
||||||
GWEN_Timestamp_GetMinute(ts)); \n
|
GWEN_Timestamp_GetMinute(ts)); \n
|
||||||
if (!$(struct_prefix)_HasTickValue(st, v)) \n
|
if (!$(struct_prefix)_HasTickValue(st, v)) \n
|
||||||
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0); \n
|
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0, (double) addSecs); \n
|
||||||
GWEN_Buffer_Reset(dbuf); \n
|
GWEN_Buffer_Reset(dbuf); \n
|
||||||
} \n
|
} \n
|
||||||
GWEN_Timestamp_AddSeconds(ts, hours*60*60); \n
|
GWEN_Timestamp_AddSeconds(ts, addSecs); \n
|
||||||
if (v>maxValue) \n
|
if (v>maxValue) \n
|
||||||
break; \n
|
break; \n
|
||||||
} \n
|
} \n
|
||||||
@@ -244,7 +276,9 @@
|
|||||||
double maxValue; \n
|
double maxValue; \n
|
||||||
GWEN_BUFFER *dbuf; \n
|
GWEN_BUFFER *dbuf; \n
|
||||||
GWEN_DATE *dt; \n
|
GWEN_DATE *dt; \n
|
||||||
|
int addSecs; \n
|
||||||
\n
|
\n
|
||||||
|
addSecs=24*60*60; \n
|
||||||
maxValue=st->maxValue; \n
|
maxValue=st->maxValue; \n
|
||||||
minValue=st->minValue; \n
|
minValue=st->minValue; \n
|
||||||
dt=GWEN_Date_fromLocalTime(minValue); \n
|
dt=GWEN_Date_fromLocalTime(minValue); \n
|
||||||
@@ -261,7 +295,7 @@
|
|||||||
GWEN_Date_GetMonth(dt), \n
|
GWEN_Date_GetMonth(dt), \n
|
||||||
GWEN_Date_GetDay(dt)); \n
|
GWEN_Date_GetDay(dt)); \n
|
||||||
if (!$(struct_prefix)_HasTickValue(st, v)) \n
|
if (!$(struct_prefix)_HasTickValue(st, v)) \n
|
||||||
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0); \n
|
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0, (double) addSecs); \n
|
||||||
GWEN_Buffer_Reset(dbuf); \n
|
GWEN_Buffer_Reset(dbuf); \n
|
||||||
} \n
|
} \n
|
||||||
GWEN_Date_AddDays(dt, 1); \n
|
GWEN_Date_AddDays(dt, 1); \n
|
||||||
@@ -290,6 +324,9 @@
|
|||||||
double maxValue; \n
|
double maxValue; \n
|
||||||
GWEN_BUFFER *dbuf; \n
|
GWEN_BUFFER *dbuf; \n
|
||||||
GWEN_DATE *dt; \n
|
GWEN_DATE *dt; \n
|
||||||
|
int addSecs; \n
|
||||||
|
\n
|
||||||
|
addSecs=7*24*60*60; \n
|
||||||
\n
|
\n
|
||||||
maxValue=st->maxValue; \n
|
maxValue=st->maxValue; \n
|
||||||
minValue=st->minValue; \n
|
minValue=st->minValue; \n
|
||||||
@@ -314,7 +351,7 @@
|
|||||||
GWEN_Date_GetMonth(dt), \n
|
GWEN_Date_GetMonth(dt), \n
|
||||||
GWEN_Date_GetDay(dt)); \n
|
GWEN_Date_GetDay(dt)); \n
|
||||||
if (!$(struct_prefix)_HasTickValue(st, v)) \n
|
if (!$(struct_prefix)_HasTickValue(st, v)) \n
|
||||||
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0); \n
|
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0, (double) addSecs); \n
|
||||||
GWEN_Buffer_Reset(dbuf); \n
|
GWEN_Buffer_Reset(dbuf); \n
|
||||||
} \n
|
} \n
|
||||||
GWEN_Date_AddDays(dt, 7); \n
|
GWEN_Date_AddDays(dt, 7); \n
|
||||||
@@ -342,6 +379,9 @@
|
|||||||
double maxValue; \n
|
double maxValue; \n
|
||||||
GWEN_BUFFER *dbuf; \n
|
GWEN_BUFFER *dbuf; \n
|
||||||
GWEN_DATE *dt; \n
|
GWEN_DATE *dt; \n
|
||||||
|
int addSecs; \n
|
||||||
|
\n
|
||||||
|
addSecs=30*24*60*60; \n
|
||||||
\n
|
\n
|
||||||
maxValue=st->maxValue; \n
|
maxValue=st->maxValue; \n
|
||||||
dt=GWEN_Date_fromLocalTime(maxValue); \n
|
dt=GWEN_Date_fromLocalTime(maxValue); \n
|
||||||
@@ -370,7 +410,7 @@
|
|||||||
GWEN_Date_GetYear(dtCurrent), \n
|
GWEN_Date_GetYear(dtCurrent), \n
|
||||||
GWEN_Date_GetMonth(dtCurrent)); \n
|
GWEN_Date_GetMonth(dtCurrent)); \n
|
||||||
if (!$(struct_prefix)_HasTickValue(st, v)) \n
|
if (!$(struct_prefix)_HasTickValue(st, v)) \n
|
||||||
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0); \n
|
$(struct_prefix)_AddNewTick(st, GWEN_Buffer_GetStart(dbuf), v, lvl, 0, (double) addSecs); \n
|
||||||
GWEN_Buffer_Reset(dbuf); \n
|
GWEN_Buffer_Reset(dbuf); \n
|
||||||
} \n
|
} \n
|
||||||
GWEN_Date_free(dt); \n
|
GWEN_Date_free(dt); \n
|
||||||
|
|||||||
@@ -56,6 +56,30 @@
|
|||||||
</content>
|
</content>
|
||||||
</inline>
|
</inline>
|
||||||
|
|
||||||
|
|
||||||
|
<inline loc="end" access="public">
|
||||||
|
<content>
|
||||||
|
$(api) $(struct_type) *$(struct_prefix)_List_GetFirstTickForLevel(const $(struct_type)_LIST *tickList, int lvl);
|
||||||
|
</content>
|
||||||
|
</inline>
|
||||||
|
|
||||||
|
<inline loc="code">
|
||||||
|
<content>
|
||||||
|
$(struct_type) *$(struct_prefix)_List_GetFirstTickForLevel(const $(struct_type)_LIST *tickList, int lvl) \n
|
||||||
|
{ \n
|
||||||
|
$(struct_type) *tick; \n
|
||||||
|
\n
|
||||||
|
tick=$(struct_prefix)_List_First(tickList); \n
|
||||||
|
while(tick) { \n
|
||||||
|
if ($(struct_prefix)_GetLevel(tick)==lvl) \n
|
||||||
|
return tick; \n
|
||||||
|
tick=$(struct_prefix)_List_Next(tick); \n
|
||||||
|
} \n
|
||||||
|
return NULL; \n
|
||||||
|
} \n
|
||||||
|
</content>
|
||||||
|
</inline>
|
||||||
|
|
||||||
</inlines>
|
</inlines>
|
||||||
|
|
||||||
|
|
||||||
@@ -85,6 +109,12 @@
|
|||||||
<access>public</access>
|
<access>public</access>
|
||||||
</member>
|
</member>
|
||||||
|
|
||||||
|
<member name="levelDist" type="double" maxlen="8" >
|
||||||
|
<default>0.0</default>
|
||||||
|
<preset>0.0</preset>
|
||||||
|
<access>public</access>
|
||||||
|
</member>
|
||||||
|
|
||||||
<member name="flags" type="uint32_t" maxlen="8">
|
<member name="flags" type="uint32_t" maxlen="8">
|
||||||
<default>0</default>
|
<default>0</default>
|
||||||
<preset>0</preset>
|
<preset>0</preset>
|
||||||
|
|||||||
@@ -334,13 +334,20 @@ int _screenDistBetweenLevelTicksX(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
|
|||||||
int _screenDistBetweenLevelTicksY(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
|
int _screenDistBetweenLevelTicksY(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
|
||||||
int contentSize, double minValue, double maxValue)
|
int contentSize, double minValue, double maxValue)
|
||||||
{
|
{
|
||||||
|
const AQDG_GRAPH_TICK *firstLevelTick;
|
||||||
|
|
||||||
|
firstLevelTick=AQDG_Graph_Tick_List_GetFirstTickForLevel(tickList, lvl);
|
||||||
|
if (firstLevelTick) {
|
||||||
double v;
|
double v;
|
||||||
int pts;
|
int pts;
|
||||||
|
|
||||||
v=AQDG_Graph_Tick_List_DistanceBetweenTicks(tickList, lvl);
|
v=AQDG_Graph_Tick_GetLevelDist(firstLevelTick);
|
||||||
pts=(v*(contentSize/(maxValue-minValue)));
|
pts=(v*(contentSize/(maxValue-minValue)));
|
||||||
|
DBG_ERROR(NULL, "Level dist %d: %d", lvl, pts);
|
||||||
return pts;
|
return pts;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -194,13 +194,20 @@ void _drawTicks(AQDG_OBJECT *o, AQDG_DRAW_CONTEXT *dc, int absX)
|
|||||||
int _screenDistBetweenLevelTicks(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
|
int _screenDistBetweenLevelTicks(const AQDG_GRAPH_TICK_LIST *tickList, int lvl,
|
||||||
int contentSize, double minValue, double maxValue)
|
int contentSize, double minValue, double maxValue)
|
||||||
{
|
{
|
||||||
|
const AQDG_GRAPH_TICK *firstLevelTick;
|
||||||
|
|
||||||
|
firstLevelTick=AQDG_Graph_Tick_List_GetFirstTickForLevel(tickList, lvl);
|
||||||
|
if (firstLevelTick) {
|
||||||
double v;
|
double v;
|
||||||
int pts;
|
int pts;
|
||||||
|
|
||||||
v=AQDG_Graph_Tick_List_DistanceBetweenTicks(tickList, lvl);
|
v=AQDG_Graph_Tick_GetLevelDist(firstLevelTick);
|
||||||
pts=(v*(contentSize/(maxValue-minValue)));
|
pts=(v*(contentSize/(maxValue-minValue)));
|
||||||
|
DBG_ERROR(NULL, "Level dist %d: %d", lvl, pts);
|
||||||
return pts;
|
return pts;
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user