LyoKICogJFJDU0lkOiB4Yy9saWIvZm9udGNvbmZpZy9zcmMvZmNzdHIuYyx2IDEuMTAgMjAwMi8wOC8zMSAyMjoxNzozMiBrZWl0aHAgRXhwICQKICoKICogQ29weXJpZ2h0IKkgMjAwMCBLZWl0aCBQYWNrYXJkCiAqCiAqIFBlcm1pc3Npb24gdG8gdXNlLCBjb3B5LCBtb2RpZnksIGRpc3RyaWJ1dGUsIGFuZCBzZWxsIHRoaXMgc29mdHdhcmUgYW5kIGl0cwogKiBkb2N1bWVudGF0aW9uIGZvciBhbnkgcHVycG9zZSBpcyBoZXJlYnkgZ3JhbnRlZCB3aXRob3V0IGZlZSwgcHJvdmlkZWQgdGhhdAogKiB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdCBib3RoIHRoYXQKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gc3VwcG9ydGluZwogKiBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBLZWl0aCBQYWNrYXJkIG5vdCBiZSB1c2VkIGluCiAqIGFkdmVydGlzaW5nIG9yIHB1YmxpY2l0eSBwZXJ0YWluaW5nIHRvIGRpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dAogKiBzcGVjaWZpYywgd3JpdHRlbiBwcmlvciBwZXJtaXNzaW9uLiAgS2VpdGggUGFja2FyZCBtYWtlcyBubwogKiByZXByZXNlbnRhdGlvbnMgYWJvdXQgdGhlIHN1aXRhYmlsaXR5IG9mIHRoaXMgc29mdHdhcmUgZm9yIGFueSBwdXJwb3NlLiAgSXQKICogaXMgcHJvdmlkZWQgImFzIGlzIiB3aXRob3V0IGV4cHJlc3Mgb3IgaW1wbGllZCB3YXJyYW50eS4KICoKICogS0VJVEggUEFDS0FSRCBESVNDTEFJTVMgQUxMIFdBUlJBTlRJRVMgV0lUSCBSRUdBUkQgVE8gVEhJUyBTT0ZUV0FSRSwKICogSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLCBJTiBOTwogKiBFVkVOVCBTSEFMTCBLRUlUSCBQQUNLQVJEIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SCiAqIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLAogKiBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSCiAqIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IKICogUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJmY2ludC5oIgoKRmNDaGFyOCAqCkZjU3RyQ29weSAoY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNDaGFyOAkqcjsKCiAgICBpZiAoIXMpCglyZXR1cm4gMDsKICAgIHIgPSAoRmNDaGFyOCAqKSBtYWxsb2MgKHN0cmxlbiAoKGNoYXIgKikgcykgKyAxKTsKICAgIGlmICghcikKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NUUklORywgc3RybGVuICgoY2hhciAqKSBzKSArIDEpOwogICAgc3RyY3B5ICgoY2hhciAqKSByLCAoY2hhciAqKSBzKTsKICAgIHJldHVybiByOwp9CgpGY0NoYXI4ICoKRmNTdHJQbHVzIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIGludAkgICAgbCA9IHN0cmxlbiAoKGNoYXIgKilzMSkgKyBzdHJsZW4gKChjaGFyICopIHMyKSArIDE7CiAgICBGY0NoYXI4ICpzID0gbWFsbG9jIChsKTsKCiAgICBpZiAoIXMpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVFJJTkcsIGwpOwogICAgc3RyY3B5ICgoY2hhciAqKSBzLCAoY2hhciAqKSBzMSk7CiAgICBzdHJjYXQgKChjaGFyICopIHMsIChjaGFyICopIHMyKTsKICAgIHJldHVybiBzOwp9Cgp2b2lkCkZjU3RyRnJlZSAoRmNDaGFyOCAqcykKewogICAgRmNNZW1GcmVlIChGQ19NRU1fU1RSSU5HLCBzdHJsZW4gKChjaGFyICopIHMpICsgMSk7CiAgICBmcmVlIChzKTsKfQoKaW50CkZjU3RyQ21wSWdub3JlQ2FzZSAoY29uc3QgRmNDaGFyOCAqczEsIGNvbnN0IEZjQ2hhcjggKnMyKQp7CiAgICBGY0NoYXI4IGMxLCBjMjsKICAgIAogICAgZm9yICg7OykgCiAgICB7CgljMSA9ICpzMSsrOwoJYzIgPSAqczIrKzsKCWlmICghYzEgfHwgKGMxICE9IGMyICYmIChjMSA9IEZjVG9Mb3dlcihjMSkpICE9IChjMiA9IEZjVG9Mb3dlcihjMikpKSkKCSAgICBicmVhazsKICAgIH0KICAgIHJldHVybiAoaW50KSBjMSAtIChpbnQpIGMyOwp9CgppbnQKRmNTdHJDbXBJZ25vcmVCbGFua3NBbmRDYXNlIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIEZjQ2hhcjggYzEsIGMyOwogICAgCiAgICBmb3IgKDs7KSAKICAgIHsKCWRvCgkgICAgYzEgPSAqczErKzsKCXdoaWxlIChjMSA9PSAnICcpOwoJZG8KCSAgICBjMiA9ICpzMisrOwoJd2hpbGUgKGMyID09ICcgJyk7CglpZiAoIWMxIHx8IChjMSAhPSBjMiAmJiAoYzEgPSBGY1RvTG93ZXIoYzEpKSAhPSAoYzIgPSBGY1RvTG93ZXIoYzIpKSkpCgkgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gKGludCkgYzEgLSAoaW50KSBjMjsKfQoKaW50CkZjU3RyQ21wIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIEZjQ2hhcjggYzEsIGMyOwogICAgCiAgICBpZiAoczEgPT0gczIpCglyZXR1cm4gMDsKICAgIGZvciAoOzspIAogICAgewoJYzEgPSAqczErKzsKCWMyID0gKnMyKys7CglpZiAoIWMxIHx8IGMxICE9IGMyKQoJICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIChpbnQpIGMxIC0gKGludCkgYzI7Cn0KCi8qCiAqIElzIHRoZSBoZWFkIG9mIHMxIGVxdWFsIHRvIHMyPwogKi8KCnN0YXRpYyBGY0Jvb2wKRmNTdHJJc0F0SWdub3JlQmxhbmtzQW5kQ2FzZSAoY29uc3QgRmNDaGFyOCAqczEsIGNvbnN0IEZjQ2hhcjggKnMyKQp7CiAgICBGY0NoYXI4IGMxLCBjMjsKICAgIAogICAgZm9yICg7OykgCiAgICB7CglkbwoJICAgIGMxID0gKnMxKys7Cgl3aGlsZSAoYzEgPT0gJyAnKTsKCWRvCgkgICAgYzIgPSAqczIrKzsKCXdoaWxlIChjMiA9PSAnICcpOwoJaWYgKCFjMSB8fCAoYzEgIT0gYzIgJiYgKGMxID0gRmNUb0xvd2VyKGMxKSkgIT0gKGMyID0gRmNUb0xvd2VyKGMyKSkpKQoJICAgIGJyZWFrOwogICAgfQogICAgcmV0dXJuIGMxID09IGMyIHx8ICFjMjsKfQoKLyoKICogRG9lcyBzMSBjb250YWluIGFuIGluc3RhbmNlIG9mIHMyIChpZ25vcmluZyBibGFua3MgYW5kIGNhc2UpPwogKi8KCmNvbnN0IEZjQ2hhcjggKgpGY1N0ckNvbnRhaW5zSWdub3JlQmxhbmtzQW5kQ2FzZSAoY29uc3QgRmNDaGFyOCAqczEsIGNvbnN0IEZjQ2hhcjggKnMyKQp7CiAgICB3aGlsZSAoKnMxKQogICAgewoJaWYgKEZjU3RySXNBdElnbm9yZUJsYW5rc0FuZENhc2UgKHMxLCBzMikpCgkgICAgcmV0dXJuIHMxOwoJczErKzsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKgogKiBJcyB0aGUgaGVhZCBvZiBzMSBlcXVhbCB0byBzMj8KICovCgpzdGF0aWMgRmNCb29sCkZjU3RySXNBdElnbm9yZUNhc2UgKGNvbnN0IEZjQ2hhcjggKnMxLCBjb25zdCBGY0NoYXI4ICpzMikKewogICAgRmNDaGFyOCBjMSwgYzI7CiAgICAKICAgIGZvciAoOzspIAogICAgewoJYzEgPSAqczErKzsKCWMyID0gKnMyKys7CglpZiAoIWMxIHx8IChjMSAhPSBjMiAmJiAoYzEgPSBGY1RvTG93ZXIoYzEpKSAhPSAoYzIgPSBGY1RvTG93ZXIoYzIpKSkpCgkgICAgYnJlYWs7CiAgICB9CiAgICByZXR1cm4gYzEgPT0gYzIgfHwgIWMyOwp9CgovKgogKiBEb2VzIHMxIGNvbnRhaW4gYW4gaW5zdGFuY2Ugb2YgczIgKGlnbm9yaW5nIGJsYW5rcyBhbmQgY2FzZSk/CiAqLwoKY29uc3QgRmNDaGFyOCAqCkZjU3RyQ29udGFpbnNJZ25vcmVDYXNlIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIHdoaWxlICgqczEpCiAgICB7CglpZiAoRmNTdHJJc0F0SWdub3JlQ2FzZSAoczEsIHMyKSkKCSAgICByZXR1cm4gczE7CglzMSsrOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCmNvbnN0IEZjQ2hhcjggKgpGY1N0clN0cklnbm9yZUNhc2UgKGNvbnN0IEZjQ2hhcjggKnMxLCBjb25zdCBGY0NoYXI4ICpzMikKewogICAgRmNDaGFyOCBjMSwgYzI7CiAgICBjb25zdCBGY0NoYXI4ICogcCA9IHMxOwogICAgY29uc3QgRmNDaGFyOCAqIGIgPSBzMjsKCiAgICBpZiAoIXMxIHx8ICFzMikKCXJldHVybiAwOwoKICAgIGlmIChzMSA9PSBzMikKCXJldHVybiBzMTsKCmFnYWluOgogICAgYzIgPSAqczIrKzsKICAgIGMyID0gRmNUb0xvd2VyIChjMik7CgogICAgaWYgKCFjMikKCXJldHVybiAwOwoKICAgIGZvciAoOzspIAogICAgewoJcCA9IHMxOwoJYzEgPSAqczErKzsKCWlmICghYzEgfHwgKGMxID0gRmNUb0xvd2VyIChjMSkpID09IGMyKQoJICAgIGJyZWFrOwogICAgfQoKICAgIGlmIChjMSAhPSBjMikKCXJldHVybiAwOwoKICAgIGZvciAoOzspCiAgICB7CgljMSA9ICpzMTsKCWMyID0gKnMyOwoJaWYgKGMxICYmIGMyICYmIChjMSA9IEZjVG9Mb3dlciAoYzEpKSAhPSAoYzIgPSBGY1RvTG93ZXIgKGMyKSkpCgl7CgkgICAgczEgPSBwICsgMTsKCSAgICBzMiA9IGI7CgkgICAgZ290byBhZ2FpbjsKCX0KCWlmICghYzIpCgkgICAgcmV0dXJuIHA7CglpZiAoIWMxKQoJICAgIHJldHVybiAwOwoJKysgczE7CgkrKyBzMjsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKY29uc3QgRmNDaGFyOCAqCkZjU3RyU3RyIChjb25zdCBGY0NoYXI4ICpzMSwgY29uc3QgRmNDaGFyOCAqczIpCnsKICAgIEZjQ2hhcjggYzEsIGMyOwogICAgY29uc3QgRmNDaGFyOCAqIHAgPSBzMTsKICAgIGNvbnN0IEZjQ2hhcjggKiBiID0gczI7CgogICAgaWYgKCFzMSB8fCAhczIpCglyZXR1cm4gMDsKCiAgICBpZiAoczEgPT0gczIpCglyZXR1cm4gczE7CgphZ2FpbjoKICAgIGMyID0gKnMyKys7CgogICAgaWYgKCFjMikKCXJldHVybiAwOwoKICAgIGZvciAoOzspIAogICAgewoJcCA9IHMxOwoJYzEgPSAqczErKzsKCWlmICghYzEgfHwgYzEgPT0gYzIpCgkgICAgYnJlYWs7CiAgICB9CgogICAgaWYgKGMxICE9IGMyKQoJcmV0dXJuIDA7CgogICAgZm9yICg7OykKICAgIHsKCWMxID0gKnMxOwoJYzIgPSAqczI7CglpZiAoYzEgJiYgYzIgJiYgYzEgIT0gYzIpCgl7CgkgICAgczEgPSBwICsgMTsKCSAgICBzMiA9IGI7CgkgICAgZ290byBhZ2FpbjsKCX0KCWlmICghYzIpCgkgICAgcmV0dXJuIHA7CglpZiAoIWMxKQoJICAgIHJldHVybiAwOwoJKysgczE7CgkrKyBzMjsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKaW50CkZjVXRmOFRvVWNzNCAoY29uc3QgRmNDaGFyOCAqc3JjX29yaWcsCgkgICAgICBGY0NoYXIzMgkgICAgKmRzdCwKCSAgICAgIGludAkgICAgbGVuKQp7CiAgICBjb25zdCBGY0NoYXI4ICAgKnNyYyA9IHNyY19vcmlnOwogICAgRmNDaGFyOAkgICAgczsKICAgIGludAkJICAgIGV4dHJhOwogICAgRmNDaGFyMzIJICAgIHJlc3VsdDsKCiAgICBpZiAobGVuID09IDApCglyZXR1cm4gMDsKICAgIAogICAgcyA9ICpzcmMrKzsKICAgIGxlbi0tOwogICAgCiAgICBpZiAoIShzICYgMHg4MCkpCiAgICB7CglyZXN1bHQgPSBzOwoJZXh0cmEgPSAwOwogICAgfSAKICAgIGVsc2UgaWYgKCEocyAmIDB4NDApKQogICAgewoJcmV0dXJuIC0xOwogICAgfQogICAgZWxzZSBpZiAoIShzICYgMHgyMCkpCiAgICB7CglyZXN1bHQgPSBzICYgMHgxZjsKCWV4dHJhID0gMTsKICAgIH0KICAgIGVsc2UgaWYgKCEocyAmIDB4MTApKQogICAgewoJcmVzdWx0ID0gcyAmIDB4ZjsKCWV4dHJhID0gMjsKICAgIH0KICAgIGVsc2UgaWYgKCEocyAmIDB4MDgpKQogICAgewoJcmVzdWx0ID0gcyAmIDB4MDc7CglleHRyYSA9IDM7CiAgICB9CiAgICBlbHNlIGlmICghKHMgJiAweDA0KSkKICAgIHsKCXJlc3VsdCA9IHMgJiAweDAzOwoJZXh0cmEgPSA0OwogICAgfQogICAgZWxzZSBpZiAoICEgKHMgJiAweDAyKSkKICAgIHsKCXJlc3VsdCA9IHMgJiAweDAxOwoJZXh0cmEgPSA1OwogICAgfQogICAgZWxzZQogICAgewoJcmV0dXJuIC0xOwogICAgfQogICAgaWYgKGV4dHJhID4gbGVuKQoJcmV0dXJuIC0xOwogICAgCiAgICB3aGlsZSAoZXh0cmEtLSkKICAgIHsKCXJlc3VsdCA8PD0gNjsKCXMgPSAqc3JjKys7CgkKCWlmICgocyAmIDB4YzApICE9IDB4ODApCgkgICAgcmV0dXJuIC0xOwoJCglyZXN1bHQgfD0gcyAmIDB4M2Y7CiAgICB9CiAgICAqZHN0ID0gcmVzdWx0OwogICAgcmV0dXJuIHNyYyAtIHNyY19vcmlnOwp9CgpGY0Jvb2wKRmNVdGY4TGVuIChjb25zdCBGY0NoYXI4ICAgICpzdHJpbmcsCgkgICBpbnQJCSAgICBsZW4sCgkgICBpbnQJCSAgICAqbmNoYXIsCgkgICBpbnQJCSAgICAqd2NoYXIpCnsKICAgIGludAkJbjsKICAgIGludAkJY2xlbjsKICAgIEZjQ2hhcjMyCWM7CiAgICBGY0NoYXIzMgltYXg7CiAgICAKICAgIG4gPSAwOwogICAgbWF4ID0gMDsKICAgIHdoaWxlIChsZW4pCiAgICB7CgljbGVuID0gRmNVdGY4VG9VY3M0IChzdHJpbmcsICZjLCBsZW4pOwoJaWYgKGNsZW4gPD0gMCkJLyogbWFsZm9ybWVkIFVURjggc3RyaW5nICovCgkgICAgcmV0dXJuIEZjRmFsc2U7CglpZiAoYyA+IG1heCkKCSAgICBtYXggPSBjOwoJc3RyaW5nICs9IGNsZW47CglsZW4gLT0gY2xlbjsKCW4rKzsKICAgIH0KICAgICpuY2hhciA9IG47CiAgICBpZiAobWF4ID49IDB4MTAwMDApCgkqd2NoYXIgPSA0OwogICAgZWxzZSBpZiAobWF4ID4gMHgxMDApCgkqd2NoYXIgPSAyOwogICAgZWxzZQoJKndjaGFyID0gMTsKICAgIHJldHVybiBGY1RydWU7Cn0KCmludApGY1VjczRUb1V0ZjggKEZjQ2hhcjMyCXVjczQsCgkgICAgICBGY0NoYXI4CWRlc3RbRkNfVVRGOF9NQVhfTEVOXSkKewogICAgaW50CWJpdHM7CiAgICBGY0NoYXI4ICpkID0gZGVzdDsKICAgIAogICAgaWYgICAgICAodWNzNCA8ICAgICAgIDB4ODApIHsgICpkKys9ICB1Y3M0OyAgICAgICAgICAgICAgICAgICAgICAgICBiaXRzPSAtNjsgfQogICAgZWxzZSBpZiAodWNzNCA8ICAgICAgMHg4MDApIHsgICpkKys9ICgodWNzNCA+PiAgNikgJiAweDFGKSB8IDB4QzA7ICBiaXRzPSAgMDsgfQogICAgZWxzZSBpZiAodWNzNCA8ICAgIDB4MTAwMDApIHsgICpkKys9ICgodWNzNCA+PiAxMikgJiAweDBGKSB8IDB4RTA7ICBiaXRzPSAgNjsgfQogICAgZWxzZSBpZiAodWNzNCA8ICAgMHgyMDAwMDApIHsgICpkKys9ICgodWNzNCA+PiAxOCkgJiAweDA3KSB8IDB4RjA7ICBiaXRzPSAxMjsgfQogICAgZWxzZSBpZiAodWNzNCA8ICAweDQwMDAwMDApIHsgICpkKys9ICgodWNzNCA+PiAyNCkgJiAweDAzKSB8IDB4Rjg7ICBiaXRzPSAxODsgfQogICAgZWxzZSBpZiAodWNzNCA8IDB4ODAwMDAwMDApIHsgICpkKys9ICgodWNzNCA+PiAzMCkgJiAweDAxKSB8IDB4RkM7ICBiaXRzPSAyNDsgfQogICAgZWxzZSByZXR1cm4gMDsKCiAgICBmb3IgKCA7IGJpdHMgPj0gMDsgYml0cy09IDYpIHsKCSpkKys9ICgodWNzNCA+PiBiaXRzKSAmIDB4M0YpIHwgMHg4MDsKICAgIH0KICAgIHJldHVybiBkIC0gZGVzdDsKfQoKI2RlZmluZSBHZXRVdGYxNihzcmMsZW5kaWFuKSBcCiAgICAoKEZjQ2hhcjE2KSAoKHNyYylbZW5kaWFuID09IEZjRW5kaWFuQmlnID8gMCA6IDFdIDw8IDgpIHwgXAogICAgIChGY0NoYXIxNikgKChzcmMpW2VuZGlhbiA9PSBGY0VuZGlhbkJpZyA/IDEgOiAwXSkpCgppbnQKRmNVdGYxNlRvVWNzNCAoY29uc3QgRmNDaGFyOAkqc3JjX29yaWcsCgkgICAgICAgRmNFbmRpYW4JCWVuZGlhbiwKCSAgICAgICBGY0NoYXIzMgkJKmRzdCwKCSAgICAgICBpbnQJCWxlbikJLyogaW4gYnl0ZXMgKi8KewogICAgY29uc3QgRmNDaGFyOCAgICpzcmMgPSBzcmNfb3JpZzsKICAgIEZjQ2hhcjE2CSAgICBhLCBiOwogICAgRmNDaGFyMzIJICAgIHJlc3VsdDsKCiAgICBpZiAobGVuIDwgMikKCXJldHVybiAwOwogICAgCiAgICBhID0gR2V0VXRmMTYgKHNyYywgZW5kaWFuKTsgc3JjICs9IDI7IGxlbiAtPSAyOwogICAgCiAgICAvKiAKICAgICAqIENoZWNrIGZvciBzdXJyb2dhdGUgCiAgICAgKi8KICAgIGlmICgoYSAmIDB4ZmMwMCkgPT0gMHhkODAwKQogICAgewoJaWYgKGxlbiA8IDIpCgkgICAgcmV0dXJuIDA7CgliID0gR2V0VXRmMTYgKHNyYywgZW5kaWFuKTsgc3JjICs9IDI7IGxlbiAtPSAyOwoJLyoKCSAqIENoZWNrIGZvciBpbnZhbGlkIHN1cnJvZ2F0ZSBzZXF1ZW5jZQoJICovCglpZiAoKGIgJiAweGZjMDApICE9IDB4ZGMwMCkKCSAgICByZXR1cm4gMDsKCXJlc3VsdCA9ICgoKChGY0NoYXIzMikgYSAmIDB4M2ZmKSA8PCAxMCkgfAoJCSAgKChGY0NoYXIzMikgYiAmIDB4M2ZmKSkgKyAweDEwMDAwOwogICAgfQogICAgZWxzZQoJcmVzdWx0ID0gYTsKICAgICpkc3QgPSByZXN1bHQ7CiAgICByZXR1cm4gc3JjIC0gc3JjX29yaWc7Cn0KCkZjQm9vbApGY1V0ZjE2TGVuIChjb25zdCBGY0NoYXI4ICAgKnN0cmluZywKCSAgICBGY0VuZGlhbgkgICAgZW5kaWFuLAoJICAgIGludAkJICAgIGxlbiwJLyogaW4gYnl0ZXMgKi8KCSAgICBpbnQJCSAgICAqbmNoYXIsCgkgICAgaW50CQkgICAgKndjaGFyKQp7CiAgICBpbnQJCW47CiAgICBpbnQJCWNsZW47CiAgICBGY0NoYXIzMgljOwogICAgRmNDaGFyMzIJbWF4OwogICAgCiAgICBuID0gMDsKICAgIG1heCA9IDA7CiAgICB3aGlsZSAobGVuKQogICAgewoJY2xlbiA9IEZjVXRmMTZUb1VjczQgKHN0cmluZywgZW5kaWFuLCAmYywgbGVuKTsKCWlmIChjbGVuIDw9IDApCS8qIG1hbGZvcm1lZCBVVEY4IHN0cmluZyAqLwoJICAgIHJldHVybiBGY0ZhbHNlOwoJaWYgKGMgPiBtYXgpCgkgICAgbWF4ID0gYzsKCXN0cmluZyArPSBjbGVuOwoJbGVuIC09IGNsZW47CgluKys7CiAgICB9CiAgICAqbmNoYXIgPSBuOwogICAgaWYgKG1heCA+PSAweDEwMDAwKQoJKndjaGFyID0gNDsKICAgIGVsc2UgaWYgKG1heCA+IDB4MTAwKQoJKndjaGFyID0gMjsKICAgIGVsc2UKCSp3Y2hhciA9IDE7CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjU3RyQnVmSW5pdCAoRmNTdHJCdWYgKmJ1ZiwgRmNDaGFyOCAqaW5pdCwgaW50IHNpemUpCnsKICAgIGJ1Zi0+YnVmID0gaW5pdDsKICAgIGJ1Zi0+YWxsb2NhdGVkID0gRmNGYWxzZTsKICAgIGJ1Zi0+ZmFpbGVkID0gRmNGYWxzZTsKICAgIGJ1Zi0+bGVuID0gMDsKICAgIGJ1Zi0+c2l6ZSA9IHNpemU7Cn0KCnZvaWQKRmNTdHJCdWZEZXN0cm95IChGY1N0ckJ1ZiAqYnVmKQp7CiAgICBpZiAoYnVmLT5hbGxvY2F0ZWQpCiAgICB7CglGY01lbUZyZWUgKEZDX01FTV9TVFJCVUYsIGJ1Zi0+c2l6ZSk7CglmcmVlIChidWYtPmJ1Zik7CglGY1N0ckJ1ZkluaXQgKGJ1ZiwgMCwgMCk7CiAgICB9Cn0KCkZjQ2hhcjggKgpGY1N0ckJ1ZkRvbmUgKEZjU3RyQnVmICpidWYpCnsKICAgIEZjQ2hhcjggKnJldDsKCiAgICByZXQgPSBtYWxsb2MgKGJ1Zi0+bGVuICsgMSk7CiAgICBpZiAocmV0KQogICAgewoJRmNNZW1BbGxvYyAoRkNfTUVNX1NUUklORywgYnVmLT5sZW4gKyAxKTsKCW1lbWNweSAocmV0LCBidWYtPmJ1ZiwgYnVmLT5sZW4pOwoJcmV0W2J1Zi0+bGVuXSA9ICdcMCc7CiAgICB9CiAgICBGY1N0ckJ1ZkRlc3Ryb3kgKGJ1Zik7CiAgICByZXR1cm4gcmV0Owp9CgpGY0Jvb2wKRmNTdHJCdWZDaGFyIChGY1N0ckJ1ZiAqYnVmLCBGY0NoYXI4IGMpCnsKICAgIGlmIChidWYtPmxlbiA9PSBidWYtPnNpemUpCiAgICB7CglGY0NoYXI4CSAgICAqbmV3OwoJaW50CSAgICBzaXplOwoKCWlmIChidWYtPmFsbG9jYXRlZCkKCXsKCSAgICBzaXplID0gYnVmLT5zaXplICogMjsKCSAgICBuZXcgPSByZWFsbG9jIChidWYtPmJ1Ziwgc2l6ZSk7Cgl9CgllbHNlCgl7CgkgICAgc2l6ZSA9IGJ1Zi0+c2l6ZSArIDEwMjQ7CgkgICAgbmV3ID0gbWFsbG9jIChzaXplKTsKCSAgICBpZiAobmV3KQoJICAgIHsKCQlidWYtPmFsbG9jYXRlZCA9IEZjVHJ1ZTsKCQltZW1jcHkgKG5ldywgYnVmLT5idWYsIGJ1Zi0+bGVuKTsKCSAgICB9Cgl9CglpZiAoIW5ldykKCXsKCSAgICBidWYtPmZhaWxlZCA9IEZjVHJ1ZTsKCSAgICByZXR1cm4gRmNGYWxzZTsKCX0KCWlmIChidWYtPnNpemUpCgkgICAgRmNNZW1GcmVlIChGQ19NRU1fU1RSQlVGLCBidWYtPnNpemUpOwoJRmNNZW1BbGxvYyAoRkNfTUVNX1NUUkJVRiwgc2l6ZSk7CglidWYtPnNpemUgPSBzaXplOwoJYnVmLT5idWYgPSBuZXc7CiAgICB9CiAgICBidWYtPmJ1ZltidWYtPmxlbisrXSA9IGM7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJCdWZTdHJpbmcgKEZjU3RyQnVmICpidWYsIGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIEZjQ2hhcjggYzsKICAgIHdoaWxlICgoYyA9ICpzKyspKQoJaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgYykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJCdWZEYXRhIChGY1N0ckJ1ZiAqYnVmLCBjb25zdCBGY0NoYXI4ICpzLCBpbnQgbGVuKQp7CiAgICB3aGlsZSAobGVuLS0gPiAwKQoJaWYgKCFGY1N0ckJ1ZkNoYXIgKGJ1ZiwgKnMrKykpCgkgICAgcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJVc2VzSG9tZSAoY29uc3QgRmNDaGFyOCAqcykKewogICAgcmV0dXJuICpzID09ICd+JzsKfQoKRmNDaGFyOCAqCkZjU3RyQ29weUZpbGVuYW1lIChjb25zdCBGY0NoYXI4ICpzKQp7CiAgICBGY0NoYXI4ICpuZXc7CiAgICAKICAgIGlmICgqcyA9PSAnficpCiAgICB7CglGY0NoYXI4CSpob21lID0gRmNDb25maWdIb21lICgpOwoJaW50CXNpemU7CglpZiAoIWhvbWUpCgkgICAgcmV0dXJuIDA7CglzaXplID0gc3RybGVuICgoY2hhciAqKSBob21lKSArIHN0cmxlbiAoKGNoYXIgKikgcyk7CgluZXcgPSAoRmNDaGFyOCAqKSBtYWxsb2MgKHNpemUpOwoJaWYgKCFuZXcpCgkgICAgcmV0dXJuIDA7CglGY01lbUFsbG9jIChGQ19NRU1fU1RSSU5HLCBzaXplKTsKCXN0cmNweSAoKGNoYXIgKikgbmV3LCAoY2hhciAqKSBob21lKTsKCXN0cmNhdCAoKGNoYXIgKikgbmV3LCAoY2hhciAqKSBzICsgMSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglpbnQJc2l6ZSA9IHN0cmxlbiAoKGNoYXIgKikgcykgKyAxOwoJbmV3ID0gKEZjQ2hhcjggKikgbWFsbG9jIChzaXplKTsKCWlmICghbmV3KQoJICAgIHJldHVybiAwOwoJRmNNZW1BbGxvYyAoRkNfTUVNX1NUUklORywgc2l6ZSk7CglzdHJjcHkgKChjaGFyICopIG5ldywgKGNvbnN0IGNoYXIgKikgcyk7CiAgICB9CiAgICByZXR1cm4gbmV3Owp9CgpGY0NoYXI4ICoKRmNTdHJMYXN0U2xhc2ggKGNvbnN0IEZjQ2hhcjggICpwYXRoKQp7CiAgICBGY0NoYXI4CSAgICAqc2xhc2g7CgogICAgc2xhc2ggPSAoRmNDaGFyOCAqKSBzdHJyY2hyICgoY29uc3QgY2hhciAqKSBwYXRoLCAnLycpOwojaWZkZWYgX1dJTjMyCiAgICB7CiAgICAgICAgRmNDaGFyOCAgICAgKmJhY2tzbGFzaDsKCgliYWNrc2xhc2ggPSAoRmNDaGFyOCAqKSBzdHJyY2hyICgoY29uc3QgY2hhciAqKSBwYXRoLCAnXFwnKTsKCWlmICghc2xhc2ggfHwgKGJhY2tzbGFzaCAmJiBiYWNrc2xhc2ggPiBzbGFzaCkpCgkgICAgc2xhc2ggPSBiYWNrc2xhc2g7CiAgICB9CiNlbmRpZgoKICAgIHJldHVybiBzbGFzaDsKfQogIApGY0NoYXI4ICoKRmNTdHJEaXJuYW1lIChjb25zdCBGY0NoYXI4ICpmaWxlKQp7CiAgICBGY0NoYXI4ICpzbGFzaDsKICAgIEZjQ2hhcjggKmRpcjsKCiAgICBzbGFzaCA9IEZjU3RyTGFzdFNsYXNoIChmaWxlKTsKICAgIGlmICghc2xhc2gpCglyZXR1cm4gRmNTdHJDb3B5ICgoRmNDaGFyOCAqKSAiLiIpOwogICAgZGlyID0gbWFsbG9jICgoc2xhc2ggLSBmaWxlKSArIDEpOwogICAgaWYgKCFkaXIpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVFJJTkcsIChzbGFzaCAtIGZpbGUpICsgMSk7CiAgICBzdHJuY3B5ICgoY2hhciAqKSBkaXIsIChjb25zdCBjaGFyICopIGZpbGUsIHNsYXNoIC0gZmlsZSk7CiAgICBkaXJbc2xhc2ggLSBmaWxlXSA9ICdcMCc7CiAgICByZXR1cm4gZGlyOwp9CgpGY0NoYXI4ICoKRmNTdHJCYXNlbmFtZSAoY29uc3QgRmNDaGFyOCAqZmlsZSkKewogICAgRmNDaGFyOCAqc2xhc2g7CgogICAgc2xhc2ggPSBGY1N0ckxhc3RTbGFzaCAoZmlsZSk7CiAgICBpZiAoIXNsYXNoKQoJcmV0dXJuIEZjU3RyQ29weSAoZmlsZSk7CiAgICByZXR1cm4gRmNTdHJDb3B5IChzbGFzaCArIDEpOwp9CgpGY1N0clNldCAqCkZjU3RyU2V0Q3JlYXRlICh2b2lkKQp7CiAgICBGY1N0clNldAkqc2V0ID0gbWFsbG9jIChzaXplb2YgKEZjU3RyU2V0KSk7CiAgICBpZiAoIXNldCkKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX1NUUlNFVCwgc2l6ZW9mIChGY1N0clNldCkpOwogICAgc2V0LT5yZWYgPSAxOwogICAgc2V0LT5udW0gPSAwOwogICAgc2V0LT5zaXplID0gMDsKICAgIHNldC0+c3RycyA9IDA7CiAgICByZXR1cm4gc2V0Owp9CgpzdGF0aWMgRmNCb29sCl9GY1N0clNldEFwcGVuZCAoRmNTdHJTZXQgKnNldCwgRmNDaGFyOCAqcykKewogICAgaWYgKEZjU3RyU2V0TWVtYmVyIChzZXQsIHMpKQogICAgewoJRmNTdHJGcmVlIChzKTsKCXJldHVybiBGY1RydWU7CiAgICB9CiAgICBpZiAoc2V0LT5udW0gPT0gc2V0LT5zaXplKQogICAgewoJRmNDaGFyOAkqKnN0cnMgPSBtYWxsb2MgKChzZXQtPnNpemUgKyAyKSAqIHNpemVvZiAoRmNDaGFyOCAqKSk7CgoJaWYgKCFzdHJzKQoJICAgIHJldHVybiBGY0ZhbHNlOwoJRmNNZW1BbGxvYyAoRkNfTUVNX1NUUlNFVCwgKHNldC0+c2l6ZSArIDIpICogc2l6ZW9mIChGY0NoYXI4ICopKTsKCXNldC0+c2l6ZSA9IHNldC0+c2l6ZSArIDE7CglpZiAoc2V0LT5udW0pCgkgICAgbWVtY3B5IChzdHJzLCBzZXQtPnN0cnMsIHNldC0+bnVtICogc2l6ZW9mIChGY0NoYXI4ICopKTsKCWlmIChzZXQtPnN0cnMpCgkgICAgZnJlZSAoc2V0LT5zdHJzKTsKCXNldC0+c3RycyA9IHN0cnM7CiAgICB9CiAgICBzZXQtPnN0cnNbc2V0LT5udW0rK10gPSBzOwogICAgc2V0LT5zdHJzW3NldC0+bnVtXSA9IDA7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJTZXRNZW1iZXIgKEZjU3RyU2V0ICpzZXQsIGNvbnN0IEZjQ2hhcjggKnMpCnsKICAgIGludAlpOwoKICAgIGZvciAoaSA9IDA7IGkgPCBzZXQtPm51bTsgaSsrKQoJaWYgKCFGY1N0ckNtcCAoc2V0LT5zdHJzW2ldLCBzKSkKCSAgICByZXR1cm4gRmNUcnVlOwogICAgcmV0dXJuIEZjRmFsc2U7Cn0KCkZjQm9vbApGY1N0clNldEVxdWFsIChGY1N0clNldCAqc2EsIEZjU3RyU2V0ICpzYikKewogICAgaW50CWk7CiAgICBpZiAoc2EtPm51bSAhPSBzYi0+bnVtKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBmb3IgKGkgPSAwOyBpIDwgc2EtPm51bTsgaSsrKQoJaWYgKCFGY1N0clNldE1lbWJlciAoc2IsIHNhLT5zdHJzW2ldKSkKCSAgICByZXR1cm4gRmNGYWxzZTsKICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1N0clNldEFkZCAoRmNTdHJTZXQgKnNldCwgY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNDaGFyOCAqbmV3ID0gRmNTdHJDb3B5IChzKTsKICAgIGlmICghbmV3KQoJcmV0dXJuIEZjRmFsc2U7CiAgICBpZiAoIV9GY1N0clNldEFwcGVuZCAoc2V0LCBuZXcpKQogICAgewoJRmNTdHJGcmVlIChuZXcpOwoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0Jvb2wKRmNTdHJTZXRBZGRGaWxlbmFtZSAoRmNTdHJTZXQgKnNldCwgY29uc3QgRmNDaGFyOCAqcykKewogICAgRmNDaGFyOCAqbmV3ID0gRmNTdHJDb3B5RmlsZW5hbWUgKHMpOwogICAgaWYgKCFuZXcpCglyZXR1cm4gRmNGYWxzZTsKICAgIGlmICghX0ZjU3RyU2V0QXBwZW5kIChzZXQsIG5ldykpCiAgICB7CglGY1N0ckZyZWUgKG5ldyk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldHVybiBGY1RydWU7Cn0KCkZjQm9vbApGY1N0clNldERlbCAoRmNTdHJTZXQgKnNldCwgY29uc3QgRmNDaGFyOCAqcykKewogICAgaW50CWk7CgogICAgZm9yIChpID0gMDsgaSA8IHNldC0+bnVtOyBpKyspCglpZiAoIUZjU3RyQ21wIChzZXQtPnN0cnNbaV0sIHMpKQoJewoJICAgIEZjU3RyRnJlZSAoc2V0LT5zdHJzW2ldKTsKCSAgICAvKgoJICAgICAqIGNvcHkgcmVtYWluaW5nIHN0cmluZyBwb2ludGVycyBhbmQgdHJhaWxpbmcKCSAgICAgKiBOVUxMCgkgICAgICovCgkgICAgbWVtbW92ZSAoJnNldC0+c3Ryc1tpXSwgJnNldC0+c3Ryc1tpKzFdLCAKCQkgICAgIChzZXQtPm51bSAtIGkpICogc2l6ZW9mIChGY0NoYXI4ICopKTsKCSAgICBzZXQtPm51bS0tOwoJICAgIHJldHVybiBGY1RydWU7Cgl9CiAgICByZXR1cm4gRmNGYWxzZTsKfQoKdm9pZApGY1N0clNldERlc3Ryb3kgKEZjU3RyU2V0ICpzZXQpCnsKICAgIGlmICgtLXNldC0+cmVmID09IDApCiAgICB7CglpbnQJaTsKICAgIAoJZm9yIChpID0gMDsgaSA8IHNldC0+bnVtOyBpKyspCgkgICAgRmNTdHJGcmVlIChzZXQtPnN0cnNbaV0pOwoJRmNNZW1GcmVlIChGQ19NRU1fU1RSU0VULCAoc2V0LT5zaXplKSAqIHNpemVvZiAoRmNDaGFyOCAqKSk7CglpZiAoc2V0LT5zdHJzKQoJICAgIGZyZWUgKHNldC0+c3Rycyk7CglGY01lbUZyZWUgKEZDX01FTV9TVFJTRVQsIHNpemVvZiAoRmNTdHJTZXQpKTsKCWZyZWUgKHNldCk7CiAgICB9Cn0KCkZjU3RyTGlzdCAqCkZjU3RyTGlzdENyZWF0ZSAoRmNTdHJTZXQgKnNldCkKewogICAgRmNTdHJMaXN0CSpsaXN0OwoKICAgIGxpc3QgPSBtYWxsb2MgKHNpemVvZiAoRmNTdHJMaXN0KSk7CiAgICBpZiAoIWxpc3QpCglyZXR1cm4gMDsKICAgIEZjTWVtQWxsb2MgKEZDX01FTV9TVFJMSVNULCBzaXplb2YgKEZjU3RyTGlzdCkpOwogICAgbGlzdC0+c2V0ID0gc2V0OwogICAgc2V0LT5yZWYrKzsKICAgIGxpc3QtPm4gPSAwOwogICAgcmV0dXJuIGxpc3Q7Cn0KCkZjQ2hhcjggKgpGY1N0ckxpc3ROZXh0IChGY1N0ckxpc3QgKmxpc3QpCnsKICAgIGlmIChsaXN0LT5uID49IGxpc3QtPnNldC0+bnVtKQoJcmV0dXJuIDA7CiAgICByZXR1cm4gbGlzdC0+c2V0LT5zdHJzW2xpc3QtPm4rK107Cn0KCnZvaWQKRmNTdHJMaXN0RG9uZSAoRmNTdHJMaXN0ICpsaXN0KQp7CiAgICBGY1N0clNldERlc3Ryb3kgKGxpc3QtPnNldCk7CiAgICBGY01lbUZyZWUgKEZDX01FTV9TVFJMSVNULCBzaXplb2YgKEZjU3RyTGlzdCkpOwogICAgZnJlZSAobGlzdCk7Cn0K