Added many GUI elements. Erosion/dilation added.
This commit is contained in:
parent
6b380ae5e7
commit
c5baa69dc5
|
@ -6,6 +6,7 @@ set(AIGO_SRCS
|
||||||
settings.cpp
|
settings.cpp
|
||||||
state.cpp
|
state.cpp
|
||||||
image.cpp
|
image.cpp
|
||||||
|
mask.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
#find SDL and its related libraries
|
#find SDL and its related libraries
|
||||||
|
|
|
@ -12,17 +12,70 @@ namespace Image
|
||||||
((uint32_t*)image->pixels)[i] = 0xffffffff;
|
((uint32_t*)image->pixels)[i] = 0xffffffff;
|
||||||
else
|
else
|
||||||
((uint32_t*)image->pixels)[i] = 0xff000000;
|
((uint32_t*)image->pixels)[i] = 0xff000000;
|
||||||
//gray | (gray << 8) | (gray << 16);
|
//gray | (gray << 8) | (gray << 16);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void dilation(SDL_Surface *dest, SDL_Surface *src, Mask::mask *mask)
|
||||||
|
{
|
||||||
|
for (int y = mask->size / 2; y < dest->h - mask->size / 2; ++y)
|
||||||
|
{
|
||||||
|
for (int x = mask->size / 2; x < dest->w - mask->size / 2; ++x)
|
||||||
|
{
|
||||||
|
bool whiteFound = false;
|
||||||
|
for (int i = 0; i < mask->size && !whiteFound; ++i)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < mask->size && !whiteFound; ++j)
|
||||||
|
{
|
||||||
|
if (mask->mask[i*mask->size + j] &&
|
||||||
|
PXR(PX(src, x - mask->size / 2 + i, y - mask->size / 2 + j))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
whiteFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (whiteFound)
|
||||||
|
((uint32_t*)dest->pixels)[y*dest->w+x] = 0xffffffff;
|
||||||
|
else
|
||||||
|
((uint32_t*)dest->pixels)[y*dest->w+x] = 0xff000000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void erosion(SDL_Surface *dest, SDL_Surface *src, Mask::mask *mask)
|
||||||
|
{
|
||||||
|
for (int y = mask->size / 2; y < dest->h - mask->size / 2; ++y)
|
||||||
|
{
|
||||||
|
for (int x = mask->size / 2; x < dest->w - mask->size / 2; ++x)
|
||||||
|
{
|
||||||
|
bool blackFound = false;
|
||||||
|
for (int i = 0; i < mask->size && !blackFound; ++i)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < mask->size && !blackFound; ++j)
|
||||||
|
{
|
||||||
|
if (mask->mask[i*mask->size + j] &&
|
||||||
|
!PXR(PX(src, x - mask->size / 2 + i, y - mask->size / 2 + j))
|
||||||
|
)
|
||||||
|
{
|
||||||
|
blackFound = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (blackFound)
|
||||||
|
((uint32_t*)dest->pixels)[y*dest->w+x] = 0xff000000;
|
||||||
|
else
|
||||||
|
((uint32_t*)dest->pixels)[y*dest->w+x] = 0xffffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
SDL_Surface *copySurface(SDL_Surface *s)
|
SDL_Surface *copySurface(SDL_Surface *s)
|
||||||
{
|
{
|
||||||
SDL_Surface *copy = SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h,
|
SDL_Surface *copy = SDL_CreateRGBSurface(SDL_SWSURFACE, s->w, s->h,
|
||||||
s->format->BitsPerPixel,
|
s->format->BitsPerPixel,
|
||||||
s->format->Rmask, s->format->Gmask,
|
s->format->Rmask, s->format->Gmask,
|
||||||
s->format->Bmask, s->format->Amask);
|
s->format->Bmask, s->format->Amask);
|
||||||
SDL_BlitSurface(s, NULL, copy, NULL);
|
SDL_BlitSurface(s, NULL, copy, NULL);
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define _IMAGE_H_
|
#define _IMAGE_H_
|
||||||
|
|
||||||
#include <SDL/SDL.h>
|
#include <SDL/SDL.h>
|
||||||
|
#include "mask.h"
|
||||||
|
|
||||||
// get pixel/something in array p of size w*h
|
// get pixel/something in array p of size w*h
|
||||||
#define PX_(p, x, y, w, h) ((p)[(x)+(y)*(w)])
|
#define PX_(p, x, y, w, h) ((p)[(x)+(y)*(w)])
|
||||||
|
@ -22,6 +23,8 @@ namespace Image
|
||||||
{
|
{
|
||||||
|
|
||||||
void threshold(SDL_Surface *image, int lowerBound, int upperBound);
|
void threshold(SDL_Surface *image, int lowerBound, int upperBound);
|
||||||
|
void erosion(SDL_Surface *dest, SDL_Surface *src, Mask::mask *mask);
|
||||||
|
void dilation(SDL_Surface *dest, SDL_Surface *src, Mask::mask *mask);
|
||||||
SDL_Surface *copySurface(SDL_Surface *s);
|
SDL_Surface *copySurface(SDL_Surface *s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,11 @@ AigoQt::AigoQt(QWidget *parent)
|
||||||
cam = new Quickcam("/dev/video0");
|
cam = new Quickcam("/dev/video0");
|
||||||
|
|
||||||
timer = new QTimer(this);
|
timer = new QTimer(this);
|
||||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateImage()));
|
connect(timer, SIGNAL(timeout()), this, SLOT(on_buttonDrawPoints_clicked()));
|
||||||
timer->start(10);
|
timer->start(10);
|
||||||
|
|
||||||
|
copy = Image::copySurface(cam->getSurface());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AigoQt::~AigoQt( void )
|
AigoQt::~AigoQt( void )
|
||||||
|
@ -24,7 +26,17 @@ void AigoQt::updateImage( void )
|
||||||
{
|
{
|
||||||
cam->update();
|
cam->update();
|
||||||
SDL_Surface *s = cam->getSurface();
|
SDL_Surface *s = cam->getSurface();
|
||||||
Image::threshold(s, sliderBlack->value(), sliderWhite->value());
|
|
||||||
|
Image::threshold(s, blackImageThreshold->value(), whiteImageThreshold->value());
|
||||||
|
SDL_BlitSurface(s, NULL, copy, NULL);
|
||||||
|
|
||||||
|
Mask::mask *mask = Mask::createCircleMask(4);
|
||||||
|
|
||||||
|
if (checkErosion->isChecked()) Image::erosion(s, copy, mask);
|
||||||
|
if (checkDilation->isChecked()) Image::dilation(s, copy, mask);
|
||||||
|
|
||||||
|
delete mask;
|
||||||
|
|
||||||
image->setPixmap(QPixmap::fromImage(QImage((uchar*)s->pixels, s->w, s->h, QImage::Format_RGB32)));
|
image->setPixmap(QPixmap::fromImage(QImage((uchar*)s->pixels, s->w, s->h, QImage::Format_RGB32)));
|
||||||
//on_buttonGenerateState_clicked();
|
//on_buttonGenerateState_clicked();
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,6 +34,8 @@ class AigoQt : public QMainWindow, public Ui::AigoQt
|
||||||
|
|
||||||
Settings settings;
|
Settings settings;
|
||||||
|
|
||||||
|
SDL_Surface *copy;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
273
qt/main.ui
273
qt/main.ui
|
@ -5,8 +5,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>880</width>
|
<width>942</width>
|
||||||
<height>728</height>
|
<height>825</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle" >
|
<property name="windowTitle" >
|
||||||
|
@ -20,62 +20,21 @@
|
||||||
<property name="spacing" >
|
<property name="spacing" >
|
||||||
<number>6</number>
|
<number>6</number>
|
||||||
</property>
|
</property>
|
||||||
<item row="0" column="0" colspan="2" >
|
<item row="4" column="0" >
|
||||||
<widget class="QGroupBox" name="groupBox" >
|
<widget class="QLabel" name="label_5" >
|
||||||
<property name="minimumSize" >
|
|
||||||
<size>
|
|
||||||
<width>700</width>
|
|
||||||
<height>550</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="title" >
|
|
||||||
<string>Preview</string>
|
|
||||||
</property>
|
|
||||||
<widget class="ClickableLabel" name="image" >
|
|
||||||
<property name="geometry" >
|
|
||||||
<rect>
|
|
||||||
<x>40</x>
|
|
||||||
<y>40</y>
|
|
||||||
<width>640</width>
|
|
||||||
<height>480</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize" >
|
|
||||||
<size>
|
|
||||||
<width>640</width>
|
|
||||||
<height>480</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="maximumSize" >
|
|
||||||
<size>
|
|
||||||
<width>640</width>
|
|
||||||
<height>480</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text" >
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" >
|
|
||||||
<widget class="QLabel" name="label_4" >
|
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>White threshold</string>
|
<string>Black threshold(image)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="0" >
|
<item row="3" column="0" >
|
||||||
<widget class="QLabel" name="label_3" >
|
<widget class="QLabel" name="label_6" >
|
||||||
<property name="text" >
|
<property name="text" >
|
||||||
<string>Black threshold</string>
|
<string>White threshold (image)</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="2" >
|
<item row="2" column="2" >
|
||||||
<widget class="QLCDNumber" name="lcdNumber_2" />
|
|
||||||
</item>
|
|
||||||
<item row="2" column="1" >
|
|
||||||
<widget class="QSlider" name="sliderBlack" >
|
<widget class="QSlider" name="sliderBlack" >
|
||||||
<property name="minimum" >
|
<property name="minimum" >
|
||||||
<number>100</number>
|
<number>100</number>
|
||||||
|
@ -89,9 +48,6 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="2" >
|
<item row="1" column="2" >
|
||||||
<widget class="QLCDNumber" name="lcdNumber" />
|
|
||||||
</item>
|
|
||||||
<item row="1" column="1" >
|
|
||||||
<widget class="QSlider" name="sliderWhite" >
|
<widget class="QSlider" name="sliderWhite" >
|
||||||
<property name="minimum" >
|
<property name="minimum" >
|
||||||
<number>100</number>
|
<number>100</number>
|
||||||
|
@ -113,7 +69,68 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="0" column="2" >
|
<item row="2" column="0" colspan="2" >
|
||||||
|
<widget class="QLabel" name="label_3" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Black threshold(state)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0" colspan="2" >
|
||||||
|
<widget class="QLabel" name="label_4" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>White threshold (state)</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1" colspan="2" >
|
||||||
|
<widget class="QSlider" name="whiteImageThreshold" >
|
||||||
|
<property name="minimum" >
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum" >
|
||||||
|
<number>1000</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep" >
|
||||||
|
<number>10</number>
|
||||||
|
</property>
|
||||||
|
<property name="pageStep" >
|
||||||
|
<number>50</number>
|
||||||
|
</property>
|
||||||
|
<property name="value" >
|
||||||
|
<number>200</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1" colspan="2" >
|
||||||
|
<widget class="QSlider" name="blackImageThreshold" >
|
||||||
|
<property name="minimum" >
|
||||||
|
<number>100</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum" >
|
||||||
|
<number>1000</number>
|
||||||
|
</property>
|
||||||
|
<property name="orientation" >
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="3" >
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_4" />
|
||||||
|
</item>
|
||||||
|
<item row="3" column="3" >
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_3" />
|
||||||
|
</item>
|
||||||
|
<item row="2" column="3" >
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber_2" />
|
||||||
|
</item>
|
||||||
|
<item row="1" column="3" >
|
||||||
|
<widget class="QLCDNumber" name="lcdNumber" />
|
||||||
|
</item>
|
||||||
|
<item row="0" column="3" >
|
||||||
<widget class="QGroupBox" name="groupBox_2" >
|
<widget class="QGroupBox" name="groupBox_2" >
|
||||||
<property name="sizePolicy" >
|
<property name="sizePolicy" >
|
||||||
<sizepolicy>
|
<sizepolicy>
|
||||||
|
@ -154,6 +171,20 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkErosion" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Erosion</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="checkDilation" >
|
||||||
|
<property name="text" >
|
||||||
|
<string>Dilation</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<spacer>
|
<spacer>
|
||||||
<property name="orientation" >
|
<property name="orientation" >
|
||||||
|
@ -170,6 +201,44 @@
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="0" column="0" colspan="3" >
|
||||||
|
<widget class="QGroupBox" name="groupBox" >
|
||||||
|
<property name="minimumSize" >
|
||||||
|
<size>
|
||||||
|
<width>700</width>
|
||||||
|
<height>550</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="title" >
|
||||||
|
<string>Preview</string>
|
||||||
|
</property>
|
||||||
|
<widget class="ClickableLabel" name="image" >
|
||||||
|
<property name="geometry" >
|
||||||
|
<rect>
|
||||||
|
<x>40</x>
|
||||||
|
<y>40</y>
|
||||||
|
<width>640</width>
|
||||||
|
<height>480</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize" >
|
||||||
|
<size>
|
||||||
|
<width>640</width>
|
||||||
|
<height>480</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="maximumSize" >
|
||||||
|
<size>
|
||||||
|
<width>640</width>
|
||||||
|
<height>480</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
<property name="text" >
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menubar" >
|
<widget class="QMenuBar" name="menubar" >
|
||||||
|
@ -177,7 +246,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>880</width>
|
<width>942</width>
|
||||||
<height>29</height>
|
<height>29</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -212,12 +281,12 @@
|
||||||
<slot>display(int)</slot>
|
<slot>display(int)</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel" >
|
||||||
<x>702</x>
|
<x>720</x>
|
||||||
<y>618</y>
|
<y>668</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel" >
|
||||||
<x>727</x>
|
<x>870</x>
|
||||||
<y>618</y>
|
<y>667</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
@ -228,12 +297,12 @@
|
||||||
<slot>display(int)</slot>
|
<slot>display(int)</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel" >
|
||||||
<x>542</x>
|
<x>702</x>
|
||||||
<y>612</y>
|
<y>668</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel" >
|
||||||
<x>834</x>
|
<x>870</x>
|
||||||
<y>619</y>
|
<y>667</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
@ -244,12 +313,12 @@
|
||||||
<slot>display(int)</slot>
|
<slot>display(int)</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel" >
|
||||||
<x>701</x>
|
<x>716</x>
|
||||||
<y>638</y>
|
<y>698</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel" >
|
||||||
<x>749</x>
|
<x>870</x>
|
||||||
<y>640</y>
|
<y>696</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
@ -260,12 +329,76 @@
|
||||||
<slot>display(int)</slot>
|
<slot>display(int)</slot>
|
||||||
<hints>
|
<hints>
|
||||||
<hint type="sourcelabel" >
|
<hint type="sourcelabel" >
|
||||||
<x>561</x>
|
<x>707</x>
|
||||||
<y>645</y>
|
<y>698</y>
|
||||||
</hint>
|
</hint>
|
||||||
<hint type="destinationlabel" >
|
<hint type="destinationlabel" >
|
||||||
<x>825</x>
|
<x>870</x>
|
||||||
<y>640</y>
|
<y>696</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>whiteImageThreshold</sender>
|
||||||
|
<signal>sliderMoved(int)</signal>
|
||||||
|
<receiver>lcdNumber_3</receiver>
|
||||||
|
<slot>display(int)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>698</x>
|
||||||
|
<y>729</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>736</x>
|
||||||
|
<y>722</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>whiteImageThreshold</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>lcdNumber_3</receiver>
|
||||||
|
<slot>display(int)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>574</x>
|
||||||
|
<y>725</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>813</x>
|
||||||
|
<y>724</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>blackImageThreshold</sender>
|
||||||
|
<signal>valueChanged(int)</signal>
|
||||||
|
<receiver>lcdNumber_4</receiver>
|
||||||
|
<slot>display(int)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>604</x>
|
||||||
|
<y>754</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>735</x>
|
||||||
|
<y>759</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>blackImageThreshold</sender>
|
||||||
|
<signal>sliderMoved(int)</signal>
|
||||||
|
<receiver>lcdNumber_4</receiver>
|
||||||
|
<slot>display(int)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel" >
|
||||||
|
<x>561</x>
|
||||||
|
<y>753</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel" >
|
||||||
|
<x>816</x>
|
||||||
|
<y>752</y>
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
|
Reference in New Issue