// copyright ◆en3PGsfOXo http://t...content-available-to-author-only...h.net/test/read.cgi/tech/1363042502/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
BYTE *gflg = "AQv/8AIYH8k5JMkBA/ACCxeSSSQBA/ABDP/4ARLJ+SACEyDkknySAAIDB/8=";
BYTE *glyf = "AAwASAU7AAD/OgAAAAAC2f0ZAAAAAP0n/zoAAAAABdEAxgAAAAD9uALnAAAAAAJI"
"AMYAAAAgAGUEYAIb/MkAAAAA/5kAPv9nADb/zwA0/9AAj//QAFYAAAByAAAA5wBb"
"ADEALAAKAAAAAP8z/6H/2P86/8r/kwAA/uoAAP7IAS0AAAEVAAABEgErAUIA9AAA"
"AOIAAAD1/vgAAP8N/0kAKv//AJT/bQCi/2oAAP9pAAD/Tf9O//T/fAAEAGwBdwAA"
"/0QAAAAABhQAvAAAABgAbwRxAi4AAP7v/uj+xP8VAAD/EwAA/ukBPAAAAREAAAER"
"ARcBPQDtAAAA6wAAARj+w/8+/u8AAADZ/1YA0/9pAAD/ZwAA/1f/LQAA/ycAAP8u"
"AKr/JwCYAAAAlgAAAKsA1wAEACwCPwEd/ub9cf9uAAAArgKPAA0AdwY2BF3+3fuj"
"/1IAAP7hA13+4/yj/1MAAP7aBF0AxAAAAM38nwEXA2EAmwAAAR78nwDCA2EAEwBy"
"A3IDkP/2AAD/1gAK/7EACf/KAAD/qQAA/17/s/+1/8MAAPzn/0QAAAAABF0AvAAA"
"AAD/WwBwAFoAqwBLAFkAAAAxAAAALP/7ACz/+QAhAGQEQwAA/0QAAAAAAHX/r/+6"
"/1D/sv+ZAAD/OAAA/xUBNAAAAREAAACOAFEA3gBFAE4ARABMALUAUABhAAAAWAAA"
"AIj/2wBL/9kAAAHkALwAAP9E+v8AAAKB/7QAIv+IABr/uQAA/2IAAP9Q/yQAAP82"
"AAD/OQCI/zEAlgAAAFAAAACkAEcACAAhAgMF0f/m+8n/VgAA/+QENwDW+i//NAAA"
"AAAA0wDMAAA=";
int glyf_len = 0;
int b64decode(BYTE *dst, size_t *dst_size, BYTE *src, int src_size)
{
static BYTE b64o[80] = {
62, 0, 62, 0, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 0,
0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
0, 0, 0, 62, 63, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51};
int i, words = src_size/4, oversize = *dst_size+2, lasti = oversize/3-1;
if(src_size % 4) return 1;
if(*dst_size < words * 3) return 2;
for(i = 0; i <= lasti; i++){
int j;
BYTE c[4];
for(j = 0; j < sizeof(c); j++)
c[j] = b64o[(src[i * sizeof(c) + j] - '+') % sizeof(b64o)];
dst[i * 3 + 0] = ((c[0] << 2) & 0x00fc) | ((c[1] >> 4) & 0x03);
if(i < lasti || oversize % 3)
dst[i * 3 + 1] = ((c[1] << 4) & 0x00f0) | ((c[2] >> 2) & 0x0f);
if(i < lasti || (oversize % 3) == 2)
dst[i * 3 + 2] = ((c[2] << 6) & 0x00c0) | (c[3] & 0x3f);
}
if(src[src_size - 1] == '='){
--(*dst_size);
if(src[src_size - 2] == '=') --(*dst_size);
}
return 0;
}
int initGlyph(BYTE *str)
{
int len
= (strlen(str
) >> 2) * 3; if(b64decode
(str
, &len
, str
, strlen(str
))) return 0; return len;
}
int b2h(BYTE *b)
{
return (short)((b[0] << 8) | b[1]);
}
int getGlyphData(BYTE **epoc, BYTE **flags, int **xcoords, int **ycoords,
int *numepoc, char ch)
{
int i, j, k, pos = 0, num = 0, code = 0, fpos = 0, epnum = 0, fnum = 0;
*epoc = *flags = NULL, *xcoords = *ycoords = NULL, *numepoc = 0;
while(pos < glyf_len){
num = b2h(&glyf[pos]), code = b2h(&glyf[pos + 2]);
epnum = gflg[fpos], fnum = (num + 7) / 8;
if(code == ch){
*epoc
= (BYTE
*)malloc(*numepoc
= epnum
); if(!*epoc) break;
for(i = 0; i < epnum; ++i) (*epoc)[i] = gflg[fpos + 1 + i];
if(!*flags) break;
for(i = 0, k = 0; i < fnum; ++i){
BYTE b = gflg[fpos + 1 + epnum + i];
BYTE m = 0x80;
for(j = 0; j < 8 - (i == fnum - 1 ? fnum * 8 - num : 0); ++j, m >>= 1)
(*flags)[k++] = b & m ? 1 : 0;
}
break;
}
pos += (num + 1) * 4;
fpos += epnum + fnum + 1;
}
if(!*epoc || !*flags) return 0;
*xcoords
= (int *)malloc(num
* sizeof(int)); *ycoords
= (int *)malloc(num
* sizeof(int)); if(!*xcoords || !*ycoords) return 0;
for(i = 0; i < num; ++i){
(*xcoords)[i] = (i ? (*xcoords)[i-1] : 0) + b2h(&glyf[pos + (i+1)*4]);
(*ycoords)[i] = (i ? (*ycoords)[i-1] : 0) + b2h(&glyf[pos + (i+1)*4 + 2]);
}
return num;
}
int drawGlyph(HDC hdc, int scale, int szx, int szy, int ox, int oy,
int *w, int *h, int ch)
{
BYTE *epoc, *flags;
int *xcoords, *ycoords, numepoc, i, j;
int numflags = getGlyphData(&epoc, &flags, &xcoords, &ycoords, &numepoc, ch);
*w = 80, *h = 160;
if(!numflags) return 0;
for(j = 0; j < numepoc; ++j){
int px, py, k = j ? epoc[j - 1] + 1 : 0;
for(i = k; i <= epoc[j]; ++i){
int flg = flags[i], x = xcoords[i], y = ycoords[i];
int r = i == k ? 4 : 3;
COLORREF col = flg & 0x01 ? RGB(0, 0, 255) : RGB(255, 0, 0);
HPEN hpen = CreatePen(PS_SOLID, 1, col);
HPEN hopen = (HPEN)SelectObject(hdc, hpen);
HBRUSH hbrush, hobrush;
if(i == k) hbrush = CreateSolidBrush(RGB(0, 255, 0));
else hbrush = (HBRUSH)GetStockObject(HOLLOW_BRUSH);
hobrush = (HBRUSH)SelectObject(hdc, hbrush);
Ellipse(hdc, ox - r + x / scale, szy - (oy - r + y / scale),
ox + r + x / scale, szy - (oy + r + y / scale));
SelectObject(hdc, hobrush);
if(i == k) DeleteObject(hbrush);
SelectObject(hdc, hopen);
DeleteObject(hpen);
if(i != k) stroke(hdc, scale, szx, szy, ox, oy, px, py, x, y);
px = x, py = y;
}
stroke(hdc, scale, szx, szy, ox, oy, px, py, xcoords[k], ycoords[k]);
}
if(xcoords
) free(xcoords
); if(ycoords
) free(ycoords
); return 0;
}
int stroke(HDC hdc, int scale, int szx, int szy, int ox, int oy,
int xs, int ys, int xe, int ye)
{
POINT p;
MoveToEx(hdc, ox + xs / scale, szy - (oy + ys / scale), &p);
LineTo(hdc, ox + xe / scale, szy - (oy + ye / scale));
return 0;
}
int drawStrokes(int scale, int ofx, int ofy, int spx, int spy, char *str)
{
int szx, szy, ox = ofx, oy = ofy;
char *p;
HWND hwnd = GetDesktopWindow();
HDC hdc = GetDC(hwnd);
HPEN hpen = CreatePen(PS_SOLID, 1, RGB(0, 255, 0));
HPEN hopen = (HPEN)SelectObject(hdc, hpen);
RECT rc;
GetClientRect(hwnd, &rc);
szx = rc.right - rc.left, szy = rc.bottom - rc.top;
for(p = str; *p; ++p){
int w, h;
drawGlyph(hdc, scale, szx, szy, ox, oy, &w, &h, *p);
if(*p == '\n') ox = ofx, oy -= h + spy;
else ox += w + spx;
}
SelectObject(hdc, hopen);
DeleteObject(hpen);
ReleaseDC(hwnd, hdc);
return 0;
}
int main(int ac, char **av)
{
if(!initGlyph
(gflg
)) fprintf(stderr
, "error 1"); if(!(glyf_len
= initGlyph
(glyf
))) fprintf(stderr
, "error 2"); drawStrokes(10, 120, 480, 40, 40, "Hello,\nworld!");
return 0;
}
Ly8gY29weXJpZ2h0IOKXhmVuM1BHc2ZPWG8gaHR0cDovL3QuLi5jb250ZW50LWF2YWlsYWJsZS10by1hdXRob3Itb25seS4uLmgubmV0L3Rlc3QvcmVhZC5jZ2kvdGVjaC8xMzYzMDQyNTAyLwoKI2luY2x1ZGUgPHdpbmRvd3MuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KCkJZVEUgKmdmbGcgPSAiQVF2LzhBSVlIOGs1Sk1rQkEvQUNDeGVTU1NRQkEvQUJEUC80QVJMSitTQUNFeURra255U0FBSURCLzg9IjsKQllURSAqZ2x5ZiA9ICJBQXdBU0FVN0FBRC9PZ0FBQUFBQzJmMFpBQUFBQVAwbi96b0FBQUFBQmRFQXhnQUFBQUQ5dUFMbkFBQUFBQUpJIgogICAgICAgICAgICAgIkFNWUFBQUFnQUdVRVlBSWIvTWtBQUFBQS81a0FQdjluQURiL3p3QTAvOUFBai8vUUFGWUFBQUJ5QUFBQTV3QmIiCiAgICAgICAgICAgICAiQURFQUxBQUtBQUFBQVA4ei82SC8yUDg2LzhyL2t3QUEvdW9BQVA3SUFTMEFBQUVWQUFBQkVnRXJBVUlBOUFBQSIKICAgICAgICAgICAgICJBT0lBQUFEMS92Z0FBUDhOLzBrQUt2Ly9BSlQvYlFDaS8yb0FBUDlwQUFEL1RmOU8vL1QvZkFBRUFHd0Jkd0FBIgogICAgICAgICAgICAgIi8wUUFBQUFBQmhRQXZBQUFBQmdBYndSeEFpNEFBUDd2L3VqK3hQOFZBQUQvRXdBQS91a0JQQUFBQVJFQUFBRVIiCiAgICAgICAgICAgICAiQVJjQlBRRHRBQUFBNndBQUFSait3LzgrL3U4QUFBRFovMVlBMC85cEFBRC9ad0FBLzFmL0xRQUEveWNBQVA4dSIKICAgICAgICAgICAgICJBS3IvSndDWUFBQUFsZ0FBQUtzQTF3QUVBQ3dDUHdFZC91YjljZjl1QUFBQXJnS1BBQTBBZHdZMkJGMyszZnVqIgogICAgICAgICAgICAgIi8xSUFBUDdoQTEzKzQveWovMU1BQVA3YUJGMEF4QUFBQU0zOG53RVhBMkVBbXdBQUFSNzhud0RDQTJFQUV3QnkiCiAgICAgICAgICAgICAiQTNJRGtQLzJBQUQvMWdBSy83RUFDZi9LQUFEL3FRQUEvMTcvcy8rMS84TUFBUHpuLzBRQUFBQUFCRjBBdkFBQSIKICAgICAgICAgICAgICJBQUQvV3dCd0FGb0Fxd0JMQUZrQUFBQXhBQUFBTFAvN0FDei8rUUFoQUdRRVF3QUEvMFFBQUFBQUFIWC9yLys2IgogICAgICAgICAgICAgIi8xRC9zditaQUFEL09BQUEveFVCTkFBQUFSRUFBQUNPQUZFQTNnQkZBRTRBUkFCTUFMVUFVQUJoQUFBQVdBQUEiCiAgICAgICAgICAgICAiQUlqLzJ3QkwvOWtBQUFIa0FMd0FBUDlFK3Y4QUFBS0IvN1FBSXYrSUFCci91UUFBLzJJQUFQOVEveVFBQVA4MiIKICAgICAgICAgICAgICJBQUQvT1FDSS96RUFsZ0FBQUZBQUFBQ2tBRWNBQ0FBaEFnTUYwZi9tKzhuL1ZnQUEvK1FFTndEVytpLy9OQUFBIgogICAgICAgICAgICAgIkFBQUEwd0RNQUFBPSI7CmludCBnbHlmX2xlbiA9IDA7CgppbnQgYjY0ZGVjb2RlKEJZVEUgKmRzdCwgc2l6ZV90ICpkc3Rfc2l6ZSwgQllURSAqc3JjLCBpbnQgc3JjX3NpemUpCnsKICBzdGF0aWMgQllURSBiNjRvWzgwXSA9IHsKICAgIDYyLCAgMCwgNjIsICAwLCA2MywgNTIsIDUzLCA1NCwgNTUsIDU2LCA1NywgNTgsIDU5LCA2MCwgNjEsICAwLAogICAgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAxLCAgMiwgIDMsICA0LCAgNSwgIDYsICA3LCAgOCwgIDksCiAgICAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LCAxNiwgMTcsIDE4LCAxOSwgMjAsIDIxLCAyMiwgMjMsIDI0LCAyNSwKICAgICAwLCAgMCwgIDAsIDYyLCA2MywgIDAsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LAogICAgMzYsIDM3LCAzOCwgMzksIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywgNDgsIDQ5LCA1MCwgNTF9OwogIGludCBpLCB3b3JkcyA9IHNyY19zaXplLzQsIG92ZXJzaXplID0gKmRzdF9zaXplKzIsIGxhc3RpID0gb3ZlcnNpemUvMy0xOwogIGlmKHNyY19zaXplICUgNCkgcmV0dXJuIDE7CiAgaWYoKmRzdF9zaXplIDwgd29yZHMgKiAzKSByZXR1cm4gMjsKICBmb3IoaSA9IDA7IGkgPD0gbGFzdGk7IGkrKyl7CiAgICBpbnQgajsKICAgIEJZVEUgY1s0XTsKICAgIGZvcihqID0gMDsgaiA8IHNpemVvZihjKTsgaisrKQogICAgICBjW2pdID0gYjY0b1soc3JjW2kgKiBzaXplb2YoYykgKyBqXSAtICcrJykgJSBzaXplb2YoYjY0byldOwogICAgZHN0W2kgKiAzICsgMF0gPSAoKGNbMF0gPDwgMikgJiAweDAwZmMpIHwgKChjWzFdID4+IDQpICYgMHgwMyk7CiAgICBpZihpIDwgbGFzdGkgfHwgb3ZlcnNpemUgJSAzKQogICAgICBkc3RbaSAqIDMgKyAxXSA9ICgoY1sxXSA8PCA0KSAmIDB4MDBmMCkgfCAoKGNbMl0gPj4gMikgJiAweDBmKTsKICAgIGlmKGkgPCBsYXN0aSB8fCAob3ZlcnNpemUgJSAzKSA9PSAyKQogICAgICBkc3RbaSAqIDMgKyAyXSA9ICgoY1syXSA8PCA2KSAmIDB4MDBjMCkgfCAoY1szXSAmIDB4M2YpOwogIH0KICBpZihzcmNbc3JjX3NpemUgLSAxXSA9PSAnPScpewogICAgLS0oKmRzdF9zaXplKTsKICAgIGlmKHNyY1tzcmNfc2l6ZSAtIDJdID09ICc9JykgLS0oKmRzdF9zaXplKTsKICB9CiAgcmV0dXJuIDA7Cn0KCmludCBpbml0R2x5cGgoQllURSAqc3RyKQp7CiAgaW50IGxlbiA9IChzdHJsZW4oc3RyKSA+PiAyKSAqIDM7CiAgaWYoYjY0ZGVjb2RlKHN0ciwgJmxlbiwgc3RyLCBzdHJsZW4oc3RyKSkpIHJldHVybiAwOwogIHJldHVybiBsZW47Cn0KCmludCBiMmgoQllURSAqYikKewogIHJldHVybiAoc2hvcnQpKChiWzBdIDw8IDgpIHwgYlsxXSk7Cn0KCmludCBnZXRHbHlwaERhdGEoQllURSAqKmVwb2MsIEJZVEUgKipmbGFncywgaW50ICoqeGNvb3JkcywgaW50ICoqeWNvb3JkcywKICBpbnQgKm51bWVwb2MsIGNoYXIgY2gpCnsKICBpbnQgaSwgaiwgaywgcG9zID0gMCwgbnVtID0gMCwgY29kZSA9IDAsIGZwb3MgPSAwLCBlcG51bSA9IDAsIGZudW0gPSAwOwogICplcG9jID0gKmZsYWdzID0gTlVMTCwgKnhjb29yZHMgPSAqeWNvb3JkcyA9IE5VTEwsICpudW1lcG9jID0gMDsKICB3aGlsZShwb3MgPCBnbHlmX2xlbil7CiAgICBudW0gPSBiMmgoJmdseWZbcG9zXSksIGNvZGUgPSBiMmgoJmdseWZbcG9zICsgMl0pOwogICAgZXBudW0gPSBnZmxnW2Zwb3NdLCBmbnVtID0gKG51bSArIDcpIC8gODsKICAgIGlmKGNvZGUgPT0gY2gpewogICAgICAqZXBvYyA9IChCWVRFICopbWFsbG9jKCpudW1lcG9jID0gZXBudW0pOwogICAgICBpZighKmVwb2MpIGJyZWFrOwogICAgICBmb3IoaSA9IDA7IGkgPCBlcG51bTsgKytpKSAoKmVwb2MpW2ldID0gZ2ZsZ1tmcG9zICsgMSArIGldOwogICAgICAqZmxhZ3MgPSAoQllURSAqKW1hbGxvYyhudW0pOwogICAgICBpZighKmZsYWdzKSBicmVhazsKICAgICAgZm9yKGkgPSAwLCBrID0gMDsgaSA8IGZudW07ICsraSl7CiAgICAgICAgQllURSBiID0gZ2ZsZ1tmcG9zICsgMSArIGVwbnVtICsgaV07CiAgICAgICAgQllURSBtID0gMHg4MDsKICAgICAgICBmb3IoaiA9IDA7IGogPCA4IC0gKGkgPT0gZm51bSAtIDEgPyBmbnVtICogOCAtIG51bSA6IDApOyArK2osIG0gPj49IDEpCiAgICAgICAgICAoKmZsYWdzKVtrKytdID0gYiAmIG0gPyAxIDogMDsKICAgICAgfQogICAgICBicmVhazsKICAgIH0KICAgIHBvcyArPSAobnVtICsgMSkgKiA0OwogICAgZnBvcyArPSBlcG51bSArIGZudW0gKyAxOwogIH0KICBpZighKmVwb2MgfHwgISpmbGFncykgcmV0dXJuIDA7CiAgKnhjb29yZHMgPSAoaW50ICopbWFsbG9jKG51bSAqIHNpemVvZihpbnQpKTsKICAqeWNvb3JkcyA9IChpbnQgKiltYWxsb2MobnVtICogc2l6ZW9mKGludCkpOwogIGlmKCEqeGNvb3JkcyB8fCAhKnljb29yZHMpIHJldHVybiAwOwogIGZvcihpID0gMDsgaSA8IG51bTsgKytpKXsKICAgICgqeGNvb3JkcylbaV0gPSAoaSA/ICgqeGNvb3JkcylbaS0xXSA6IDApICsgYjJoKCZnbHlmW3BvcyArIChpKzEpKjRdKTsKICAgICgqeWNvb3JkcylbaV0gPSAoaSA/ICgqeWNvb3JkcylbaS0xXSA6IDApICsgYjJoKCZnbHlmW3BvcyArIChpKzEpKjQgKyAyXSk7CiAgfQogIHJldHVybiBudW07Cn0KCmludCBkcmF3R2x5cGgoSERDIGhkYywgaW50IHNjYWxlLCBpbnQgc3p4LCBpbnQgc3p5LCBpbnQgb3gsIGludCBveSwKICBpbnQgKncsIGludCAqaCwgaW50IGNoKQp7CiAgQllURSAqZXBvYywgKmZsYWdzOwogIGludCAqeGNvb3JkcywgKnljb29yZHMsIG51bWVwb2MsIGksIGo7CiAgaW50IG51bWZsYWdzID0gZ2V0R2x5cGhEYXRhKCZlcG9jLCAmZmxhZ3MsICZ4Y29vcmRzLCAmeWNvb3JkcywgJm51bWVwb2MsIGNoKTsKICAqdyA9IDgwLCAqaCA9IDE2MDsKICBpZighbnVtZmxhZ3MpIHJldHVybiAwOwogIGZvcihqID0gMDsgaiA8IG51bWVwb2M7ICsrail7CiAgICBpbnQgcHgsIHB5LCBrID0gaiA/IGVwb2NbaiAtIDFdICsgMSA6IDA7CiAgICBmb3IoaSA9IGs7IGkgPD0gZXBvY1tqXTsgKytpKXsKICAgICAgaW50IGZsZyA9IGZsYWdzW2ldLCB4ID0geGNvb3Jkc1tpXSwgeSA9IHljb29yZHNbaV07CiAgICAgIGludCByID0gaSA9PSBrID8gNCA6IDM7CiAgICAgIENPTE9SUkVGIGNvbCA9IGZsZyAmIDB4MDEgPyBSR0IoMCwgMCwgMjU1KSA6IFJHQigyNTUsIDAsIDApOwogICAgICBIUEVOIGhwZW4gPSBDcmVhdGVQZW4oUFNfU09MSUQsIDEsIGNvbCk7CiAgICAgIEhQRU4gaG9wZW4gPSAoSFBFTilTZWxlY3RPYmplY3QoaGRjLCBocGVuKTsKICAgICAgSEJSVVNIIGhicnVzaCwgaG9icnVzaDsKICAgICAgaWYoaSA9PSBrKSBoYnJ1c2ggPSBDcmVhdGVTb2xpZEJydXNoKFJHQigwLCAyNTUsIDApKTsKICAgICAgZWxzZSBoYnJ1c2ggPSAoSEJSVVNIKUdldFN0b2NrT2JqZWN0KEhPTExPV19CUlVTSCk7CiAgICAgIGhvYnJ1c2ggPSAoSEJSVVNIKVNlbGVjdE9iamVjdChoZGMsIGhicnVzaCk7CiAgICAgIEVsbGlwc2UoaGRjLCBveCAtIHIgKyB4IC8gc2NhbGUsIHN6eSAtIChveSAtIHIgKyB5IC8gc2NhbGUpLAogICAgICAgIG94ICsgciArIHggLyBzY2FsZSwgc3p5IC0gKG95ICsgciArIHkgLyBzY2FsZSkpOwogICAgICBTZWxlY3RPYmplY3QoaGRjLCBob2JydXNoKTsKICAgICAgaWYoaSA9PSBrKSBEZWxldGVPYmplY3QoaGJydXNoKTsKICAgICAgU2VsZWN0T2JqZWN0KGhkYywgaG9wZW4pOwogICAgICBEZWxldGVPYmplY3QoaHBlbik7CiAgICAgIGlmKGkgIT0gaykgc3Ryb2tlKGhkYywgc2NhbGUsIHN6eCwgc3p5LCBveCwgb3ksIHB4LCBweSwgeCwgeSk7CiAgICAgIHB4ID0geCwgcHkgPSB5OwogICAgfQogICAgc3Ryb2tlKGhkYywgc2NhbGUsIHN6eCwgc3p5LCBveCwgb3ksIHB4LCBweSwgeGNvb3Jkc1trXSwgeWNvb3Jkc1trXSk7CiAgfQogIGlmKGVwb2MpIGZyZWUoZXBvYyk7CiAgaWYoZmxhZ3MpIGZyZWUoZmxhZ3MpOwogIGlmKHhjb29yZHMpIGZyZWUoeGNvb3Jkcyk7CiAgaWYoeWNvb3JkcykgZnJlZSh5Y29vcmRzKTsKICByZXR1cm4gMDsKfQoKaW50IHN0cm9rZShIREMgaGRjLCBpbnQgc2NhbGUsIGludCBzengsIGludCBzenksIGludCBveCwgaW50IG95LAogIGludCB4cywgaW50IHlzLCBpbnQgeGUsIGludCB5ZSkKewogIFBPSU5UIHA7CiAgTW92ZVRvRXgoaGRjLCBveCArIHhzIC8gc2NhbGUsIHN6eSAtIChveSArIHlzIC8gc2NhbGUpLCAmcCk7CiAgTGluZVRvKGhkYywgb3ggKyB4ZSAvIHNjYWxlLCBzenkgLSAob3kgKyB5ZSAvIHNjYWxlKSk7CiAgcmV0dXJuIDA7Cn0KCmludCBkcmF3U3Ryb2tlcyhpbnQgc2NhbGUsIGludCBvZngsIGludCBvZnksIGludCBzcHgsIGludCBzcHksIGNoYXIgKnN0cikKewogIGludCBzengsIHN6eSwgb3ggPSBvZngsIG95ID0gb2Z5OwogIGNoYXIgKnA7CiAgSFdORCBod25kID0gR2V0RGVza3RvcFdpbmRvdygpOwogIEhEQyBoZGMgPSBHZXREQyhod25kKTsKICBIUEVOIGhwZW4gPSBDcmVhdGVQZW4oUFNfU09MSUQsIDEsIFJHQigwLCAyNTUsIDApKTsKICBIUEVOIGhvcGVuID0gKEhQRU4pU2VsZWN0T2JqZWN0KGhkYywgaHBlbik7CiAgUkVDVCByYzsKICBHZXRDbGllbnRSZWN0KGh3bmQsICZyYyk7CiAgc3p4ID0gcmMucmlnaHQgLSByYy5sZWZ0LCBzenkgPSByYy5ib3R0b20gLSByYy50b3A7CiAgZm9yKHAgPSBzdHI7ICpwOyArK3ApewogICAgaW50IHcsIGg7CiAgICBkcmF3R2x5cGgoaGRjLCBzY2FsZSwgc3p4LCBzenksIG94LCBveSwgJncsICZoLCAqcCk7CiAgICBpZigqcCA9PSAnXG4nKSBveCA9IG9meCwgb3kgLT0gaCArIHNweTsKICAgIGVsc2Ugb3ggKz0gdyArIHNweDsKICB9CiAgU2VsZWN0T2JqZWN0KGhkYywgaG9wZW4pOwogIERlbGV0ZU9iamVjdChocGVuKTsKICBSZWxlYXNlREMoaHduZCwgaGRjKTsKICByZXR1cm4gMDsKfQoKaW50IG1haW4oaW50IGFjLCBjaGFyICoqYXYpCnsKICBpZighaW5pdEdseXBoKGdmbGcpKSBmcHJpbnRmKHN0ZGVyciwgImVycm9yIDEiKTsKICBpZighKGdseWZfbGVuID0gaW5pdEdseXBoKGdseWYpKSkgZnByaW50ZihzdGRlcnIsICJlcnJvciAyIik7CiAgZHJhd1N0cm9rZXMoMTAsIDEyMCwgNDgwLCA0MCwgNDAsICJIZWxsbyxcbndvcmxkISIpOwogIHJldHVybiAwOwp9