LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAibWFpbi5oIgojaW5jbHVkZSAibGFuZ3VhZ2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CgpWT0lEIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKFZPSUQpIHsKCiAgICBpZihHbG9iYWxzLmJBbmFsb2cgPT0gVFJVRSkgewoKICAgICAgICAvKiBhbmFsb2cgY2xvY2sgKi8KCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDAsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMSwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX1VOQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTAzLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfR1JBWUVEKTsKICAgIH0KICAgICAgICBlbHNlCiAgICB7CgogICAgICAgIC8qIGRpZ2l0YWwgY2xvY2sgKi8KCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDAsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9VTkNIRUNLRUQpOwogICAgICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTAxLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTAzLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EKTsKCiAgICB9CgogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDUsIE1GX0JZQ09NTUFORCB8IFwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iV2l0aG91dFRpdGxlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhTeXN0ZW1NZW51LCAweDEwRCwgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJBbHdheXNPblRvcCA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpKTsKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTA3LCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYlNlY29uZHMgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7CiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwOCwgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJEYXRlID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwp9CgpWT0lEIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oVk9JRCkgewoKICBDSEFSIHN6Q2FwdGlvbltNQVhfU1RSSU5HX0xFTl07CiAgQ0hBUiBzekRhdGVbTUFYX1NUUklOR19MRU5dOwoKICBMUFNUUiBkYXRlID0gc3pEYXRlOwoKICBTWVNURU1USU1FIHN0OwogIExQU1lTVEVNVElNRSBscHN0ID0gJnN0OwoKICBHZXRMb2NhbFRpbWUoJnN0KTsKICBHZXREYXRlRm9ybWF0KExPQ0FMRV9VU0VSX0RFRkFVTFQsIExPQ0FMRV9TTE9OR0RBVEUsIGxwc3QsIE5VTEwsIGRhdGUsCiAgICAgICAgICAgICAgICBNQVhfU1RSSU5HX0xFTik7CgogIC8qIFNldCBmcmFtZSBjYXB0aW9uICovCiAgTG9hZFN0cmluZyhHbG9iYWxzLmhJbnN0YW5jZSwgMHgxMEMsIHN6Q2FwdGlvbiwgc2l6ZW9mKHN6Q2FwdGlvbikpOwogIGlmIChHbG9iYWxzLmJEYXRlKSB7CiAgICAgbHN0cmNhdChzekNhcHRpb24sICIgLSAiKTsKICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgc3pEYXRlKTsKICB9CiAgU2V0V2luZG93VGV4dChHbG9iYWxzLmhNYWluV25kLCBzekNhcHRpb24pOwoKfQoKVk9JRCBMQU5HVUFHRV9Mb2FkTWVudXMoVk9JRCkKewoKICBDSEFSICAgc3pJdGVtW01BWF9TVFJJTkdfTEVOXTsKICBITUVOVSAgaE1haW5NZW51OwoKCiAgLyogQ3JlYXRlIG1lbnUgKi8KICBoTWFpbk1lbnUgPSBMb2FkTWVudShHbG9iYWxzLmhJbnN0YW5jZSwgTUFLRUlOVFJFU09VUkNFKE1BSU5fTUVOVSkpOwogICAgR2xvYmFscy5oUHJvcGVydGllc01lbnUgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDApOwogICAgR2xvYmFscy5oTGFuZ3VhZ2VNZW51ICAgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDEpOwogICAgR2xvYmFscy5oSW5mb01lbnUgICAgICAgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDIpOwoKICBTZXRNZW51KEdsb2JhbHMuaE1haW5XbmQsIGhNYWluTWVudSk7CgogIC8qIERlc3Ryb3kgb2xkIG1lbnUgKi8KICBpZiAoR2xvYmFscy5oTWFpbk1lbnUpIERlc3Ryb3lNZW51KEdsb2JhbHMuaE1haW5NZW51KTsKICBHbG9iYWxzLmhNYWluTWVudSA9IGhNYWluTWVudTsKCiAgLyogc3BlY2lmaWMgZm9yIENsb2NrOiAqLwoKICBMQU5HVUFHRV9VcGRhdGVNZW51Q2hlY2ttYXJrcygpOwogIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oKTsKCiAgR2xvYmFscy5oU3lzdGVtTWVudSA9IEdldFN5c3RlbU1lbnUoR2xvYmFscy5oTWFpblduZCwgVFJVRSk7CgogIC8qIEZJWE1FOiBBcHBlbmQgYSBTRVBBUkFUT1IgdG8gR2xvYmFscy5oU3lzdGVtTWVudSBoZXJlICovCgogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIDB4MTBELCBzekl0ZW0sIHNpemVvZihzekl0ZW0pKTsKICBBcHBlbmRNZW51KEdsb2JhbHMuaFN5c3RlbU1lbnUsIE1GX1NUUklORyB8IE1GX0JZQ09NTUFORCwgMTAwMCwgc3pJdGVtKTsKfQoKLyoKVk9JRCBMQU5HVUFHRV9EZWZhdWx0SGFuZGxlKFdQQVJBTSB3UGFyYW0pCnsKICBpZiAoKHdQYXJhbSA+PUNMX0ZJUlNUX0xBTkdVQUdFKSAmJiAod1BhcmFtPD1DTF9MQVNUX0xBTkdVQUdFKSkKICAgICAgICAgIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKHdQYXJhbSAtIENMX0ZJUlNUX0xBTkdVQUdFKTsKICAgICBlbHNlIHByaW50ZigiVW5pbXBsZW1lbnRlZCBtZW51IGNvbW1hbmQgJWlcbiIsIHdQYXJhbSk7Cn0KKi8KCi8qIExvY2FsIFZhcmlhYmxlczogICAgKi8KLyogYy1maWxlLXN0eWxlOiAiR05VIiAqLwovKiBFbmQ6ICAgICAgICAgICAgICAgICovCg==