]]);
S imgID = bot ? botImageID : userImageID;
new Matches m;
bool dontSay = bot && startsWith(text, "[don't say]", m);
if (dontSay) text = m.rest();
if (nempty(imgID))
buf.append([[

]]
.replace("$IMG", snippetImgLink(imgID)));
buf.append(([[
$TEXT
]]).replace("$LR", bot != botOnRight ? "left" : "right")
.replace("$NAME", name)
.replace("$TIME", time)
.replace("$TEXT", text));
}
S replaceButtonText(S s) {
if (eqicOneOf(s, "back", "zurück")) ret unicode_undoArrow();
if (eqicOneOf(s, "cancel", "Abbrechen")) ret unicode_crossProduct();
ret s;
}
S renderButtons(LS buttons) {
new LS out;
for i over buttons: {
S code = buttons.get(i);
S text = replaceButtonText(code);
out.add(hbuttonOnClick_returnFalse(text, "submitAMsg(" + jsQuote(text) + ")", class := "chatbot-choice-button", title := eq(code, text) ? null : code));
if (!specialButtons.contains(code)
&& i+1 < l(buttons) && specialButtons.contains(buttons.get(i+1)))
out.add(" ");
}
ret lines(out);
}
void appendButtons(StringBuilder buf, MsgOut out, Set