LyoKICogQ29weXJpZ2h0IChDKSAyMDA3LTIwMDggQVJNIExpbWl0ZWQKICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wCiAqCiAqIFVubGVzcyByZXF1aXJlZCBieSBhcHBsaWNhYmxlIGxhdyBvciBhZ3JlZWQgdG8gaW4gd3JpdGluZywgc29mdHdhcmUKICogZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIExpY2Vuc2UgaXMgZGlzdHJpYnV0ZWQgb24gYW4gIkFTIElTIiBCQVNJUywKICogV0lUSE9VVCBXQVJSQU5USUVTIE9SIENPTkRJVElPTlMgT0YgQU5ZIEtJTkQsIGVpdGhlciBleHByZXNzIG9yIGltcGxpZWQuCiAqIFNlZSB0aGUgTGljZW5zZSBmb3IgdGhlIHNwZWNpZmljIGxhbmd1YWdlIGdvdmVybmluZyBwZXJtaXNzaW9ucyBhbmQKICogbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuCiAqCiAqLwovKioKICogCiAqIEZpbGUgTmFtZTogIGFybVZDTTRQMl9CbG9ja01hdGNoX0hhbGYuYwogKiBPcGVuTUFYIERMOiB2MS4wLjIKICogUmV2aXNpb246ICAgOTY0MQogKiBEYXRlOiAgICAgICBUaHVyc2RheSwgRmVicnVhcnkgNywgMjAwOAogKiAKICogCiAqIAogKiAKICogRGVzY3JpcHRpb246CiAqIENvbnRhaW5zIG1vZHVsZXMgZm9yIEJsb2NrIG1hdGNoaW5nLCBhIGZ1bGwgc2VhcmNoIGFsZ29yaXRobQogKiBpcyBpbXBsZW1lbnRlZAogKgogKi8KCiNpbmNsdWRlICJvbXh0eXBlcy5oIgojaW5jbHVkZSAiYXJtT01YLmgiCiNpbmNsdWRlICJvbXhWQy5oIgoKI2luY2x1ZGUgImFybVZDLmgiCiNpbmNsdWRlICJhcm1DT01NLmgiCgovKioKICogRnVuY3Rpb246IGFybVZDTTRQMl9CbG9ja01hdGNoX0hhbGYKICoKICogRGVzY3JpcHRpb246CiAqIFBlcmZvcm1zIGEgMTZ4MTYgYmxvY2sgbWF0Y2ggd2l0aCBoYWxmLXBpeGVsIHJlc29sdXRpb24uICBSZXR1cm5zIHRoZSBlc3RpbWF0ZWQgCiAqIG1vdGlvbiB2ZWN0b3IgYW5kIGFzc29jaWF0ZWQgbWluaW11bSBTQUQuICBUaGlzIGZ1bmN0aW9uIGVzdGltYXRlcyB0aGUgaGFsZi1waXhlbCAKICogbW90aW9uIHZlY3RvciBieSBpbnRlcnBvbGF0aW5nIHRoZSBpbnRlZ2VyIHJlc29sdXRpb24gbW90aW9uIHZlY3RvciByZWZlcmVuY2VkIAogKiBieSB0aGUgaW5wdXQgcGFyYW1ldGVyIHBTcmNEc3RNViwgaS5lLiwgdGhlIGluaXRpYWwgaW50ZWdlciBNViBpcyBnZW5lcmF0ZWQgCiAqIGV4dGVybmFsbHkuICBUaGUgaW5wdXQgcGFyYW1ldGVycyBwU3JjUmVmQnVmIGFuZCBwU2VhcmNoUG9pbnRSZWZQb3Mgc2hvdWxkIGJlIAogKiBzaGlmdGVkIGJ5IHRoZSB3aW5uaW5nIE1WIG9mIDE2eDE2IGludGVnZXIgc2VhcmNoIHByaW9yIHRvIGNhbGxpbmcgQmxvY2tNYXRjaF9IYWxmXzE2eDE2LiAgCiAqIFRoZSBmdW5jdGlvbiBCbG9ja01hdGNoX0ludGVnZXJfMTZ4MTYgbWF5IGJlIHVzZWQgZm9yIGludGVnZXIgbW90aW9uIGVzdGltYXRpb24uCiAqCiAqIFJlbWFya3M6CiAqCiAqIFBhcmFtZXRlcnM6CiAqIFtpbl0JcFNyY1JlZkJ1ZgkJcG9pbnRlciB0byB0aGUgcmVmZXJlbmNlIFkgcGxhbmU7IHBvaW50cyB0byB0aGUgcmVmZXJlbmNlIE1CIAogKiAgICAgICAgICAgICAgICAgICAgdGhhdCBjb3JyZXNwb25kcyB0byB0aGUgbG9jYXRpb24gb2YgdGhlIGN1cnJlbnQgbWFjcm9ibG9jayBpbiAKICogICAgICAgICAgICAgICAgICAgIHRoZQljdXJyZW50IHBsYW5lLgogKiBbaW5dCXJlZldpZHRoCQkgIHdpZHRoIG9mIHRoZSByZWZlcmVuY2UgcGxhbmUKICogW2luXQlwUmVmUmVjdAkJICByZWZlcmVuY2UgcGxhbmUgdmFsaWQgcmVnaW9uIHJlY3RhbmdsZQogKiBbaW5dCXBTcmNDdXJyQnVmCQlwb2ludGVyIHRvIHRoZSBjdXJyZW50IG1hY3JvYmxvY2sgZXh0cmFjdGVkIGZyb20gb3JpZ2luYWwgcGxhbmUgCiAqICAgICAgICAgICAgICAgICAgICAobGluZWFyIGFycmF5LCAyNTYgZW50cmllcyk7IG11c3QgYmUgYWxpZ25lZCBvbiBhbiA4LWJ5dGUgYm91bmRhcnkuIAogKiBbaW5dCXBTZWFyY2hQb2ludFJlZlBvcwlwb3NpdGlvbiBvZiB0aGUgc3RhcnRpbmcgcG9pbnQgZm9yIGhhbGYgcGl4ZWwgc2VhcmNoIChzcGVjaWZpZWQgCiAqICAgICAgICAgICAgICAgICAgICAgICAgICBpbiB0ZXJtcyBvZiBpbnRlZ2VyIHBpeGVsIHVuaXRzKSBpbiB0aGUgcmVmZXJlbmNlIHBsYW5lLgogKiBbaW5dCXJuZFZhbAkJCSAgcm91bmRpbmcgY29udHJvbCBiaXQgZm9yIGhhbGYgcGl4ZWwgbW90aW9uIGVzdGltYXRpb247IAogKiAgICAgICAgICAgICAgICAgICAgMD1yb3VuZGluZyBjb250cm9sIGRpc2FibGVkOyAxPXJvdW5kaW5nIGNvbnRyb2wgZW5hYmxlZAogKiBbaW5dCXBTcmNEc3RNVgkJcG9pbnRlciB0byB0aGUgaW5pdGlhbCBNViBlc3RpbWF0ZTsgdHlwaWNhbGx5IGdlbmVyYXRlZCBkdXJpbmcgYSBwcmlvciAKICogICAgICAgICAgICAgICAgICAxNlgxNiBpbnRlZ2VyIHNlYXJjaCBhbmQgaXRzIHVuaXQgaXMgaGFsZiBwaXhlbC4KICogW2luXSBCbG9ja1NpemUgICAgIE1hY3JvQmxvY2sgU2l6ZSBpLmUgZWl0aGVyIDE2eDE2IG9yIDh4OC4KICogW291dF1wU3JjRHN0TVYJCXBvaW50ZXIgdG8gZXN0aW1hdGVkIE1WCiAqIFtvdXRdcERzdFNBRAkJCXBvaW50ZXIgdG8gbWluaW11bSBTQUQKICoKICogUmV0dXJuIFZhbHVlOgogKiBPTVhfU3RzX05vRXJyIKhDIG5vIGVycm9yCiAqIE9NWF9TdHNfQmFkQXJnRXJyIKhDIGJhZCBhcmd1bWVudHMKICoKICovCgpPTVhSZXN1bHQgYXJtVkNNNFAyX0Jsb2NrTWF0Y2hfSGFsZigKICAgICBjb25zdCBPTVhfVTggKnBTcmNSZWZCdWYsCiAgICAgT01YX0lOVCByZWZXaWR0aCwKICAgICBjb25zdCBPTVhSZWN0ICpwUmVmUmVjdCwKICAgICBjb25zdCBPTVhfVTggKnBTcmNDdXJyQnVmLAogICAgIGNvbnN0IE9NWFZDTTRQMkNvb3JkaW5hdGUgKnBTZWFyY2hQb2ludFJlZlBvcywKICAgICBPTVhfSU5UIHJuZFZhbCwKICAgICBPTVhWQ01vdGlvblZlY3RvciAqcFNyY0RzdE1WLAogICAgIE9NWF9JTlQgKnBEc3RTQUQsCiAgICAgT01YX1U4IEJsb2NrU2l6ZQopCnsKICAgIE9NWF9JTlQgICAgIG91dGVyLCBpbm5lciwgY291bnQsIGluZGV4OwogICAgT01YX1MxNiAgICAgaGFsZlBlbFggPSAwLCBoYWxmUGVsWSA9IDAsIHgsIHk7CiAgICBPTVhfSU5UICAgICBjYW5kU0FELCByZWZTQUQgPSAwOwogICAgT01YX0lOVCAgICAgbWluU0FELCBmcm9tWCwgdG9YLCBmcm9tWSwgdG9ZOwogICAgLyogT2Zmc2V0IHRvIHRoZSByZWZlcmVuY2UgYXQgdGhlIGJlZ2luaW5nIG9mIHRoZSBib3VuZGluZyBib3ggKi8KICAgIGNvbnN0IE9NWF9VOCAgICAgICpwVGVtcFNyY1JlZkJ1ZjsKICAgIE9NWF9VOCB0ZW1wUGVsOwogICAgICAgIAogICAgLyogQXJndW1lbnQgZXJyb3IgY2hlY2tzICovCiAgICBhcm1SZXRBcmdFcnJJZihwU3JjUmVmQnVmID09IE5VTEwsIE9NWF9TdHNfQmFkQXJnRXJyKTsKICAgIGFybVJldEFyZ0VycklmKHBSZWZSZWN0ID09IE5VTEwsIE9NWF9TdHNfQmFkQXJnRXJyKTsKICAgIGFybVJldEFyZ0VycklmKHBTcmNDdXJyQnVmID09IE5VTEwsIE9NWF9TdHNfQmFkQXJnRXJyKTsKICAgIGFybVJldEFyZ0VycklmKHBTZWFyY2hQb2ludFJlZlBvcyA9PSBOVUxMLCBPTVhfU3RzX0JhZEFyZ0Vycik7CiAgICBhcm1SZXRBcmdFcnJJZihwU3JjRHN0TVYgPT0gTlVMTCwgT01YX1N0c19CYWRBcmdFcnIpOwogICAgYXJtUmV0QXJnRXJySWYocERzdFNBRCA9PSBOVUxMLCBPTVhfU3RzX0JhZEFyZ0Vycik7CgogICAgLyogUG9zaXRpb25pbmcgdGhlIHBvaW50ZXIgKi8KICAgIHBUZW1wU3JjUmVmQnVmID0gcFNyY1JlZkJ1ZiArIChyZWZXaWR0aCAqIChwU3JjRHN0TVYtPmR5LzIpKSArIChwU3JjRHN0TVYtPmR4LzIpOwoKICAgIC8qIENvcHkgdGhlIGNhbmRpZGF0ZSB0byB0aGUgdGVtcG9yYXJ5IGxpbmVhciBhcnJheSAqLwogICAgZm9yIChvdXRlciA9IDAsIGNvdW50ID0gMCxpbmRleCA9IDA7CiAgICAgICAgIG91dGVyIDwgQmxvY2tTaXplOwogICAgICAgICBvdXRlcisrLCBpbmRleCArPSByZWZXaWR0aCAtIEJsb2NrU2l6ZSkKICAgIHsKICAgICAgICBmb3IgKGlubmVyID0gMDsgaW5uZXIgPCBCbG9ja1NpemU7IGlubmVyKyssIGNvdW50KyssIGluZGV4KyspCiAgICAgICAgewogICAgICAgICAgICByZWZTQUQgKz0gYXJtQWJzIChwVGVtcFNyY1JlZkJ1ZltpbmRleF0gLSBwU3JjQ3VyckJ1Zltjb3VudF0pOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBTZXQgdGhlIG1pblNhZCBhcyByZWZlcmVuY2UgU0FEICovCiAgICBtaW5TQUQgPSByZWZTQUQ7CiAgICAqcERzdFNBRCA9IHJlZlNBRDsKCiAgICAvKiBDaGVjayBmb3IgdmFsaWQgcmVnaW9uICovCiAgICBmcm9tWCA9IDE7CiAgICB0b1ggICA9IDE7CiAgICBmcm9tWSA9IDE7CiAgICB0b1kgICA9IDE7CiAgICBpZiAoKHBTZWFyY2hQb2ludFJlZlBvcy0+eCAtIDEpIDwgcFJlZlJlY3QtPngpCiAgICB7CiAgICAgICAgZnJvbVggPSAwOwogICAgfQoKICAgIGlmICgocFNlYXJjaFBvaW50UmVmUG9zLT54ICsgQmxvY2tTaXplICsgMSkgPiAocFJlZlJlY3QtPnggKyBwUmVmUmVjdC0+d2lkdGgpKQogICAgewogICAgICAgIHRvWCAgID0gMDsKICAgIH0KCiAgICBpZiAoKHBTZWFyY2hQb2ludFJlZlBvcy0+eSAtIDEpIDwgcFJlZlJlY3QtPnkpCiAgICB7CiAgICAgICAgZnJvbVkgPSAwOwogICAgfQoKICAgIGlmICgocFNlYXJjaFBvaW50UmVmUG9zLT55ICsgQmxvY2tTaXplICsgMSkgPiAocFJlZlJlY3QtPnkgKyBwUmVmUmVjdC0+aGVpZ2h0KSkKICAgIHsKICAgICAgICB0b1kgICA9IDA7CiAgICB9CgogICAgLyogTG9vcGluZyBvbiB5LSBheGlzICovCiAgICBmb3IgKHkgPSAtZnJvbVk7IHkgPD0gdG9ZOyB5KyspCiAgICB7CiAgICAgICAgLyogTG9vcGluZyBvbiB4LSBheGlzICovCiAgICAgICAgZm9yICh4ID0gLWZyb21YOyB4IDw9IHRvWDsgeCsrKQogICAgICAgIHsKICAgICAgICAgICAgLyogY2hlY2sgZm9yIGludGVnZXIgcG9zaXRpb24gKi8KICAgICAgICAgICAgaWYgKCB4ID09IDAgJiYgeSA9PSAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBQb3NpdGlvbmluZyB0aGUgcG9pbnRlciAqLwogICAgICAgICAgICBwVGVtcFNyY1JlZkJ1ZiA9IHBTcmNSZWZCdWYgKyAocmVmV2lkdGggKiAocFNyY0RzdE1WLT5keS8yKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIChwU3JjRHN0TVYtPmR4LzIpOwoKICAgICAgICAgICAgLyogSW50ZXJwb2xhdGUgdGhlIHBpeGVsIGFuZCBjYWxjdWxhdGUgdGhlIFNBRCovCiAgICAgICAgICAgIGZvciAob3V0ZXIgPSAwLCBjb3VudCA9IDAsIGNhbmRTQUQgPSAwLGluZGV4ID0gMDsKICAgICAgICAgICAgICAgICBvdXRlciA8IEJsb2NrU2l6ZTsKICAgICAgICAgICAgICAgICBvdXRlcisrLCBpbmRleCArPSByZWZXaWR0aCAtIEJsb2NrU2l6ZSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZm9yIChpbm5lciA9IDA7IGlubmVyIDwgQmxvY2tTaXplOyBpbm5lcisrLCBjb3VudCsrLGluZGV4KyspCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdGVtcFBlbCA9ICgKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwVGVtcFNyY1JlZkJ1ZltpbmRleF0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHBUZW1wU3JjUmVmQnVmW2luZGV4ICsgeF0gKiBhcm1BYnMoeCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICArIHBUZW1wU3JjUmVmQnVmW2luZGV4ICsgcmVmV2lkdGggKiB5XSAqIGFybUFicyh5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgcFRlbXBTcmNSZWZCdWZbaW5kZXggKyByZWZXaWR0aCAqIHkgKyB4XQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBhcm1BYnMoeCp5KQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgYXJtQWJzICh4KSArIGFybUFicyAoeSkgLSBybmRWYWwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAvICgyICogKGFybUFicyAoeCkgKyBhcm1BYnMgKHkpKSk7CiAgICAgICAgICAgICAgICAgICAgY2FuZFNBRCArPSBhcm1BYnMgKHRlbXBQZWwgLSBwU3JjQ3VyckJ1Zltjb3VudF0pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiBSZXN1bHQgY2FsY3VsYXRpb25zICovCiAgICAgICAgICAgIGlmIChhcm1WQ000UDJfQ29tcGFyZU1WICh4LCB5LCBjYW5kU0FELCBoYWxmUGVsWCwgaGFsZlBlbFksIG1pblNBRCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpwRHN0U0FEID0gY2FuZFNBRDsKICAgICAgICAgICAgICAgIG1pblNBRCAgID0gY2FuZFNBRDsKICAgICAgICAgICAgICAgIGhhbGZQZWxYID0geDsKICAgICAgICAgICAgICAgIGhhbGZQZWxZID0geTsKICAgICAgICAgICAgfQoKICAgICAgICB9IC8qIEVuZCBvZiB4LSBheGlzICovCiAgICB9IC8qIEVuZCBvZiB5LWF4aXMgKi8KCiAgICBwU3JjRHN0TVYtPmR4ICs9IGhhbGZQZWxYOwogICAgcFNyY0RzdE1WLT5keSArPSBoYWxmUGVsWTsKCiAgICByZXR1cm4gT01YX1N0c19Ob0VycjsKCn0KCi8qIEVuZCBvZiBmaWxlICovCg==