mirror of
https://git.code.sf.net/p/zint/code
synced 2025-12-17 18:07:02 +00:00
Add compliant height, using ZINT_COMPLIANT_HEIGHT flag for back-compatibility
Rename barcode funcs to same as BARCODE_XXX name library: barcode funcs array for dispatch, used for ZBarcode_ValidID() also general: change is_sane() comparison to nonzero from ZINT_ERROR_INVALID_OPTION MAILMARK: fuller error messages CODABAR: add option to show check character in HRT zint.h: use 0xNNNN for OR-able defines GUI: add guard descent height reset button, add Zint version to window title, static get_zint_version() method, use QStringLiteral (QSL shorthand), use SIGNAL(toggled()), add errtxt "popup" and status bar, add icons, add saveAs shortcut, add main menu, context menus and actions, add help, reset_view() -> reset_colours(), add copy to clipboard as EMF/GIF/PNG/TIF, lessen triggering of update_preview(), shorten names of getters/setters, simplify/shorten some update_preview() logic in switch, CODEONE disable structapp for Version S qzint.cpp: add on_errored signal, add missing getters, add test
This commit is contained in:
175
backend/code.c
175
backend/code.c
@@ -1,7 +1,8 @@
|
||||
/* code.c - Handles Code 11, 39, 39+, 93, PZN, Channel and VIN */
|
||||
/* LOGMARS MIL-STD-1189 Rev. B https://apps.dtic.mil/dtic/tr/fulltext/u2/a473534.pdf */
|
||||
/* PZN https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/IFA_Info_Code_39_EN.pdf */
|
||||
/* PZN https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/IFA-Info_Check_Digit_Calculations_PZN_PPN_UDI_EN.pdf */
|
||||
/* PZN https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/
|
||||
IFA-Info_Check_Digit_Calculations_PZN_PPN_UDI_EN.pdf */
|
||||
|
||||
/*
|
||||
libzint - the open source barcode library
|
||||
@@ -98,11 +99,11 @@ static const char *C93Table[47] = {
|
||||
};
|
||||
|
||||
/* *********************** CODE 11 ******************** */
|
||||
INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int length) { /* Code 11 */
|
||||
INTERNAL int code11(struct zint_symbol *symbol, unsigned char source[], int length) { /* Code 11 */
|
||||
|
||||
int i;
|
||||
int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count;
|
||||
int weight[122], error_number;
|
||||
int weight[122], error_number = 0;
|
||||
char dest[750]; /* 6 + 121 * 6 + 2 * 6 + 5 + 1 == 750 */
|
||||
char checkstr[3];
|
||||
int num_check_digits;
|
||||
@@ -114,10 +115,9 @@ INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
strcpy(symbol->errtxt, "320: Input too long (121 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
error_number = is_sane(SODIUM, source, length);
|
||||
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
||||
if (is_sane(SODIUM, source, length) != 0) {
|
||||
strcpy(symbol->errtxt, "321: Invalid character in data (digits and \"-\" only)");
|
||||
return error_number;
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
if (symbol->option_2 < 0 || symbol->option_2 > 2) {
|
||||
@@ -215,13 +215,12 @@ INTERNAL int code_11(struct zint_symbol *symbol, unsigned char source[], int len
|
||||
}
|
||||
|
||||
/* Code 39 */
|
||||
INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
INTERNAL int code39(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
int i;
|
||||
int counter;
|
||||
int error_number;
|
||||
int error_number = 0;
|
||||
char dest[880]; /* 10 (Start) + 85 * 10 + 10 (Check) + 9 (Stop) + 1 = 880 */
|
||||
char localstr[2] = {0};
|
||||
float height;
|
||||
|
||||
counter = 0;
|
||||
|
||||
@@ -242,10 +241,9 @@ INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
to_upper(source);
|
||||
error_number = is_sane(SILVER, source, length);
|
||||
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
||||
if (is_sane(SILVER, source, length) != 0) {
|
||||
strcpy(symbol->errtxt, "324: Invalid character in data (alphanumerics, space and \"-.$/+%\" only)");
|
||||
return error_number;
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
/* Start character */
|
||||
@@ -291,26 +289,27 @@ INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
|
||||
expand(symbol, dest);
|
||||
|
||||
#ifdef COMPLIANT_HEIGHTS
|
||||
if (symbol->symbology == BARCODE_LOGMARS) {
|
||||
/* MIL-STD-1189 Rev. B Section 5.2
|
||||
Min height 0.25" / 0.04" (X max) = 6.25
|
||||
Default height 0.625" (average of 0.375" - 0.875") / 0.01375" (average of 0.0075" - 0.02") ~ 45.45 */
|
||||
height = (float) (0.625 / 0.01375);
|
||||
error_number = set_height(symbol, 6.25f, height, (float) (0.875 / 0.0075), 0 /*no_errtxt*/);
|
||||
} else if (symbol->symbology == BARCODE_CODE39 || symbol->symbology == BARCODE_EXCODE39
|
||||
|| symbol->symbology == BARCODE_HIBC_39) {
|
||||
/* ISO/IEC 16388:2007 4.4 (e) recommended min height 5.0mm or 15% of width excluding quiet zones;
|
||||
as X left to application specification use
|
||||
width = (C + 2) * (3 * N + 6) * X + (C + 1) * I = (C + 2) * 9 + C + 1) * X = (10 * C + 19) */
|
||||
height = (float) ((10.0 * (symbol->option_2 == 1 ? length + 1 : length) + 19.0) * 0.15);
|
||||
/* Using 50 as default as none recommended */
|
||||
error_number = set_height(symbol, height, height > 50.0f ? height : 50.0f, 0.0f, 0 /*no_errtxt*/);
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
if (symbol->symbology == BARCODE_LOGMARS) {
|
||||
/* MIL-STD-1189 Rev. B Section 5.2
|
||||
Min height 0.25" / 0.04" (X max) = 6.25
|
||||
Default height 0.625" (average of 0.375" - 0.875") / 0.01375" (average of 0.0075" - 0.02") ~ 45.45 */
|
||||
error_number = set_height(symbol, 6.25f, stripf(0.625f / 0.01375f), stripf(0.875f / 0.0075f),
|
||||
0 /*no_errtxt*/);
|
||||
} else if (symbol->symbology == BARCODE_CODE39 || symbol->symbology == BARCODE_EXCODE39
|
||||
|| symbol->symbology == BARCODE_HIBC_39) {
|
||||
/* ISO/IEC 16388:2007 4.4 (e) recommended min height 5.0mm or 15% of width excluding quiet zones;
|
||||
as X left to application specification use
|
||||
width = (C + 2) * (3 * N + 6) * X + (C + 1) * I = (C + 2) * 9 + C + 1) * X = (10 * C + 19);
|
||||
use 50 as default as none recommended */
|
||||
const float min_height = stripf((10.0f * (symbol->option_2 == 1 ? length + 1 : length) + 19.0f) * 0.15f);
|
||||
error_number = set_height(symbol, min_height, min_height > 50.0f ? min_height : 50.0f, 0.0f,
|
||||
0 /*no_errtxt*/);
|
||||
}
|
||||
// PZN and CODE32 set their own heights
|
||||
} else {
|
||||
(void) set_height(symbol, 0.0f, 50.f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
#else
|
||||
height = 50.0f;
|
||||
(void) set_height(symbol, 0.0f, height, 0.0f, 1 /*no_errtxt*/);
|
||||
#endif
|
||||
|
||||
if (symbol->symbology == BARCODE_CODE39) {
|
||||
ustrcpy(symbol->text, "*");
|
||||
@@ -325,7 +324,7 @@ INTERNAL int c39(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
}
|
||||
|
||||
/* Pharmazentral Nummer (PZN) */
|
||||
INTERNAL int pharmazentral(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
INTERNAL int pzn(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
|
||||
int i, error_number, zeroes;
|
||||
unsigned int count, check_digit;
|
||||
@@ -335,10 +334,9 @@ INTERNAL int pharmazentral(struct zint_symbol *symbol, unsigned char source[], i
|
||||
strcpy(symbol->errtxt, "325: Input wrong length (7 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
error_number = is_sane(NEON, source, length);
|
||||
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
||||
if (is_sane(NEON, source, length) != 0) {
|
||||
strcpy(symbol->errtxt, "326: Invalid character in data (digits only)");
|
||||
return error_number;
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
localstr[0] = '-';
|
||||
@@ -364,29 +362,29 @@ INTERNAL int pharmazentral(struct zint_symbol *symbol, unsigned char source[], i
|
||||
}
|
||||
localstr[8] = itoc(check_digit);
|
||||
localstr[9] = '\0';
|
||||
error_number = c39(symbol, (unsigned char *) localstr, 9);
|
||||
error_number = code39(symbol, (unsigned char *) localstr, 9);
|
||||
ustrcpy(symbol->text, "PZN ");
|
||||
ustrcat(symbol->text, localstr);
|
||||
|
||||
#ifdef COMPLIANT_HEIGHTS
|
||||
/* Technical Information regarding PZN Coding V 2.1 (25 Feb 2019) Code size
|
||||
https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/IFA_Info_Code_39_EN.pdf
|
||||
"normal" X 0.25mm (0.187mm - 0.45mm), height 8mm - 20mm for 0.25mm X, 10mm mentioned so use that as default,
|
||||
10mm / 0.25mm = 40 */
|
||||
if (error_number < ZINT_ERROR) {
|
||||
error_number = set_height(symbol, (float) (8.0 / 0.45), 40.0f, (float) (20.0 / 0.187), 0 /*no_errtxt*/);
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* Technical Information regarding PZN Coding V 2.1 (25 Feb 2019) Code size
|
||||
https://www.ifaffm.de/mandanten/1/documents/04_ifa_coding_system/IFA_Info_Code_39_EN.pdf
|
||||
"normal" X 0.25mm (0.187mm - 0.45mm), height 8mm - 20mm for 0.25mm X, 10mm mentioned so use that
|
||||
as default, 10mm / 0.25mm = 40 */
|
||||
if (error_number < ZINT_ERROR) {
|
||||
error_number = set_height(symbol, stripf(8.0f / 0.45f), 40.0f, stripf(20.0f / 0.187f), 0 /*no_errtxt*/);
|
||||
}
|
||||
} else {
|
||||
if (error_number < ZINT_ERROR) {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (error_number < ZINT_ERROR) {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
#endif
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Extended Code 39 - ISO/IEC 16388:2007 Annex A */
|
||||
INTERNAL int ec39(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
INTERNAL int excode39(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
|
||||
unsigned char buffer[85 * 2 + 1] = {0};
|
||||
int i;
|
||||
@@ -408,21 +406,21 @@ INTERNAL int ec39(struct zint_symbol *symbol, unsigned char source[], int length
|
||||
}
|
||||
|
||||
/* Then sends the buffer to the C39 function */
|
||||
error_number = c39(symbol, buffer, (int) ustrlen(buffer));
|
||||
error_number = code39(symbol, buffer, (int) ustrlen(buffer));
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
symbol->text[i] = source[i] >= ' ' && source[i] != 0x7F ? source[i] : ' ';
|
||||
symbol->text[length] = '\0';
|
||||
symbol->text[length] = '\0'; /* Chops off check digit */
|
||||
|
||||
return error_number;
|
||||
}
|
||||
|
||||
/* Code 93 is an advancement on Code 39 and the definition is a lot tighter */
|
||||
INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
INTERNAL int code93(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
|
||||
/* SILVER includes the extra characters a, b, c and d to represent Code 93 specific
|
||||
shift characters 1, 2, 3 and 4 respectively. These characters are never used by
|
||||
c39() and ec39() */
|
||||
`code39()` and `excode39()` */
|
||||
|
||||
int i;
|
||||
int h, weight, c, k, error_number = 0;
|
||||
@@ -430,7 +428,6 @@ INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
char buffer[216]; /* 107*2 (107 full ASCII) + 1 = 215 */
|
||||
char dest[668]; /* 6 (Start) + 107*6 + 2*6 (Checks) + 7 (Stop) + 1 (NUL) = 668 */
|
||||
char set_copy[] = SILVER;
|
||||
float height;
|
||||
|
||||
/* Suppresses clang-tidy clang-analyzer-core.CallAndMessage warning */
|
||||
assert(length > 0);
|
||||
@@ -503,19 +500,15 @@ INTERNAL int c93(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
strcat(dest, "1111411");
|
||||
expand(symbol, dest);
|
||||
|
||||
#ifdef COMPLIANT_HEIGHTS
|
||||
/* ANSI/AIM BC5-1995 Section 2.6 minimum height 0.2" or 15% of symbol length, whichever is greater
|
||||
0.2" / 0.0075" (min X) = ~26.66; symbol length = (9 * (C + 4) + 1) * X + 2 * Q = symbol->width + 20 */
|
||||
height = (float) ((symbol->width + 20) * 0.15);
|
||||
if (height < 0.2f / 0.0075f) {
|
||||
height = 0.2f / 0.0075f;
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* ANSI/AIM BC5-1995 Section 2.6 minimum height 0.2" or 15% of symbol length, whichever is greater
|
||||
no max X given so for min height use symbol length = (9 * (C + 4) + 1) * X + 2 * Q = symbol->width + 20;
|
||||
use 40 as default height based on figures in spec */
|
||||
float min_height = stripf((symbol->width + 20) * 0.15f);
|
||||
error_number = set_height(symbol, min_height, min_height > 40.0f ? min_height : 40.0f, 0.0f, 0 /*no_errtxt*/);
|
||||
} else {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
/* Using 50 as default for back-compatibility */
|
||||
error_number = set_height(symbol, height, height > 50.0f ? height : 50.0f, 0.0f, 0 /*no_errtxt*/);
|
||||
#else
|
||||
height = 50.0f;
|
||||
(void) set_height(symbol, 0.0f, height, 0.0f, 1 /*no_errtxt*/);
|
||||
#endif
|
||||
|
||||
if (symbol->option_2 == 1) {
|
||||
symbol->text[length] = set_copy[c];
|
||||
@@ -578,12 +571,18 @@ static void CHNCHR(int channels, long target_value, int B[8], int S[8]) {
|
||||
/* Use of initial pre-calculations taken from Barcode Writer in Pure PostScript (BWIPP)
|
||||
* Copyright (c) 2004-2020 Terry Burton (MIT/X-Consortium license) */
|
||||
static channel_precalc initial_precalcs[6] = {
|
||||
{ 0, { 1, 1, 1, 1, 1, 2, 1, 2, }, { 1, 1, 1, 1, 1, 1, 1, 3, }, { 1, 1, 1, 1, 1, 3, 2, }, { 1, 1, 1, 1, 1, 3, 3, }, },
|
||||
{ 0, { 1, 1, 1, 1, 2, 1, 1, 3, }, { 1, 1, 1, 1, 1, 1, 1, 4, }, { 1, 1, 1, 1, 4, 3, 3, }, { 1, 1, 1, 1, 4, 4, 4, }, },
|
||||
{ 0, { 1, 1, 1, 2, 1, 1, 2, 3, }, { 1, 1, 1, 1, 1, 1, 1, 5, }, { 1, 1, 1, 5, 4, 4, 4, }, { 1, 1, 1, 5, 5, 5, 5, }, },
|
||||
{ 0, { 1, 1, 2, 1, 1, 2, 1, 4, }, { 1, 1, 1, 1, 1, 1, 1, 6, }, { 1, 1, 6, 5, 5, 5, 4, }, { 1, 1, 6, 6, 6, 6, 6, }, },
|
||||
{ 0, { 1, 2, 1, 1, 2, 1, 1, 5, }, { 1, 1, 1, 1, 1, 1, 1, 7, }, { 1, 7, 6, 6, 6, 5, 5, }, { 1, 7, 7, 7, 7, 7, 7, }, },
|
||||
{ 0, { 2, 1, 1, 2, 1, 1, 2, 5, }, { 1, 1, 1, 1, 1, 1, 1, 8, }, { 8, 7, 7, 7, 6, 6, 6, }, { 8, 8, 8, 8, 8, 8, 8, }, },
|
||||
{ 0, { 1, 1, 1, 1, 1, 2, 1, 2, }, { 1, 1, 1, 1, 1, 1, 1, 3, }, { 1, 1, 1, 1, 1, 3, 2, },
|
||||
{ 1, 1, 1, 1, 1, 3, 3, }, },
|
||||
{ 0, { 1, 1, 1, 1, 2, 1, 1, 3, }, { 1, 1, 1, 1, 1, 1, 1, 4, }, { 1, 1, 1, 1, 4, 3, 3, },
|
||||
{ 1, 1, 1, 1, 4, 4, 4, }, },
|
||||
{ 0, { 1, 1, 1, 2, 1, 1, 2, 3, }, { 1, 1, 1, 1, 1, 1, 1, 5, }, { 1, 1, 1, 5, 4, 4, 4, },
|
||||
{ 1, 1, 1, 5, 5, 5, 5, }, },
|
||||
{ 0, { 1, 1, 2, 1, 1, 2, 1, 4, }, { 1, 1, 1, 1, 1, 1, 1, 6, }, { 1, 1, 6, 5, 5, 5, 4, },
|
||||
{ 1, 1, 6, 6, 6, 6, 6, }, },
|
||||
{ 0, { 1, 2, 1, 1, 2, 1, 1, 5, }, { 1, 1, 1, 1, 1, 1, 1, 7, }, { 1, 7, 6, 6, 6, 5, 5, },
|
||||
{ 1, 7, 7, 7, 7, 7, 7, }, },
|
||||
{ 0, { 2, 1, 1, 2, 1, 1, 2, 5, }, { 1, 1, 1, 1, 1, 1, 1, 8, }, { 8, 7, 7, 7, 6, 6, 6, },
|
||||
{ 8, 8, 8, 8, 8, 8, 8, }, },
|
||||
};
|
||||
int bmax[7], smax[7];
|
||||
long value = 0;
|
||||
@@ -655,24 +654,22 @@ nb0: if (++B[0] <= bmax[0]) goto lb0;
|
||||
}
|
||||
|
||||
/* Channel Code - According to ANSI/AIM BC12-1998 */
|
||||
INTERNAL int channel_code(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
INTERNAL int channel(struct zint_symbol *symbol, unsigned char source[], int length) {
|
||||
static int max_ranges[] = { -1, -1, -1, 26, 292, 3493, 44072, 576688, 7742862 };
|
||||
int S[8] = {0}, B[8] = {0};
|
||||
long target_value = 0;
|
||||
char pattern[30];
|
||||
int channels, i;
|
||||
int error_number, zeroes;
|
||||
int error_number = 0, zeroes;
|
||||
char hrt[9];
|
||||
float height;
|
||||
|
||||
if (length > 7) {
|
||||
strcpy(symbol->errtxt, "333: Input too long (7 character maximum)");
|
||||
return ZINT_ERROR_TOO_LONG;
|
||||
}
|
||||
error_number = is_sane(NEON, source, length);
|
||||
if (error_number == ZINT_ERROR_INVALID_DATA) {
|
||||
if (is_sane(NEON, source, length) != 0) {
|
||||
strcpy(symbol->errtxt, "334: Invalid character in data (digits only)");
|
||||
return error_number;
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
if ((symbol->option_2 < 3) || (symbol->option_2 > 8)) {
|
||||
@@ -735,17 +732,15 @@ INTERNAL int channel_code(struct zint_symbol *symbol, unsigned char source[], in
|
||||
|
||||
expand(symbol, pattern);
|
||||
|
||||
#ifdef COMPLIANT_HEIGHTS
|
||||
/* ANSI/AIM BC12-1998 gives min height as 5mm or 15% of length but X left as application specification so use
|
||||
15% of length where
|
||||
length = (3 (quiet zones) + 9 (finder) + 4 * channels - 2) * X */
|
||||
height = (float) ((10 + 4 * channels) * 0.15);
|
||||
/* Using 50 as default for back-compatibility */
|
||||
error_number = set_height(symbol, height > 50.0f ? height : 50.0f, height, 0.0f, 0 /*no_errtxt*/);
|
||||
#else
|
||||
height = 50.0f;
|
||||
(void) set_height(symbol, 0.0f, height, 0.0f, 1 /*no_errtxt*/);
|
||||
#endif
|
||||
if (symbol->output_options & COMPLIANT_HEIGHT) {
|
||||
/* ANSI/AIM BC12-1998 gives min height as 5mm or 15% of length; X left as application specification so use
|
||||
length = 1X (left qz) + (9 (finder) + 4 * 8 - 2) * X + 2X (right qz);
|
||||
use 20 as default based on figures in spec */
|
||||
const float min_height = stripf((1 + 9 + 4 * channels - 2 + 2) * 0.15f);
|
||||
error_number = set_height(symbol, min_height, 20.0f, 0.0f, 0 /*no_errtxt*/);
|
||||
} else {
|
||||
(void) set_height(symbol, 0.0f, 50.0f, 0.0f, 1 /*no_errtxt*/);
|
||||
}
|
||||
|
||||
return error_number;
|
||||
}
|
||||
@@ -771,7 +766,7 @@ INTERNAL int vin(struct zint_symbol *symbol, unsigned char source[], int length)
|
||||
}
|
||||
|
||||
// Check input characters, I, O and Q are not allowed
|
||||
if (is_sane(ARSENIC, source, length) == ZINT_ERROR_INVALID_DATA) {
|
||||
if (is_sane(ARSENIC, source, length) != 0) {
|
||||
sprintf(symbol->errtxt, "337: Invalid character in data (\"%s\" only)", ARSENIC);
|
||||
return ZINT_ERROR_INVALID_DATA;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user