LyoKICogQ2xvY2sKICoKICogQ29weXJpZ2h0IDE5OTggTWFyY2VsIEJhdXIgPG1iYXVyQGcyNi5ldGh6LmNoPgogKiBDb3B5cmlnaHQgMTk5OCBLYXJsIEJhY2tzdHL2bSA8a2FybF9iQGdlb2NpdGllcy5jb20+CiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSAid2luZG93cy5oIgojaW5jbHVkZSAibWFpbi5oIgojaW5jbHVkZSAibGFuZ3VhZ2UuaCIKI2luY2x1ZGUgIndpbm5scy5oIgoKQ0hBUiBTVFJJTkdfTUVOVV9YeFtdICAgICAgPSAiTUVOVV9YeCI7CgpWT0lEIExBTkdVQUdFX1VwZGF0ZU1lbnVDaGVja21hcmtzKFZPSUQpIHsKCiAgICBpZihHbG9iYWxzLmJBbmFsb2cgPT0gVFJVRSkgewogICAgCiAgICAgICAgLyogYW5hbG9nIGNsb2NrICovCiAgICAgICAgCiAgICAgICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDAsIFwKICAgICAgICAgICAgICAgICAgICAgICBNRl9CWUNPTU1BTkQgfCBNRl9DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMSwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX1VOQ0hFQ0tFRCk7CiAgICAgICAgRW5hYmxlTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTAzLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfR1JBWUVEKTsKICAgIH0KICAgICAgICBlbHNlIAogICAgewogICAgCiAgICAgICAgLyogZGlnaXRhbCBjbG9jayAqLwogICAgICAgIAogICAgICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTAwLCBcCiAgICAgICAgICAgICAgICAgICAgICAgTUZfQllDT01NQU5EIHwgTUZfVU5DSEVDS0VEKTsKICAgICAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMSwgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCB8IE1GX0NIRUNLRUQpOwogICAgICAgIEVuYWJsZU1lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwMywgXAogICAgICAgICAgICAgICAgICAgICAgIE1GX0JZQ09NTUFORCk7CiAgICAgICAgICAgICAgICAgICAgICAgCiAgICB9CiAgICAKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oUHJvcGVydGllc01lbnUsIDB4MTA1LCBNRl9CWUNPTU1BTkQgfCBcCiAgICAgICAgICAgICAgICAgKEdsb2JhbHMuYldpdGhvdXRUaXRsZSA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpKTsKICAgIENoZWNrTWVudUl0ZW0oR2xvYmFscy5oU3lzdGVtTWVudSwgMHgxMEQsIE1GX0JZQ09NTUFORCB8IFwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iQWx3YXlzT25Ub3AgPyBNRl9DSEVDS0VEIDogTUZfVU5DSEVDS0VEKSk7CiAgICBDaGVja01lbnVJdGVtKEdsb2JhbHMuaFByb3BlcnRpZXNNZW51LCAweDEwNywgTUZfQllDT01NQU5EIHwgXAogICAgICAgICAgICAgICAgIChHbG9iYWxzLmJTZWNvbmRzID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCkpOwogICAgQ2hlY2tNZW51SXRlbShHbG9iYWxzLmhQcm9wZXJ0aWVzTWVudSwgMHgxMDgsIE1GX0JZQ09NTUFORCB8IFwKICAgICAgICAgICAgICAgICAoR2xvYmFscy5iRGF0ZSA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpKTsKfQoKVk9JRCBMQU5HVUFHRV9VcGRhdGVXaW5kb3dDYXB0aW9uKFZPSUQpIHsKCiAgQ0hBUiBzekNhcHRpb25bTUFYX1NUUklOR19MRU5dOwogIENIQVIgc3pEYXRlW01BWF9TVFJJTkdfTEVOXTsKICAKICBMUFNUUiBkYXRlID0gc3pEYXRlOwogIAogIFNZU1RFTVRJTUUgc3Q7CiAgTFBTWVNURU1USU1FIGxwc3QgPSAmc3Q7CgogIEdldExvY2FsVGltZSgmc3QpOwogIEdldERhdGVGb3JtYXQoTE9DQUxFX1VTRVJfREVGQVVMVCwgTE9DQUxFX1NMT05HREFURSwgbHBzdCwgTlVMTCwgZGF0ZSwKICAgICAgICAgICAgICAgIE1BWF9TVFJJTkdfTEVOKTsKCiAgLyogU2V0IGZyYW1lIGNhcHRpb24gKi8KICBMb2FkU3RyaW5nKEdsb2JhbHMuaEluc3RhbmNlLCAweDEwQywgc3pDYXB0aW9uLCBzaXplb2Yoc3pDYXB0aW9uKSk7CiAgaWYgKEdsb2JhbHMuYkRhdGUpIHsKICAgICBsc3RyY2F0KHN6Q2FwdGlvbiwgIiAtICIpOwogICAgIGxzdHJjYXQoc3pDYXB0aW9uLCBzekRhdGUpOwogIH0KICBTZXRXaW5kb3dUZXh0KEdsb2JhbHMuaE1haW5XbmQsIHN6Q2FwdGlvbik7Cgp9CgpWT0lEIExBTkdVQUdFX0xvYWRNZW51cyhWT0lEKQp7CgogIENIQVIgICBzekl0ZW1bTUFYX1NUUklOR19MRU5dOwogIEhNRU5VICBoTWFpbk1lbnU7CgoKICAvKiBDcmVhdGUgbWVudSAqLwogIGhNYWluTWVudSA9IExvYWRNZW51KEdsb2JhbHMuaEluc3RhbmNlLCBNQUlOX01FTlUpOwogICAgR2xvYmFscy5oUHJvcGVydGllc01lbnUgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDApOwogICAgR2xvYmFscy5oTGFuZ3VhZ2VNZW51ICAgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDEpOwogICAgR2xvYmFscy5oSW5mb01lbnUgICAgICAgICAgID0gR2V0U3ViTWVudShoTWFpbk1lbnUsIDIpOwoKICBTZXRNZW51KEdsb2JhbHMuaE1haW5XbmQsIGhNYWluTWVudSk7CgogIC8qIERlc3Ryb3kgb2xkIG1lbnUgKi8KICBpZiAoR2xvYmFscy5oTWFpbk1lbnUpIERlc3Ryb3lNZW51KEdsb2JhbHMuaE1haW5NZW51KTsKICBHbG9iYWxzLmhNYWluTWVudSA9IGhNYWluTWVudTsKCiAgLyogc3BlY2lmaWMgZm9yIENsb2NrOiAqLwoKICBMQU5HVUFHRV9VcGRhdGVNZW51Q2hlY2ttYXJrcygpOwogIExBTkdVQUdFX1VwZGF0ZVdpbmRvd0NhcHRpb24oKTsgICAKCiAgR2xvYmFscy5oU3lzdGVtTWVudSA9IEdldFN5c3RlbU1lbnUoR2xvYmFscy5oTWFpblduZCwgVFJVRSk7CgogIC8qIEZJWE1FOiBBcHBlbmQgYSBTRVBBUkFUT1IgdG8gR2xvYmFscy5oU3lzdGVtTWVudSBoZXJlICovCgogIExvYWRTdHJpbmcoR2xvYmFscy5oSW5zdGFuY2UsIDB4MTBELCBzekl0ZW0sIHNpemVvZihzekl0ZW0pKTsKICBBcHBlbmRNZW51KEdsb2JhbHMuaFN5c3RlbU1lbnUsIE1GX1NUUklORyB8IE1GX0JZQ09NTUFORCwgMTAwMCwgc3pJdGVtKTsKfQoKLyoKVk9JRCBMQU5HVUFHRV9EZWZhdWx0SGFuZGxlKFdQQVJBTSB3UGFyYW0pCnsKICBpZiAoKHdQYXJhbSA+PUNMX0ZJUlNUX0xBTkdVQUdFKSAmJiAod1BhcmFtPD1DTF9MQVNUX0xBTkdVQUdFKSkKICAgICAgICAgIExBTkdVQUdFX1NlbGVjdEJ5TnVtYmVyKHdQYXJhbSAtIENMX0ZJUlNUX0xBTkdVQUdFKTsKICAgICBlbHNlIHByaW50ZigiVW5pbXBsZW1lbnRlZCBtZW51IGNvbW1hbmQgJWlcbiIsIHdQYXJhbSk7Cn0KKi8KCi8qIExvY2FsIFZhcmlhYmxlczogICAgKi8KLyogYy1maWxlLXN0eWxlOiAiR05VIiAqLwovKiBFbmQ6ICAgICAgICAgICAgICAgICovCg==