LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgogICB1bmljb2RlZGF0YSAtLSBQcm92aWRlcyBhY2Nlc3MgdG8gdGhlIFVuaWNvZGUgMy4yIGRhdGEgYmFzZS4KCiAgIERhdGEgd2FzIGV4dHJhY3RlZCBmcm9tIHRoZSBVbmljb2RlIDMuMiBVbmljb2RlRGF0YS50eHQgZmlsZS4KCiAgIFdyaXR0ZW4gYnkgTWFyYy1BbmRyZSBMZW1idXJnIChtYWxAbGVtYnVyZy5jb20pLgogICBNb2RpZmllZCBmb3IgUHl0aG9uIDIuMCBieSBGcmVkcmlrIEx1bmRoIChmcmVkcmlrQHB5dGhvbndhcmUuY29tKQogICBNb2RpZmllZCBieSBNYXJ0aW4gdi4gTPZ3aXMgKG1hcnRpbkB2LmxvZXdpcy5kZSkKCiAgIENvcHlyaWdodCAoYykgQ29ycG9yYXRpb24gZm9yIE5hdGlvbmFsIFJlc2VhcmNoIEluaXRpYXRpdmVzLgoKICAgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaW5jbHVkZSAiUHl0aG9uLmgiCiNpbmNsdWRlICJ1Y25oYXNoLmgiCgovKiBjaGFyYWN0ZXIgcHJvcGVydGllcyAqLwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgY29uc3QgdW5zaWduZWQgY2hhciBjYXRlZ29yeTsJLyogaW5kZXggaW50bwoJCQkJCSAgIF9QeVVuaWNvZGVfQ2F0ZWdvcnlOYW1lcyAqLwogICAgY29uc3QgdW5zaWduZWQgY2hhcgljb21iaW5pbmc7IAkvKiBjb21iaW5pbmcgY2xhc3MgdmFsdWUgMCAtIDI1NSAqLwogICAgY29uc3QgdW5zaWduZWQgY2hhcgliaWRpcmVjdGlvbmFsOyAJLyogaW5kZXggaW50bwoJCQkJCSAgIF9QeVVuaWNvZGVfQmlkaXJlY3Rpb25hbE5hbWVzICovCiAgICBjb25zdCB1bnNpZ25lZCBjaGFyIG1pcnJvcmVkOwkvKiB0cnVlIGlmIG1pcnJvcmVkIGluIGJpZGlyIG1vZGUgKi8KfSBfUHlVbmljb2RlX0RhdGFiYXNlUmVjb3JkOwoKLyogZGF0YSBmaWxlIGdlbmVyYXRlZCBieSBUb29scy91bmljb2RlL21ha2V1bmljb2RlZGF0YS5weSAqLwojaW5jbHVkZSAidW5pY29kZWRhdGFfZGIuaCIKCnN0YXRpYyBjb25zdCBfUHlVbmljb2RlX0RhdGFiYXNlUmVjb3JkKgpfZ2V0cmVjb3JkX2V4KFB5X1VDUzQgY29kZSkKewogICAgaW50IGluZGV4OwogICAgaWYgKGNvZGUgPj0gMHgxMTAwMDApCiAgICAgICAgaW5kZXggPSAwOwogICAgZWxzZSB7CiAgICAgICAgaW5kZXggPSBpbmRleDFbKGNvZGU+PlNISUZUKV07CiAgICAgICAgaW5kZXggPSBpbmRleDJbKGluZGV4PDxTSElGVCkrKGNvZGUmKCgxPDxTSElGVCktMSkpXTsKICAgIH0KCiAgICByZXR1cm4gJl9QeVVuaWNvZGVfRGF0YWJhc2VfUmVjb3Jkc1tpbmRleF07Cn0KCnN0YXRpYyBjb25zdCBfUHlVbmljb2RlX0RhdGFiYXNlUmVjb3JkKgpfZ2V0cmVjb3JkKFB5VW5pY29kZU9iamVjdCogdikKewogICAgcmV0dXJuIF9nZXRyZWNvcmRfZXgoKlB5VW5pY29kZV9BU19VTklDT0RFKHYpKTsKfQoKLyogLS0tIE1vZHVsZSBBUEkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgUHlPYmplY3QgKgp1bmljb2RlZGF0YV9kZWNpbWFsKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKewogICAgUHlVbmljb2RlT2JqZWN0ICp2OwogICAgUHlPYmplY3QgKmRlZm9iaiA9IE5VTEw7CiAgICBsb25nIHJjOwoKICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyF8TzpkZWNpbWFsIiwgJlB5VW5pY29kZV9UeXBlLCAmdiwgJmRlZm9iaikpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHYpICE9IDEpIHsKCVB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCgkJCSJuZWVkIGEgc2luZ2xlIFVuaWNvZGUgY2hhcmFjdGVyIGFzIHBhcmFtZXRlciIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgcmMgPSBQeV9VTklDT0RFX1RPREVDSU1BTCgqUHlVbmljb2RlX0FTX1VOSUNPREUodikpOwogICAgaWYgKHJjIDwgMCkgewoJaWYgKGRlZm9iaiA9PSBOVUxMKSB7CgkgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCgkJCSAgICAibm90IGEgZGVjaW1hbCIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKCX0KCWVsc2UgewoJICAgIFB5X0lOQ1JFRihkZWZvYmopOwoJICAgIHJldHVybiBkZWZvYmo7Cgl9CiAgICB9CiAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcocmMpOwp9CgpzdGF0aWMgUHlPYmplY3QgKgp1bmljb2RlZGF0YV9kaWdpdChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIFB5VW5pY29kZU9iamVjdCAqdjsKICAgIFB5T2JqZWN0ICpkZWZvYmogPSBOVUxMOwogICAgbG9uZyByYzsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hfE86ZGlnaXQiLCAmUHlVbmljb2RlX1R5cGUsICZ2LCAmZGVmb2JqKSkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUodikgIT0gMSkgewoJUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKCQkJIm5lZWQgYSBzaW5nbGUgVW5pY29kZSBjaGFyYWN0ZXIgYXMgcGFyYW1ldGVyIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICByYyA9IFB5X1VOSUNPREVfVE9ESUdJVCgqUHlVbmljb2RlX0FTX1VOSUNPREUodikpOwogICAgaWYgKHJjIDwgMCkgewoJaWYgKGRlZm9iaiA9PSBOVUxMKSB7CgkgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJub3QgYSBkaWdpdCIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKCX0KCWVsc2UgewoJICAgIFB5X0lOQ1JFRihkZWZvYmopOwoJICAgIHJldHVybiBkZWZvYmo7Cgl9CiAgICB9CiAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcocmMpOwp9CgpzdGF0aWMgUHlPYmplY3QgKgp1bmljb2RlZGF0YV9udW1lcmljKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKewogICAgUHlVbmljb2RlT2JqZWN0ICp2OwogICAgUHlPYmplY3QgKmRlZm9iaiA9IE5VTEw7CiAgICBkb3VibGUgcmM7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPIXxPOm51bWVyaWMiLCAmUHlVbmljb2RlX1R5cGUsICZ2LCAmZGVmb2JqKSkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUodikgIT0gMSkgewoJUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKCQkJIm5lZWQgYSBzaW5nbGUgVW5pY29kZSBjaGFyYWN0ZXIgYXMgcGFyYW1ldGVyIik7CglyZXR1cm4gTlVMTDsKICAgIH0KICAgIHJjID0gUHlfVU5JQ09ERV9UT05VTUVSSUMoKlB5VW5pY29kZV9BU19VTklDT0RFKHYpKTsKICAgIGlmIChyYyA8IDApIHsKCWlmIChkZWZvYmogPT0gTlVMTCkgewoJICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAibm90IGEgbnVtZXJpYyBjaGFyYWN0ZXIiKTsKCSAgICByZXR1cm4gTlVMTDsKCX0KCWVsc2UgewoJICAgIFB5X0lOQ1JFRihkZWZvYmopOwoJICAgIHJldHVybiBkZWZvYmo7Cgl9CiAgICB9CiAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKHJjKTsKfQoKc3RhdGljIFB5T2JqZWN0ICoKdW5pY29kZWRhdGFfY2F0ZWdvcnkoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBQeVVuaWNvZGVPYmplY3QgKnY7CiAgICBpbnQgaW5kZXg7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPITpjYXRlZ29yeSIsCgkJCSAgJlB5VW5pY29kZV9UeXBlLCAmdikpCglyZXR1cm4gTlVMTDsKICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUodikgIT0gMSkgewoJUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKCQkJIm5lZWQgYSBzaW5nbGUgVW5pY29kZSBjaGFyYWN0ZXIgYXMgcGFyYW1ldGVyIik7CglyZXR1cm4gTlVMTDsKICAgIH0KICAgIGluZGV4ID0gKGludCkgX2dldHJlY29yZCh2KS0+Y2F0ZWdvcnk7CiAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhfUHlVbmljb2RlX0NhdGVnb3J5TmFtZXNbaW5kZXhdKTsKfQoKc3RhdGljIFB5T2JqZWN0ICoKdW5pY29kZWRhdGFfYmlkaXJlY3Rpb25hbChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCnsKICAgIFB5VW5pY29kZU9iamVjdCAqdjsKICAgIGludCBpbmRleDsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hOmJpZGlyZWN0aW9uYWwiLAoJCQkgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQoJcmV0dXJuIE5VTEw7CiAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHYpICE9IDEpIHsKCVB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCgkJCSJuZWVkIGEgc2luZ2xlIFVuaWNvZGUgY2hhcmFjdGVyIGFzIHBhcmFtZXRlciIpOwoJcmV0dXJuIE5VTEw7CiAgICB9CiAgICBpbmRleCA9IChpbnQpIF9nZXRyZWNvcmQodiktPmJpZGlyZWN0aW9uYWw7CiAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhfUHlVbmljb2RlX0JpZGlyZWN0aW9uYWxOYW1lc1tpbmRleF0pOwp9CgpzdGF0aWMgUHlPYmplY3QgKgp1bmljb2RlZGF0YV9jb21iaW5pbmcoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBQeVVuaWNvZGVPYmplY3QgKnY7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPITpjb21iaW5pbmciLAoJCQkgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQoJcmV0dXJuIE5VTEw7CiAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHYpICE9IDEpIHsKCVB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCgkJCSJuZWVkIGEgc2luZ2xlIFVuaWNvZGUgY2hhcmFjdGVyIGFzIHBhcmFtZXRlciIpOwoJcmV0dXJuIE5VTEw7CiAgICB9CiAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoKGludCkgX2dldHJlY29yZCh2KS0+Y29tYmluaW5nKTsKfQoKc3RhdGljIFB5T2JqZWN0ICoKdW5pY29kZWRhdGFfbWlycm9yZWQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBQeVVuaWNvZGVPYmplY3QgKnY7CgogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPITptaXJyb3JlZCIsCgkJCSAgJlB5VW5pY29kZV9UeXBlLCAmdikpCglyZXR1cm4gTlVMTDsKICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUodikgIT0gMSkgewoJUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKCQkJIm5lZWQgYSBzaW5nbGUgVW5pY29kZSBjaGFyYWN0ZXIgYXMgcGFyYW1ldGVyIik7CglyZXR1cm4gTlVMTDsKICAgIH0KICAgIHJldHVybiBQeUludF9Gcm9tTG9uZygoaW50KSBfZ2V0cmVjb3JkKHYpLT5taXJyb3JlZCk7Cn0KCnN0YXRpYyBQeU9iamVjdCAqCnVuaWNvZGVkYXRhX2RlY29tcG9zaXRpb24oUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQp7CiAgICBQeVVuaWNvZGVPYmplY3QgKnY7CiAgICBjaGFyIGRlY29tcFsyNTZdOwogICAgaW50IGNvZGUsIGluZGV4LCBjb3VudCwgaTsKCiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hOmRlY29tcG9zaXRpb24iLAoJCQkgICZQeVVuaWNvZGVfVHlwZSwgJnYpKQoJcmV0dXJuIE5VTEw7CiAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHYpICE9IDEpIHsKCVB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCgkJCSJuZWVkIGEgc2luZ2xlIFVuaWNvZGUgY2hhcmFjdGVyIGFzIHBhcmFtZXRlciIpOwoJcmV0dXJuIE5VTEw7CiAgICB9CgogICAgY29kZSA9IChpbnQpICpQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKCiAgICBpZiAoY29kZSA8IDAgfHwgY29kZSA+PSAweDExMDAwMCkKICAgICAgICBpbmRleCA9IDA7CiAgICBlbHNlIHsKICAgICAgICBpbmRleCA9IGRlY29tcF9pbmRleDFbKGNvZGU+PkRFQ09NUF9TSElGVCldOwogICAgICAgIGluZGV4ID0gZGVjb21wX2luZGV4MlsoaW5kZXg8PERFQ09NUF9TSElGVCkrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvZGUmKCgxPDxERUNPTVBfU0hJRlQpLTEpKV07CiAgICB9CgogICAgLyogaGlnaCBieXRlIGlzIG51bWJlciBvZiBoZXggYnl0ZXMgKHVzdWFsbHkgb25lIG9yIHR3byksIGxvdyBieXRlCiAgICAgICBpcyBwcmVmaXggY29kZSAoZnJvbSovCiAgICBjb3VudCA9IGRlY29tcF9kYXRhW2luZGV4XSA+PiA4OwoKICAgIC8qIFhYWDogY291bGQgYWxsb2NhdGUgdGhlIFB5U3RyaW5nIHVwIGZyb250IGluc3RlYWQKICAgICAgIChzdHJsZW4ocHJlZml4KSArIDUgKiBjb3VudCArIDEgYnl0ZXMpICovCgogICAgLyogY29weSBwcmVmaXggKi8KICAgIGkgPSBzdHJsZW4oZGVjb21wX3ByZWZpeFtkZWNvbXBfZGF0YVtpbmRleF0gJiAyNTVdKTsKICAgIG1lbWNweShkZWNvbXAsIGRlY29tcF9wcmVmaXhbZGVjb21wX2RhdGFbaW5kZXhdICYgMjU1XSwgaSk7CgogICAgd2hpbGUgKGNvdW50LS0gPiAwKSB7CiAgICAgICAgaWYgKGkpCiAgICAgICAgICAgIGRlY29tcFtpKytdID0gJyAnOwogICAgICAgIGFzc2VydCgoc2l6ZV90KWkgPCBzaXplb2YoZGVjb21wKSk7CiAgICAgICAgUHlPU19zbnByaW50ZihkZWNvbXAgKyBpLCBzaXplb2YoZGVjb21wKSAtIGksICIlMDRYIiwKICAgICAgICAgICAgICAgICAgICAgIGRlY29tcF9kYXRhWysraW5kZXhdKTsKICAgICAgICBpICs9IHN0cmxlbihkZWNvbXAgKyBpKTsKICAgIH0KICAgIAogICAgZGVjb21wW2ldID0gJ1wwJzsKCiAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhkZWNvbXApOwp9Cgp2b2lkCmdldF9kZWNvbXBfcmVjb3JkKFB5X1VDUzQgY29kZSwgaW50ICppbmRleCwgaW50ICpwcmVmaXgsIGludCAqY291bnQpCnsKICAgIGlmIChjb2RlID49IDB4MTEwMDAwKSB7CiAgICAgICAgKmluZGV4ID0gMDsKICAgIH0gCiAgICBlbHNlIHsKICAgICAgICAqaW5kZXggPSBkZWNvbXBfaW5kZXgxWyhjb2RlPj5ERUNPTVBfU0hJRlQpXTsKICAgICAgICAqaW5kZXggPSBkZWNvbXBfaW5kZXgyWygqaW5kZXg8PERFQ09NUF9TSElGVCkrCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY29kZSYoKDE8PERFQ09NUF9TSElGVCktMSkpXTsKICAgIH0KCQogICAgLyogaGlnaCBieXRlIGlzIG51bWJlciBvZiBoZXggYnl0ZXMgKHVzdWFsbHkgb25lIG9yIHR3byksIGxvdyBieXRlCiAgICAgICBpcyBwcmVmaXggY29kZSAoZnJvbSovCiAgICAqY291bnQgPSBkZWNvbXBfZGF0YVsqaW5kZXhdID4+IDg7CiAgICAqcHJlZml4ID0gZGVjb21wX2RhdGFbKmluZGV4XSAmIDI1NTsKCiAgICAoKmluZGV4KSsrOwp9CgojZGVmaW5lIFNCYXNlICAgMHhBQzAwCiNkZWZpbmUgTEJhc2UgICAweDExMDAKI2RlZmluZSBWQmFzZSAgIDB4MTE2MQojZGVmaW5lIFRCYXNlICAgMHgxMUE3CiNkZWZpbmUgTENvdW50ICAxOQojZGVmaW5lIFZDb3VudCAgMjEKI2RlZmluZSBUQ291bnQgIDI4CiNkZWZpbmUgTkNvdW50ICAoVkNvdW50KlRDb3VudCkKI2RlZmluZSBTQ291bnQgIChMQ291bnQqTkNvdW50KQoKc3RhdGljIFB5T2JqZWN0KgpuZmRfbmZrZChQeU9iamVjdCAqaW5wdXQsIGludCBrKQp7CiAgICBQeU9iamVjdCAqcmVzdWx0OwogICAgUHlfVU5JQ09ERSAqaSwgKmVuZCwgKm87CiAgICAvKiBMb25nZXN0IGRlY29tcG9zaXRpb24gaW4gVW5pY29kZSAzLjI6IFUrRkRGQSAqLwogICAgUHlfVU5JQ09ERSBzdGFja1syMF07IAogICAgaW50IHNwYWNlLCBzdGFja3B0ciwgaXNpemU7CiAgICBpbnQgaW5kZXgsIHByZWZpeCwgY291bnQ7CiAgICB1bnNpZ25lZCBjaGFyIHByZXYsIGN1cjsKCQogICAgc3RhY2twdHIgPSAwOwogICAgaXNpemUgPSBQeVVuaWNvZGVfR0VUX1NJWkUoaW5wdXQpOwogICAgLyogT3ZlcmFsbG9jYXRlIGF0bW9zdCAxMCBjaGFyYWN0ZXJzLiAqLwogICAgc3BhY2UgPSAoaXNpemUgPiAxMCA/IDEwIDogaXNpemUpICsgaXNpemU7CiAgICByZXN1bHQgPSBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoTlVMTCwgc3BhY2UpOwogICAgaWYgKCFyZXN1bHQpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBpID0gUHlVbmljb2RlX0FTX1VOSUNPREUoaW5wdXQpOwogICAgZW5kID0gaSArIGlzaXplOwogICAgbyA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCk7CgogICAgd2hpbGUgKGkgPCBlbmQpIHsKICAgICAgICBzdGFja1tzdGFja3B0cisrXSA9ICppKys7CiAgICAgICAgd2hpbGUoc3RhY2twdHIpIHsKICAgICAgICAgICAgUHlfVU5JQ09ERSBjb2RlID0gc3RhY2tbLS1zdGFja3B0cl07CiAgICAgICAgICAgIC8qIEhhbmd1bCBEZWNvbXBvc2l0aW9uIGFkZHMgdGhyZWUgY2hhcmFjdGVycyBpbgogICAgICAgICAgICAgICBhIHNpbmdsZSBzdGVwLCBzbyB3ZSBuZWVkIGF0bGVhc3QgdGhhdCBtdWNoIHJvb20uICovCiAgICAgICAgICAgIGlmIChzcGFjZSA8IDMpIHsKICAgICAgICAgICAgICAgIGludCBuZXdzaXplID0gUHlTdHJpbmdfR0VUX1NJWkUocmVzdWx0KSArIDEwOwogICAgICAgICAgICAgICAgc3BhY2UgKz0gMTA7CiAgICAgICAgICAgICAgICBpZiAoUHlVbmljb2RlX1Jlc2l6ZSgmcmVzdWx0LCBuZXdzaXplKSA9PSAtMSkKICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICAgICAgICAgIG8gPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXN1bHQpICsgbmV3c2l6ZSAtIHNwYWNlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIEhhbmd1bCBEZWNvbXBvc2l0aW9uLiAqLwogICAgICAgICAgICBpZiAoU0Jhc2UgPD0gY29kZSAmJiBjb2RlIDwgKFNCYXNlK1NDb3VudCkpIHsKICAgICAgICAgICAgICAgIGludCBTSW5kZXggPSBjb2RlIC0gU0Jhc2U7CiAgICAgICAgICAgICAgICBpbnQgTCA9IExCYXNlICsgU0luZGV4IC8gTkNvdW50OwogICAgICAgICAgICAgICAgaW50IFYgPSBWQmFzZSArIChTSW5kZXggJSBOQ291bnQpIC8gVENvdW50OwogICAgICAgICAgICAgICAgaW50IFQgPSBUQmFzZSArIFNJbmRleCAlIFRDb3VudDsKICAgICAgICAgICAgICAgICpvKysgPSBMOwogICAgICAgICAgICAgICAgKm8rKyA9IFY7CiAgICAgICAgICAgICAgICBzcGFjZSAtPSAyOwogICAgICAgICAgICAgICAgaWYgKFQgIT0gVEJhc2UpIHsKICAgICAgICAgICAgICAgICAgICAqbysrID0gVDsKICAgICAgICAgICAgICAgICAgICBzcGFjZSAtLTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIE90aGVyIGRlY29tcG9pc3Rpb25zLiAqLwogICAgICAgICAgICBnZXRfZGVjb21wX3JlY29yZChjb2RlLCAmaW5kZXgsICZwcmVmaXgsICZjb3VudCk7CgogICAgICAgICAgICAvKiBDb3B5IGNoYXJhY3RlciBpZiBpdCBpcyBub3QgZGVjb21wb3NhYmxlLCBvciBoYXMgYQogICAgICAgICAgICAgICBjb21wYXRpYmlsaXR5IGRlY29tcG9zaXRpb24sIGJ1dCB3ZSBkbyBORkQuICovCiAgICAgICAgICAgIGlmICghY291bnQgfHwgKHByZWZpeCAmJiAhaykpIHsKICAgICAgICAgICAgICAgICpvKysgPSBjb2RlOwogICAgICAgICAgICAgICAgc3BhY2UtLTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIENvcHkgZGVjb21wb3NpdGlvbiBvbnRvIHRoZSBzdGFjaywgaW4gcmV2ZXJzZQogICAgICAgICAgICAgICBvcmRlci4gICovCiAgICAgICAgICAgIHdoaWxlKGNvdW50KSB7CiAgICAgICAgICAgICAgICBjb2RlID0gZGVjb21wX2RhdGFbaW5kZXggKyAoLS1jb3VudCldOwogICAgICAgICAgICAgICAgc3RhY2tbc3RhY2twdHIrK10gPSBjb2RlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIC8qIERyb3Agb3ZlcmFsbG9jYXRpb24uIENhbm5vdCBmYWlsLiAqLwogICAgUHlVbmljb2RlX1Jlc2l6ZSgmcmVzdWx0LCBQeVVuaWNvZGVfR0VUX1NJWkUocmVzdWx0KSAtIHNwYWNlKTsKCiAgICAvKiBTb3J0IGNhbm9uaWNhbGx5LiAqLwogICAgaSA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCk7CiAgICBwcmV2ID0gX2dldHJlY29yZF9leCgqaSktPmNvbWJpbmluZzsKICAgIGVuZCA9IGkgKyBQeVVuaWNvZGVfR0VUX1NJWkUocmVzdWx0KTsKICAgIGZvciAoaSsrOyBpIDwgZW5kOyBpKyspIHsKICAgICAgICBjdXIgPSBfZ2V0cmVjb3JkX2V4KCppKS0+Y29tYmluaW5nOwogICAgICAgIGlmIChwcmV2ID09IDAgfHwgY3VyID09IDAgfHwgcHJldiA8PSBjdXIpIHsKICAgICAgICAgICAgcHJldiA9IGN1cjsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgICAgIC8qIE5vbi1jYW5vbmljYWwgb3JkZXIuIE5lZWQgdG8gc3dpdGNoICppIHdpdGggcHJldmlvdXMuICovCiAgICAgICAgbyA9IGkgLSAxOwogICAgICAgIHdoaWxlICgxKSB7CiAgICAgICAgICAgIFB5X1VOSUNPREUgdG1wID0gb1sxXTsKICAgICAgICAgICAgb1sxXSA9IG9bMF07CiAgICAgICAgICAgIG9bMF0gPSB0bXA7CiAgICAgICAgICAgIG8tLTsKICAgICAgICAgICAgaWYgKG8gPCBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXN1bHQpKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIHByZXYgPSBfZ2V0cmVjb3JkX2V4KCpvKS0+Y29tYmluaW5nOwogICAgICAgICAgICBpZiAocHJldiA9PSAwIHx8IHByZXYgPD0gY3VyKQogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgICAgIHByZXYgPSBfZ2V0cmVjb3JkX2V4KCppKS0+Y29tYmluaW5nOwogICAgfQogICAgcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIGludApmaW5kX25mY19pbmRleChzdHJ1Y3QgcmVpbmRleCogbmZjLCBQeV9VTklDT0RFIGNvZGUpCnsKICAgIGludCBpbmRleDsKICAgIGZvciAoaW5kZXggPSAwOyBuZmNbaW5kZXhdLnN0YXJ0OyBpbmRleCsrKSB7CiAgICAgICAgaW50IHN0YXJ0ID0gbmZjW2luZGV4XS5zdGFydDsKICAgICAgICBpZiAoY29kZSA8IHN0YXJ0KQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgaWYgKGNvZGUgPD0gc3RhcnQgKyBuZmNbaW5kZXhdLmNvdW50KSB7CiAgICAgICAgICAgIGludCBkZWx0YSA9IGNvZGUgLSBzdGFydDsKICAgICAgICAgICAgcmV0dXJuIG5mY1tpbmRleF0uaW5kZXggKyBkZWx0YTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gLTE7Cn0KCnN0YXRpYyBQeU9iamVjdCoKbmZjX25ma2MoUHlPYmplY3QgKmlucHV0LCBpbnQgaykKewogICAgUHlPYmplY3QgKnJlc3VsdDsKICAgIFB5X1VOSUNPREUgKmksICppMSwgKm8sICplbmQ7CiAgICBpbnQgZixsLGluZGV4LGluZGV4MSxjb21iOwogICAgUHlfVU5JQ09ERSBjb2RlOwogICAgUHlfVU5JQ09ERSAqc2tpcHBlZFsyMF07CiAgICBpbnQgY3NraXBwZWQgPSAwOwoKICAgIHJlc3VsdCA9IG5mZF9uZmtkKGlucHV0LCBrKTsKICAgIGlmICghcmVzdWx0KQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIC8qIFdlIGFyZSBnb2luZyB0byBtb2RpZnkgcmVzdWx0IGluLXBsYWNlLgogICAgICAgSWYgbmZkX25ma2QgaXMgY2hhbmdlZCB0byBzb21ldGltZXMgcmV0dXJuIHRoZSBpbnB1dCwKICAgICAgIHRoaXMgY29kZSBuZWVkcyB0byBiZSByZXZpZXdlZC4gKi8KICAgIGFzc2VydChyZXN1bHQgIT0gaW5wdXQpOwoKICAgIGkgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXN1bHQpOwogICAgZW5kID0gaSArIFB5VW5pY29kZV9HRVRfU0laRShyZXN1bHQpOwogICAgbyA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCk7CgkKICBhZ2FpbjoKICAgIHdoaWxlIChpIDwgZW5kKSB7CiAgICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IGNza2lwcGVkOyBpbmRleCsrKSB7CiAgICAgICAgICBpZiAoc2tpcHBlZFtpbmRleF0gPT0gaSkgewogICAgICAgICAgICAgIC8qICppIGNoYXJhY3RlciBpcyBza2lwcGVkLiAKICAgICAgICAgICAgICAgICBSZW1vdmUgZnJvbSBsaXN0LiAqLwogICAgICAgICAgICAgIHNraXBwZWRbaW5kZXhdID0gc2tpcHBlZFtjc2tpcHBlZC0xXTsKICAgICAgICAgICAgICBjc2tpcHBlZC0tOwogICAgICAgICAgICAgIGkrKzsKICAgICAgICAgICAgICBnb3RvIGFnYWluOyAvKiBjb250aW51ZSB3aGlsZSAqLwogICAgICAgICAgfQogICAgICB9CiAgICAgIC8qIEhhbmd1bCBDb21wb3NpdGlvbi4gV2UgZG9uJ3QgbmVlZCB0byBjaGVjayBmb3IgPExWLFQ+CiAgICAgICAgIHBhaXJzLCBzaW5jZSB3ZSBhbHdheXMgaGF2ZSBkZWNvbXBvc2VkIGRhdGEuICovCiAgICAgIGlmIChMQmFzZSA8PSAqaSAmJiAqaSA8IChMQmFzZStMQ291bnQpICYmCiAgICAgICAgICBpICsgMSA8IGVuZCAmJiAKICAgICAgICAgIFZCYXNlIDw9IGlbMV0gJiYgaVsxXSA8PSAoVkJhc2UrVkNvdW50KSkgewogICAgICAgICAgaW50IExJbmRleCwgVkluZGV4OwogICAgICAgICAgTEluZGV4ID0gaVswXSAtIExCYXNlOwogICAgICAgICAgVkluZGV4ID0gaVsxXSAtIFZCYXNlOwogICAgICAgICAgY29kZSA9IFNCYXNlICsgKExJbmRleCpWQ291bnQrVkluZGV4KSpUQ291bnQ7CiAgICAgICAgICBpKz0yOwogICAgICAgICAgaWYgKGkgPCBlbmQgJiYKICAgICAgICAgICAgICBUQmFzZSA8PSAqaSAmJiAqaSA8PSAoVEJhc2UrVENvdW50KSkgewogICAgICAgICAgICAgIGNvZGUgKz0gKmktVEJhc2U7CiAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgfQogICAgICAgICAgKm8rKyA9IGNvZGU7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgZiA9IGZpbmRfbmZjX2luZGV4KG5mY19maXJzdCwgKmkpOwogICAgICBpZiAoZiA9PSAtMSkgewogICAgICAgICAgKm8rKyA9ICppKys7CiAgICAgICAgICBjb250aW51ZTsKICAgICAgfQogICAgICAvKiBGaW5kIG5leHQgdW5ibG9ja2VkIGNoYXJhY3Rlci4gKi8KICAgICAgaTEgPSBpKzE7CiAgICAgIGNvbWIgPSAwOwogICAgICB3aGlsZSAoaTEgPCBlbmQpIHsKICAgICAgICAgIGludCBjb21iMSA9IF9nZXRyZWNvcmRfZXgoKmkxKS0+Y29tYmluaW5nOwogICAgICAgICAgaWYgKGNvbWIxICYmIGNvbWIgPT0gY29tYjEpIHsKICAgICAgICAgICAgICAvKiBDaGFyYWN0ZXIgaXMgYmxvY2tlZC4gKi8KICAgICAgICAgICAgICBpMSsrOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgbCA9IGZpbmRfbmZjX2luZGV4KG5mY19sYXN0LCAqaTEpOwogICAgICAgICAgLyogKmkxIGNhbm5vdCBiZSBjb21iaW5lZCB3aXRoICppLiBJZiAqaTEKICAgICAgICAgICAgIGlzIGEgc3RhcnRlciwgd2UgZG9uJ3QgbmVlZCB0byBsb29rIGZ1cnRoZXIuCiAgICAgICAgICAgICBPdGhlcndpc2UsIHJlY29yZCB0aGUgY29tYmluaW5nIGNsYXNzLiAqLwogICAgICAgICAgaWYgKGwgPT0gLTEpIHsKICAgICAgICAgICAgbm90X2NvbWJpbmFibGU6CiAgICAgICAgICAgICAgaWYgKGNvbWIxID09IDApCiAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgIGNvbWIgPSBjb21iMTsKICAgICAgICAgICAgICBpMSsrOwogICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgfQogICAgICAgICAgaW5kZXggPSBmKlRPVEFMX0xBU1QgKyBsOwogICAgICAgICAgaW5kZXgxID0gY29tcF9pbmRleFtpbmRleCA+PiBDT01QX1NISUZUXTsKICAgICAgICAgIGNvZGUgPSBjb21wX2RhdGFbKGluZGV4MTw8Q09NUF9TSElGVCkrCiAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbmRleCYoKDE8PENPTVBfU0hJRlQpLTEpKV07CiAgICAgICAgICBpZiAoY29kZSA9PSAwKQogICAgICAgICAgICAgIGdvdG8gbm90X2NvbWJpbmFibGU7CgkJCQogICAgICAgICAgLyogUmVwbGFjZSB0aGUgb3JpZ2luYWwgY2hhcmFjdGVyLiAqLwogICAgICAgICAgKmkgPSBjb2RlOwogICAgICAgICAgLyogTWFyayB0aGUgc2Vjb25kIGNoYXJhY3RlciB1bnVzZWQuICovCiAgICAgICAgICBza2lwcGVkW2Nza2lwcGVkKytdID0gaTE7CiAgICAgICAgICBpMSsrOwogICAgICAgICAgZiA9IGZpbmRfbmZjX2luZGV4KG5mY19maXJzdCwgKmkpOwogICAgICAgICAgaWYgKGYgPT0gLTEpCiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgKm8rKyA9ICppKys7CiAgICB9CiAgICBpZiAobyAhPSBlbmQpCiAgICAgICAgUHlVbmljb2RlX1Jlc2l6ZSgmcmVzdWx0LCBvIC0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KSk7CiAgICByZXR1cm4gcmVzdWx0Owp9CgkJCnN0YXRpYyBQeU9iamVjdCoKdW5pY29kZWRhdGFfbm9ybWFsaXplKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKewogICAgY2hhciAqZm9ybTsKICAgIFB5T2JqZWN0ICppbnB1dDsKCiAgICBpZighUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAic08hOm5vcm1hbGl6ZWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgJmZvcm0sICZQeVVuaWNvZGVfVHlwZSwgJmlucHV0KSkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBpZiAoc3RyY21wKGZvcm0sICJORkMiKSA9PSAwKQogICAgICAgIHJldHVybiBuZmNfbmZrYyhpbnB1dCwgMCk7CiAgICBpZiAoc3RyY21wKGZvcm0sICJORktDIikgPT0gMCkKICAgICAgICByZXR1cm4gbmZjX25ma2MoaW5wdXQsIDEpOwogICAgaWYgKHN0cmNtcChmb3JtLCAiTkZEIikgPT0gMCkKICAgICAgICByZXR1cm4gbmZkX25ma2QoaW5wdXQsIDApOwogICAgaWYgKHN0cmNtcChmb3JtLCAiTkZLRCIpID09IDApCiAgICAgICAgcmV0dXJuIG5mZF9uZmtkKGlucHV0LCAxKTsKICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiaW52YWxpZCBub3JtYWxpemF0aW9uIGZvcm0iKTsKICAgIHJldHVybiBOVUxMOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiB1bmljb2RlIGNoYXJhY3RlciBuYW1lIHRhYmxlcyAqLwoKLyogZGF0YSBmaWxlIGdlbmVyYXRlZCBieSBUb29scy91bmljb2RlL21ha2V1bmljb2RlZGF0YS5weSAqLwojaW5jbHVkZSAidW5pY29kZW5hbWVfZGIuaCIKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qIGRhdGFiYXNlIGNvZGUgKGN1dCBhbmQgcGFzdGVkIGZyb20gdGhlIHVuaWRiIHBhY2thZ2UpICovCgpzdGF0aWMgdW5zaWduZWQgbG9uZwpfZ2V0aGFzaChjb25zdCBjaGFyICpzLCBpbnQgbGVuLCBpbnQgc2NhbGUpCnsKICAgIGludCBpOwogICAgdW5zaWduZWQgbG9uZyBoID0gMDsKICAgIHVuc2lnbmVkIGxvbmcgaXg7CiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKICAgICAgICBoID0gKGggKiBzY2FsZSkgKyAodW5zaWduZWQgY2hhcikgdG91cHBlcihzW2ldKTsKICAgICAgICBpeCA9IGggJiAweGZmMDAwMDAwOwogICAgICAgIGlmIChpeCkKICAgICAgICAgICAgaCA9IChoIF4gKChpeD4+MjQpICYgMHhmZikpICYgMHgwMGZmZmZmZjsKICAgIH0KICAgIHJldHVybiBoOwp9CgpzdGF0aWMgY2hhciAqaGFuZ3VsX3N5bGxhYmxlc1tdWzNdID0gewogICAgeyAiRyIsICAiQSIsICAgIiIgICB9LAogICAgeyAiR0ciLCAiQUUiLCAgIkciICB9LAogICAgeyAiTiIsICAiWUEiLCAgIkdHIiB9LAogICAgeyAiRCIsICAiWUFFIiwgIkdTIiB9LAogICAgeyAiREQiLCAiRU8iLCAgIk4iLCB9LAogICAgeyAiUiIsICAiRSIsICAgIk5KIiB9LAogICAgeyAiTSIsICAiWUVPIiwgIk5IIiB9LAogICAgeyAiQiIsICAiWUUiLCAgIkQiICB9LAogICAgeyAiQkIiLCAiTyIsICAgIkwiICB9LAogICAgeyAiUyIsICAiV0EiLCAgIkxHIiB9LAogICAgeyAiU1MiLCAiV0FFIiwgIkxNIiB9LAogICAgeyAiIiwgICAiT0UiLCAgIkxCIiB9LAogICAgeyAiSiIsICAiWU8iLCAgIkxTIiB9LAogICAgeyAiSkoiLCAiVSIsICAgIkxUIiB9LAogICAgeyAiQyIsICAiV0VPIiwgIkxQIiB9LAogICAgeyAiSyIsICAiV0UiLCAgIkxIIiB9LAogICAgeyAiVCIsICAiV0kiLCAgIk0iICB9LAogICAgeyAiUCIsICAiWVUiLCAgIkIiICB9LAogICAgeyAiSCIsICAiRVUiLCAgIkJTIiB9LAogICAgeyAwLCAgICAiWUkiLCAgIlMiICB9LAogICAgeyAwLCAgICAiSSIsICAgIlNTIiB9LAogICAgeyAwLCAgICAwLCAgICAgIk5HIiB9LAogICAgeyAwLCAgICAwLCAgICAgIkoiICB9LAogICAgeyAwLCAgICAwLCAgICAgIkMiICB9LAogICAgeyAwLCAgICAwLCAgICAgIksiICB9LAogICAgeyAwLCAgICAwLCAgICAgIlQiICB9LAogICAgeyAwLCAgICAwLCAgICAgIlAiICB9LAogICAgeyAwLCAgICAwLCAgICAgIkgiICB9Cn07CgpzdGF0aWMgaW50CmlzX3VuaWZpZWRfaWRlb2dyYXBoKFB5X1VDUzQgY29kZSkKewogICAgcmV0dXJuICgKICAgICAgICAoMHgzNDAwIDw9IGNvZGUgJiYgY29kZSA8PSAweDREQjUpIHx8IC8qIENKSyBJZGVvZ3JhcGggRXh0ZW5zaW9uIEEgKi8KICAgICAgICAoMHg0RTAwIDw9IGNvZGUgJiYgY29kZSA8PSAweDlGQTUpIHx8IC8qIENKSyBJZGVvZ3JhcGggKi8KICAgICAgICAoMHgyMDAwMCA8PSBjb2RlICYmIGNvZGUgPD0gMHgyQTZENikpOy8qIENKSyBJZGVvZ3JhcGggRXh0ZW5zaW9uIEIgKi8KfQoKc3RhdGljIGludApfZ2V0dWNuYW1lKFB5X1VDUzQgY29kZSwgY2hhciogYnVmZmVyLCBpbnQgYnVmbGVuKQp7CiAgICBpbnQgb2Zmc2V0OwogICAgaW50IGk7CiAgICBpbnQgd29yZDsKICAgIHVuc2lnbmVkIGNoYXIqIHc7CgogICAgaWYgKFNCYXNlIDw9IGNvZGUgJiYgY29kZSA8IFNCYXNlK1NDb3VudCkgewoJLyogSGFuZ3VsIHN5bGxhYmxlLiAqLwoJaW50IFNJbmRleCA9IGNvZGUgLSBTQmFzZTsKCWludCBMID0gU0luZGV4IC8gTkNvdW50OwoJaW50IFYgPSAoU0luZGV4ICUgTkNvdW50KSAvIFRDb3VudDsKCWludCBUID0gU0luZGV4ICUgVENvdW50OwoKCWlmIChidWZsZW4gPCAyNykKCSAgICAvKiBXb3JzdCBjYXNlOiBIQU5HVUwgU1lMTEFCTEUgPDEwY2hhcnM+LiAqLwoJICAgIHJldHVybiAwOwoJc3RyY3B5KGJ1ZmZlciwgIkhBTkdVTCBTWUxMQUJMRSAiKTsKCWJ1ZmZlciArPSAxNjsKCXN0cmNweShidWZmZXIsIGhhbmd1bF9zeWxsYWJsZXNbTF1bMF0pOwoJYnVmZmVyICs9IHN0cmxlbihoYW5ndWxfc3lsbGFibGVzW0xdWzBdKTsKCXN0cmNweShidWZmZXIsIGhhbmd1bF9zeWxsYWJsZXNbVl1bMV0pOwoJYnVmZmVyICs9IHN0cmxlbihoYW5ndWxfc3lsbGFibGVzW1ZdWzFdKTsKCXN0cmNweShidWZmZXIsIGhhbmd1bF9zeWxsYWJsZXNbVF1bMl0pOwoJYnVmZmVyICs9IHN0cmxlbihoYW5ndWxfc3lsbGFibGVzW1RdWzJdKTsKCSpidWZmZXIgPSAnXDAnOwoJcmV0dXJuIDE7CiAgICB9CgogICAgaWYgKGlzX3VuaWZpZWRfaWRlb2dyYXBoKGNvZGUpKSB7CiAgICAgICAgaWYgKGJ1ZmxlbiA8IDI4KQogICAgICAgICAgICAvKiBXb3JzdCBjYXNlOiBDSksgVU5JRklFRCBJREVPR1JBUEgtMjAwMDAgKi8KICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgc3ByaW50ZihidWZmZXIsICJDSksgVU5JRklFRCBJREVPR1JBUEgtJVgiLCBjb2RlKTsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICBpZiAoY29kZSA+PSAweDExMDAwMCkKICAgICAgICByZXR1cm4gMDsKCiAgICAvKiBnZXQgb2Zmc2V0IGludG8gcGhyYXNlYm9vayAqLwogICAgb2Zmc2V0ID0gcGhyYXNlYm9va19vZmZzZXQxWyhjb2RlPj5waHJhc2Vib29rX3NoaWZ0KV07CiAgICBvZmZzZXQgPSBwaHJhc2Vib29rX29mZnNldDJbKG9mZnNldDw8cGhyYXNlYm9va19zaGlmdCkgKwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvZGUmKCgxPDxwaHJhc2Vib29rX3NoaWZ0KS0xKSldOwogICAgaWYgKCFvZmZzZXQpCiAgICAgICAgcmV0dXJuIDA7CgogICAgaSA9IDA7CgogICAgZm9yICg7OykgewogICAgICAgIC8qIGdldCB3b3JkIGluZGV4ICovCiAgICAgICAgd29yZCA9IHBocmFzZWJvb2tbb2Zmc2V0XSAtIHBocmFzZWJvb2tfc2hvcnQ7CiAgICAgICAgaWYgKHdvcmQgPj0gMCkgewogICAgICAgICAgICB3b3JkID0gKHdvcmQgPDwgOCkgKyBwaHJhc2Vib29rW29mZnNldCsxXTsKICAgICAgICAgICAgb2Zmc2V0ICs9IDI7CiAgICAgICAgfSBlbHNlCiAgICAgICAgICAgIHdvcmQgPSBwaHJhc2Vib29rW29mZnNldCsrXTsKICAgICAgICBpZiAoaSkgewogICAgICAgICAgICBpZiAoaSA+IGJ1ZmxlbikKICAgICAgICAgICAgICAgIHJldHVybiAwOyAvKiBidWZmZXIgb3ZlcmZsb3cgKi8KICAgICAgICAgICAgYnVmZmVyW2krK10gPSAnICc7CiAgICAgICAgfQogICAgICAgIC8qIGNvcHkgd29yZCBzdHJpbmcgZnJvbSBsZXhpY29uLiAgdGhlIGxhc3QgY2hhcmFjdGVyIGluIHRoZQogICAgICAgICAgIHdvcmQgaGFzIGJpdCA3IHNldC4gIHRoZSBsYXN0IHdvcmQgaW4gYSBzdHJpbmcgZW5kcyB3aXRoCiAgICAgICAgICAgMHg4MCAqLwogICAgICAgIHcgPSBsZXhpY29uICsgbGV4aWNvbl9vZmZzZXRbd29yZF07CiAgICAgICAgd2hpbGUgKCp3IDwgMTI4KSB7CiAgICAgICAgICAgIGlmIChpID49IGJ1ZmxlbikKICAgICAgICAgICAgICAgIHJldHVybiAwOyAvKiBidWZmZXIgb3ZlcmZsb3cgKi8KICAgICAgICAgICAgYnVmZmVyW2krK10gPSAqdysrOwogICAgICAgIH0KICAgICAgICBpZiAoaSA+PSBidWZsZW4pCiAgICAgICAgICAgIHJldHVybiAwOyAvKiBidWZmZXIgb3ZlcmZsb3cgKi8KICAgICAgICBidWZmZXJbaSsrXSA9ICp3ICYgMTI3OwogICAgICAgIGlmICgqdyA9PSAxMjgpCiAgICAgICAgICAgIGJyZWFrOyAvKiBlbmQgb2Ygd29yZCAqLwogICAgfQoKICAgIHJldHVybiAxOwp9CgpzdGF0aWMgaW50Cl9jbXBuYW1lKGludCBjb2RlLCBjb25zdCBjaGFyKiBuYW1lLCBpbnQgbmFtZWxlbikKewogICAgLyogY2hlY2sgaWYgY29kZSBjb3JyZXNwb25kcyB0byB0aGUgZ2l2ZW4gbmFtZSAqLwogICAgaW50IGk7CiAgICBjaGFyIGJ1ZmZlcltOQU1FX01BWExFTl07CiAgICBpZiAoIV9nZXR1Y25hbWUoY29kZSwgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSkpCiAgICAgICAgcmV0dXJuIDA7CiAgICBmb3IgKGkgPSAwOyBpIDwgbmFtZWxlbjsgaSsrKSB7CiAgICAgICAgaWYgKHRvdXBwZXIobmFtZVtpXSkgIT0gYnVmZmVyW2ldKQogICAgICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBidWZmZXJbbmFtZWxlbl0gPT0gJ1wwJzsKfQoKc3RhdGljIHZvaWQgCmZpbmRfc3lsbGFibGUoY29uc3QgY2hhciAqc3RyLCBpbnQgKmxlbiwgaW50ICpwb3MsIGludCBjb3VudCwgaW50IGNvbHVtbikKewogICAgaW50IGksIGxlbjE7CiAgICAqbGVuID0gLTE7CiAgICBmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJY2hhciAqcyA9IGhhbmd1bF9zeWxsYWJsZXNbaV1bY29sdW1uXTsKCWxlbjEgPSBzdHJsZW4ocyk7CglpZiAobGVuMSA8PSAqbGVuKQoJICAgIGNvbnRpbnVlOwoJaWYgKHN0cm5jbXAoc3RyLCBzLCBsZW4xKSA9PSAwKSB7CgkgICAgKmxlbiA9IGxlbjE7CgkgICAgKnBvcyA9IGk7Cgl9CiAgICB9CiAgICBpZiAoKmxlbiA9PSAtMSkgewoJKmxlbiA9IDA7CgkqcG9zID0gLTE7CiAgICB9Cn0KCnN0YXRpYyBpbnQKX2dldGNvZGUoY29uc3QgY2hhciogbmFtZSwgaW50IG5hbWVsZW4sIFB5X1VDUzQqIGNvZGUpCnsKICAgIHVuc2lnbmVkIGludCBoLCB2OwogICAgdW5zaWduZWQgaW50IG1hc2sgPSBjb2RlX3NpemUtMTsKICAgIHVuc2lnbmVkIGludCBpLCBpbmNyOwoKICAgIC8qIENoZWNrIGZvciBoYW5ndWwgc3lsbGFibGVzLiAqLwogICAgaWYgKHN0cm5jbXAobmFtZSwgIkhBTkdVTCBTWUxMQUJMRSAiLCAxNikgPT0gMCkgewoJaW50IEwsIFYsIFQsIGxlbjsKCWNvbnN0IGNoYXIgKnBvcyA9IG5hbWUgKyAxNjsKCWZpbmRfc3lsbGFibGUocG9zLCAmbGVuLCAmTCwgTENvdW50LCAwKTsKCXBvcyArPSBsZW47CglmaW5kX3N5bGxhYmxlKHBvcywgJmxlbiwgJlYsIFZDb3VudCwgMSk7Cglwb3MgKz0gbGVuOwoJZmluZF9zeWxsYWJsZShwb3MsICZsZW4sICZULCBUQ291bnQsIDIpOwoJcG9zICs9IGxlbjsKCWlmIChWICE9IC0xICYmIFYgIT0gLTEgJiYgVCAhPSAtMSAmJiBwb3MtbmFtZSA9PSBuYW1lbGVuKSB7CgkgICAgKmNvZGUgPSBTQmFzZSArIChMKlZDb3VudCtWKSpUQ291bnQgKyBUOwoJICAgIHJldHVybiAxOwoJfQogICAgICAgIC8qIE90aGVyd2lzZSwgaXQncyBhbiBpbGxlZ2FsIHN5bGxhYmxlIG5hbWUuICovCiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyogQ2hlY2sgZm9yIHVuaWZpZWQgaWRlb2dyYXBocy4gKi8KICAgIGlmIChzdHJuY21wKG5hbWUsICJDSksgVU5JRklFRCBJREVPR1JBUEgtIiwgMjIpID09IDApIHsKICAgICAgICAvKiBGb3VyIG9yIGZpdmUgaGV4ZGlnaXRzIG11c3QgZm9sbG93LiAqLwogICAgICAgIHYgPSAwOwogICAgICAgIG5hbWUgKz0gMjI7CiAgICAgICAgbmFtZWxlbiAtPSAyMjsKICAgICAgICBpZiAobmFtZWxlbiAhPSA0ICYmIG5hbWVsZW4gIT0gNSkKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgd2hpbGUgKG5hbWVsZW4tLSkgewogICAgICAgICAgICB2ICo9IDE2OwogICAgICAgICAgICBpZiAoKm5hbWUgPj0gJzAnICYmICpuYW1lIDw9ICc5JykKICAgICAgICAgICAgICAgIHYgKz0gKm5hbWUgLSAnMCc7CiAgICAgICAgICAgIGVsc2UgaWYgKCpuYW1lID49ICdBJyAmJiAqbmFtZSA8PSAnRicpCiAgICAgICAgICAgICAgICB2ICs9ICpuYW1lIC0gJ0EnICsgMTA7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICBuYW1lKys7CiAgICAgICAgfQogICAgICAgIGlmICghaXNfdW5pZmllZF9pZGVvZ3JhcGgodikpCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICpjb2RlID0gdjsKICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICAvKiB0aGUgZm9sbG93aW5nIGlzIHRoZSBzYW1lIGFzIHB5dGhvbidzIGRpY3Rpb25hcnkgbG9va3VwLCB3aXRoCiAgICAgICBvbmx5IG1pbm9yIGNoYW5nZXMuICBzZWUgdGhlIG1ha2V1bmljb2RlZGF0YSBzY3JpcHQgZm9yIG1vcmUKICAgICAgIGRldGFpbHMgKi8KCiAgICBoID0gKHVuc2lnbmVkIGludCkgX2dldGhhc2gobmFtZSwgbmFtZWxlbiwgY29kZV9tYWdpYyk7CiAgICBpID0gKH5oKSAmIG1hc2s7CiAgICB2ID0gY29kZV9oYXNoW2ldOwogICAgaWYgKCF2KQogICAgICAgIHJldHVybiAwOwogICAgaWYgKF9jbXBuYW1lKHYsIG5hbWUsIG5hbWVsZW4pKSB7CiAgICAgICAgKmNvZGUgPSB2OwogICAgICAgIHJldHVybiAxOwogICAgfQogICAgaW5jciA9IChoIF4gKGggPj4gMykpICYgbWFzazsKICAgIGlmICghaW5jcikKICAgICAgICBpbmNyID0gbWFzazsKICAgIGZvciAoOzspIHsKICAgICAgICBpID0gKGkgKyBpbmNyKSAmIG1hc2s7CiAgICAgICAgdiA9IGNvZGVfaGFzaFtpXTsKICAgICAgICBpZiAoIXYpCiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIGlmIChfY21wbmFtZSh2LCBuYW1lLCBuYW1lbGVuKSkgewogICAgICAgICAgICAqY29kZSA9IHY7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBpbmNyID0gaW5jciA8PCAxOwogICAgICAgIGlmIChpbmNyID4gbWFzaykKICAgICAgICAgICAgaW5jciA9IGluY3IgXiBjb2RlX3BvbHk7CiAgICB9Cn0KCnN0YXRpYyBjb25zdCBfUHlVbmljb2RlX05hbWVfQ0FQSSBoYXNoQVBJID0gCnsKICAgIHNpemVvZihfUHlVbmljb2RlX05hbWVfQ0FQSSksCiAgICBfZ2V0dWNuYW1lLAogICAgX2dldGNvZGUKfTsKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qIFB5dGhvbiBiaW5kaW5ncyAqLwoKc3RhdGljIFB5T2JqZWN0ICoKdW5pY29kZWRhdGFfbmFtZShQeU9iamVjdCogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCnsKICAgIGNoYXIgbmFtZVtOQU1FX01BWExFTl07CgogICAgUHlVbmljb2RlT2JqZWN0KiB2OwogICAgUHlPYmplY3QqIGRlZm9iaiA9IE5VTEw7CiAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hfE86bmFtZSIsICZQeVVuaWNvZGVfVHlwZSwgJnYsICZkZWZvYmopKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUodikgIT0gMSkgewoJUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKCQkJIm5lZWQgYSBzaW5nbGUgVW5pY29kZSBjaGFyYWN0ZXIgYXMgcGFyYW1ldGVyIik7CglyZXR1cm4gTlVMTDsKICAgIH0KCiAgICBpZiAoIV9nZXR1Y25hbWUoKFB5X1VDUzQpICpQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBzaXplb2YobmFtZSkpKSB7CglpZiAoZGVmb2JqID09IE5VTEwpIHsKCSAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIm5vIHN1Y2ggbmFtZSIpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKCX0KCWVsc2UgewoJICAgIFB5X0lOQ1JFRihkZWZvYmopOwoJICAgIHJldHVybiBkZWZvYmo7Cgl9CiAgICB9CgogICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoInMiLCBuYW1lKTsKfQoKc3RhdGljIFB5T2JqZWN0ICoKdW5pY29kZWRhdGFfbG9va3VwKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCogYXJncykKewogICAgUHlfVUNTNCBjb2RlOwogICAgUHlfVU5JQ09ERSBzdHJbMV07CgogICAgY2hhciogbmFtZTsKICAgIGludCBuYW1lbGVuOwogICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJzIzpsb29rdXAiLCAmbmFtZSwgJm5hbWVsZW4pKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIGlmICghX2dldGNvZGUobmFtZSwgbmFtZWxlbiwgJmNvZGUpKSB7CiAgICAgICAgY2hhciBmbXRbXSA9ICJ1bmRlZmluZWQgY2hhcmFjdGVyIG5hbWUgJyVzJyI7CiAgICAgICAgY2hhciAqYnVmID0gUHlNZW1fTUFMTE9DKHNpemVvZihmbXQpICsgbmFtZWxlbik7CiAgICAgICAgc3ByaW50ZihidWYsIGZtdCwgbmFtZSk7CiAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0tleUVycm9yLCBidWYpOwogICAgICAgIFB5TWVtX0ZSRUUoYnVmKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBzdHJbMF0gPSAoUHlfVU5JQ09ERSkgY29kZTsKICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoc3RyLCAxKTsKfQoKLyogWFhYIEFkZCBkb2Mgc3RyaW5ncy4gKi8KCnN0YXRpYyBQeU1ldGhvZERlZiB1bmljb2RlZGF0YV9mdW5jdGlvbnNbXSA9IHsKICAgIHsiZGVjaW1hbCIsIHVuaWNvZGVkYXRhX2RlY2ltYWwsIE1FVEhfVkFSQVJHU30sCiAgICB7ImRpZ2l0IiwgdW5pY29kZWRhdGFfZGlnaXQsIE1FVEhfVkFSQVJHU30sCiAgICB7Im51bWVyaWMiLCB1bmljb2RlZGF0YV9udW1lcmljLCBNRVRIX1ZBUkFSR1N9LAogICAgeyJjYXRlZ29yeSIsIHVuaWNvZGVkYXRhX2NhdGVnb3J5LCBNRVRIX1ZBUkFSR1N9LAogICAgeyJiaWRpcmVjdGlvbmFsIiwgdW5pY29kZWRhdGFfYmlkaXJlY3Rpb25hbCwgTUVUSF9WQVJBUkdTfSwKICAgIHsiY29tYmluaW5nIiwgdW5pY29kZWRhdGFfY29tYmluaW5nLCBNRVRIX1ZBUkFSR1N9LAogICAgeyJtaXJyb3JlZCIsIHVuaWNvZGVkYXRhX21pcnJvcmVkLCBNRVRIX1ZBUkFSR1N9LAogICAgeyJkZWNvbXBvc2l0aW9uIix1bmljb2RlZGF0YV9kZWNvbXBvc2l0aW9uLCBNRVRIX1ZBUkFSR1N9LAogICAgeyJuYW1lIiwgdW5pY29kZWRhdGFfbmFtZSwgTUVUSF9WQVJBUkdTfSwKICAgIHsibG9va3VwIiwgdW5pY29kZWRhdGFfbG9va3VwLCBNRVRIX1ZBUkFSR1N9LAogICAgeyJub3JtYWxpemUiLCB1bmljb2RlZGF0YV9ub3JtYWxpemUsIE1FVEhfVkFSQVJHU30sCiAgICB7TlVMTCwgTlVMTH0JCS8qIHNlbnRpbmVsICovCn07CgpQeURvY19TVFJWQVIodW5pY29kZWRhdGFfZG9jc3RyaW5nLCAidW5pY29kZSBjaGFyYWN0ZXIgZGF0YWJhc2UiKTsKClB5TU9ESU5JVF9GVU5DCmluaXR1bmljb2RlZGF0YSh2b2lkKQp7CiAgICBQeU9iamVjdCAqbSwgKnY7CgogICAgbSA9IFB5X0luaXRNb2R1bGUzKAogICAgICAgICJ1bmljb2RlZGF0YSIsIHVuaWNvZGVkYXRhX2Z1bmN0aW9ucywgdW5pY29kZWRhdGFfZG9jc3RyaW5nKTsKICAgIGlmICghbSkKICAgICAgICByZXR1cm47CgogICAgUHlNb2R1bGVfQWRkU3RyaW5nQ29uc3RhbnQobSwgInVuaWRhdGFfdmVyc2lvbiIsIFVOSURBVEFfVkVSU0lPTik7CgogICAgLyogRXhwb3J0IEMgQVBJICovCiAgICB2ID0gUHlDT2JqZWN0X0Zyb21Wb2lkUHRyKCh2b2lkICopICZoYXNoQVBJLCBOVUxMKTsKICAgIGlmICh2ICE9IE5VTEwpCiAgICAgICAgUHlNb2R1bGVfQWRkT2JqZWN0KG0sICJ1Y25oYXNoX0NBUEkiLCB2KTsKfQoKLyogCkxvY2FsIHZhcmlhYmxlczoKYy1iYXNpYy1vZmZzZXQ6IDQKaW5kZW50LXRhYnMtbW9kZTogbmlsCkVuZDoKKi8K