feat(client): 标签名下改两配对行居中(编号+度数/规格+日期)
保留深蓝表头+Code128 条码+位图字体+二维码外壳;品名与副字段 水平居中,行1=编号值+度数、行2=规格+日期,去掉「编号」前缀。 覆盖 canvas 预览/热敏栅格/PDF/web 四条渲染路径 + 原型 devices.html。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Bupi8Kdqkfx2N5acFsHTx5
This commit is contained in:
@@ -213,19 +213,28 @@ double _fitFont(String s, double maxW, double maxH, bool bold, double cap) {
|
||||
return size;
|
||||
}
|
||||
|
||||
/// 组装标签底部平铺的三字段:度数(型号) / 规格(版本) / 生产日期。
|
||||
/// 各值为空则跳过;日期截断到 10 字符(YYYY-MM-DD)。四路渲染共用,口径一致。
|
||||
/// 组装标签左列名下两行副字段(居中排布):
|
||||
/// 行1 = 编号 + 度数(型号) 行2 = 规格(版本) + 生产日期
|
||||
/// 2026-08-28 用户口径「编号和度数放一行、规格和日期放一行、居中」。
|
||||
/// 各字段为空则跳过(该行可只剩一个字段或整行消失);日期截断到 10 字符。四路渲染共用。
|
||||
List<String> _labelSubFields(
|
||||
String? series, String? spec, String? productionDate) {
|
||||
String code, String? series, String? spec, String? productionDate) {
|
||||
final date = (productionDate ?? '').isNotEmpty
|
||||
? (productionDate!.length > 10
|
||||
? productionDate.substring(0, 10)
|
||||
: productionDate)
|
||||
: '';
|
||||
return [
|
||||
final line1 = [
|
||||
if (code.isNotEmpty) code,
|
||||
if ((series ?? '').isNotEmpty) series!,
|
||||
].join(' ');
|
||||
final line2 = [
|
||||
if ((spec ?? '').isNotEmpty) spec!,
|
||||
if (date.isNotEmpty) date,
|
||||
].join(' ');
|
||||
return [
|
||||
if (line1.isNotEmpty) line1,
|
||||
if (line2.isNotEmpty) line2,
|
||||
];
|
||||
}
|
||||
|
||||
@@ -236,7 +245,7 @@ Future<ui.Image> _renderLabelBitmap({
|
||||
required String shop,
|
||||
required String name,
|
||||
required String code,
|
||||
required List<String> subs, // 底部平铺字段:度数 / 规格 / 日期(已过滤空)
|
||||
required List<String> subs, // 左列逐行副字段:型号规格 / 日期(已过滤空)
|
||||
required Uint8List qrBytes,
|
||||
bool drawBarcode = true, // 热敏光栅路径置 false:条码改用原生 TSPL BARCODE 保证扫码
|
||||
bool drawQr = true, // 热敏光栅路径置 false:二维码改用原生 TSPL BITMAP 保证扫码
|
||||
@@ -272,10 +281,11 @@ Future<ui.Image> _renderLabelBitmap({
|
||||
const padV = 6.0, padH = 8.0; // 收紧留白,给二维码腾空间
|
||||
const double colGap = 6.0; // 左列与二维码列间距(原 10,收小)
|
||||
|
||||
// 右列:二维码占主体整高(正方形)
|
||||
const double qrSize = (bodyBot - bodyTop) - 2 * padV; // 109
|
||||
const double qrTop = bodyTop + padV; // 30
|
||||
const double qrLeft = w - padH - qrSize; // 203
|
||||
// 右列:二维码略放大,占主体近满高(正方形),2026-08-28 用户口径「二维码调大一点」
|
||||
const double qrPad = 1.0;
|
||||
const double qrSize = (bodyBot - bodyTop) - 2 * qrPad; // 134
|
||||
const double qrTop = bodyTop + qrPad; // 25
|
||||
const double qrLeft = w - padH - qrSize; // 178
|
||||
if (drawQr) {
|
||||
try {
|
||||
final codec = await ui.instantiateImageCodec(qrBytes);
|
||||
@@ -293,79 +303,38 @@ Future<ui.Image> _renderLabelBitmap({
|
||||
|
||||
// 左列几何
|
||||
const double leftX = padH; // 8
|
||||
const double leftRight = qrLeft - colGap; // 197
|
||||
const double leftW = leftRight - leftX; // 189
|
||||
const double leftRight = qrLeft - colGap; // 172
|
||||
const double leftW = leftRight - leftX; // 164
|
||||
|
||||
// 左列底部一维条码(Code128,内容=商品编号),供扫码枪扫码出库
|
||||
const double barH = 40.0;
|
||||
const double barBottom = bodyBot - padV; // 137
|
||||
const double barTop = barBottom - barH; // 97
|
||||
const double barBottom = bodyBot - padV; // 154
|
||||
const double barTop = barBottom - barH; // 114
|
||||
if (drawBarcode) _drawBarcode(canvas, code, leftX, barTop, leftW, barH);
|
||||
|
||||
// 左列文字块(品名+编号 一行居中;度数/规格/日期 平铺一行),在条码上方居中
|
||||
const double infoTop = bodyTop + padV; // 32
|
||||
const double infoBot = barTop - 4; // 93
|
||||
const double infoH = infoBot - infoTop; // 61
|
||||
// 左列文字块:品名 + 两行副字段(行1=编号+度数、行2=规格+日期),整体水平居中、
|
||||
// 竖直均分。2026-08-28 用户口径「编号和度数放一行、规格和日期放一行、字体在空白处居中」。
|
||||
const double infoTop = bodyTop + padV; // 30
|
||||
const double infoBot = barTop - 4; // 110
|
||||
const double infoH = infoBot - infoTop; // 80
|
||||
|
||||
// 品名自适应字号(为编号留出约 28% 宽度),上限 17
|
||||
const double kSmallSize = 12.0; // 编号+度数 / 规格+日期
|
||||
final double nameSize =
|
||||
_fitFont(name, leftW * 0.72, 1000, true, 17.0).clamp(11.0, 17.0);
|
||||
const double codeSize = 10.0;
|
||||
const double subSize = 10.0;
|
||||
final double nameLineH = nameSize * 1.2;
|
||||
const double subLineH = subSize * 1.2;
|
||||
const double interGap = 8.0;
|
||||
final double blockH = nameLineH + interGap + subLineH;
|
||||
double blockTop = infoTop + (infoH - blockH) / 2;
|
||||
if (blockTop < infoTop) blockTop = infoTop;
|
||||
|
||||
// 品名 + 编号:整体水平居中,基线对齐
|
||||
final double nameW = _measureWidth(name, nameSize, true);
|
||||
final bool hasCode = code.isNotEmpty;
|
||||
const double codeGap = 9.0;
|
||||
final double codeW = hasCode ? _measureWidth(code, codeSize, false) : 0;
|
||||
final double groupW = nameW + (hasCode ? codeGap + codeW : 0);
|
||||
double gx = leftX + (leftW - groupW) / 2;
|
||||
if (gx < leftX) gx = leftX;
|
||||
_drawText(canvas, name, gx, blockTop, nameSize, leftW,
|
||||
bold: true, color: cInk);
|
||||
if (hasCode) {
|
||||
_drawText(canvas, code, gx + nameW + codeGap,
|
||||
blockTop + (nameSize - codeSize) * 0.82, codeSize, codeW + 4,
|
||||
color: cCode);
|
||||
}
|
||||
|
||||
// 三字段平铺一行(space-between,两侧留内边距使外白 > 中白)
|
||||
final double subY = blockTop + nameLineH + interGap;
|
||||
const double innerPad = 10.0; // 对齐原型 .lbl-sub padding:0 10px
|
||||
const double innerLeft = leftX + innerPad; // 18
|
||||
const double innerRight = leftRight - innerPad; // 187
|
||||
const double innerW = innerRight - innerLeft; // 169
|
||||
if (subs.length == 1) {
|
||||
final double sw0 = _measureWidth(subs[0], subSize, false);
|
||||
_drawText(
|
||||
canvas, subs[0], innerLeft + (innerW - sw0) / 2, subY, subSize, innerW,
|
||||
color: cCode);
|
||||
} else if (subs.isNotEmpty) {
|
||||
// 字段间必须留可见最小间隔;总宽超限时按比例缩字号,避免贴死
|
||||
const double minGap = 5.0;
|
||||
double fs = subSize;
|
||||
double sumW = subs.fold(
|
||||
0.0, (s, x) => s + _measureWidth(x, fs, false));
|
||||
final double avail = innerW - minGap * (subs.length - 1);
|
||||
if (sumW > avail && sumW > 0) {
|
||||
fs = (subSize * avail / sumW).clamp(7.0, subSize);
|
||||
sumW = subs.fold(0.0, (s, x) => s + _measureWidth(x, fs, false));
|
||||
}
|
||||
final double gap = subs.length > 1
|
||||
? ((innerW - sumW) / (subs.length - 1)).clamp(minGap, innerW)
|
||||
: 0.0;
|
||||
double cx = innerLeft;
|
||||
for (int i = 0; i < subs.length; i++) {
|
||||
final double wi = _measureWidth(subs[i], fs, false);
|
||||
_drawText(canvas, subs[i], cx, subY, fs, wi + 4, color: cCode);
|
||||
cx += wi + gap;
|
||||
}
|
||||
_fitFont(name, leftW, 1000, true, 16.0).clamp(11.0, 16.0);
|
||||
final rows = <(String, double, bool)>[
|
||||
if (name.isNotEmpty) (name, nameSize, true), // 品名粗体
|
||||
for (final s in subs) (s, kSmallSize, false), // 编号+度数 / 规格+日期
|
||||
];
|
||||
const double kLineH = 1.3; // 行高倍数
|
||||
final double totalTextH = rows.fold(0.0, (s, r) => s + r.$2 * kLineH);
|
||||
final int n = rows.length;
|
||||
final double rawGap = n > 0 ? (infoH - totalTextH) / (n + 1) : 2.0;
|
||||
final double gap = rawGap < 1.0 ? 1.0 : rawGap;
|
||||
double yy = infoTop + gap;
|
||||
for (final r in rows) {
|
||||
_drawText(canvas, r.$1, leftX, yy, r.$2, leftW,
|
||||
bold: r.$3, color: r.$3 ? cInk : cCode, center: true);
|
||||
yy += r.$2 * kLineH + gap;
|
||||
}
|
||||
|
||||
return recorder.endRecording().toImage(sw, sh); // 返回 2× 图(640×320)
|
||||
@@ -438,10 +407,10 @@ Future<bool> _printFlatLabelThermal({
|
||||
buf.add(ascii.encode('\r\n'));
|
||||
|
||||
// ── 右列二维码(原生 BITMAP,避免光栅降采样糊码):占主体整高、右对齐 ──
|
||||
const qrW = 118, qrH = 118;
|
||||
const qrX = 320 - 8 - qrW; // 194
|
||||
const qrW = 130, qrH = 130; // 2026-08-28 放大,对齐画布 QR(134)
|
||||
const qrX = 320 - 8 - qrW; // 182
|
||||
const bodyTop = 24, bodyBot = 160; // 无页脚:主体直抵纸底
|
||||
const qrY = bodyTop + ((bodyBot - bodyTop) - qrH) ~/ 2; // 33
|
||||
const qrY = bodyTop + ((bodyBot - bodyTop) - qrH) ~/ 2; // 27
|
||||
const qrWBytes = (qrW + 7) >> 3; // 13
|
||||
final qrCodec = await ui.instantiateImageCodec(qrBytes,
|
||||
targetWidth: qrW, targetHeight: qrH);
|
||||
@@ -509,7 +478,7 @@ Future<void> printProductLabelImpl({
|
||||
const headerH = labelH * 0.20;
|
||||
|
||||
// 底部平铺三字段:度数(型号) / 规格(版本) / 日期(口径与预览、TSPL 一致)
|
||||
final subs = _labelSubFields(series, spec, productionDate);
|
||||
final subs = _labelSubFields(code, series, spec, productionDate);
|
||||
|
||||
// 桌面端热敏机:直接画扁平标签位图 + TSPL 裸发(不走会多走纸的系统打印)
|
||||
if (await _printFlatLabelThermal(
|
||||
@@ -563,55 +532,34 @@ Future<void> printProductLabelImpl({
|
||||
child: pw.Column(
|
||||
crossAxisAlignment: pw.CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
// 文字块(品名+编号 居中 / 三字段平铺),条码上方居中
|
||||
// 文字块:品名 + 两行副字段(行1=编号+度数、行2=规格+日期),整体居中。
|
||||
// 2026-08-28 用户口径「编号和度数放一行、规格和日期放一行、居中」。
|
||||
pw.Expanded(
|
||||
child: pw.Column(
|
||||
mainAxisAlignment: pw.MainAxisAlignment.center,
|
||||
crossAxisAlignment: pw.CrossAxisAlignment.stretch,
|
||||
crossAxisAlignment: pw.CrossAxisAlignment.center,
|
||||
children: [
|
||||
// 品名 + 编号(整体居中,编号小字随后)
|
||||
pw.RichText(
|
||||
textAlign: pw.TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: pw.TextOverflow.clip,
|
||||
text: pw.TextSpan(children: [
|
||||
pw.TextSpan(
|
||||
text: name,
|
||||
style: pw.TextStyle(
|
||||
font: font,
|
||||
fontSize: nameFs,
|
||||
fontWeight: pw.FontWeight.bold,
|
||||
color: _ink,
|
||||
letterSpacing: 0.3)),
|
||||
if (code.isNotEmpty)
|
||||
pw.TextSpan(
|
||||
text: ' $code',
|
||||
style: pw.TextStyle(
|
||||
font: font,
|
||||
fontSize: 5,
|
||||
color: _footnote)),
|
||||
]),
|
||||
),
|
||||
pw.SizedBox(height: 4),
|
||||
// 三字段平铺一行(两侧留边距,外白 > 中白)
|
||||
if (subs.isNotEmpty)
|
||||
pw.Padding(
|
||||
padding: const pw.EdgeInsets.symmetric(
|
||||
horizontal: 4),
|
||||
child: pw.Row(
|
||||
mainAxisAlignment: subs.length == 1
|
||||
? pw.MainAxisAlignment.center
|
||||
: pw.MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
for (final s in subs)
|
||||
pw.Text(s,
|
||||
style: pw.TextStyle(
|
||||
font: font,
|
||||
fontSize: 5,
|
||||
color: _footnote)),
|
||||
],
|
||||
),
|
||||
),
|
||||
pw.Text(name,
|
||||
textAlign: pw.TextAlign.center,
|
||||
maxLines: 2,
|
||||
overflow: pw.TextOverflow.clip,
|
||||
style: pw.TextStyle(
|
||||
font: font,
|
||||
fontSize: nameFs,
|
||||
fontWeight: pw.FontWeight.bold,
|
||||
color: _ink,
|
||||
letterSpacing: 0.3)),
|
||||
for (final s in subs) ...[
|
||||
pw.SizedBox(height: 2),
|
||||
pw.Text(s,
|
||||
textAlign: pw.TextAlign.center,
|
||||
maxLines: 1,
|
||||
overflow: pw.TextOverflow.clip,
|
||||
style: pw.TextStyle(
|
||||
font: font,
|
||||
fontSize: 5,
|
||||
color: _footnote)),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -668,7 +616,8 @@ Future<Uint8List> renderLabelPreviewImpl(LabelData label) async {
|
||||
shop: label.shopName,
|
||||
name: label.name,
|
||||
code: label.code,
|
||||
subs: _labelSubFields(label.series, label.spec, label.productionDate),
|
||||
subs: _labelSubFields(
|
||||
label.code, label.series, label.spec, label.productionDate),
|
||||
qrBytes: label.qrBytes!,
|
||||
);
|
||||
final bd = await img.toByteData(format: ui.ImageByteFormat.png);
|
||||
|
||||
@@ -41,13 +41,21 @@ Future<void> printProductLabelImpl({
|
||||
? productionDate.substring(0, 10)
|
||||
: productionDate)
|
||||
: '';
|
||||
// 底部平铺三字段:度数(型号) / 规格(版本) / 日期(口径与预览、PDF、TSPL 一致)
|
||||
final subs = <String>[
|
||||
// 左列名下两行副字段(居中):行1=编号+度数、行2=规格+日期(口径与预览、PDF、TSPL 一致)
|
||||
// 2026-08-28 用户口径「编号和度数放一行、规格和日期放一行、字体在空白处居中」。
|
||||
final line1 = [
|
||||
if (code.isNotEmpty) code,
|
||||
if (seriesVal.isNotEmpty) seriesVal,
|
||||
].join(' ');
|
||||
final line2 = [
|
||||
if (specVal.isNotEmpty) specVal,
|
||||
if (dateVal.isNotEmpty) dateVal,
|
||||
].join(' ');
|
||||
final subs = <String>[
|
||||
if (line1.isNotEmpty) line1,
|
||||
if (line2.isNotEmpty) line2,
|
||||
];
|
||||
final subSpans = subs.map((s) => '<span>$s</span>').join();
|
||||
final subLines = subs.map((s) => '<div class="sub">$s</div>').join();
|
||||
// 商品名过长时缩小字号
|
||||
final nameLen = name.runes.length;
|
||||
final nameFontPt = nameLen > 10 ? 7.0 : (nameLen > 7 ? 8.0 : 9.0);
|
||||
@@ -98,18 +106,16 @@ body { width: 40mm; height: 20mm; overflow: hidden; background: #fff; }
|
||||
.left { flex: 1; min-width: 0; display: flex; flex-direction: column; }
|
||||
.info {
|
||||
flex: 1; min-height: 0; display: flex; flex-direction: column;
|
||||
justify-content: center; gap: 1mm; overflow: hidden;
|
||||
justify-content: center; align-items: center; gap: 0.6mm; overflow: hidden;
|
||||
}
|
||||
.pname {
|
||||
font-weight: 700; text-align: center; line-height: 1.1;
|
||||
font-weight: 700; text-align: center; line-height: 1.1; max-width: 100%;
|
||||
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.pcode { font-size: 5pt; font-weight: 400; color: #333; margin-left: 1.2mm; }
|
||||
.sub {
|
||||
font-size: 5pt; color: #333; display: flex;
|
||||
justify-content: space-between; gap: 1mm; padding: 0 1.2mm;
|
||||
font-size: 5pt; color: #333; line-height: 1.15; text-align: center;
|
||||
max-width: 100%; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
|
||||
}
|
||||
.sub span { white-space: nowrap; }
|
||||
.bc { flex-shrink: 0; height: 4.6mm; }
|
||||
.bc svg { width: 100%; height: 100%; display: block; }
|
||||
|
||||
@@ -128,8 +134,8 @@ body { width: 40mm; height: 20mm; overflow: hidden; background: #fff; }
|
||||
<div class="middle">
|
||||
<div class="left">
|
||||
<div class="info">
|
||||
<div class="pname" style="font-size:${nameFontPt}pt">$name<span class="pcode">$code</span></div>
|
||||
<div class="sub">$subSpans</div>
|
||||
<div class="pname" style="font-size:${nameFontPt}pt">$name</div>
|
||||
$subLines
|
||||
</div>
|
||||
<div class="bc">$barcodeSvg</div>
|
||||
</div>
|
||||
|
||||
@@ -68,10 +68,9 @@
|
||||
.lbl-hdr{height:26px; flex:none; display:flex; align-items:center; padding:0 10px; font-size:13px; font-weight:700; letter-spacing:.05em; background:#1f2a3a; color:#f4ecd8;} /* ds-allow 打印纸面固定尺寸 */
|
||||
.lbl-mid{flex:1; min-height:0; display:flex; gap:6px; padding:6px 8px;}
|
||||
.lbl-left{flex:1; min-width:0; display:flex; flex-direction:column;}
|
||||
.lbl-info{flex:1; min-height:0; display:flex; flex-direction:column; justify-content:center; gap:9px;}
|
||||
.lbl-name{font-size:18px; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-align:center;}
|
||||
.lbl-code{font-size:11px; font-weight:400; color:#333; margin-left:10px;} /* ds-allow 打印纸面固定尺寸 */
|
||||
.lbl-sub{font-size:11px; color:#333; display:flex; justify-content:space-between; gap:6px; padding:0 10px;} /* ds-allow 打印纸面固定尺寸 */
|
||||
.lbl-info{flex:1; min-height:0; display:flex; flex-direction:column; justify-content:center; align-items:center; gap:5px;}
|
||||
.lbl-name{font-size:18px; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; text-align:center; max-width:100%;} /* ds-allow 打印纸面固定尺寸 */
|
||||
.lbl-sub{font-size:11px; color:#333; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; line-height:1.15; text-align:center; max-width:100%;} /* ds-allow 打印纸面固定尺寸;名下两行居中 */
|
||||
.lbl-bc{flex:none; height:46px; margin-top:4px;}
|
||||
.lbl-bc img{width:100%; height:100%; display:block; object-fit:fill;}
|
||||
.lbl-qr{flex:none; height:100%; aspect-ratio:1;}
|
||||
@@ -164,8 +163,9 @@
|
||||
<div class="lbl-mid">
|
||||
<div class="lbl-left">
|
||||
<div class="lbl-info">
|
||||
<div class="lbl-name">飞天茅台<span class="lbl-code">P1297</span></div>
|
||||
<div class="lbl-sub"><span>53°</span><span>500ml</span><span>2023-05-18</span></div>
|
||||
<div class="lbl-name">飞天茅台</div>
|
||||
<div class="lbl-sub">P1297 53°</div>
|
||||
<div class="lbl-sub">500ml 2023-05-18</div>
|
||||
</div>
|
||||
<div class="lbl-bc"><img alt="一维条码 P1297" src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwLjAwMDAwIDAuMDAwMDAgMzAwLjAwMDAwIDYwLjAwMDAwIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik0gMC4wMDAwMCAwLjAwMDAwIGggNy41OTQ5NCB2IDYwLjAwMDAwIGggLTcuNTk0OTQgeiBNIDExLjM5MjQxIDAuMDAwMDAgaCAzLjc5NzQ3IHYgNjAuMDAwMDAgaCAtMy43OTc0NyB6IE0gMzAuMzc5NzUgMC4wMDAwMCBoIDMuNzk3NDcgdiA2MC4wMDAwMCBoIC0zLjc5NzQ3IHogTSA0MS43NzIxNSAwLjAwMDAwIGggMTEuMzkyNDEgdiA2MC4wMDAwMCBoIC0xMS4zOTI0MSB6IE0gNTYuOTYyMDMgMC4wMDAwMCBoIDExLjM5MjQxIHYgNjAuMDAwMDAgaCAtMTEuMzkyNDEgeiBNIDcyLjE1MTkwIDAuMDAwMDAgaCA3LjU5NDk0IHYgNjAuMDAwMDAgaCAtNy41OTQ5NCB6IE0gODMuNTQ0MzAgMC4wMDAwMCBoIDMuNzk3NDcgdiA2MC4wMDAwMCBoIC0zLjc5NzQ3IHogTSA5MS4xMzkyNCAwLjAwMDAwIGggMTEuMzkyNDEgdiA2MC4wMDAwMCBoIC0xMS4zOTI0MSB6IE0gMTA2LjMyOTExIDAuMDAwMDAgaCAxNS4xODk4NyB2IDYwLjAwMDAwIGggLTE1LjE4OTg3IHogTSAxMjUuMzE2NDYgMC4wMDAwMCBoIDMuNzk3NDcgdiA2MC4wMDAwMCBoIC0zLjc5NzQ3IHogTSAxMzIuOTExMzkgMC4wMDAwMCBoIDcuNTk0OTQgdiA2MC4wMDAwMCBoIC03LjU5NDk0IHogTSAxNDguMTAxMjcgMC4wMDAwMCBoIDExLjM5MjQxIHYgNjAuMDAwMDAgaCAtMTEuMzkyNDEgeiBNIDE2Ny4wODg2MSAwLjAwMDAwIGggMTUuMTg5ODcgdiA2MC4wMDAwMCBoIC0xNS4xODk4NyB6IE0gMTg2LjA3NTk1IDAuMDAwMDAgaCAzLjc5NzQ3IHYgNjAuMDAwMDAgaCAtMy43OTc0NyB6IE0gMTkzLjY3MDg5IDAuMDAwMDAgaCAzLjc5NzQ3IHYgNjAuMDAwMDAgaCAtMy43OTc0NyB6IE0gMjA4Ljg2MDc2IDAuMDAwMDAgaCA3LjU5NDk0IHYgNjAuMDAwMDAgaCAtNy41OTQ5NCB6IE0gMjIwLjI1MzE2IDAuMDAwMDAgaCAxMS4zOTI0MSB2IDYwLjAwMDAwIGggLTExLjM5MjQxIHogTSAyNDMuMDM3OTcgMC4wMDAwMCBoIDMuNzk3NDcgdiA2MC4wMDAwMCBoIC0zLjc5NzQ3IHogTSAyNTAuNjMyOTEgMC4wMDAwMCBoIDcuNTk0OTQgdiA2MC4wMDAwMCBoIC03LjU5NDk0IHogTSAyNjkuNjIwMjUgMC4wMDAwMCBoIDExLjM5MjQxIHYgNjAuMDAwMDAgaCAtMTEuMzkyNDEgeiBNIDI4NC44MTAxMyAwLjAwMDAwIGggMy43OTc0NyB2IDYwLjAwMDAwIGggLTMuNzk3NDcgeiBNIDI5Mi40MDUwNiAwLjAwMDAwIGggNy41OTQ5NCB2IDYwLjAwMDAwIGggLTcuNTk0OTQgeiAiIHN0eWxlPSJmaWxsOiAjMDAwMDAwIi8+PHRleHQgc3R5bGU9ImZpbGw6ICMwMDAwMDA7IGZvbnQtZmFtaWx5OiAmcXVvdDttb25vc3BhY2UmcXVvdDs7IGZvbnQtc2l6ZTogMTIuMDAwMDBweCIgeD0iMC4wMDAwMCIgeT0iMC4wMDAwMCI+PC90ZXh0Pjwvc3ZnPg==" /></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user