LyoqIEBmaWxlDQoNCiAgQ29weXJpZ2h0IChjKSAyMDA0ICAtIDIwMTQsIEludGVsIENvcnBvcmF0aW9uLiBBbGwgcmlnaHRzIHJlc2VydmVkLjxCUj4NCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQ0KICBUaGlzIHByb2dyYW0gYW5kIHRoZSBhY2NvbXBhbnlpbmcgbWF0ZXJpYWxzIGFyZSBsaWNlbnNlZCBhbmQgbWFkZSBhdmFpbGFibGUgdW5kZXINDQogIHRoZSB0ZXJtcyBhbmQgY29uZGl0aW9ucyBvZiB0aGUgQlNEIExpY2Vuc2UgdGhhdCBhY2NvbXBhbmllcyB0aGlzIGRpc3RyaWJ1dGlvbi4gIA0NCiAgVGhlIGZ1bGwgdGV4dCBvZiB0aGUgbGljZW5zZSBtYXkgYmUgZm91bmQgYXQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgDQ0KICBodHRwOi8vb3BlbnNvdXJjZS5vcmcvbGljZW5zZXMvYnNkLWxpY2Vuc2UucGhwLiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICANDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0NCiAgVEhFIFBST0dSQU0gSVMgRElTVFJJQlVURUQgVU5ERVIgVEhFIEJTRCBMSUNFTlNFIE9OIEFOICJBUyBJUyIgQkFTSVMsICAgICAgICAgICAgDQ0KICBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgUkVQUkVTRU5UQVRJT05TIE9GIEFOWSBLSU5ELCBFSVRIRVIgRVhQUkVTUyBPUiBJTVBMSUVELiAgICANDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIA0NCg0KTW9kdWxlIE5hbWU6DQoNCg0KICBCb290TW9kZS5jDQoNCkFic3RyYWN0Og0KDQogIEVGSSBQRUlNIHRvIHByb3ZpZGUgdGhlIHBsYXRmb3JtIHN1cHBvcnQgZnVuY3Rpb25hbGl0eSBvbiB0aGUgVGh1cmxleS4NCg0KDQotLSovDQojaW5jbHVkZSAiQ29tbW9uSGVhZGVyLmgiDQojaW5jbHVkZSAiUGxhdGZvcm0uaCINCiNpbmNsdWRlICJQbGF0Zm9ybUJhc2VBZGRyZXNzZXMuaCINCiNpbmNsdWRlICJQY2hBY2Nlc3MuaCINCiNpbmNsdWRlICJQbGF0Zm9ybUJvb3RNb2RlLmgiDQojaW5jbHVkZSA8R3VpZC9TZXR1cFZhcmlhYmxlLmg+DQoNCiNpbmNsdWRlIDxHdWlkL0Jvb3RTdGF0ZS5oPg0KDQovLw0KLy8gUHJpb3JpdHkgb2Ygb3VyIGJvb3QgbW9kZXMsIGhpZ2hlc3QgcHJpb3JpdHkgZmlyc3QNCi8vDQpFRklfQk9PVF9NT0RFIG1Cb290TW9kZVByaW9yaXR5W10gPSB7DQogIEJPT1RfSU5fUkVDT1ZFUllfTU9ERSwNCiAgQk9PVF9XSVRIX0RFRkFVTFRfU0VUVElOR1MsDQogIEJPT1RfT05fRkxBU0hfVVBEQVRFLA0KICBCT09UX09OX1MyX1JFU1VNRSwNCiAgQk9PVF9PTl9TM19SRVNVTUUsDQogIEJPT1RfT05fUzRfUkVTVU1FLA0KICBCT09UX1dJVEhfTUlOSU1BTF9DT05GSUdVUkFUSU9OLA0KICBCT09UX0FTU1VNSU5HX05PX0NPTkZJR1VSQVRJT05fQ0hBTkdFUywNCiAgQk9PVF9XSVRIX0ZVTExfQ09ORklHVVJBVElPTl9QTFVTX0RJQUdOT1NUSUNTLA0KICBCT09UX1dJVEhfRlVMTF9DT05GSUdVUkFUSU9OLA0KICBCT09UX09OX1M1X1JFU1VNRQ0KfTsNCg0KRUZJX1BFSV9OT1RJRllfREVTQ1JJUFRPUiBtQ2Fwc3VsZU5vdGlmeUxpc3RbMV0gPSB7DQogIHsNCiAgICAoRUZJX1BFSV9QUElfREVTQ1JJUFRPUl9OT1RJRllfQ0FMTEJBQ0sgfCBFRklfUEVJX1BQSV9ERVNDUklQVE9SX1RFUk1JTkFURV9MSVNUKSwNCiAgICAmZ1BlaUNhcHN1bGVQcGlHdWlkLA0KICAgIENhcHN1bGVQcGlOb3RpZnlDYWxsYmFjaw0KICB9DQp9Ow0KDQpCT09MRUFODQpHZXRTbGVlcFR5cGVBZnRlcldha2V1cCAoDQogIElOICBDT05TVCBFRklfUEVJX1NFUlZJQ0VTICAgICAgICAgICoqUGVpU2VydmljZXMsDQogIE9VVCBVSU5UMTYgICAgICAgICAgICAgICAgICAgICpTbGVlcFR5cGUNCiAgKTsNCg0KRUZJX1NUQVRVUw0KRUZJQVBJDQpDYXBzdWxlUHBpTm90aWZ5Q2FsbGJhY2sgKA0KICBJTiBFRklfUEVJX1NFUlZJQ0VTICAgICAgICAgICAqKlBlaVNlcnZpY2VzLA0KICBJTiBFRklfUEVJX05PVElGWV9ERVNDUklQVE9SICAqTm90aWZ5RGVzY3JpcHRvciwNCiAgSU4gVk9JRCAgICAgICAgICAgICAgICAgICAgICAgKlBwaQ0KICApDQp7DQogIEVGSV9TVEFUVVMgICAgICBTdGF0dXM7DQogIEVGSV9CT09UX01PREUgICBCb290TW9kZTsNCiAgUEVJX0NBUFNVTEVfUFBJICpDYXBzdWxlOw0KDQogIFN0YXR1cyA9ICgqUGVpU2VydmljZXMpLT5HZXRCb290TW9kZSgoY29uc3QgRUZJX1BFSV9TRVJWSUNFUyAqKilQZWlTZXJ2aWNlcywgJkJvb3RNb2RlKTsNCiAgQVNTRVJUX0VGSV9FUlJPUiAoU3RhdHVzKTsNCg0KICBpZiAoQm9vdE1vZGUgPT0gQk9PVF9PTl9TM19SRVNVTUUpIHsNCiAgICAvLw0KICAgIC8vIERldGVybWluZSBpZiB3ZSdyZSBpbiBjYXBzdWxlIHVwZGF0ZSBtb2RlDQogICAgLy8NCiAgICBTdGF0dXMgPSAoKlBlaVNlcnZpY2VzKS0+TG9jYXRlUHBpICgoY29uc3QgRUZJX1BFSV9TRVJWSUNFUyAqKilQZWlTZXJ2aWNlcywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZ1BlaUNhcHN1bGVQcGlHdWlkLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVk9JRCAqKikmQ2Fwc3VsZQ0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7DQoNCiAgICBpZiAoU3RhdHVzID09IEVGSV9TVUNDRVNTKSB7DQogICAgICBpZiAoQ2Fwc3VsZS0+Q2hlY2tDYXBzdWxlVXBkYXRlICgoRUZJX1BFSV9TRVJWSUNFUyoqKVBlaVNlcnZpY2VzKSA9PSBFRklfU1VDQ0VTUykgew0KICAgICAgICBCb290TW9kZSA9IEJPT1RfT05fRkxBU0hfVVBEQVRFOw0KICAgICAgICBTdGF0dXMgPSAoKlBlaVNlcnZpY2VzKS0+U2V0Qm9vdE1vZGUoKGNvbnN0IEVGSV9QRUlfU0VSVklDRVMgKiopUGVpU2VydmljZXMsIEJvb3RNb2RlKTsNCiAgICAgICAgQVNTRVJUX0VGSV9FUlJPUiAoU3RhdHVzKTsNCiAgICAgIH0NCiAgICB9DQogIH0NCg0KICByZXR1cm4gU3RhdHVzOw0KfQ0KDQovKioNCiAgQ2hlY2sgQ01PUyByZWdpc3RlciBiaXQgdG8gZGV0ZXJtaW5lIGlmIHByZXZpb3VzIGJvb3Qgd2FzIHN1Y2Nlc3NmdWwNCg0KICBAcGFyYW0gUGVpU2VydmljZXMgICAgcG9pbnRlciB0byB0aGUgUEVJIFNlcnZpY2UgVGFibGUNCg0KICBAcmV0dmFsIFRSVUUgICAgICAgICAgLSBQcmV2aW91cyBCb290IHdhcyBzdWNjZXNzDQogIEByZXR2YWwgRkFMU0UgICAgICAgICAtIFByZXZpb3VzIEJvb3Qgd2Fzbid0IHN1Y2Nlc3MNCg0KKiovDQpCT09MRUFODQpJc1ByZXZpb3VzQm9vdFN1Y2Nlc3NmdWwoDQogIElOIENPTlNUIEVGSV9QRUlfU0VSVklDRVMgICAqKlBlaVNlcnZpY2VzDQoNCiAgKQ0Kew0KICBFRklfU1RBVFVTICAgICAgICAgICAgICAgICAgICAgIFN0YXR1czsNCiAgQk9PTEVBTiAgICAgICAgICAgICAgICAgICAgICAgICBCb290U3RhdGU7DQogIFVJTlROICAgICAgICAgICAgICAgICAgICAgICAgICAgRGF0YVNpemU7DQogIENIQVIxNiAgICAgICAgICAgICAgICAgICAgICAgICAgVmFyTmFtZVtdID0gQk9PVF9TVEFURV9WQVJJQUJMRV9OQU1FOw0KICBFRklfUEVJX1JFQURfT05MWV9WQVJJQUJMRTJfUFBJICpQZWlWYXI7DQoNCiAgU3RhdHVzID0gKCoqUGVpU2VydmljZXMpLkxvY2F0ZVBwaSAoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlaVNlcnZpY2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZ0VmaVBlaVJlYWRPbmx5VmFyaWFibGUyUHBpR3VpZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKiopJlBlaVZhcg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICApOw0KICBBU1NFUlRfRUZJX0VSUk9SIChTdGF0dXMpOw0KDQogIC8vDQogIC8vIEdldCBsYXN0IEJvb3QgU3RhdGUgVmFyaWFibGUgdG8gY29uZmlybSB0aGF0IGl0IGlzIG5vdCBhIGZpcnN0IGJvb3QgLg0KICAvLw0KDQogIERhdGFTaXplID0gc2l6ZW9mIChCT09MRUFOKTsNCiAgU3RhdHVzID0gUGVpVmFyLT5HZXRWYXJpYWJsZSAoDQogICAgICAgICAgICAgICAgICAgICBQZWlWYXIsDQogICAgICAgICAgICAgICAgICAgICBWYXJOYW1lLA0KICAgICAgICAgICAgICAgICAgICAgJmdFZmlCb290U3RhdGVHdWlkLA0KICAgICAgICAgICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICZEYXRhU2l6ZSwNCiAgICAgICAgICAgICAgICAgICAgICZCb290U3RhdGUNCiAgICAgICAgICAgICAgICAgICAgICk7DQogIGlmIChFRklfRVJST1IgKFN0YXR1cykgfHwgKEJvb3RTdGF0ZSA9PSBUUlVFKSkgew0KICAgIHJldHVybiBGQUxTRTsNCiAgfQ0KDQogIERFQlVHICgoRUZJX0RfSU5GTywgIlByZXZpb3VzIGJvb3QgY3ljbGUgc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZCBoYW5kb3ZlciB0byBPU1xuIikpOw0KICByZXR1cm4gVFJVRTsNCn0NCiNpZmRlZiBOT0NTX1MzX1NVUFBPUlQNCkVGSV9TVEFUVVMNClVwZGF0ZUJvb3RNb2RlICgNCiAgSU4gQ09OU1QgRUZJX1BFSV9TRVJWSUNFUyAgICAgKipQZWlTZXJ2aWNlcw0KICApDQp7DQogIEVGSV9TVEFUVVMgICAgICBTdGF0dXM7DQogIEVGSV9CT09UX01PREUgICBCb290TW9kZTsNCiAgVUlOVDE2ICAgICAgICAgIFNsZWVwVHlwZTsNCiAgQ0hBUjE2ICAgICAgICAgICpzdHJCb290TW9kZTsNCg0KICBTdGF0dXMgPSAoKlBlaVNlcnZpY2VzKS0+R2V0Qm9vdE1vZGUoUGVpU2VydmljZXMsICZCb290TW9kZSk7DQogIEFTU0VSVF9FRklfRVJST1IgKFN0YXR1cyk7DQogIGlmIChCb290TW9kZSAgPT0gQk9PVF9JTl9SRUNPVkVSWV9NT0RFKXsNCiAgICByZXR1cm4gU3RhdHVzOw0KICB9DQoNCiAgLy8NCiAgLy8gTGV0J3MgYXNzdW1lIHRoaW5ncyBhcmUgT0sgaWYgbm90IHRvbGQgb3RoZXJ3aXNlDQogIC8vDQogIEJvb3RNb2RlID0gQk9PVF9XSVRIX0ZVTExfQ09ORklHVVJBVElPTjsNCg0KICBpZiAoR2V0U2xlZXBUeXBlQWZ0ZXJXYWtldXAgKFBlaVNlcnZpY2VzLCAmU2xlZXBUeXBlKSkgew0KICAgIHN3aXRjaCAoU2xlZXBUeXBlKSB7DQogICAgICBjYXNlIFZfUENIX0FDUElfUE0xX0NOVF9TMzoNCiAgICAgICAgQm9vdE1vZGUgPSBCT09UX09OX1MzX1JFU1VNRTsNCiAgICAgICAgU3RhdHVzID0gKCpQZWlTZXJ2aWNlcyktPk5vdGlmeVBwaSAoUGVpU2VydmljZXMsICZtQ2Fwc3VsZU5vdGlmeUxpc3RbMF0pOw0KICAgICAgICBBU1NFUlRfRUZJX0VSUk9SIChTdGF0dXMpOw0KICAgICAgICBicmVhazsNCg0KICAgICAgY2FzZSBWX1BDSF9BQ1BJX1BNMV9DTlRfUzQ6DQogICAgICAgIEJvb3RNb2RlID0gQk9PVF9PTl9TNF9SRVNVTUU7DQogICAgICAgIGJyZWFrOw0KDQogICAgICBjYXNlIFZfUENIX0FDUElfUE0xX0NOVF9TNToNCiAgICAgICAgQm9vdE1vZGUgPSBCT09UX09OX1M1X1JFU1VNRTsNCiAgICAgICAgYnJlYWs7DQogICAgfSAvLyBzd2l0Y2ggKFNsZWVwVHlwZSkNCiAgfQ0KDQogIGlmIChJc0Zhc3RCb290RW5hYmxlZCAoUGVpU2VydmljZXMpICYmIElzUHJldmlvdXNCb290U3VjY2Vzc2Z1bCAoUGVpU2VydmljZXMpKSB7DQogICAgREVCVUcgKChFRklfRF9JTkZPLCAiUHJpb3JpdGl6aW5nIEJvb3QgbW9kZSB0byBCT09UX1dJVEhfTUlOSU1BTF9DT05GSUdVUkFUSU9OXG4iKSk7DQogICAgUHJpb3JpdGl6ZUJvb3RNb2RlICgmQm9vdE1vZGUsIEJPT1RfV0lUSF9NSU5JTUFMX0NPTkZJR1VSQVRJT04pOw0KICB9DQoNCiAgc3dpdGNoIChCb290TW9kZSkgew0KICAgIGNhc2UgQk9PVF9XSVRIX0ZVTExfQ09ORklHVVJBVElPTjoNCiAgICAgIHN0ckJvb3RNb2RlID0gTCJCT09UX1dJVEhfRlVMTF9DT05GSUdVUkFUSU9OIjsNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgQk9PVF9XSVRIX01JTklNQUxfQ09ORklHVVJBVElPTjoNCiAgICAgIHN0ckJvb3RNb2RlID0gTCJCT09UX1dJVEhfTUlOSU1BTF9DT05GSUdVUkFUSU9OIjsNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgQk9PVF9BU1NVTUlOR19OT19DT05GSUdVUkFUSU9OX0NIQU5HRVM6DQogICAgICBzdHJCb290TW9kZSA9IEwiQk9PVF9BU1NVTUlOR19OT19DT05GSUdVUkFUSU9OX0NIQU5HRVMiOw0KICAgICAgYnJlYWs7DQogICAgY2FzZSBCT09UX1dJVEhfRlVMTF9DT05GSUdVUkFUSU9OX1BMVVNfRElBR05PU1RJQ1M6DQogICAgICBzdHJCb290TW9kZSA9IEwiQk9PVF9XSVRIX0ZVTExfQ09ORklHVVJBVElPTl9QTFVTX0RJQUdOT1NUSUNTIjsNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgQk9PVF9XSVRIX0RFRkFVTFRfU0VUVElOR1M6DQogICAgICBzdHJCb290TW9kZSA9IEwiQk9PVF9XSVRIX0RFRkFVTFRfU0VUVElOR1MiOw0KICAgICAgYnJlYWs7DQogICAgY2FzZSBCT09UX09OX1M0X1JFU1VNRToNCiAgICAgIHN0ckJvb3RNb2RlID0gTCJCT09UX09OX1M0X1JFU1VNRSI7DQogICAgICBicmVhazsNCiAgICBjYXNlIEJPT1RfT05fUzVfUkVTVU1FOg0KICAgICAgc3RyQm9vdE1vZGUgPSBMIkJPT1RfT05fUzVfUkVTVU1FIjsNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgQk9PVF9PTl9TMl9SRVNVTUU6DQogICAgICBzdHJCb290TW9kZSA9IEwiQk9PVF9PTl9TMl9SRVNVTUUiOw0KICAgICAgYnJlYWs7DQogICAgY2FzZSBCT09UX09OX1MzX1JFU1VNRToNCiAgICAgIHN0ckJvb3RNb2RlID0gTCJCT09UX09OX1MzX1JFU1VNRSI7DQoNCiAgICAgIGJyZWFrOw0KICAgIGNhc2UgQk9PVF9PTl9GTEFTSF9VUERBVEU6DQogICAgICBzdHJCb290TW9kZSA9IEwiQk9PVF9PTl9GTEFTSF9VUERBVEUiOw0KICAgICAgYnJlYWs7DQogICAgY2FzZSBCT09UX0lOX1JFQ09WRVJZX01PREU6DQogICAgICBzdHJCb290TW9kZSA9IEwiQk9PVF9JTl9SRUNPVkVSWV9NT0RFIjsNCiAgICAgIGJyZWFrOw0KICAgIGRlZmF1bHQ6DQogICAgICBzdHJCb290TW9kZSA9IEwiVW5rbm93biBib290IG1vZGUiOw0KICB9IC8vIHN3aXRjaCAoQm9vdE1vZGUpDQoNCiAgREVCVUcgKChFRklfRF9FUlJPUiwgIlNldHRpbmcgQm9vdE1vZGUgdG8gJXNcbiIsIHN0ckJvb3RNb2RlKSk7DQogIFN0YXR1cyA9ICgqUGVpU2VydmljZXMpLT5TZXRCb290TW9kZShQZWlTZXJ2aWNlcywgQm9vdE1vZGUpOw0KICBBU1NFUlRfRUZJX0VSUk9SIChTdGF0dXMpOw0KDQogIHJldHVybiBTdGF0dXM7DQp9DQojZW5kaWYNCg0KLyoqDQogIEdldCBzbGVlcCB0eXBlIGFmdGVyIHdha2V1cA0KDQogIEBwYXJhbSBQZWlTZXJ2aWNlcyAgICAgICBQb2ludGVyIHRvIHRoZSBQRUkgU2VydmljZSBUYWJsZS4NCiAgQHBhcmFtIFNsZWVwVHlwZSAgICAgICAgIFNsZWVwIHR5cGUgdG8gYmUgcmV0dXJuZWQuDQoNCiAgQHJldHZhbCBUUlVFICAgICAgICAgICAgICBBIHdha2UgZXZlbnQgb2NjdXJlZCB3aXRob3V0IHBvd2VyIGZhaWx1cmUuDQogIEByZXR2YWwgRkFMU0UgICAgICAgICAgICAgUG93ZXIgZmFpbHVyZSBvY2N1cmVkIG9yIG5vdCBhIHdha2V1cC4NCg0KKiovDQpCT09MRUFODQpHZXRTbGVlcFR5cGVBZnRlcldha2V1cCAoDQogIElOICBDT05TVCBFRklfUEVJX1NFUlZJQ0VTICAgICAgICAgICoqUGVpU2VydmljZXMsDQogIE9VVCBVSU5UMTYgICAgICAgICAgICAgICAgICAgICpTbGVlcFR5cGUNCiAgKQ0Kew0KICBVSU5UMTYgIFBtMVN0czsNCiAgVUlOVDE2ICBQbTFDbnQ7DQogIFVJTlQxNiAgR2VuUG1Db24xOw0KICAvLw0KICAvLyBWTFYgQklPUyBTcGVjaWZpY2F0aW9uIDAuNi4yIC0gU2VjdGlvbiAxOC40LCAiUG93ZXIgRmFpbHVyZSBDb25zaWRlcmF0aW9uIg0KICAvLw0KICAvLyBXaGVuIHRoZSBTVVNfUFdSX0ZMUiBiaXQgaXMgc2V0LCBpdCBpbmRpY2F0ZXMgdGhlIFNVUyB3ZWxsIHBvd2VyIGlzIGxvc3QuDQogIC8vIFRoaXMgYml0IGlzIGluIHRoZSBTVVMgV2VsbCBhbmQgZGVmYXVsdHMgdG8gMZJiMSBiYXNlZCBvbiBSU01SU1QjIGFzc2VydGlvbiAobm90IGNsZWFyZWQgYnkgYW55IHR5cGUgb2YgcmVzZXQpLg0KICAvLyBTeXN0ZW0gQklPUyBzaG91bGQgZm9sbG93IGNvbGQgYm9vdCBwYXRoIGlmIFNVU19QV1JfRkxSIChQQkFTRSArIDB4MjBbMTRdKSwNCiAgLy8gR0VOX1JTVF9TVFMgKFBCQVNFICsgMHgyMFs5XSkgb3IgUFdSQlROT1JfU1RTIChBQkFTRSArIDB4MDBbMTFdKSBpcyBzZXQgdG8gMZJiMQ0KICAvLyByZWdhcmRsZXNzIG9mIHRoZSB2YWx1ZSBpbiB0aGUgU0xQX1RZUCAoQUJBU0UgKyAweDA0WzEyOjEwXSkgZmllbGQuDQogIC8vDQogIEdlblBtQ29uMSA9IE1taW9SZWFkMTYgKFBNQ19CQVNFX0FERFJFU1MgKyBSX1BDSF9QTUNfR0VOX1BNQ09OXzEpOw0KDQogIC8vDQogIC8vIFJlYWQgdGhlIEFDUEkgcmVnaXN0ZXJzDQogIC8vDQogIFBtMVN0cyAgPSBJb1JlYWQxNiAoQUNQSV9CQVNFX0FERFJFU1MgKyBSX1BDSF9BQ1BJX1BNMV9TVFMpOw0KICBQbTFDbnQgID0gSW9SZWFkMTYgKEFDUElfQkFTRV9BRERSRVNTICsgUl9QQ0hfQUNQSV9QTTFfQ05UKTsNCg0KICBpZiAoKEdlblBtQ29uMSAmIChCX1BDSF9QTUNfR0VOX1BNQ09OX1NVU19QV1JfRkxSIHwgQl9QQ0hfUE1DX0dFTl9QTUNPTl9HRU5fUlNUX1NUUykpIHx8DQogICAgIChQbTFTdHMgJiBCX1BDSF9BQ1BJX1BNMV9TVFNfUFJCVE5PUikpIHsNCgkgIC8vDQogICAgLy8gSWYgcG93ZXIgZmFpbHVyZSBpbmRpY2F0b3IsIHRoZW4gZG9uJ3QgYXR0ZW1wdCBzMyByZXN1bWUuDQogICAgLy8gQ2xlYXIgUE0xX0NOVCBvZiBTMyBhbmQgc2V0IGl0IHRvIFM1IGFzIHdlIGp1c3QgaGFkIGEgcG93ZXIgZmFpbHVyZSwgYW5kIG1lbW9yeSBoYXMNCiAgICAvLyBsb3N0IGFscmVhZHkuICBUaGlzIGlzIHRvIG1ha2Ugc3VyZSBubyBvbmUgd2lsbCB1c2UgUE0xX0NOVCB0byBjaGVjayBmb3IgUzMgYWZ0ZXINCiAgICAvLyBwb3dlciBmYWlsdXJlLg0KCSAgLy8NCiAgICBpZiAoKFBtMUNudCAmIEJfUENIX0FDUElfUE0xX0NOVF9TTFBfVFlQKSA9PSBWX1BDSF9BQ1BJX1BNMV9DTlRfUzMpIHsNCiAgICAgIFBtMUNudCA9ICgoUG0xQ250ICYgfkJfUENIX0FDUElfUE0xX0NOVF9TTFBfVFlQKSB8IFZfUENIX0FDUElfUE0xX0NOVF9TNSk7DQogICAgICBJb1dyaXRlMTYgKEFDUElfQkFTRV9BRERSRVNTICsgUl9QQ0hfQUNQSV9QTTFfQ05ULCBQbTFDbnQpOw0KICAgIH0NCgkgIC8vDQogICAgLy8gQ2xlYXIgV2FrZSBTdGF0dXMgKFdBS19TVFMpDQogICAgLy8NCiAgfQ0KICAvLw0KICAvLyBHZXQgc2xlZXAgdHlwZSBpZiBhIHdha2UgZXZlbnQgb2NjdXJyZWQgYW5kIHRoZXJlIGlzIG5vIHBvd2VyIGZhaWx1cmUNCiAgLy8NCiAgaWYgKChQbTFDbnQgJiBCX1BDSF9BQ1BJX1BNMV9DTlRfU0xQX1RZUCkgPT0gVl9QQ0hfQUNQSV9QTTFfQ05UX1MzKSB7DQogICAgKlNsZWVwVHlwZSA9IFBtMUNudCAmIEJfUENIX0FDUElfUE0xX0NOVF9TTFBfVFlQOw0KICAgIHJldHVybiBUUlVFOw0KICB9IGVsc2UgaWYgKChQbTFDbnQgJiBCX1BDSF9BQ1BJX1BNMV9DTlRfU0xQX1RZUCkgPT0gVl9QQ0hfQUNQSV9QTTFfQ05UX1M0KSB7DQogICAgKlNsZWVwVHlwZSA9IFBtMUNudCAmIEJfUENIX0FDUElfUE0xX0NOVF9TTFBfVFlQOw0KICAgIHJldHVybiBUUlVFOw0KICB9DQogIHJldHVybiBGQUxTRTsNCn0NCg0KQk9PTEVBTg0KRUZJQVBJDQpJc0Zhc3RCb290RW5hYmxlZCAoDQogIElOIENPTlNUIEVGSV9QRUlfU0VSVklDRVMgICAgICAgICAgICoqUGVpU2VydmljZXMNCiAgKQ0Kew0KICBFRklfU1RBVFVTICAgICAgICAgICAgICAgICAgICAgIFN0YXR1czsNCiAgRUZJX1BFSV9SRUFEX09OTFlfVkFSSUFCTEUyX1BQSSAqUGVpUmVhZE9ubHlWYXJQcGk7DQogIFVJTlROICAgICAgICAgICAgICAgICAgICAgICAgICAgVmFyU2l6ZTsNCiAgU1lTVEVNX0NPTkZJR1VSQVRJT04gICAgICAgICAgICBTeXN0ZW1Db25maWd1cmF0aW9uOw0KICBCT09MRUFOICAgICAgICAgICAgICAgICAgICAgICAgIEZhc3RCb290RW5hYmxlZFN0YXR1czsNCg0KICBGYXN0Qm9vdEVuYWJsZWRTdGF0dXMgPSBGQUxTRTsNCiAgU3RhdHVzID0gKCoqUGVpU2VydmljZXMpLkxvY2F0ZVBwaSAoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBlaVNlcnZpY2VzLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZ0VmaVBlaVJlYWRPbmx5VmFyaWFibGUyUHBpR3VpZCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKiopJlBlaVJlYWRPbmx5VmFyUHBpDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7DQogIGlmIChTdGF0dXMgPT0gRUZJX1NVQ0NFU1MpIHsNCiAgICBWYXJTaXplID0gc2l6ZW9mIChTWVNURU1fQ09ORklHVVJBVElPTik7DQogICAgU3RhdHVzID0gUGVpUmVhZE9ubHlWYXJQcGktPkdldFZhcmlhYmxlICgNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQZWlSZWFkT25seVZhclBwaSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQTEFURk9STV9TRVRVUF9WQVJJQUJMRV9OQU1FLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZnRWZpU2V0dXBWYXJpYWJsZUd1aWQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmVmFyU2l6ZSwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmU3lzdGVtQ29uZmlndXJhdGlvbg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7DQogICAgaWYgKFN0YXR1cyA9PSBFRklfU1VDQ0VTUykgew0KICAgICAgaWYgKFN5c3RlbUNvbmZpZ3VyYXRpb24uRmFzdEJvb3QgIT0gMCkgew0KICAgICAgICBGYXN0Qm9vdEVuYWJsZWRTdGF0dXMgPSBUUlVFOw0KICAgICAgfQ0KICAgIH0NCiAgfQ0KDQogIHJldHVybiBGYXN0Qm9vdEVuYWJsZWRTdGF0dXM7DQp9DQoNCi8qKg0KICBHaXZlbiB0aGUgY3VycmVudCBib290IG1vZGUsIGFuZCBhIHByb3Bvc2VkIG5ldyBib290IG1vZGUsIGRldGVybWluZQ0KICB3aGljaCBoYXMgcHJpb3JpdHkuIElmIHRoZSBuZXcgYm9vdCBtb2RlIGhhcyBoaWdoZXIgcHJpb3JpdHksIHRoZW4NCiAgbWFrZSBpdCB0aGUgY3VycmVudCBib290IG1vZGUuDQoNCiAgQHBhcmFtIEN1cnJlbnRCb290TW9kZSAgICBwb2ludGVyIHRvIGN1cnJlbnQgcGxhbm5lZCBib290IG1vZGUNCiAgQHBhcmFtIE5ld0Jvb3RNb2RlICAgICAgICBwcm9wb3NlZCBib290IG1vZGUNCg0KICBAcmV0dmFsIEVGSV9OT1RfRk9VTkQgICAgICBpZiBlaXRoZXIgYm9vdCBtb2RlIGlzIG5vdCByZWNvZ25pemVkDQogIEByZXR2YWwgRUZJX1NVQ0NFU1MgICAgICAgIGlmIGJvdGggYm9vdCBtb2RlIHZhbHVlcyB3ZXJlIHJlY29nbml6ZWQgYW5kDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdlcmUgcHJvY2Vzc2VkLg0KKiovDQpFRklfU1RBVFVTDQpQcmlvcml0aXplQm9vdE1vZGUgKA0KICBJTiBPVVQgRUZJX0JPT1RfTU9ERSAgICAqQ3VycmVudEJvb3RNb2RlLA0KICBJTiBFRklfQk9PVF9NT0RFICAgICAgICBOZXdCb290TW9kZQ0KICApDQp7DQogIFVJTlQzMiBDdXJyZW50SW5kZXg7DQogIFVJTlQzMiBOZXdJbmRleDsNCg0KICAvLw0KICAvLyBGaW5kIHRoZSBwb3NpdGlvbiBvZiB0aGUgY3VycmVudCBib290IG1vZGUgaW4gb3VyIHByaW9yaXR5IGFycmF5DQogIC8vDQogIGZvciAoIEN1cnJlbnRJbmRleCA9IDA7DQogICAgICAgIEN1cnJlbnRJbmRleCA8IEFSUkFZX1NJWkUgKG1Cb290TW9kZVByaW9yaXR5KTsNCiAgICAgICAgQ3VycmVudEluZGV4KyspIHsNCiAgICBpZiAobUJvb3RNb2RlUHJpb3JpdHlbQ3VycmVudEluZGV4XSA9PSAqQ3VycmVudEJvb3RNb2RlKSB7DQogICAgICBicmVhazsNCiAgICB9DQogIH0NCiAgaWYgKEN1cnJlbnRJbmRleCA+PSBBUlJBWV9TSVpFIChtQm9vdE1vZGVQcmlvcml0eSkpIHsNCiAgICByZXR1cm4gRUZJX05PVF9GT1VORDsNCiAgfQ0KDQogIC8vDQogIC8vIEZpbmQgdGhlIHBvc2l0aW9uIG9mIHRoZSBuZXcgYm9vdCBtb2RlIGluIG91ciBwcmlvcml0eSBhcnJheQ0KICAvLw0KICBmb3IgKCBOZXdJbmRleCA9IDA7DQogICAgICAgIE5ld0luZGV4IDwgQVJSQVlfU0laRSAobUJvb3RNb2RlUHJpb3JpdHkpOw0KICAgICAgICBOZXdJbmRleCsrKSB7DQogICAgaWYgKG1Cb290TW9kZVByaW9yaXR5W05ld0luZGV4XSA9PSBOZXdCb290TW9kZSkgew0KICAgICAgLy8NCiAgICAgIC8vIElmIHRoaXMgbmV3IGJvb3QgbW9kZSBvY2N1cnMgYmVmb3JlIHRoZSBjdXJyZW50IGJvb3QgbW9kZSBpbiB0aGUNCiAgICAgIC8vIHByaW9yaXR5IGFycmF5LCB0aGVuIHRha2UgaXQuDQogICAgICAvLw0KICAgICAgaWYgKE5ld0luZGV4IDwgQ3VycmVudEluZGV4KSB7DQogICAgICAgICpDdXJyZW50Qm9vdE1vZGUgPSBOZXdCb290TW9kZTsNCiAgICAgIH0NCiAgICAgIHJldHVybiBFRklfU1VDQ0VTUzsNCiAgICB9DQogIH0NCiAgcmV0dXJuIEVGSV9OT1RfRk9VTkQ7DQp9DQo=