Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBKUEVHMjAwMCBoZWxwZXJzCi8vCi8vIERlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLwovLyBUaGlzIGZpbGUgaXMgcGFydCBvZiBGcmVlSW1hZ2UgMwovLwovLyBDT1ZFUkVEIENPREUgSVMgUFJPVklERUQgVU5ERVIgVEhJUyBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsIFdJVEhPVVQgV0FSUkFOVFkKLy8gT0YgQU5ZIEtJTkQsIEVJVEhFUiBFWFBSRVNTRUQgT1IgSU1QTElFRCwgSU5DTFVESU5HLCBXSVRIT1VUIExJTUlUQVRJT04sIFdBUlJBTlRJRVMKLy8gVEhBVCBUSEUgQ09WRVJFRCBDT0RFIElTIEZSRUUgT0YgREVGRUNUUywgTUVSQ0hBTlRBQkxFLCBGSVQgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFCi8vIE9SIE5PTi1JTkZSSU5HSU5HLiBUSEUgRU5USVJFIFJJU0sgQVMgVE8gVEhFIFFVQUxJVFkgQU5EIFBFUkZPUk1BTkNFIE9GIFRIRSBDT1ZFUkVECi8vIENPREUgSVMgV0lUSCBZT1UuIFNIT1VMRCBBTlkgQ09WRVJFRCBDT0RFIFBST1ZFIERFRkVDVElWRSBJTiBBTlkgUkVTUEVDVCwgWU9VIChOT1QKLy8gVEhFIElOSVRJQUwgREVWRUxPUEVSIE9SIEFOWSBPVEhFUiBDT05UUklCVVRPUikgQVNTVU1FIFRIRSBDT1NUIE9GIEFOWSBORUNFU1NBUlkKLy8gU0VSVklDSU5HLCBSRVBBSVIgT1IgQ09SUkVDVElPTi4gVEhJUyBESVNDTEFJTUVSIE9GIFdBUlJBTlRZIENPTlNUSVRVVEVTIEFOIEVTU0VOVElBTAovLyBQQVJUIE9GIFRISVMgTElDRU5TRS4gTk8gVVNFIE9GIEFOWSBDT1ZFUkVEIENPREUgSVMgQVVUSE9SSVpFRCBIRVJFVU5ERVIgRVhDRVBUIFVOREVSCi8vIFRISVMgRElTQ0xBSU1FUi4KLy8KLy8gVXNlIGF0IHlvdXIgb3duIHJpc2shCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiNpbmNsdWRlICJGcmVlSW1hZ2UuaCIKI2luY2x1ZGUgIlV0aWxpdGllcy5oIgojaW5jbHVkZSAiLi4vTGliT3BlbkpQRUcvb3BlbmpwZWcuaCIKCi8qKgpEaXZpZGUgYW4gaW50ZWdlciBieSBhIHBvd2VyIG9mIDIgYW5kIHJvdW5kIHVwd2FyZHMKQHJldHVybiBSZXR1cm5zIGEgZGl2aWRlZCBieSAyXmIKKi8Kc3RhdGljIGludCBpbnRfY2VpbGRpdnBvdzIoaW50IGEsIGludCBiKSB7CglyZXR1cm4gKGEgKyAoMSA8PCBiKSAtIDEpID4+IGI7Cn0KCi8qKgpDb252ZXJ0IGEgT3BlbkpQRUcgaW1hZ2UgdG8gYSBGSUJJVE1BUApAcGFyYW0gZm9ybWF0X2lkIFBsdWdpbiBJRApAcGFyYW0gaW1hZ2UgT3BlbkpQRUcgaW1hZ2UKQHJldHVybiBSZXR1cm5zIHRoZSBjb252ZXJ0ZWQgaW1hZ2UgaWYgc3VjY2Vzc2Z1bCwgcmV0dXJucyBOVUxMIG90aGVyd2lzZQoqLwpGSUJJVE1BUCogSjJLSW1hZ2VUb0ZJQklUTUFQKGludCBmb3JtYXRfaWQsIGNvbnN0IG9wal9pbWFnZV90ICppbWFnZSkgewoJRklCSVRNQVAgKmRpYiA9IE5VTEw7CgoJdHJ5IHsKCQkvLyBjb21wdXRlIGltYWdlIHdpZHRoIGFuZCBoZWlnaHQKCgkJLy9pbnQgdyA9IGludF9jZWlsZGl2KGltYWdlLT54MSAtIGltYWdlLT54MCwgaW1hZ2UtPmNvbXBzWzBdLmR4KTsKCQlpbnQgd3IgPSBpbWFnZS0+Y29tcHNbMF0udzsKCQlpbnQgd3JyID0gaW50X2NlaWxkaXZwb3cyKGltYWdlLT5jb21wc1swXS53LCBpbWFnZS0+Y29tcHNbMF0uZmFjdG9yKTsKCQkKCQkvL2ludCBoID0gaW50X2NlaWxkaXYoaW1hZ2UtPnkxIC0gaW1hZ2UtPnkwLCBpbWFnZS0+Y29tcHNbMF0uZHkpOwoJCS8vaW50IGhyID0gaW1hZ2UtPmNvbXBzWzBdLmg7CgkJaW50IGhyciA9IGludF9jZWlsZGl2cG93MihpbWFnZS0+Y29tcHNbMF0uaCwgaW1hZ2UtPmNvbXBzWzBdLmZhY3Rvcik7CgoJCS8vIGNoZWNrIHRoZSBudW1iZXIgb2YgY29tcG9uZW50cwoKCQlpbnQgbnVtY29tcHMgPSBpbWFnZS0+bnVtY29tcHM7CgoJCUJPT0wgYklzVmFsaWQgPSBUUlVFOwoJCWZvcihpbnQgYyA9IDA7IGMgPCBudW1jb21wcyAtIDE7IGMrKykgewoJCQlpZigJKGltYWdlLT5jb21wc1tjXS5keCA9PSBpbWFnZS0+Y29tcHNbYysxXS5keCkgJiYgCgkJCQkoaW1hZ2UtPmNvbXBzW2NdLmR5ID09IGltYWdlLT5jb21wc1tjKzFdLmR5KSAmJgoJCQkJKGltYWdlLT5jb21wc1tjXS5wcmVjID09IGltYWdlLT5jb21wc1tjKzFdLnByZWMpICkgewoJCQkJY29udGludWU7CgkJCX0gZWxzZSB7CgkJCQliSXNWYWxpZCA9IEZBTFNFOwoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJYklzVmFsaWQgJj0gKChudW1jb21wcyA9PSAxKSB8fCAobnVtY29tcHMgPT0gMykgfHwgKG51bWNvbXBzID09IDQpKTsKCQlpZighYklzVmFsaWQpIHsKCQkJaWYobnVtY29tcHMpIHsKCQkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhmb3JtYXRfaWQsICJXYXJuaW5nOiBpbWFnZSBjb250YWlucyAlZCBncmV5c2NhbGUgY29tcG9uZW50cy4gT25seSB0aGUgZmlyc3Qgd2lsbCBiZSBsb2FkZWQuXG4iLCBudW1jb21wcyk7CgkJCQludW1jb21wcyA9IDE7CgkJCX0gZWxzZSB7CgkJCQkvLyB1bmtub3duIHR5cGUKCQkJCXRocm93IEZJX01TR19FUlJPUl9VTlNVUFBPUlRFRF9GT1JNQVQ7CgkJCX0KCQl9CgoJCS8vIGNyZWF0ZSBhIG5ldyBESUIKCgkJaWYoaW1hZ2UtPmNvbXBzWzBdLnByZWMgPD0gOCkgewoJCQlzd2l0Y2gobnVtY29tcHMpIHsKCQkJCWNhc2UgMToKCQkJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUod3JyLCBocnIsIDgpOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAzOgoJCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZSh3cnIsIGhyciwgMjQsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSA0OgoJCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZSh3cnIsIGhyciwgMzIsIEZJX1JHQkFfUkVEX01BU0ssIEZJX1JHQkFfR1JFRU5fTUFTSywgRklfUkdCQV9CTFVFX01BU0spOwoJCQkJCWJyZWFrOwoJCQl9CgkJfSBlbHNlIGlmKGltYWdlLT5jb21wc1swXS5wcmVjIDw9IDE2KSB7CgkJCXN3aXRjaChudW1jb21wcykgewoJCQkJY2FzZSAxOgoJCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX1VJTlQxNiwgd3JyLCBocnIpOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSAzOgoJCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZVQoRklUX1JHQjE2LCB3cnIsIGhycik7CgkJCQkJYnJlYWs7CgkJCQljYXNlIDQ6CgkJCQkJZGliID0gRnJlZUltYWdlX0FsbG9jYXRlVChGSVRfUkdCQTE2LCB3cnIsIGhycik7CgkJCQkJYnJlYWs7CgkJCX0KCQl9IGVsc2UgewoJCQl0aHJvdyBGSV9NU0dfRVJST1JfVU5TVVBQT1JURURfRk9STUFUOwoJCX0KCQlpZighZGliKSB7CgkJCXRocm93IEZJX01TR19FUlJPUl9ESUJfTUVNT1JZOwoJCX0KCQkKCQlpZihpbWFnZS0+Y29tcHNbMF0ucHJlYyA8PSA4KSB7CgkJCWlmKG51bWNvbXBzID09IDEpIHsKCQkJCS8vIDgtYml0IGdyZXlzY2FsZQoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCQkJCS8vIGJ1aWxkIGEgZ3JleXNjYWxlIHBhbGV0dGUKCQkJCQoJCQkJUkdCUVVBRCAqcGFsID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCQkJCWZvciAoaW50IGkgPSAwOyBpIDwgMjU2OyBpKyspIHsKCQkJCQlwYWxbaV0ucmdiUmVkCT0gKEJZVEUpaTsKCQkJCQlwYWxbaV0ucmdiR3JlZW4gPSAoQllURSlpOwoJCQkJCXBhbFtpXS5yZ2JCbHVlCT0gKEJZVEUpaTsKCQkJCX0KCgkJCQkvLyBsb2FkIHBpeGVsIGRhdGEKCgkJCQl1bnNpZ25lZCBwaXhlbF9jb3VudCA9IDA7CgoJCQkJZm9yKGludCB5ID0gMDsgeSA8IGhycjsgeSsrKSB7CQkKCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaHJyIC0gMSAtIHkpOwoKCQkJCQlmb3IoaW50IHggPSAwOyB4IDwgd3JyOyB4KyspIHsKCQkJCQkJY29uc3QgdW5zaWduZWQgcGl4ZWxfcG9zID0gcGl4ZWxfY291bnQgLyB3cnIgKiB3ciArIHBpeGVsX2NvdW50ICUgd3JyOwoKCQkJCQkJaW50IGluZGV4ID0gaW1hZ2UtPmNvbXBzWzBdLmRhdGFbcGl4ZWxfcG9zXTsKCQkJCQkJaW5kZXggKz0gKGltYWdlLT5jb21wc1swXS5zZ25kID8gMSA8PCAoaW1hZ2UtPmNvbXBzWzBdLnByZWMgLSAxKSA6IDApOwoKCQkJCQkJYml0c1t4XSA9IChCWVRFKWluZGV4OwoKCQkJCQkJcGl4ZWxfY291bnQrKzsKCQkJCQl9CgkJCQl9CgkJCX0KCQkJZWxzZSBpZihudW1jb21wcyA9PSAzKSB7CgoJCQkJLy8gMjQtYml0IFJHQgoJCQkJLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQkKCQkJCQoJCQkJLy8gbG9hZCBwaXhlbCBkYXRhCgoJCQkJdW5zaWduZWQgcGl4ZWxfY291bnQgPSAwOwoKCQkJCWZvcihpbnQgeSA9IDA7IHkgPCBocnI7IHkrKykgewkJCgkJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGhyciAtIDEgLSB5KTsKCgkJCQkJZm9yKGludCB4ID0gMDsgeCA8IHdycjsgeCsrKSB7CgkJCQkJCWNvbnN0IHVuc2lnbmVkIHBpeGVsX3BvcyA9IHBpeGVsX2NvdW50IC8gd3JyICogd3IgKyBwaXhlbF9jb3VudCAlIHdycjsKCgkJCQkJCWludCByID0gaW1hZ2UtPmNvbXBzWzBdLmRhdGFbcGl4ZWxfcG9zXTsKCQkJCQkJciArPSAoaW1hZ2UtPmNvbXBzWzBdLnNnbmQgPyAxIDw8IChpbWFnZS0+Y29tcHNbMF0ucHJlYyAtIDEpIDogMCk7CgkJCQkJCQoJCQkJCQlpbnQgZyA9IGltYWdlLT5jb21wc1sxXS5kYXRhW3BpeGVsX3Bvc107CgkJCQkJCWcgKz0gKGltYWdlLT5jb21wc1sxXS5zZ25kID8gMSA8PCAoaW1hZ2UtPmNvbXBzWzFdLnByZWMgLSAxKSA6IDApOwoJCQkJCQkKCQkJCQkJaW50IGIgPSBpbWFnZS0+Y29tcHNbMl0uZGF0YVtwaXhlbF9wb3NdOwoJCQkJCQliICs9IChpbWFnZS0+Y29tcHNbMl0uc2duZCA/IDEgPDwgKGltYWdlLT5jb21wc1syXS5wcmVjIC0gMSkgOiAwKTsKCgkJCQkJCWJpdHNbRklfUkdCQV9SRURdICAgPSAoQllURSlyOwoJCQkJCQliaXRzW0ZJX1JHQkFfR1JFRU5dID0gKEJZVEUpZzsKCQkJCQkJYml0c1tGSV9SR0JBX0JMVUVdICA9IChCWVRFKWI7CgkJCQkJCWJpdHMgKz0gMzsKCgkJCQkJCXBpeGVsX2NvdW50Kys7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UgaWYobnVtY29tcHMgPT0gNCkgewoKCQkJCS8vIDMyLWJpdCBSR0JBCgkJCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCQoJCQkJCgkJCQkvLyBsb2FkIHBpeGVsIGRhdGEKCgkJCQl1bnNpZ25lZCBwaXhlbF9jb3VudCA9IDA7CgoJCQkJZm9yKGludCB5ID0gMDsgeSA8IGhycjsgeSsrKSB7CQkKCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaHJyIC0gMSAtIHkpOwoKCQkJCQlmb3IoaW50IHggPSAwOyB4IDwgd3JyOyB4KyspIHsKCQkJCQkJY29uc3QgdW5zaWduZWQgcGl4ZWxfcG9zID0gcGl4ZWxfY291bnQgLyB3cnIgKiB3ciArIHBpeGVsX2NvdW50ICUgd3JyOwoKCQkJCQkJaW50IHIgPSBpbWFnZS0+Y29tcHNbMF0uZGF0YVtwaXhlbF9wb3NdOwoJCQkJCQlyICs9IChpbWFnZS0+Y29tcHNbMF0uc2duZCA/IDEgPDwgKGltYWdlLT5jb21wc1swXS5wcmVjIC0gMSkgOiAwKTsKCQkJCQkJCgkJCQkJCWludCBnID0gaW1hZ2UtPmNvbXBzWzFdLmRhdGFbcGl4ZWxfcG9zXTsKCQkJCQkJZyArPSAoaW1hZ2UtPmNvbXBzWzFdLnNnbmQgPyAxIDw8IChpbWFnZS0+Y29tcHNbMV0ucHJlYyAtIDEpIDogMCk7CgkJCQkJCQoJCQkJCQlpbnQgYiA9IGltYWdlLT5jb21wc1syXS5kYXRhW3BpeGVsX3Bvc107CgkJCQkJCWIgKz0gKGltYWdlLT5jb21wc1syXS5zZ25kID8gMSA8PCAoaW1hZ2UtPmNvbXBzWzJdLnByZWMgLSAxKSA6IDApOwoKCQkJCQkJaW50IGEgPSBpbWFnZS0+Y29tcHNbM10uZGF0YVtwaXhlbF9wb3NdOwoJCQkJCQlhICs9IChpbWFnZS0+Y29tcHNbM10uc2duZCA/IDEgPDwgKGltYWdlLT5jb21wc1szXS5wcmVjIC0gMSkgOiAwKTsKCgkJCQkJCWJpdHNbRklfUkdCQV9SRURdICAgPSAoQllURSlyOwoJCQkJCQliaXRzW0ZJX1JHQkFfR1JFRU5dID0gKEJZVEUpZzsKCQkJCQkJYml0c1tGSV9SR0JBX0JMVUVdICA9IChCWVRFKWI7CgkJCQkJCWJpdHNbRklfUkdCQV9BTFBIQV0gPSAoQllURSlhOwoJCQkJCQliaXRzICs9IDQ7CgoJCQkJCQlwaXhlbF9jb3VudCsrOwoJCQkJCX0KCQkJCX0KCQkJfQoJCX0KCQllbHNlIGlmKGltYWdlLT5jb21wc1swXS5wcmVjIDw9IDE2KSB7CgkJCWlmKG51bWNvbXBzID09IDEpIHsKCQkJCS8vIDE2LWJpdCBncmV5c2NhbGUKCQkJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCgkJCQkvLyBsb2FkIHBpeGVsIGRhdGEKCgkJCQl1bnNpZ25lZCBwaXhlbF9jb3VudCA9IDA7CgoJCQkJZm9yKGludCB5ID0gMDsgeSA8IGhycjsgeSsrKSB7CQkKCQkJCQl1bnNpZ25lZCBzaG9ydCAqYml0cyA9ICh1bnNpZ25lZCBzaG9ydCopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaHJyIC0gMSAtIHkpOwoKCQkJCQlmb3IoaW50IHggPSAwOyB4IDwgd3JyOyB4KyspIHsKCQkJCQkJY29uc3QgdW5zaWduZWQgcGl4ZWxfcG9zID0gcGl4ZWxfY291bnQgLyB3cnIgKiB3ciArIHBpeGVsX2NvdW50ICUgd3JyOwoKCQkJCQkJaW50IGluZGV4ID0gaW1hZ2UtPmNvbXBzWzBdLmRhdGFbcGl4ZWxfcG9zXTsKCQkJCQkJaW5kZXggKz0gKGltYWdlLT5jb21wc1swXS5zZ25kID8gMSA8PCAoaW1hZ2UtPmNvbXBzWzBdLnByZWMgLSAxKSA6IDApOwoKCQkJCQkJYml0c1t4XSA9ICh1bnNpZ25lZCBzaG9ydClpbmRleDsKCgkJCQkJCXBpeGVsX2NvdW50Kys7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UgaWYobnVtY29tcHMgPT0gMykgewoKCQkJCS8vIDQ4LWJpdCBSR0IKCQkJCS8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JCgkJCQkKCQkJCS8vIGxvYWQgcGl4ZWwgZGF0YQoKCQkJCXVuc2lnbmVkIHBpeGVsX2NvdW50ID0gMDsKCgkJCQlmb3IoaW50IHkgPSAwOyB5IDwgaHJyOyB5KyspIHsJCQoJCQkJCUZJUkdCMTYgKmJpdHMgPSAoRklSR0IxNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaHJyIC0gMSAtIHkpOwoKCQkJCQlmb3IoaW50IHggPSAwOyB4IDwgd3JyOyB4KyspIHsKCQkJCQkJY29uc3QgdW5zaWduZWQgcGl4ZWxfcG9zID0gcGl4ZWxfY291bnQgLyB3cnIgKiB3ciArIHBpeGVsX2NvdW50ICUgd3JyOwoKCQkJCQkJaW50IHIgPSBpbWFnZS0+Y29tcHNbMF0uZGF0YVtwaXhlbF9wb3NdOwoJCQkJCQlyICs9IChpbWFnZS0+Y29tcHNbMF0uc2duZCA/IDEgPDwgKGltYWdlLT5jb21wc1swXS5wcmVjIC0gMSkgOiAwKTsKCQkJCQkJCgkJCQkJCWludCBnID0gaW1hZ2UtPmNvbXBzWzFdLmRhdGFbcGl4ZWxfcG9zXTsKCQkJCQkJZyArPSAoaW1hZ2UtPmNvbXBzWzFdLnNnbmQgPyAxIDw8IChpbWFnZS0+Y29tcHNbMV0ucHJlYyAtIDEpIDogMCk7CgkJCQkJCQoJCQkJCQlpbnQgYiA9IGltYWdlLT5jb21wc1syXS5kYXRhW3BpeGVsX3Bvc107CgkJCQkJCWIgKz0gKGltYWdlLT5jb21wc1syXS5zZ25kID8gMSA8PCAoaW1hZ2UtPmNvbXBzWzJdLnByZWMgLSAxKSA6IDApOwoKCQkJCQkJYml0c1t4XS5yZWQgICA9IChXT1JEKXI7CgkJCQkJCWJpdHNbeF0uZ3JlZW4gPSAoV09SRClnOwoJCQkJCQliaXRzW3hdLmJsdWUgID0gKFdPUkQpYjsKCgkJCQkJCXBpeGVsX2NvdW50Kys7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWVsc2UgaWYobnVtY29tcHMgPT0gNCkgewoKCQkJCS8vIDY0LWJpdCBSR0JBCgkJCQkvLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCQoJCQkJCgkJCQkvLyBsb2FkIHBpeGVsIGRhdGEKCgkJCQl1bnNpZ25lZCBwaXhlbF9jb3VudCA9IDA7CgoJCQkJZm9yKGludCB5ID0gMDsgeSA8IGhycjsgeSsrKSB7CQkKCQkJCQlGSVJHQkExNiAqYml0cyA9IChGSVJHQkExNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaHJyIC0gMSAtIHkpOwoKCQkJCQlmb3IoaW50IHggPSAwOyB4IDwgd3JyOyB4KyspIHsKCQkJCQkJY29uc3QgdW5zaWduZWQgcGl4ZWxfcG9zID0gcGl4ZWxfY291bnQgLyB3cnIgKiB3ciArIHBpeGVsX2NvdW50ICUgd3JyOwoKCQkJCQkJaW50IHIgPSBpbWFnZS0+Y29tcHNbMF0uZGF0YVtwaXhlbF9wb3NdOwoJCQkJCQlyICs9IChpbWFnZS0+Y29tcHNbMF0uc2duZCA/IDEgPDwgKGltYWdlLT5jb21wc1swXS5wcmVjIC0gMSkgOiAwKTsKCQkJCQkJCgkJCQkJCWludCBnID0gaW1hZ2UtPmNvbXBzWzFdLmRhdGFbcGl4ZWxfcG9zXTsKCQkJCQkJZyArPSAoaW1hZ2UtPmNvbXBzWzFdLnNnbmQgPyAxIDw8IChpbWFnZS0+Y29tcHNbMV0ucHJlYyAtIDEpIDogMCk7CgkJCQkJCQoJCQkJCQlpbnQgYiA9IGltYWdlLT5jb21wc1syXS5kYXRhW3BpeGVsX3Bvc107CgkJCQkJCWIgKz0gKGltYWdlLT5jb21wc1syXS5zZ25kID8gMSA8PCAoaW1hZ2UtPmNvbXBzWzJdLnByZWMgLSAxKSA6IDApOwoKCQkJCQkJaW50IGEgPSBpbWFnZS0+Y29tcHNbM10uZGF0YVtwaXhlbF9wb3NdOwoJCQkJCQlhICs9IChpbWFnZS0+Y29tcHNbM10uc2duZCA/IDEgPDwgKGltYWdlLT5jb21wc1szXS5wcmVjIC0gMSkgOiAwKTsKCgkJCQkJCWJpdHNbeF0ucmVkICAgPSAoV09SRClyOwoJCQkJCQliaXRzW3hdLmdyZWVuID0gKFdPUkQpZzsKCQkJCQkJYml0c1t4XS5ibHVlICA9IChXT1JEKWI7CgkJCQkJCWJpdHNbeF0uYWxwaGEgPSAoV09SRClhOwoKCQkJCQkJcGl4ZWxfY291bnQrKzsKCQkJCQl9CgkJCQl9CgkJCX0KCQl9CgoJCXJldHVybiBkaWI7CgoJfSBjYXRjaChjb25zdCBjaGFyICp0ZXh0KSB7CgkJaWYoZGliKSBGcmVlSW1hZ2VfVW5sb2FkKGRpYik7CgkJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKGZvcm1hdF9pZCwgdGV4dCk7CgkJcmV0dXJuIE5VTEw7Cgl9Cgp9CgovKioKQ29udmVydCBhIEZJQklUTUFQIHRvIGEgT3BlbkpQRUcgaW1hZ2UKQHBhcmFtIGZvcm1hdF9pZCBQbHVnaW4gSUQKQHBhcmFtIGRpYiBGcmVlSW1hZ2UgaW1hZ2UKQHBhcmFtIHBhcmFtZXRlcnMgQ29tcHJlc3Npb24gcGFyYW1ldGVycwpAcmV0dXJuIFJldHVybnMgdGhlIGNvbnZlcnRlZCBpbWFnZSBpZiBzdWNjZXNzZnVsLCByZXR1cm5zIE5VTEwgb3RoZXJ3aXNlCiovCm9wal9pbWFnZV90KiBGSUJJVE1BUFRvSjJLSW1hZ2UoaW50IGZvcm1hdF9pZCwgRklCSVRNQVAgKmRpYiwgY29uc3Qgb3BqX2NwYXJhbWV0ZXJzX3QgKnBhcmFtZXRlcnMpIHsKCWludCBwcmVjLCBudW1jb21wcywgeCwgeSwgaW5kZXg7CglPUEpfQ09MT1JfU1BBQ0UgY29sb3Jfc3BhY2U7CglvcGpfaW1hZ2VfY21wdHBhcm1fdCBjbXB0cGFybVs0XTsJLy8gbWF4aW11bSBvZiA0IGNvbXBvbmVudHMgCglvcGpfaW1hZ2VfdCAqaW1hZ2UgPSBOVUxMOwkJCS8vIGltYWdlIHRvIGVuY29kZQoKCXRyeSB7CgkJaW50IHcgPSBGcmVlSW1hZ2VfR2V0V2lkdGgoZGliKTsKCQlpbnQgaCA9IEZyZWVJbWFnZV9HZXRIZWlnaHQoZGliKTsKCgkJLy8gZ2V0IGltYWdlIGNoYXJhY3RlcmlzdGljcwoJCUZSRUVfSU1BR0VfVFlQRSBpbWFnZV90eXBlID0gRnJlZUltYWdlX0dldEltYWdlVHlwZShkaWIpOwoKCQlpZihpbWFnZV90eXBlID09IEZJVF9CSVRNQVApIHsKCQkJLy8gc3RhbmRhcmQgaW1hZ2UgLi4uCgkJCXByZWMgPSA4OwoJCQlzd2l0Y2goRnJlZUltYWdlX0dldENvbG9yVHlwZShkaWIpKSB7CgkJCQljYXNlIEZJQ19NSU5JU0JMQUNLOgoJCQkJCW51bWNvbXBzID0gMTsKCQkJCQljb2xvcl9zcGFjZSA9IENMUlNQQ19HUkFZOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBGSUNfUkdCOgoJCQkJCW51bWNvbXBzID0gMzsKCQkJCQljb2xvcl9zcGFjZSA9IENMUlNQQ19TUkdCOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBGSUNfUkdCQUxQSEE6CgkJCQkJbnVtY29tcHMgPSA0OwoJCQkJCWNvbG9yX3NwYWNlID0gQ0xSU1BDX1NSR0I7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCXJldHVybiBOVUxMOwoJCQl9CgkJfSBlbHNlIHsKCQkJLy8gSERSIGltYWdlIC4uLgoJCQlwcmVjID0gMTY7CgkJCXN3aXRjaChpbWFnZV90eXBlKSB7CgkJCQljYXNlIEZJVF9VSU5UMTY6CgkJCQkJbnVtY29tcHMgPSAxOwoJCQkJCWNvbG9yX3NwYWNlID0gQ0xSU1BDX0dSQVk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEZJVF9SR0IxNjoKCQkJCQludW1jb21wcyA9IDM7CgkJCQkJY29sb3Jfc3BhY2UgPSBDTFJTUENfU1JHQjsKCQkJCQlicmVhazsKCQkJCWNhc2UgRklUX1JHQkExNjoKCQkJCQludW1jb21wcyA9IDQ7CgkJCQkJY29sb3Jfc3BhY2UgPSBDTFJTUENfU1JHQjsKCQkJCQlicmVhazsKCQkJCWRlZmF1bHQ6CgkJCQkJcmV0dXJuIE5VTEw7CgkJCX0KCQl9CgoJCS8vIGluaXRpYWxpemUgaW1hZ2UgY29tcG9uZW50cyAKCQltZW1zZXQoJmNtcHRwYXJtWzBdLCAwLCA0ICogc2l6ZW9mKG9wal9pbWFnZV9jbXB0cGFybV90KSk7CgkJZm9yKGludCBpID0gMDsgaSA8IG51bWNvbXBzOyBpKyspIHsKCQkJY21wdHBhcm1baV0uZHggPSBwYXJhbWV0ZXJzLT5zdWJzYW1wbGluZ19keDsKCQkJY21wdHBhcm1baV0uZHkgPSBwYXJhbWV0ZXJzLT5zdWJzYW1wbGluZ19keTsKCQkJY21wdHBhcm1baV0udyA9IHc7CgkJCWNtcHRwYXJtW2ldLmggPSBoOwoJCQljbXB0cGFybVtpXS5wcmVjID0gcHJlYzsKCQkJY21wdHBhcm1baV0uYnBwID0gcHJlYzsKCQkJY21wdHBhcm1baV0uc2duZCA9IDA7CgkJfQoJCS8vIGNyZWF0ZSB0aGUgaW1hZ2UgCgkJaW1hZ2UgPSBvcGpfaW1hZ2VfY3JlYXRlKG51bWNvbXBzLCAmY21wdHBhcm1bMF0sIGNvbG9yX3NwYWNlKTsKCQlpZighaW1hZ2UpIHsKCQkJdGhyb3cgRklfTVNHX0VSUk9SX0RJQl9NRU1PUlk7CgkJfQoKCQkvLyBzZXQgaW1hZ2Ugb2Zmc2V0IGFuZCByZWZlcmVuY2UgZ3JpZCAKCQlpbWFnZS0+eDAgPSBwYXJhbWV0ZXJzLT5pbWFnZV9vZmZzZXRfeDA7CgkJaW1hZ2UtPnkwID0gcGFyYW1ldGVycy0+aW1hZ2Vfb2Zmc2V0X3kwOwoJCWltYWdlLT54MSA9IHBhcmFtZXRlcnMtPmltYWdlX29mZnNldF94MCArICh3IC0gMSkgKglwYXJhbWV0ZXJzLT5zdWJzYW1wbGluZ19keCArIDE7CgkJaW1hZ2UtPnkxID0gcGFyYW1ldGVycy0+aW1hZ2Vfb2Zmc2V0X3kwICsgKGggLSAxKSAqCXBhcmFtZXRlcnMtPnN1YnNhbXBsaW5nX2R5ICsgMTsKCgkJLy8gc2V0IGltYWdlIGRhdGEgCgkJaWYocHJlYyA9PSA4KSB7CgkJCXN3aXRjaChudW1jb21wcykgewoJCQkJY2FzZSAxOgoJCQkJCWluZGV4ID0gMDsKCQkJCQlmb3IoeSA9IDA7IHkgPCBoOyB5KyspIHsKCQkJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGggLSAxIC0geSk7CgkJCQkJCWZvcih4ID0gMDsgeCA8IHc7IHgrKykgewoJCQkJCQkJaW1hZ2UtPmNvbXBzWzBdLmRhdGFbaW5kZXhdID0gYml0c1t4XTsKCQkJCQkJCWluZGV4Kys7CgkJCQkJCX0KCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlIDM6CgkJCQkJaW5kZXggPSAwOwoJCQkJCWZvcih5ID0gMDsgeSA8IGg7IHkrKykgewoJCQkJCQlCWVRFICpiaXRzID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaCAtIDEgLSB5KTsKCQkJCQkJZm9yKHggPSAwOyB4IDwgdzsgeCsrKSB7CgkJCQkJCQlpbWFnZS0+Y29tcHNbMF0uZGF0YVtpbmRleF0gPSBiaXRzW0ZJX1JHQkFfUkVEXTsKCQkJCQkJCWltYWdlLT5jb21wc1sxXS5kYXRhW2luZGV4XSA9IGJpdHNbRklfUkdCQV9HUkVFTl07CgkJCQkJCQlpbWFnZS0+Y29tcHNbMl0uZGF0YVtpbmRleF0gPSBiaXRzW0ZJX1JHQkFfQkxVRV07CgkJCQkJCQliaXRzICs9IDM7CgkJCQkJCQlpbmRleCsrOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSA0OgoJCQkJCWluZGV4ID0gMDsKCQkJCQlmb3IoeSA9IDA7IHkgPCBoOyB5KyspIHsKCQkJCQkJQllURSAqYml0cyA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGggLSAxIC0geSk7CgkJCQkJCWZvcih4ID0gMDsgeCA8IHc7IHgrKykgewoJCQkJCQkJaW1hZ2UtPmNvbXBzWzBdLmRhdGFbaW5kZXhdID0gYml0c1tGSV9SR0JBX1JFRF07CgkJCQkJCQlpbWFnZS0+Y29tcHNbMV0uZGF0YVtpbmRleF0gPSBiaXRzW0ZJX1JHQkFfR1JFRU5dOwoJCQkJCQkJaW1hZ2UtPmNvbXBzWzJdLmRhdGFbaW5kZXhdID0gYml0c1tGSV9SR0JBX0JMVUVdOwoJCQkJCQkJaW1hZ2UtPmNvbXBzWzNdLmRhdGFbaW5kZXhdID0gYml0c1tGSV9SR0JBX0FMUEhBXTsKCQkJCQkJCWJpdHMgKz0gNDsKCQkJCQkJCWluZGV4Kys7CgkJCQkJCX0KCQkJCQl9CgkJCQkJYnJlYWs7CgkJCX0KCQl9CgkJZWxzZSBpZihwcmVjID09IDE2KSB7CgkJCXN3aXRjaChudW1jb21wcykgewoJCQkJY2FzZSAxOgoJCQkJCWluZGV4ID0gMDsKCQkJCQlmb3IoeSA9IDA7IHkgPCBoOyB5KyspIHsKCQkJCQkJV09SRCAqYml0cyA9IChXT1JEKilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoIC0gMSAtIHkpOwoJCQkJCQlmb3IoeCA9IDA7IHggPCB3OyB4KyspIHsKCQkJCQkJCWltYWdlLT5jb21wc1swXS5kYXRhW2luZGV4XSA9IGJpdHNbeF07CgkJCQkJCQlpbmRleCsrOwoJCQkJCQl9CgkJCQkJfQoJCQkJCWJyZWFrOwoJCQkJY2FzZSAzOgoJCQkJCWluZGV4ID0gMDsKCQkJCQlmb3IoeSA9IDA7IHkgPCBoOyB5KyspIHsKCQkJCQkJRklSR0IxNiAqYml0cyA9IChGSVJHQjE2KilGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBoIC0gMSAtIHkpOwoJCQkJCQlmb3IoeCA9IDA7IHggPCB3OyB4KyspIHsKCQkJCQkJCWltYWdlLT5jb21wc1swXS5kYXRhW2luZGV4XSA9IGJpdHNbeF0ucmVkOwoJCQkJCQkJaW1hZ2UtPmNvbXBzWzFdLmRhdGFbaW5kZXhdID0gYml0c1t4XS5ncmVlbjsKCQkJCQkJCWltYWdlLT5jb21wc1syXS5kYXRhW2luZGV4XSA9IGJpdHNbeF0uYmx1ZTsKCQkJCQkJCWluZGV4Kys7CgkJCQkJCX0KCQkJCQl9CgkJCQkJYnJlYWs7CgkJCQljYXNlIDQ6CgkJCQkJaW5kZXggPSAwOwoJCQkJCWZvcih5ID0gMDsgeSA8IGg7IHkrKykgewoJCQkJCQlGSVJHQkExNiAqYml0cyA9IChGSVJHQkExNiopRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgaCAtIDEgLSB5KTsKCQkJCQkJZm9yKHggPSAwOyB4IDwgdzsgeCsrKSB7CgkJCQkJCQlpbWFnZS0+Y29tcHNbMF0uZGF0YVtpbmRleF0gPSBiaXRzW3hdLnJlZDsKCQkJCQkJCWltYWdlLT5jb21wc1sxXS5kYXRhW2luZGV4XSA9IGJpdHNbeF0uZ3JlZW47CgkJCQkJCQlpbWFnZS0+Y29tcHNbMl0uZGF0YVtpbmRleF0gPSBiaXRzW3hdLmJsdWU7CgkJCQkJCQlpbWFnZS0+Y29tcHNbM10uZGF0YVtpbmRleF0gPSBiaXRzW3hdLmFscGhhOwoJCQkJCQkJaW5kZXgrKzsKCQkJCQkJfQoJCQkJCX0KCQkJCQlicmVhazsKCQkJfQoJCX0KCgkJcmV0dXJuIGltYWdlOwoKCX0gY2F0Y2ggKGNvbnN0IGNoYXIgKnRleHQpIHsKCQlpZihpbWFnZSkgb3BqX2ltYWdlX2Rlc3Ryb3koaW1hZ2UpOwoJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhmb3JtYXRfaWQsIHRleHQpOwoJCXJldHVybiBOVUxMOwoJfQp9Cg==