* fix(server): 保留候选文本中的逗号和私用字符
* fix(server): render candidate frame from one snapshot
* fix(server): use captured preedit for sticky card key
* fix(server): dedup candidate frames by item-aware signature
Candidate text now keeps raw commas, so the comma-joined candidate_string
could make ["a,b","c"] and ["a","b,c"] share one frame signature and drop
a real page change as a duplicate repaint. Length-prefix each item instead.
Also serialize the WebView candidate items with the replace error handler
so an invalid UTF-8 translation gloss cannot throw on the UI thread, and
let CandidateWindowContent own its preedit and page snapshot rather than
referencing caller locals.
---------
Co-authored-by: fanlusky <1730976608@qq.com>