Merge pull request #5371 from Dikay900:ports_to_master
This commit is contained in:
commit
d945aff132
@ -20,21 +20,24 @@ endif(NOT OPENCV_CUSTOM_PACKAGE_INFO)
|
||||
|
||||
#arch
|
||||
if(X86)
|
||||
set(CPACK_DEBIAN_ARCHITECTURE "i386")
|
||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "i386")
|
||||
set(CPACK_RPM_PACKAGE_ARCHITECTURE "i686")
|
||||
elseif(X86_64)
|
||||
set(CPACK_DEBIAN_ARCHITECTURE "amd64")
|
||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "amd64")
|
||||
set(CPACK_RPM_PACKAGE_ARCHITECTURE "x86_64")
|
||||
elseif(ARM)
|
||||
set(CPACK_DEBIAN_ARCHITECTURE "armhf")
|
||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "armhf")
|
||||
set(CPACK_RPM_PACKAGE_ARCHITECTURE "armhf")
|
||||
elseif(AARCH64)
|
||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "arm64")
|
||||
set(CPACK_RPM_PACKAGE_ARCHITECTURE "aarch64")
|
||||
else()
|
||||
set(CPACK_DEBIAN_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
||||
set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
||||
set(CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
|
||||
endif()
|
||||
|
||||
if(CPACK_GENERATOR STREQUAL "DEB")
|
||||
set(OPENCV_PACKAGE_ARCH_SUFFIX ${CPACK_DEBIAN_ARCHITECTURE})
|
||||
set(OPENCV_PACKAGE_ARCH_SUFFIX ${CPACK_DEBIAN_PACKAGE_ARCHITECTURE})
|
||||
elseif(CPACK_GENERATOR STREQUAL "RPM")
|
||||
set(OPENCV_PACKAGE_ARCH_SUFFIX ${CPACK_RPM_PACKAGE_ARCHITECTURE})
|
||||
else()
|
||||
@ -96,6 +99,46 @@ if(HAVE_CUDA)
|
||||
set(CPACK_COMPONENT_dev_DEPENDS libs)
|
||||
endif()
|
||||
|
||||
if(HAVE_TBB AND NOT BUILD_TBB)
|
||||
if(CPACK_DEB_DEV_PACKAGE_DEPENDS)
|
||||
set(CPACK_DEB_DEV_PACKAGE_DEPENDS "${CPACK_DEB_DEV_PACKAGE_DEPENDS}, libtbb-dev")
|
||||
else()
|
||||
set(CPACK_DEB_DEV_PACKAGE_DEPENDS "libtbb-dev")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(STD_OPENCV_LIBS opencv-data)
|
||||
set(STD_OPENCV_DEV libopencv-dev)
|
||||
|
||||
foreach(module calib3d core cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters
|
||||
cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping
|
||||
cudev features2d flann hal highgui imgcodecs imgproc ml objdetect ocl
|
||||
photo shape stitching superres ts video videoio videostab viz)
|
||||
if(HAVE_opencv_${module})
|
||||
list(APPEND STD_OPENCV_LIBS "libopencv-${module}3.0")
|
||||
list(APPEND STD_OPENCV_DEV "libopencv-${module}-dev")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
string(REPLACE ";" ", " CPACK_COMPONENT_LIBS_CONFLICTS "${STD_OPENCV_LIBS}")
|
||||
string(REPLACE ";" ", " CPACK_COMPONENT_LIBS_PROVIDES "${STD_OPENCV_LIBS}")
|
||||
string(REPLACE ";" ", " CPACK_COMPONENT_LIBS_REPLACES "${STD_OPENCV_LIBS}")
|
||||
|
||||
string(REPLACE ";" ", " CPACK_COMPONENT_DEV_CONFLICTS "${STD_OPENCV_DEV}")
|
||||
string(REPLACE ";" ", " CPACK_COMPONENT_DEV_PROVIDES "${STD_OPENCV_DEV}")
|
||||
string(REPLACE ";" ", " CPACK_COMPONENT_DEV_REPLACES "${STD_OPENCV_DEV}")
|
||||
|
||||
set(CPACK_COMPONENT_PYTHON_CONFLICTS python-opencv)
|
||||
set(CPACK_COMPONENT_PYTHON_PROVIDES python-opencv)
|
||||
set(CPACK_COMPONENT_PYTHON_REPLACES python-opencv)
|
||||
|
||||
set(CPACK_COMPONENT_JAVA_CONFLICTS "libopencv3.0-java, libopencv3.0-jni")
|
||||
set(CPACK_COMPONENT_JAVA_PROVIDES "libopencv3.0-java, libopencv3.0-jni")
|
||||
set(CPACK_COMPONENT_JAVA_REPLACES "libopencv3.0-java, libopencv3.0-jni")
|
||||
|
||||
set(CPACK_COMPONENT_DOCS_CONFLICTS opencv-doc)
|
||||
set(CPACK_COMPONENT_SAMPLES_CONFLICTS opencv-doc)
|
||||
|
||||
if(NOT OPENCV_CUSTOM_PACKAGE_INFO)
|
||||
set(CPACK_COMPONENT_LIBS_DESCRIPTION "Open Computer Vision Library")
|
||||
set(CPACK_DEBIAN_COMPONENT_LIBS_NAME "lib${CMAKE_PROJECT_NAME}")
|
||||
|
@ -55,6 +55,15 @@ OPENCV_TEST_PATH=@CMAKE_INSTALL_PREFIX@/@OPENCV_TEST_INSTALL_PATH@
|
||||
OPENCV_PYTHON_TESTS=@OPENCV_PYTHON_TESTS_LIST@
|
||||
export OPENCV_TEST_DATA_PATH=@CMAKE_INSTALL_PREFIX@/share/OpenCV/testdata
|
||||
|
||||
CUR_DIR=`pwd`
|
||||
if [ -d "$CUR_DIR" -a -w "$CUR_DIR" ]; then
|
||||
echo "${TEXT_CYAN}CUR_DIR : $CUR_DIR${TEXT_RESET}"
|
||||
else
|
||||
echo "${TEXT_RED}Error: Do not have permissions to write to $CUR_DIR${TEXT_RESET}"
|
||||
echo "${TEXT_RED}Please run the script from directory with write access${TEXT_RESET}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Run tests
|
||||
|
||||
SUMMARY_STATUS=0
|
||||
@ -64,9 +73,8 @@ PASSED_TESTS=""
|
||||
for t in "$OPENCV_TEST_PATH/"opencv_test_* "$OPENCV_TEST_PATH/"opencv_perf_*;
|
||||
do
|
||||
test_name=`basename "$t"`
|
||||
report="$test_name-`date --rfc-3339=date`.xml"
|
||||
|
||||
cmd="$t --perf_min_samples=1 --perf_force_samples=1 --gtest_output=xml:\"$report\""
|
||||
cmd="$t --perf_min_samples=1 --perf_force_samples=1 --gtest_output=xml:$test_name.xml"
|
||||
|
||||
seg_reg="s/^/${TEXT_CYAN}[$test_name]${TEXT_RESET} /" # append test name
|
||||
if [ $COLOR_OUTPUT -eq 1 ]; then
|
||||
@ -79,7 +87,7 @@ do
|
||||
fi
|
||||
|
||||
echo "${TEXT_CYAN}[$test_name]${TEXT_RESET} RUN : $cmd"
|
||||
$cmd | sed -r "$seg_reg"
|
||||
eval "$cmd" | tee "$test_name.log" | sed -r "$seg_reg"
|
||||
ret=${PIPESTATUS[0]}
|
||||
echo "${TEXT_CYAN}[$test_name]${TEXT_RESET} RETURN_CODE : $ret"
|
||||
|
||||
@ -98,14 +106,13 @@ done
|
||||
for t in $OPENCV_PYTHON_TESTS;
|
||||
do
|
||||
test_name=`basename "$t"`
|
||||
report="$test_name-`date --rfc-3339=date`.xml"
|
||||
|
||||
cmd="py.test --junitxml $report \"$OPENCV_TEST_PATH\"/$t"
|
||||
cmd="py.test --junitxml $test_name.xml \"$OPENCV_TEST_PATH\"/$t"
|
||||
|
||||
seg_reg="s/^/${TEXT_CYAN}[$test_name]${TEXT_RESET} /" # append test name
|
||||
|
||||
echo "${TEXT_CYAN}[$test_name]${TEXT_RESET} RUN : $cmd"
|
||||
eval "$cmd" | sed -r "$seg_reg"
|
||||
eval "$cmd" | tee "$test_name.log" | sed -r "$seg_reg"
|
||||
|
||||
ret=${PIPESTATUS[0]}
|
||||
echo "${TEXT_CYAN}[$test_name]${TEXT_RESET} RETURN_CODE : $ret"
|
||||
|
@ -1695,6 +1695,9 @@ cvSeqRemoveSlice( CvSeq* seq, CvSlice slice )
|
||||
|
||||
slice.end_index = slice.start_index + length;
|
||||
|
||||
if ( slice.start_index == slice.end_index )
|
||||
return;
|
||||
|
||||
if( slice.end_index < total )
|
||||
{
|
||||
CvSeqReader reader_to, reader_from;
|
||||
|
@ -2331,8 +2331,8 @@ void cv::minMaxIdx(InputArray _src, double* minVal,
|
||||
|
||||
size_t minidx = 0, maxidx = 0;
|
||||
int iminval = INT_MAX, imaxval = INT_MIN;
|
||||
float fminval = FLT_MAX, fmaxval = -FLT_MAX;
|
||||
double dminval = DBL_MAX, dmaxval = -DBL_MAX;
|
||||
float fminval = std::numeric_limits<float>::infinity(), fmaxval = -fminval;
|
||||
double dminval = std::numeric_limits<double>::infinity(), dmaxval = -dminval;
|
||||
size_t startidx = 1;
|
||||
int *minval = &iminval, *maxval = &imaxval;
|
||||
int planeSize = (int)it.size*cn;
|
||||
@ -2345,6 +2345,14 @@ void cv::minMaxIdx(InputArray _src, double* minVal,
|
||||
for( size_t i = 0; i < it.nplanes; i++, ++it, startidx += planeSize )
|
||||
func( ptrs[0], ptrs[1], minval, maxval, &minidx, &maxidx, planeSize, startidx );
|
||||
|
||||
if (!src.empty() && mask.empty())
|
||||
{
|
||||
if( minidx == 0 )
|
||||
minidx = 1;
|
||||
if( maxidx == 0 )
|
||||
maxidx = 1;
|
||||
}
|
||||
|
||||
if( minidx == 0 )
|
||||
dminval = dmaxval = 0;
|
||||
else if( depth == CV_32F )
|
||||
|
@ -1792,7 +1792,6 @@ INSTANTIATE_TEST_CASE_P(Arithm, SubtractOutputMatNotEmpty, testing::Combine(
|
||||
testing::Values(-1, CV_16S, CV_32S, CV_32F),
|
||||
testing::Bool()));
|
||||
|
||||
|
||||
TEST(Core_FindNonZero, singular)
|
||||
{
|
||||
Mat img(10, 10, CV_8U, Scalar::all(0));
|
||||
@ -1816,3 +1815,21 @@ TEST(Core_BoolVector, support)
|
||||
ASSERT_EQ( nz, countNonZero(test) );
|
||||
ASSERT_FLOAT_EQ((float)nz/n, (float)(mean(test)[0]));
|
||||
}
|
||||
|
||||
TEST(MinMaxLoc, Mat_IntMax_Without_Mask)
|
||||
{
|
||||
Mat_<int> mat(50, 50);
|
||||
int iMaxVal = numeric_limits<int>::max();
|
||||
mat.setTo(iMaxVal);
|
||||
|
||||
double min, max;
|
||||
Point minLoc, maxLoc;
|
||||
|
||||
minMaxLoc(mat, &min, &max, &minLoc, &maxLoc, Mat());
|
||||
|
||||
ASSERT_EQ(iMaxVal, min);
|
||||
ASSERT_EQ(iMaxVal, max);
|
||||
|
||||
ASSERT_EQ(Point(0, 0), minLoc);
|
||||
ASSERT_EQ(Point(0, 0), maxLoc);
|
||||
}
|
||||
|
@ -1372,6 +1372,49 @@ void CV_GetQuadSubPixTest::prepare_to_validation( int /*test_case_idx*/ )
|
||||
dst.convertTo(dst0, dst0.depth());
|
||||
}
|
||||
|
||||
////////////////////////////// resizeArea /////////////////////////////////
|
||||
|
||||
template <typename T>
|
||||
static void check_resize_area(const Mat& expected, const Mat& actual, double tolerance = 1.0)
|
||||
{
|
||||
ASSERT_EQ(actual.type(), expected.type());
|
||||
ASSERT_EQ(actual.size(), expected.size());
|
||||
|
||||
Mat diff;
|
||||
absdiff(actual, expected, diff);
|
||||
|
||||
Mat one_channel_diff = diff; //.reshape(1);
|
||||
|
||||
Size dsize = actual.size();
|
||||
bool next = true;
|
||||
for (int dy = 0; dy < dsize.height && next; ++dy)
|
||||
{
|
||||
const T* eD = expected.ptr<T>(dy);
|
||||
const T* aD = actual.ptr<T>(dy);
|
||||
|
||||
for (int dx = 0; dx < dsize.width && next; ++dx)
|
||||
if (fabs(static_cast<double>(aD[dx] - eD[dx])) > tolerance)
|
||||
{
|
||||
cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Inf norm: %f\n", static_cast<float>(norm(actual, expected, NORM_INF)));
|
||||
cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Error in : (%d, %d)\n", dx, dy);
|
||||
|
||||
const int radius = 3;
|
||||
int rmin = MAX(dy - radius, 0), rmax = MIN(dy + radius, dsize.height);
|
||||
int cmin = MAX(dx - radius, 0), cmax = MIN(dx + radius, dsize.width);
|
||||
|
||||
std::cout << "Abs diff:" << std::endl << diff << std::endl;
|
||||
std::cout << "actual result:\n" << actual(Range(rmin, rmax), Range(cmin, cmax)) << std::endl;
|
||||
std::cout << "expected result:\n" << expected(Range(rmin, rmax), Range(cmin, cmax)) << std::endl;
|
||||
|
||||
next = false;
|
||||
}
|
||||
}
|
||||
|
||||
ASSERT_EQ(0, norm(one_channel_diff, cv::NORM_INF));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TEST(Imgproc_cvWarpAffine, regression)
|
||||
{
|
||||
IplImage* src = cvCreateImage(cvSize(100, 100), IPL_DEPTH_8U, 1);
|
||||
@ -1501,41 +1544,45 @@ TEST(Imgproc_resize_area, regression)
|
||||
|
||||
cv::resize(src, actual, cv::Size(), 0.3, 0.3, INTER_AREA);
|
||||
|
||||
ASSERT_EQ(actual.type(), expected.type());
|
||||
ASSERT_EQ(actual.size(), expected.size());
|
||||
check_resize_area<ushort>(expected, actual, 1.0);
|
||||
}
|
||||
|
||||
Mat diff;
|
||||
absdiff(actual, expected, diff);
|
||||
TEST(Imgproc_resize_area, regression_half_round)
|
||||
{
|
||||
static uchar input_data[32 * 32];
|
||||
for(int i = 0; i < 32 * 32; ++i)
|
||||
input_data[i] = (uchar)(i % 2 + 253 + i / (16 * 32));
|
||||
|
||||
Mat one_channel_diff = diff; //.reshape(1);
|
||||
static uchar expected_data[16 * 16];
|
||||
for(int i = 0; i < 16 * 16; ++i)
|
||||
expected_data[i] = (uchar)(254 + i / (16 * 8));
|
||||
|
||||
float elem_diff = 1.0f;
|
||||
Size dsize = actual.size();
|
||||
bool next = true;
|
||||
for (int dy = 0; dy < dsize.height && next; ++dy)
|
||||
{
|
||||
ushort* eD = expected.ptr<ushort>(dy);
|
||||
ushort* aD = actual.ptr<ushort>(dy);
|
||||
cv::Mat src(32, 32, CV_8UC1, input_data);
|
||||
cv::Mat expected(16, 16, CV_8UC1, expected_data);
|
||||
cv::Mat actual(expected.size(), expected.type());
|
||||
|
||||
for (int dx = 0; dx < dsize.width && next; ++dx)
|
||||
if (fabs(static_cast<float>(aD[dx] - eD[dx])) > elem_diff)
|
||||
{
|
||||
cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Inf norm: %f\n", static_cast<float>(norm(actual, expected, NORM_INF)));
|
||||
cvtest::TS::ptr()->printf(cvtest::TS::SUMMARY, "Error in : (%d, %d)\n", dx, dy);
|
||||
cv::resize(src, actual, cv::Size(), 0.5, 0.5, INTER_AREA);
|
||||
|
||||
const int radius = 3;
|
||||
int rmin = MAX(dy - radius, 0), rmax = MIN(dy + radius, dsize.height);
|
||||
int cmin = MAX(dx - radius, 0), cmax = MIN(dx + radius, dsize.width);
|
||||
check_resize_area<uchar>(expected, actual, 0.5);
|
||||
}
|
||||
|
||||
std::cout << "Abs diff:" << std::endl << diff << std::endl;
|
||||
std::cout << "actual result:\n" << actual(Range(rmin, rmax), Range(cmin, cmax)) << std::endl;
|
||||
std::cout << "expected result:\n" << expected(Range(rmin, rmax), Range(cmin, cmax)) << std::endl;
|
||||
TEST(Imgproc_resize_area, regression_quarter_round)
|
||||
{
|
||||
static uchar input_data[32 * 32];
|
||||
for(int i = 0; i < 32 * 32; ++i)
|
||||
input_data[i] = (uchar)(i % 2 + 253 + i / (16 * 32));
|
||||
|
||||
next = false;
|
||||
}
|
||||
}
|
||||
static uchar expected_data[8 * 8];
|
||||
for(int i = 0; i < 8 * 8; ++i)
|
||||
expected_data[i] = 254;
|
||||
|
||||
ASSERT_EQ(cvtest::norm(one_channel_diff, cv::NORM_INF), 0);
|
||||
cv::Mat src(32, 32, CV_8UC1, input_data);
|
||||
cv::Mat expected(8, 8, CV_8UC1, expected_data);
|
||||
cv::Mat actual(expected.size(), expected.type());
|
||||
|
||||
cv::resize(src, actual, cv::Size(), 0.25, 0.25, INTER_AREA);
|
||||
|
||||
check_resize_area<uchar>(expected, actual, 0.5);
|
||||
}
|
||||
|
||||
|
||||
|
@ -980,12 +980,12 @@ minMaxLoc_(const _Tp* src, size_t total, size_t startidx,
|
||||
for( size_t i = 0; i < total; i++ )
|
||||
{
|
||||
_Tp val = src[i];
|
||||
if( minval > val )
|
||||
if( minval > val || !minpos )
|
||||
{
|
||||
minval = val;
|
||||
minpos = startidx + i;
|
||||
}
|
||||
if( maxval < val )
|
||||
if( maxval < val || !maxpos )
|
||||
{
|
||||
maxval = val;
|
||||
maxpos = startidx + i;
|
||||
@ -997,12 +997,12 @@ minMaxLoc_(const _Tp* src, size_t total, size_t startidx,
|
||||
for( size_t i = 0; i < total; i++ )
|
||||
{
|
||||
_Tp val = src[i];
|
||||
if( minval > val && mask[i] )
|
||||
if( (minval > val || !minpos) && mask[i] )
|
||||
{
|
||||
minval = val;
|
||||
minpos = startidx + i;
|
||||
}
|
||||
if( maxval < val && mask[i] )
|
||||
if( (maxval < val || !maxpos) && mask[i] )
|
||||
{
|
||||
maxval = val;
|
||||
maxpos = startidx + i;
|
||||
@ -1049,8 +1049,8 @@ void minMaxLoc(const Mat& src, double* _minval, double* _maxval,
|
||||
size_t startidx = 1, total = planes[0].total();
|
||||
size_t i, nplanes = it.nplanes;
|
||||
int depth = src.depth();
|
||||
double maxval = depth < CV_32F ? INT_MIN : depth == CV_32F ? -FLT_MAX : -DBL_MAX;
|
||||
double minval = depth < CV_32F ? INT_MAX : depth == CV_32F ? FLT_MAX : DBL_MAX;
|
||||
double minval = 0;
|
||||
double maxval = 0;
|
||||
size_t maxidx = 0, minidx = 0;
|
||||
|
||||
for( i = 0; i < nplanes; i++, ++it, startidx += total )
|
||||
@ -1093,9 +1093,6 @@ void minMaxLoc(const Mat& src, double* _minval, double* _maxval,
|
||||
}
|
||||
}
|
||||
|
||||
if( minidx == 0 )
|
||||
minval = maxval = 0;
|
||||
|
||||
if( _maxval )
|
||||
*_maxval = maxval;
|
||||
if( _minval )
|
||||
|
@ -71,6 +71,7 @@
|
||||
@property (nonatomic, readonly) BOOL captureSessionLoaded;
|
||||
|
||||
@property (nonatomic, assign) int defaultFPS;
|
||||
@property (nonatomic, readonly) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;
|
||||
@property (nonatomic, assign) AVCaptureDevicePosition defaultAVCaptureDevicePosition;
|
||||
@property (nonatomic, assign) AVCaptureVideoOrientation defaultAVCaptureVideoOrientation;
|
||||
@property (nonatomic, assign) BOOL useAVCaptureVideoPreviewLayer;
|
||||
@ -145,6 +146,7 @@
|
||||
- (void)layoutPreviewLayer;
|
||||
- (void)saveVideo;
|
||||
- (NSURL *)videoFileURL;
|
||||
- (NSString *)videoFileString;
|
||||
|
||||
|
||||
@end
|
||||
|
@ -41,7 +41,9 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}
|
||||
|
||||
|
||||
|
||||
@interface CvVideoCamera ()
|
||||
@interface CvVideoCamera () {
|
||||
int recordingCountDown;
|
||||
}
|
||||
|
||||
- (void)createVideoDataOutput;
|
||||
- (void)createVideoFileOutput;
|
||||
@ -98,6 +100,7 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}
|
||||
|
||||
- (void)start;
|
||||
{
|
||||
recordingCountDown = 10;
|
||||
[super start];
|
||||
|
||||
if (self.recordVideo == YES) {
|
||||
@ -551,7 +554,8 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}
|
||||
});
|
||||
|
||||
|
||||
if (self.recordVideo == YES) {
|
||||
recordingCountDown--;
|
||||
if (self.recordVideo == YES && recordingCountDown < 0) {
|
||||
lastSampleTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer);
|
||||
// CMTimeShow(lastSampleTime);
|
||||
if (self.recordAssetWriter.status != AVAssetWriterStatusWriting) {
|
||||
@ -571,6 +575,8 @@ static CGFloat DegreesToRadians(CGFloat degrees) {return degrees * M_PI / 180;}
|
||||
withPresentationTime:lastSampleTime] ) {
|
||||
NSLog(@"Video Writing Error");
|
||||
}
|
||||
if (pixelBuffer != nullptr)
|
||||
CVPixelBufferRelease(pixelBuffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user