LyoKICogVkdBIGhhcmR3YXJlIGVtdWxhdGlvbgogKiAKICogQ29weXJpZ2h0IDE5OTggT3ZlIEvldmVuICh3aXRoIHNvbWUgaGVscCBmcm9tIE1hcmN1cyBNZWlzc25lcikKICoKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW51c2VyLmgiCiNpbmNsdWRlICJ3aW5lL3dpbnVzZXIxNi5oIgojaW5jbHVkZSAibWlzY2VtdS5oIgojaW5jbHVkZSAidmdhLmgiCiNpbmNsdWRlICJkZHJhdy5oIgojaW5jbHVkZSAiZGVidWd0b29scy5oIgoKREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KQoKc3RhdGljIElEaXJlY3REcmF3ICpscGRkcmF3ID0gTlVMTDsKc3RhdGljIElEaXJlY3REcmF3U3VyZmFjZSAqbHBkZHN1cmY7CnN0YXRpYyBJRGlyZWN0RHJhd1BhbGV0dGUgKmxwZGRwYWw7CnN0YXRpYyBERFNVUkZBQ0VERVNDIHNkZXNjOwpzdGF0aWMgV09SRCBwb2xsX3RpbWVyOwpzdGF0aWMgQ1JJVElDQUxfU0VDVElPTiB2Z2FfY3JpdDsKc3RhdGljIGludCB2Z2FfcG9sbGluZyx2Z2FfcmVmcmVzaDsKCmludCBWR0FfU2V0TW9kZSh1bnNpZ25lZCBYcmVzLHVuc2lnbmVkIFlyZXMsdW5zaWduZWQgRGVwdGgpCnsKICAgIGlmIChscGRkcmF3KSBWR0FfRXhpdCgpOwogICAgaWYgKCFscGRkcmF3KSB7CiAgICAgICAgRGlyZWN0RHJhd0NyZWF0ZShOVUxMLCZscGRkcmF3LE5VTEwpOwogICAgICAgIGlmICghbHBkZHJhdykgewogICAgICAgICAgICBFUlIoIkRpcmVjdERyYXcgaXMgbm90IGF2YWlsYWJsZVxuIik7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBpZiAoSURpcmVjdERyYXdfU2V0RGlzcGxheU1vZGUobHBkZHJhdyxYcmVzLFlyZXMsRGVwdGgpKSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0RHJhdyBkb2VzIG5vdCBzdXBwb3J0IHJlcXVlc3RlZCBkaXNwbGF5IG1vZGVcbiIpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBJRGlyZWN0RHJhd19DcmVhdGVQYWxldHRlKGxwZGRyYXcsRERQQ0FQU184QklULE5VTEwsJmxwZGRwYWwsTlVMTCk7CiAgICAgICAgbWVtc2V0KCZzZGVzYywwLHNpemVvZihzZGVzYykpOwogICAgICAgIHNkZXNjLmR3U2l6ZT1zaXplb2Yoc2Rlc2MpOwoJc2Rlc2MuZHdGbGFncyA9IEREU0RfQ0FQUzsKCXNkZXNjLmRkc0NhcHMuZHdDYXBzID0gRERTQ0FQU19QUklNQVJZU1VSRkFDRTsKICAgICAgICBpZiAoSURpcmVjdERyYXdfQ3JlYXRlU3VyZmFjZShscGRkcmF3LCZzZGVzYywmbHBkZHN1cmYsTlVMTCl8fCghbHBkZHN1cmYpKSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0RHJhdyBzdXJmYWNlIGlzIG5vdCBhdmFpbGFibGVcbiIpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICB2Z2FfcmVmcmVzaD0wOwogICAgICAgIEluaXRpYWxpemVDcml0aWNhbFNlY3Rpb24oJnZnYV9jcml0KTsKICAgICAgICBNYWtlQ3JpdGljYWxTZWN0aW9uR2xvYmFsKCZ2Z2FfY3JpdCk7CiAgICAgICAgLyogcG9sbCBldmVyeSAyMG1zICg1MGZwcyBzaG91bGQgcHJvdmlkZSBhZGVxdWF0ZSByZXNwb25zaXZlbmVzcykgKi8KICAgICAgICBwb2xsX3RpbWVyID0gQ3JlYXRlU3lzdGVtVGltZXIoIDIwLCBWR0FfUG9sbCApOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCmludCBWR0FfR2V0TW9kZSh1bnNpZ25lZCpIZWlnaHQsdW5zaWduZWQqV2lkdGgsdW5zaWduZWQqRGVwdGgpCnsKICAgIGlmICghbHBkZHJhdykgcmV0dXJuIDE7CiAgICBpZiAoIWxwZGRzdXJmKSByZXR1cm4gMTsKICAgIGlmIChIZWlnaHQpICpIZWlnaHQ9c2Rlc2MuZHdIZWlnaHQ7CiAgICBpZiAoV2lkdGgpICpXaWR0aD1zZGVzYy5kd1dpZHRoOwogICAgaWYgKERlcHRoKSAqRGVwdGg9c2Rlc2MuZGRwZlBpeGVsRm9ybWF0LnUuZHdSR0JCaXRDb3VudDsKICAgIHJldHVybiAwOwp9Cgp2b2lkIFZHQV9FeGl0KHZvaWQpCnsKICAgIGlmIChscGRkcmF3KSB7CiAgICAgICAgU1lTVEVNX0tpbGxTeXN0ZW1UaW1lcihwb2xsX3RpbWVyKTsKICAgICAgICBEZWxldGVDcml0aWNhbFNlY3Rpb24oJnZnYV9jcml0KTsKICAgICAgICBJRGlyZWN0RHJhd1N1cmZhY2VfUmVsZWFzZShscGRkc3VyZik7CiAgICAgICAgbHBkZHN1cmY9TlVMTDsKICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgIGxwZGRyYXc9TlVMTDsKICAgIH0KfQoKdm9pZCBWR0FfU2V0UGFsZXR0ZShQQUxFVFRFRU5UUlkqcGFsLGludCBzdGFydCxpbnQgbGVuKQp7CiAgICBpZiAoIWxwZGRyYXcpIHJldHVybjsKICAgIElEaXJlY3REcmF3UGFsZXR0ZV9TZXRFbnRyaWVzKGxwZGRwYWwsMCxzdGFydCxsZW4scGFsKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLGxwZGRwYWwpOwp9Cgp2b2lkIFZHQV9TZXRRdWFkUGFsZXR0ZShSR0JRVUFEKmNvbG9yLGludCBzdGFydCxpbnQgbGVuKQp7CiAgICBQQUxFVFRFRU5UUlkgcGFsWzI1Nl07CiAgICBpbnQgYzsKCiAgICBpZiAoIWxwZGRyYXcpIHJldHVybjsKICAgIGZvciAoYz0wOyBjPGxlbjsgYysrKSB7CiAgICAgICAgcGFsW2NdLnBlUmVkICA9Y29sb3JbY10ucmdiUmVkOwogICAgICAgIHBhbFtjXS5wZUdyZWVuPWNvbG9yW2NdLnJnYkdyZWVuOwogICAgICAgIHBhbFtjXS5wZUJsdWUgPWNvbG9yW2NdLnJnYkJsdWU7CiAgICAgICAgcGFsW2NdLnBlRmxhZ3M9MDsKICAgIH0KICAgIElEaXJlY3REcmF3UGFsZXR0ZV9TZXRFbnRyaWVzKGxwZGRwYWwsMCxzdGFydCxsZW4scGFsKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLGxwZGRwYWwpOwp9CgpMUFNUUiBWR0FfTG9jayh1bnNpZ25lZCpQaXRjaCx1bnNpZ25lZCpIZWlnaHQsdW5zaWduZWQqV2lkdGgsdW5zaWduZWQqRGVwdGgpCnsKICAgIGlmICghbHBkZHJhdykgcmV0dXJuIE5VTEw7CiAgICBpZiAoIWxwZGRzdXJmKSByZXR1cm4gTlVMTDsKICAgIGlmIChJRGlyZWN0RHJhd1N1cmZhY2VfTG9jayhscGRkc3VyZixOVUxMLCZzZGVzYywwLDApKSB7CiAgICAgICAgRVJSKCJjb3VsZCBub3QgbG9jayBzdXJmYWNlIVxuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBpZiAoUGl0Y2gpICpQaXRjaD1zZGVzYy5sUGl0Y2g7CiAgICBpZiAoSGVpZ2h0KSAqSGVpZ2h0PXNkZXNjLmR3SGVpZ2h0OwogICAgaWYgKFdpZHRoKSAqV2lkdGg9c2Rlc2MuZHdXaWR0aDsKICAgIGlmIChEZXB0aCkgKkRlcHRoPXNkZXNjLmRkcGZQaXhlbEZvcm1hdC51LmR3UkdCQml0Q291bnQ7CiAgICByZXR1cm4gc2Rlc2MudTEubHBTdXJmYWNlOwp9Cgp2b2lkIFZHQV9VbmxvY2sodm9pZCkKewogICAgSURpcmVjdERyYXdTdXJmYWNlX1VubG9jayhscGRkc3VyZixzZGVzYy51MS5scFN1cmZhY2UpOwp9CgovKiBXZSBhcmUgY2FsbGVkIGZyb20gU0lHQUxSTSwgYXJlbid0IHdlPyBXZSBzaG91bGQgX05PVF8gZG8gc3luY2hyb25pemF0aW9uCiAqIHN0dWZmIQogKi8Kdm9pZCBWR0FfUG9sbCggV09SRCB0aW1lciApCnsKICAgIGNoYXIgKmRhdDsKICAgIHVuc2lnbmVkIFBpdGNoLEhlaWdodCxXaWR0aDsKICAgIGNoYXIgKnN1cmY7CiAgICBpbnQgWTsKICAgIC8qIGludCBYOyAqLwoKICAgIEVudGVyQ3JpdGljYWxTZWN0aW9uKCZ2Z2FfY3JpdCk7CiAgICBpZiAoIXZnYV9wb2xsaW5nKSB7CiAgICAgICAgdmdhX3BvbGxpbmcrKzsKICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2NyaXQpOwogICAgICAgIC8qIEZJWE1FOiBvcHRpbWl6ZSBieSBkb2luZyB0aGlzIG9ubHkgaWYgdGhlIGRhdGEgaGFzIGFjdHVhbGx5IGNoYW5nZWQKICAgICAgICAgKiAgICAgICAgKGluIGEgd2F5IHNpbWlsYXIgdG8gRElCU2VjdGlvbiwgcGVyaGFwcykgKi8KICAgICAgICBzdXJmID0gVkdBX0xvY2soJlBpdGNoLCZIZWlnaHQsJldpZHRoLE5VTEwpOwogICAgICAgIGlmICghc3VyZikgcmV0dXJuOwogICAgICAgIGRhdCA9IERPU01FTV9NYXBEb3NUb0xpbmVhcigweGEwMDAwKTsKICAgICAgICAvKiBjb3B5IGZyb20gdmlydHVhbCBWR0EgZnJhbWUgYnVmZmVyIHRvIERpcmVjdERyYXcgc3VyZmFjZSAqLwogICAgICAgIGZvciAoWT0wOyBZPEhlaWdodDsgWSsrLHN1cmYrPVBpdGNoLGRhdCs9V2lkdGgpIHsKICAgICAgICAgICAgbWVtY3B5KHN1cmYsZGF0LFdpZHRoKTsKICAgICAgICAgICAgLypmb3IgKFg9MDsgWDxXaWR0aDsgWCsrKSBpZiAoZGF0W1hdKSBUUkFDRShkZHJhdywiZGF0YSglZCkgYXQgKCVkLCVkKVxuIixkYXRbWF0sWCxZKTsqLwogICAgICAgIH0KICAgICAgICBWR0FfVW5sb2NrKCk7CiAgICAgICAgdmdhX3JlZnJlc2g9MTsKICAgICAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmdmdhX2NyaXQpOwogICAgICAgIHZnYV9wb2xsaW5nLS07CiAgICB9CiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmdmdhX2NyaXQpOwp9CgpzdGF0aWMgQllURSBwYWxyZWcscGFsY250OwpzdGF0aWMgUEFMRVRURUVOVFJZIHBhbGRhdDsKCnZvaWQgVkdBX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwgKQp7CiAgICBzd2l0Y2ggKHBvcnQpIHsKICAgICAgICBjYXNlIDB4M2M4OgogICAgICAgICAgICBwYWxyZWc9dmFsOyBwYWxjbnQ9MDsgYnJlYWs7CiAgICAgICAgY2FzZSAweDNjOToKICAgICAgICAgICAgKChCWVRFKikmcGFsZGF0KVtwYWxjbnQrK109dmFsIDw8IDI7CiAgICAgICAgICAgIGlmIChwYWxjbnQ9PTMpIHsKICAgICAgICAgICAgICAgIFZHQV9TZXRQYWxldHRlKCZwYWxkYXQscGFscmVnKyssMSk7CiAgICAgICAgICAgICAgICBwYWxjbnQ9MDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKQllURSBWR0FfaW9wb3J0X2luKCBXT1JEIHBvcnQgKQp7CiAgICBCWVRFIHJldDsKCiAgICBzd2l0Y2ggKHBvcnQpIHsKICAgICAgICBjYXNlIDB4M2RhOgogICAgICAgICAgICAvKiBzaW5jZSB3ZSBkb24ndCAoeWV0Pykgc2VydmUgRE9TIFZNIHJlcXVlc3RzIHdoaWxlIFZHQV9Qb2xsIGlzIHJ1bm5pbmcsCiAgICAgICAgICAgICAgIHdlIG5lZWQgdG8gZmFrZSB0aGUgb2NjdXJyZW5jZSBvZiB0aGUgdmVydGljYWwgcmVmcmVzaCAqLwogICAgICAgICAgICBpZiAobHBkZHJhdykgewogICAgICAgICAgICAgICAgcmV0PXZnYV9yZWZyZXNoPzB4MDA6MHgwODsKICAgICAgICAgICAgICAgIHZnYV9yZWZyZXNoPTA7CiAgICAgICAgICAgIH0gZWxzZSByZXQ9MHgwODsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgcmV0PTB4ZmY7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9Cg==