LyoKICogVkdBIGhhcmR3YXJlIGVtdWxhdGlvbgogKiAKICogQ29weXJpZ2h0IDE5OTggT3ZlIEvldmVuICh3aXRoIHNvbWUgaGVscCBmcm9tIE1hcmN1cyBNZWlzc25lcikKICoKICovCgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlICJ3aW5iYXNlLmgiCiNpbmNsdWRlICJ3aW5jb24uaCIKI2luY2x1ZGUgIm1pc2NlbXUuaCIKI2luY2x1ZGUgInZnYS5oIgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgInNlcnZpY2VzLmgiCiNpbmNsdWRlICJkZWJ1Z3Rvb2xzLmgiCgpERUZBVUxUX0RFQlVHX0NIQU5ORUwoZGRyYXcpCgpzdGF0aWMgSURpcmVjdERyYXcgKmxwZGRyYXcgPSBOVUxMOwpzdGF0aWMgSURpcmVjdERyYXdTdXJmYWNlICpscGRkc3VyZjsKc3RhdGljIElEaXJlY3REcmF3UGFsZXR0ZSAqbHBkZHBhbDsKc3RhdGljIEREU1VSRkFDRURFU0Mgc2Rlc2M7CnN0YXRpYyBMT05HIHZnYV9wb2xsaW5nLHZnYV9yZWZyZXNoOwpzdGF0aWMgSEFORExFIHBvbGxfdGltZXI7CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgKCpwRGlyZWN0RHJhd0NyZWF0ZSkoTFBHVUlELExQRElSRUNURFJBVyAqLExQVU5LTk9XTik7CgpzdGF0aWMgdm9pZCBWR0FfRGVpbnN0YWxsVGltZXIodm9pZCkKewogICAgaWYgKHBvbGxfdGltZXIpIHsKICAgICAgICBTRVJWSUNFX0RlbGV0ZSggcG9sbF90aW1lciApOwogICAgICAgIHBvbGxfdGltZXIgPSAwOwogICAgfQp9CgpzdGF0aWMgdm9pZCBWR0FfSW5zdGFsbFRpbWVyKHVuc2lnbmVkIFJhdGUpCnsKICAgIFZHQV9EZWluc3RhbGxUaW1lcigpOwogICAgaWYgKCFwb2xsX3RpbWVyKQogICAgICAgIHBvbGxfdGltZXIgPSBTRVJWSUNFX0FkZFRpbWVyKCBSYXRlLCBWR0FfUG9sbCwgMCApOwp9CgpIQU5ETEUgVkdBX0FscGhhQ29uc29sZSh2b2lkKQp7CiAgICAvKiB0aGlzIGFzc3VtZXMgdGhhdCBubyBXaW4zMiByZWRpcmVjdGlvbiBoYXMgdGFrZW4gcGxhY2UsIGJ1dCB0aGVuIGFnYWluLAogICAgICogb25seSAxNi1iaXQgYXBwcyBhcmUgbGlrZWx5IHRvIHVzZSB0aGlzIHBhcnQgb2YgV2luZS4uLiAqLwogICAgcmV0dXJuIEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSk7Cn0KCmNoYXIqVkdBX0FscGhhQnVmZmVyKHZvaWQpCnsKICAgIHJldHVybiBET1NNRU1fTWFwRG9zVG9MaW5lYXIoMHhiODAwMCk7Cn0KCi8qKiogR1JBUEhJQ1MgTU9ERSAqKiovCgppbnQgVkdBX1NldE1vZGUodW5zaWduZWQgWHJlcyx1bnNpZ25lZCBZcmVzLHVuc2lnbmVkIERlcHRoKQp7CiAgICBpZiAobHBkZHJhdykgVkdBX0V4aXQoKTsKICAgIGlmICghbHBkZHJhdykgewogICAgICAgIGlmICghcERpcmVjdERyYXdDcmVhdGUpCiAgICAgICAgewogICAgICAgICAgICBITU9EVUxFIGhtb2QgPSBMb2FkTGlicmFyeUEoICJkZHJhdy5kbGwiICk7CiAgICAgICAgICAgIGlmIChobW9kKSBwRGlyZWN0RHJhd0NyZWF0ZSA9IEdldFByb2NBZGRyZXNzKCBobW9kLCAiRGlyZWN0RHJhd0NyZWF0ZSIgKTsKICAgICAgICB9CiAgICAgICAgaWYgKHBEaXJlY3REcmF3Q3JlYXRlKSBwRGlyZWN0RHJhd0NyZWF0ZShOVUxMLCZscGRkcmF3LE5VTEwpOwogICAgICAgIGlmICghbHBkZHJhdykgewogICAgICAgICAgICBFUlIoIkRpcmVjdERyYXcgaXMgbm90IGF2YWlsYWJsZVxuIik7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBpZiAoSURpcmVjdERyYXdfU2V0RGlzcGxheU1vZGUobHBkZHJhdyxYcmVzLFlyZXMsRGVwdGgpKSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0RHJhdyBkb2VzIG5vdCBzdXBwb3J0IHJlcXVlc3RlZCBkaXNwbGF5IG1vZGVcbiIpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBJRGlyZWN0RHJhd19DcmVhdGVQYWxldHRlKGxwZGRyYXcsRERQQ0FQU184QklULE5VTEwsJmxwZGRwYWwsTlVMTCk7CiAgICAgICAgbWVtc2V0KCZzZGVzYywwLHNpemVvZihzZGVzYykpOwogICAgICAgIHNkZXNjLmR3U2l6ZT1zaXplb2Yoc2Rlc2MpOwoJc2Rlc2MuZHdGbGFncyA9IEREU0RfQ0FQUzsKCXNkZXNjLmRkc0NhcHMuZHdDYXBzID0gRERTQ0FQU19QUklNQVJZU1VSRkFDRTsKICAgICAgICBpZiAoSURpcmVjdERyYXdfQ3JlYXRlU3VyZmFjZShscGRkcmF3LCZzZGVzYywmbHBkZHN1cmYsTlVMTCl8fCghbHBkZHN1cmYpKSB7CiAgICAgICAgICAgIEVSUigiRGlyZWN0RHJhdyBzdXJmYWNlIGlzIG5vdCBhdmFpbGFibGVcbiIpOwogICAgICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgICAgICBscGRkcmF3PU5VTEw7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBGSVhNRSgibm8gZGVmYXVsdCBwYWxldHRlIGVudHJpZXNcbiIpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLGxwZGRwYWwpOwogICAgICAgIHZnYV9yZWZyZXNoPTA7CiAgICAgICAgLyogcG9sbCBldmVyeSAyMG1zICg1MGZwcyBzaG91bGQgcHJvdmlkZSBhZGVxdWF0ZSByZXNwb25zaXZlbmVzcykgKi8KICAgICAgICBWR0FfSW5zdGFsbFRpbWVyKDIwKTsKICAgIH0KICAgIHJldHVybiAwOwp9CgppbnQgVkdBX0dldE1vZGUodW5zaWduZWQqSGVpZ2h0LHVuc2lnbmVkKldpZHRoLHVuc2lnbmVkKkRlcHRoKQp7CiAgICBpZiAoIWxwZGRyYXcpIHJldHVybiAxOwogICAgaWYgKCFscGRkc3VyZikgcmV0dXJuIDE7CiAgICBpZiAoSGVpZ2h0KSAqSGVpZ2h0PXNkZXNjLmR3SGVpZ2h0OwogICAgaWYgKFdpZHRoKSAqV2lkdGg9c2Rlc2MuZHdXaWR0aDsKICAgIGlmIChEZXB0aCkgKkRlcHRoPXNkZXNjLmRkcGZQaXhlbEZvcm1hdC51LmR3UkdCQml0Q291bnQ7CiAgICByZXR1cm4gMDsKfQoKdm9pZCBWR0FfRXhpdCh2b2lkKQp7CiAgICBpZiAobHBkZHJhdykgewogICAgICAgIFZHQV9EZWluc3RhbGxUaW1lcigpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9TZXRQYWxldHRlKGxwZGRzdXJmLE5VTEwpOwogICAgICAgIElEaXJlY3REcmF3U3VyZmFjZV9SZWxlYXNlKGxwZGRzdXJmKTsKICAgICAgICBscGRkc3VyZj1OVUxMOwogICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZV9SZWxlYXNlKGxwZGRwYWwpOwogICAgICAgIGxwZGRwYWw9TlVMTDsKICAgICAgICBJRGlyZWN0RHJhd19SZWxlYXNlKGxwZGRyYXcpOwogICAgICAgIGxwZGRyYXc9TlVMTDsKICAgIH0KfQoKdm9pZCBWR0FfU2V0UGFsZXR0ZShQQUxFVFRFRU5UUlkqcGFsLGludCBzdGFydCxpbnQgbGVuKQp7CiAgICBpZiAoIWxwZGRyYXcpIHJldHVybjsKICAgIElEaXJlY3REcmF3UGFsZXR0ZV9TZXRFbnRyaWVzKGxwZGRwYWwsMCxzdGFydCxsZW4scGFsKTsKfQoKdm9pZCBWR0FfU2V0UXVhZFBhbGV0dGUoUkdCUVVBRCpjb2xvcixpbnQgc3RhcnQsaW50IGxlbikKewogICAgUEFMRVRURUVOVFJZIHBhbFsyNTZdOwogICAgaW50IGM7CgogICAgaWYgKCFscGRkcmF3KSByZXR1cm47CiAgICBmb3IgKGM9MDsgYzxsZW47IGMrKykgewogICAgICAgIHBhbFtjXS5wZVJlZCAgPWNvbG9yW2NdLnJnYlJlZDsKICAgICAgICBwYWxbY10ucGVHcmVlbj1jb2xvcltjXS5yZ2JHcmVlbjsKICAgICAgICBwYWxbY10ucGVCbHVlID1jb2xvcltjXS5yZ2JCbHVlOwogICAgICAgIHBhbFtjXS5wZUZsYWdzPTA7CiAgICB9CiAgICBJRGlyZWN0RHJhd1BhbGV0dGVfU2V0RW50cmllcyhscGRkcGFsLDAsc3RhcnQsbGVuLHBhbCk7Cn0KCkxQU1RSIFZHQV9Mb2NrKHVuc2lnbmVkKlBpdGNoLHVuc2lnbmVkKkhlaWdodCx1bnNpZ25lZCpXaWR0aCx1bnNpZ25lZCpEZXB0aCkKewogICAgaWYgKCFscGRkcmF3KSByZXR1cm4gTlVMTDsKICAgIGlmICghbHBkZHN1cmYpIHJldHVybiBOVUxMOwogICAgaWYgKElEaXJlY3REcmF3U3VyZmFjZV9Mb2NrKGxwZGRzdXJmLE5VTEwsJnNkZXNjLDAsMCkpIHsKICAgICAgICBFUlIoImNvdWxkIG5vdCBsb2NrIHN1cmZhY2UhXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIGlmIChQaXRjaCkgKlBpdGNoPXNkZXNjLmxQaXRjaDsKICAgIGlmIChIZWlnaHQpICpIZWlnaHQ9c2Rlc2MuZHdIZWlnaHQ7CiAgICBpZiAoV2lkdGgpICpXaWR0aD1zZGVzYy5kd1dpZHRoOwogICAgaWYgKERlcHRoKSAqRGVwdGg9c2Rlc2MuZGRwZlBpeGVsRm9ybWF0LnUuZHdSR0JCaXRDb3VudDsKICAgIHJldHVybiBzZGVzYy51MS5scFN1cmZhY2U7Cn0KCnZvaWQgVkdBX1VubG9jayh2b2lkKQp7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VfVW5sb2NrKGxwZGRzdXJmLHNkZXNjLnUxLmxwU3VyZmFjZSk7Cn0KCi8qKiogVEVYVCBNT0RFICoqKi8KCmludCBWR0FfU2V0QWxwaGFNb2RlKHVuc2lnbmVkIFhyZXMsdW5zaWduZWQgWXJlcykKewogICAgQ09PUkQgc2l6OwoKICAgIGlmIChscGRkcmF3KSBWR0FfRXhpdCgpOwoKICAgIC8qIHRoZSB4dGVybSBpcyBzbG93LCBzbyByZWZyZXNoIG9ubHkgZXZlcnkgMjAwbXMgKDVmcHMpICovCiAgICBWR0FfSW5zdGFsbFRpbWVyKDIwMCk7CgogICAgc2l6LlggPSBYcmVzOwogICAgc2l6LlkgPSBZcmVzOwogICAgU2V0Q29uc29sZVNjcmVlbkJ1ZmZlclNpemUoVkdBX0FscGhhQ29uc29sZSgpLHNpeik7CiAgICByZXR1cm4gMDsKfQoKdm9pZCBWR0FfR2V0QWxwaGFNb2RlKHVuc2lnbmVkKlhyZXMsdW5zaWduZWQqWXJlcykKewogICAgQ09OU09MRV9TQ1JFRU5fQlVGRkVSX0lORk8gaW5mbzsKICAgIEdldENvbnNvbGVTY3JlZW5CdWZmZXJJbmZvKFZHQV9BbHBoYUNvbnNvbGUoKSwmaW5mbyk7CiAgICBpZiAoWHJlcykgKlhyZXM9aW5mby5kd1NpemUuWDsKICAgIGlmIChZcmVzKSAqWXJlcz1pbmZvLmR3U2l6ZS5ZOwp9Cgp2b2lkIFZHQV9TZXRDdXJzb3JQb3ModW5zaWduZWQgWCx1bnNpZ25lZCBZKQp7CiAgICBDT09SRCBwb3M7CiAgICAKICAgIHBvcy5YID0gWDsKICAgIHBvcy5ZID0gWTsKICAgIFNldENvbnNvbGVDdXJzb3JQb3NpdGlvbihWR0FfQWxwaGFDb25zb2xlKCkscG9zKTsKfQoKdm9pZCBWR0FfR2V0Q3Vyc29yUG9zKHVuc2lnbmVkKlgsdW5zaWduZWQqWSkKewogICAgQ09OU09MRV9TQ1JFRU5fQlVGRkVSX0lORk8gaW5mbzsKICAgIEdldENvbnNvbGVTY3JlZW5CdWZmZXJJbmZvKFZHQV9BbHBoYUNvbnNvbGUoKSwmaW5mbyk7CiAgICBpZiAoWCkgKlg9aW5mby5kd0N1cnNvclBvc2l0aW9uLlg7CiAgICBpZiAoWSkgKlk9aW5mby5kd0N1cnNvclBvc2l0aW9uLlk7Cn0KCnZvaWQgVkdBX1dyaXRlQ2hhcnModW5zaWduZWQgWCx1bnNpZ25lZCBZLHVuc2lnbmVkIGNoLGludCBhdHRyLGludCBjb3VudCkKewogICAgdW5zaWduZWQgWFIsIFlSOwogICAgY2hhcipkYXQ7CgogICAgVkdBX0dldEFscGhhTW9kZSgmWFIsICZZUik7CiAgICBkYXQgPSBWR0FfQWxwaGFCdWZmZXIoKSArICgoWFIqWSArIFgpICogMik7CiAgICAvKiBGSVhNRTogYWxzbyBjYWxsIFdyaXRlQ29uc29sZU91dHB1dEEsIGZvciBiZXR0ZXIgcmVzcG9uc2l2ZW5lc3MgKi8KICAgIHdoaWxlIChjb3VudC0tKSB7CiAgICAgICAgKmRhdCsrID0gY2g7CiAgICAgICAgaWYgKGF0dHI+PTApICpkYXQgPSBhdHRyOwogICAgICAgIGRhdCsrOwogICAgfQp9CgovKioqIENPTlRST0wgKioqLwoKdm9pZCBDQUxMQkFDSyBWR0FfUG9sbCggVUxPTkdfUFRSIGFyZyApCnsKICAgIGNoYXIgKmRhdDsKICAgIHVuc2lnbmVkIFBpdGNoLEhlaWdodCxXaWR0aDsKICAgIGNoYXIgKnN1cmY7CiAgICBpbnQgWSxYOwoKICAgIGlmICghSW50ZXJsb2NrZWRFeGNoYW5nZUFkZCgmdmdhX3BvbGxpbmcsIDEpKSB7CiAgICAgICAgLyogRklYTUU6IG9wdGltaXplIGJ5IGRvaW5nIHRoaXMgb25seSBpZiB0aGUgZGF0YSBoYXMgYWN0dWFsbHkgY2hhbmdlZAogICAgICAgICAqICAgICAgICAoaW4gYSB3YXkgc2ltaWxhciB0byBESUJTZWN0aW9uLCBwZXJoYXBzKSAqLwogICAgICAgIGlmIChscGRkcmF3KSB7CiAgICAgICAgICAvKiBncmFwaGljcyBtb2RlICovCiAgICAgICAgICBzdXJmID0gVkdBX0xvY2soJlBpdGNoLCZIZWlnaHQsJldpZHRoLE5VTEwpOwogICAgICAgICAgaWYgKCFzdXJmKSByZXR1cm47CiAgICAgICAgICBkYXQgPSBET1NNRU1fTWFwRG9zVG9MaW5lYXIoMHhhMDAwMCk7CiAgICAgICAgICAvKiBjb3B5IGZyb20gdmlydHVhbCBWR0EgZnJhbWUgYnVmZmVyIHRvIERpcmVjdERyYXcgc3VyZmFjZSAqLwogICAgICAgICAgZm9yIChZPTA7IFk8SGVpZ2h0OyBZKyssc3VyZis9UGl0Y2gsZGF0Kz1XaWR0aCkgewogICAgICAgICAgICAgIG1lbWNweShzdXJmLGRhdCxXaWR0aCk7CiAgICAgICAgICAgICAgLypmb3IgKFg9MDsgWDxXaWR0aDsgWCsrKSBpZiAoZGF0W1hdKSBUUkFDRShkZHJhdywiZGF0YSglZCkgYXQgKCVkLCVkKVxuIixkYXRbWF0sWCxZKTsqLwogICAgICAgICAgfQogICAgICAgICAgVkdBX1VubG9jaygpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAvKiB0ZXh0IG1vZGUgKi8KICAgICAgICAgIENIQVJfSU5GTyBjaFs4MF07CiAgICAgICAgICBDT09SRCBzaXosIG9mZjsKICAgICAgICAgIFNNQUxMX1JFQ1QgZGVzdDsKICAgICAgICAgIEhBTkRMRSBjb24gPSBWR0FfQWxwaGFDb25zb2xlKCk7CgogICAgICAgICAgVkdBX0dldEFscGhhTW9kZSgmV2lkdGgsJkhlaWdodCk7CiAgICAgICAgICBkYXQgPSBWR0FfQWxwaGFCdWZmZXIoKTsKICAgICAgICAgIHNpei5YID0gODA7IHNpei5ZID0gMTsKICAgICAgICAgIG9mZi5YID0gMDsgb2ZmLlkgPSAwOwogICAgICAgICAgLyogY29weSBmcm9tIHZpcnR1YWwgVkdBIGZyYW1lIGJ1ZmZlciB0byBjb25zb2xlICovCiAgICAgICAgICBmb3IgKFk9MDsgWTxIZWlnaHQ7IFkrKykgewogICAgICAgICAgICAgIGRlc3QuVG9wPVk7IGRlc3QuQm90dG9tPVk7CiAgICAgICAgICAgICAgZm9yIChYPTA7IFg8V2lkdGg7IFgrKykgewogICAgICAgICAgICAgICAgICBjaFtYXS5DaGFyLkFzY2lpQ2hhciA9ICpkYXQrKzsKICAgICAgICAgICAgICAgICAgY2hbWF0uQXR0cmlidXRlcyA9ICpkYXQrKzsKICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgZGVzdC5MZWZ0PTA7IGRlc3QuUmlnaHQ9V2lkdGgrMTsKICAgICAgICAgICAgICBXcml0ZUNvbnNvbGVPdXRwdXRBKGNvbiwgY2gsIHNpeiwgb2ZmLCAmZGVzdCk7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIHZnYV9yZWZyZXNoPTE7CiAgICB9CiAgICBJbnRlcmxvY2tlZERlY3JlbWVudCgmdmdhX3BvbGxpbmcpOwp9CgpzdGF0aWMgQllURSBwYWxyZWcscGFsY250OwpzdGF0aWMgUEFMRVRURUVOVFJZIHBhbGRhdDsKCnZvaWQgVkdBX2lvcG9ydF9vdXQoIFdPUkQgcG9ydCwgQllURSB2YWwgKQp7CiAgICBzd2l0Y2ggKHBvcnQpIHsKICAgICAgICBjYXNlIDB4M2M4OgogICAgICAgICAgICBwYWxyZWc9dmFsOyBwYWxjbnQ9MDsgYnJlYWs7CiAgICAgICAgY2FzZSAweDNjOToKICAgICAgICAgICAgKChCWVRFKikmcGFsZGF0KVtwYWxjbnQrK109dmFsIDw8IDI7CiAgICAgICAgICAgIGlmIChwYWxjbnQ9PTMpIHsKICAgICAgICAgICAgICAgIFZHQV9TZXRQYWxldHRlKCZwYWxkYXQscGFscmVnKyssMSk7CiAgICAgICAgICAgICAgICBwYWxjbnQ9MDsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgIH0KfQoKQllURSBWR0FfaW9wb3J0X2luKCBXT1JEIHBvcnQgKQp7CiAgICBCWVRFIHJldDsKCiAgICBzd2l0Y2ggKHBvcnQpIHsKICAgICAgICBjYXNlIDB4M2RhOgogICAgICAgICAgICAvKiBzaW5jZSB3ZSBkb24ndCAoeWV0Pykgc2VydmUgRE9TIFZNIHJlcXVlc3RzIHdoaWxlIFZHQV9Qb2xsIGlzIHJ1bm5pbmcsCiAgICAgICAgICAgICAgIHdlIG5lZWQgdG8gZmFrZSB0aGUgb2NjdXJyZW5jZSBvZiB0aGUgdmVydGljYWwgcmVmcmVzaCAqLwogICAgICAgICAgICByZXQ9dmdhX3JlZnJlc2g/MHgwMDoweDA4OwogICAgICAgICAgICB2Z2FfcmVmcmVzaD0wOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICByZXQ9MHhmZjsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCnZvaWQgVkdBX0NsZWFuKHZvaWQpCnsKICAgIFZHQV9FeGl0KCk7CiAgICBWR0FfRGVpbnN0YWxsVGltZXIoKTsKfQo=