LyoKICogQ29weXJpZ2h0IChDKSAyMDEwIE5YUCBTZW1pY29uZHVjdG9ycwogKgogKiBMaWNlbnNlZCB1bmRlciB0aGUgQXBhY2hlIExpY2Vuc2UsIFZlcnNpb24gMi4wICh0aGUgIkxpY2Vuc2UiKTsKICogeW91IG1heSBub3QgdXNlIHRoaXMgZmlsZSBleGNlcHQgaW4gY29tcGxpYW5jZSB3aXRoIHRoZSBMaWNlbnNlLgogKiBZb3UgbWF5IG9idGFpbiBhIGNvcHkgb2YgdGhlIExpY2Vuc2UgYXQKICoKICogICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgovKiEKICogXGZpbGUgIHBoRnJpTmZjX0ZlbGljYU1hcC5jCiAqIFxicmllZiBUaGlzIGNvbXBvbmVudCBlbmNhcHN1bGF0ZXMgcmVhZC93cml0ZS9jaGVjayBuZGVmL3Byb2Nlc3MgZnVuY3Rpb25hbGl0aWVzLAogKiAgICAgICAgZm9yIHRoZSBGZWxpY2EgU21hcnQgQ2FyZC4gCiAqCiAqIFByb2plY3Q6IE5GQy1GUkkKICoKICogJERhdGU6IFRodSBNYXkgIDYgMTQ6MDE6MzUgMjAxMCAkCiAqICRBdXRob3I6IGluZzA3Mzg1ICQKICogJFJldmlzaW9uOiAxLjEwICQKICogJEFsaWFzZXM6IE5GQ19GUkkxLjFfV0sxMDE3X1IzNF80LE5GQ19GUkkxLjFfV0sxMDIzX1IzNV8xICQKICoKICovCgojaWZuZGVmIFBIX0ZSSU5GQ19NQVBfRkVMSUNBX0RJU0FCTEVECgojaW5jbHVkZSA8cGhOZmNUeXBlcy5oPgojaW5jbHVkZSA8cGhGcmlOZmNfT3ZySGFsLmg+CiNpbmNsdWRlIDxwaEZyaU5mY19GZWxpY2FNYXAuaD4KI2luY2x1ZGUgPHBoRnJpTmZjX01hcFRvb2xzLmg+CgoKLyohIFxpbmdyb3VwIGdycF9maWxlX2F0dHJpYnV0ZXMKICogIFxuYW1lIE5ERUYgTWFwcGluZwogKgogKiBGaWxlOiBccmVmIHBoRnJpTmZjX0ZlbGljYU1hcC5jCiAqCiAqLwovKkB7Ki8KCiNkZWZpbmUgUEhGUklORkNOREVGTUFQX0ZJTEVSRVZJU0lPTiAiJFJldmlzaW9uOiAxLjEwICQiCiNkZWZpbmUgUEhGUklORkNOREVGTUFQX0ZJTEVBTElBU0VTICAiJEFsaWFzZXM6IE5GQ19GUkkxLjFfV0sxMDE3X1IzNF80LE5GQ19GUkkxLjFfV0sxMDIzX1IzNV8xICQiCgovKkB9Ki8KCi8qIEhlbHBlcnMgZm9yIFJlYWQgYW5kIHVwZGF0aW5nIHRoZSBhdHRyaWJ1dGUgaW5mb3JtYXRpb25zKi8Kc3RhdGljIE5GQ1NUQVRVUyAgIHBoRnJpTmZjX0ZlbGljYV9IUmRBdHRySW5mbyhwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXApOwpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hVcGRhdGVBdHRySW5mbyhwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXApOwpzdGF0aWMgTkZDU1RBVFVTIHBoRnJpTmZjX0ZlbGljYV9IQ2FsQ2hlY2tTdW0oY29uc3QgdWludDhfdCAqVGVtcEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgU3RhcnRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgRW5kSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MTZfdCBSZWN2Q2hrU3VtKTsKCi8qIEhlbHBlcnMgZm9yIFBvbGwgUmVsYXRlZCBPcGVyYXRpb25zKi8Kc3RhdGljIE5GQ1NUQVRVUyAgIHBoRnJpTmZjX0ZlbGljYV9IUG9sbENhcmQoIHBoRnJpTmZjX05kZWZNYXBfdCAgICpOZGVmTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDhfdCBzeXNDb2RlW10sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90IHN0YXRlKTsKCnN0YXRpYyBORkNTVEFUVVMgICBwaEZyaU5mY19GZWxpY2FfSFVwZGF0ZU1hbnVmSWREZXRhaWxzKGNvbnN0IHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCk7CgovKkhlbHBlcnMgZm9yIFJlYWRpbmcgT3BlcmF0aW9ucyovCnN0YXRpYyBORkNTVEFUVVMgcGhGcmlOZmNfRmVsaWNhX0hSZWFkRGF0YShwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXAsdWludDhfdCBvZmZzZXQpOwpzdGF0aWMgdWludDE2X3QgICAgcGhGcmlOZmNfRmVsaWNhX0hHZXRNYXhpbXVtQmxrc1RvUmVhZChjb25zdCBwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXAsdWludDhfdCBOYmNPck5tYXhiICk7CnN0YXRpYyB2b2lkICAgICAgICBwaEZyaU5mY19GZWxpY2FfSEFmdGVyUmVhZF9Db3B5RGF0YVRvQnVmZihwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXApOwpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hTZXRUcmFuc2NlaXZlRm9yUmVhZChwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXAsdWludDE2X3QgVHJ4TGVuLHVpbnQ4X3QgT2Zmc2V0KTsKc3RhdGljIHVpbnQxNl90ICAgIHBoRnJpTmZjX0ZlbGljYV9IU2V0VHJ4TGVuKHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCx1aW50MTZfdCBOYmMpOwpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hDaGtBcGR1QnVmZl9TaXplKCBwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXApOwoKLyogSGVscGVycyBmb3IgV3JpdGluZyBPcGVyYXRpb25zKi8Kc3RhdGljIE5GQ1NUQVRVUyAgIHBoRnJpTmZjX0ZlbGljYV9IQ2hrQXR0ckJsa0ZvcldyT3AocGhGcmlOZmNfTmRlZk1hcF90ICpOZGVmTWFwKTsKc3RhdGljIE5GQ1NUQVRVUyAgIHBoRnJpTmZjX0ZlbGljYV9IQ2hrQXR0ckJsa0ZvclJkT3AocGhGcmlOZmNfTmRlZk1hcF90ICpOZGVmTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCBOZGVmTGVuKTsKc3RhdGljIE5GQ1NUQVRVUyAgcGhGcmlOZmNfRmVsaWNhX0hVcGRhdGVBdHRyQmxrRm9yV3JPcChwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXAsdWludDhfdCBpc1N0YXJ0ZWQpOwpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hVcGRhdGVEYXRhKHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCk7CnN0YXRpYyBORkNTVEFUVVMgcGhGcmlOZmNfRmVsaWNhX0hXcml0ZURhdGFCbGsocGhGcmlOZmNfTmRlZk1hcF90ICpOZGVmTWFwKTsKCi8qIFdyaXRlIEVtcHR5IE5ERUYgTWVzc2FnZSovCnN0YXRpYyBORkNTVEFUVVMgcGhGcmlOZmNfRmVsaWNhX0hXckVtcHR5TXNnKHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCk7CgovKkhlbHBlcnMgZm9yIGNvbW1vbiBjaGVja3MqLwpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hDaGVja01hbnVmSWQoY29uc3QgcGhGcmlOZmNfTmRlZk1hcF90ICpOZGVmTWFwKTsKc3RhdGljIHZvaWQgcGhGcmlOZmNfRmVsaWNhX0hDckhhbmRsZXIocGhGcmlOZmNfTmRlZk1hcF90ICAqTmRlZk1hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCAgICAgICAgICAgICAgQ3JJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTICAgICAgICAgICAgU3RhdHVzKTsKCnN0YXRpYyB2b2lkIHBoRnJpTmZjX0ZlbGljYV9ISW5pdEludGVybmFsQnVmKHVpbnQ4X3QgKkJ1ZmZlcik7CgpzdGF0aWMgaW50IHBoRnJpTmZjX0ZlbGljYV9NZW1Db21wYXJlICggdm9pZCAqczEsIHZvaWQgKnMyLCB1bnNpZ25lZCBpbnQgbiApOwoKLyohCiAqIFxicmllZiByZXR1cm5zIG1heGltdW0gbnVtYmVyIG9mIGJsb2NrcyBjYW4gYmUgcmVhZCBmcm9tIHRoZSBGZWxpY2EgU21hcnQgQ2FyZC4KICoKICogVGhlIGZ1bmN0aW9uIGlzIHVzZWZ1bCBpbiByZWFkaW5nIG9mIE5ERUYgaW5mb3JtYXRpb24gZnJvbSBhIGZlbGljYSB0YWcuCiAqLwoKc3RhdGljIHVpbnQxNl90ICAgIHBoRnJpTmZjX0ZlbGljYV9IR2V0TWF4aW11bUJsa3NUb1JlYWQoY29uc3QgcGhGcmlOZmNfTmRlZk1hcF90ICpOZGVmTWFwLCB1aW50OF90IE5iY09yTm1heGIgKQp7CiAgIHVpbnQxNl90ICAgIEJsa3NUb1JlYWQ9MDsKICAgdWludDMyX3QgICAgRGF0YUxlbiA9IDA7CiAgICAvKiBUaGlzIHBhcnQgb2YgdGhlIGNvZGUgaXMgdXNlZnVsIGlmIHdlIHRha2UgYWNjb3VudCBvZiBOYmMgYmxrcyByZWFkaW5nKi8KICAgIGlmICggTmJjT3JObWF4YiA9PSBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX05CQyApCiAgICB7CiAgICAgICAgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9DQUxfTEVOX0JZVEVTKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTGVuQnl0ZXNbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1syXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGFMZW4pOwogICAgICAgIC8qIENhbGN1bGF0ZSBOYmMqLwogICAgICAgIEJsa3NUb1JlYWQgPSAodWludDE2X3QpICggKChEYXRhTGVuICUgMTYpID09IDApID8gKERhdGFMZW4gPj4gNCkgOiAoKERhdGFMZW4gPj4gNCkgKzEpICk7CgogICAgICAgIAogICAgfQogICAgZWxzZSBpZiAoIE5iY09yTm1heGIgPT0gUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9OTUFYQikKICAgIHsKICAgICAgICBCbGtzVG9SZWFkID0gTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGI7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgLyogV0FSTklORyAhISEgY29kZSBzaG91bGQgbm90IHJlYWNoIHRoaXMgcG9pbnQqLwogICAgICAgIDsKICAgIH0KICAgIHJldHVybiAoQmxrc1RvUmVhZCk7Cn0KCi8qIQogKiBcYnJpZWYgSW5pdGlhdGVzIFJlYWRpbmcgb2YgTkRFRiBpbmZvcm1hdGlvbiBmcm9tIHRoZSBGZWxpY2EgQ2FyZC4KICoKICogVGhlIGZ1bmN0aW9uIGluaXRpYXRlcyB0aGUgcmVhZGluZyBvZiBOREVGIGluZm9ybWF0aW9uIGZyb20gYSBSZW1vdGUgRGV2aWNlLgogKiBJdCBwZXJmb3JtcyBhIHJlc2V0IG9mIHRoZSBzdGF0ZSBhbmQgc3RhcnRzIHRoZSBhY3Rpb24gKHN0YXRlIG1hY2hpbmUpLgogKiBBIHBlcmlvZGljIGNhbGwgb2YgdGhlIFxyZWYgcGhGcmlOZmNOZGVmTWFwX1Byb2Nlc3MgaGFzIHRvIGJlIAogKiBkb25lIG9uY2UgdGhlIGFjdGlvbiBoYXMgYmVlbiB0cmlnZ2VyZWQuCiAqLwoKTkZDU1RBVFVTIHBoRnJpTmZjX0ZlbGljYV9SZE5kZWYoICBwaEZyaU5mY19OZGVmTWFwX3QgICpOZGVmTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICAgICAgICAgICAgICpQYWNrZXREYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MzJfdCAgICAgICAgICAgICpQYWNrZXREYXRhTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICAgICAgICAgICAgIE9mZnNldCkKewoKICAgIE5GQ1NUQVRVUyBzdGF0dXMgPSBORkNTVEFUVVNfUEVORElORzsKICAgIHVpbnQzMl90ICBOYmMgPSAwOwoKICAgIE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplID0gKlBhY2tldERhdGFMZW5ndGg7CiAgICAvKlN0b3JlIHRoZSBwYWNrZXQgZGF0YSBidWZmZXIqLwogICAgTmRlZk1hcC0+QXBkdUJ1ZmZlciA9IFBhY2tldERhdGE7CgogICAgTmRlZk1hcC0+TnVtT2ZCeXRlc1JlYWQgPSBQYWNrZXREYXRhTGVuZ3RoIDsKICAgICpOZGVmTWFwLT5OdW1PZkJ5dGVzUmVhZCA9IDA7CiAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ID0gMDsKCiAgICBOZGVmTWFwLT5QcmV2T3BlcmF0aW9uID0gUEhfRlJJTkZDX05ERUZNQVBfUkVBRF9PUEU7CiAgICBOZGVmTWFwLT5GZWxpY2EuT2Zmc2V0ID0gT2Zmc2V0OwoKICAgIGlmKCAoIE9mZnNldCA9PSBQSF9GUklORkNfTkRFRk1BUF9TRUVLX0JFR0lOICl8fCggTmRlZk1hcC0+UHJldk9wZXJhdGlvbiA9PSBQSF9GUklORkNfTkRFRk1BUF9XUklURV9PUEUpKQogICAgewogICAgICAgIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vID0gMDsKICAgICAgICBOZGVmTWFwLT5GZWxpY2EuT3BGbGFnID0gUEhfRlJJTkZDX05ERUZNQVBfRkVMSV9SRF9BVFRSX1JEX09QOwogICAgICAgIE5kZWZNYXAtPkZlbGljYS5JbnRlcm1lZGlhdGVDcHlGbGFnID0gRkFMU0U7CiAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkludGVybWVkaWF0ZUNweUxlbiA9IDA7CiAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgPSAwOwogICAgICAgIE5kZWZNYXAtPkZlbGljYS5Fb2ZDYXJkUmVhY2hlZEZsYWc9IEZBTFNFIDsKICAgICAgICBOZGVmTWFwLT5GZWxpY2EuTGFzdEJsa1JlYWNoZWRGbGFnID0gRkFMU0U7CiAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkN1cnJCeXRlc1JlYWQgPSAwOwoKICAgICAgICBwaEZyaU5mY19GZWxpY2FfSEluaXRJbnRlcm5hbEJ1ZihOZGVmTWFwLT5GZWxpY2EuUmRfQnl0ZXNUb0NvcHlCdWZmKTsKICAgICAgICAKICAgICAgICAvKiBzZW5kIHJlcXVlc3QgdG8gcmVhZCBhdHRyaWJ1dGUgaW5mb3JtYXRpb24qLwogICAgICAgIHN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IUmRBdHRySW5mbyhOZGVmTWFwKTsKICAgICAgICAvKiBoYW5kbGUgdGhlIGVycm9yIGluIFRyYW5zYyBmdW5jdGlvbiovCiAgICAgICAgaWYgKCAoc3RhdHVzICYgUEhORkNTVEJMT1dFUikgIT0gKE5GQ1NUQVRVU19QRU5ESU5HICYgUEhORkNTVEJMT1dFUikpCiAgICAgICAgewogICAgICAgICAgICAvKiBjYWxsIHJlc3BlY3RpdmUgQ1IgKi8KICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hDckhhbmRsZXIoTmRlZk1hcCxQSF9GUklORkNfTkRFRk1BUF9DUl9DSEtfTkRFRixzdGF0dXMpOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAgTmJjID0gcGhGcmlOZmNfRmVsaWNhX0hHZXRNYXhpbXVtQmxrc1RvUmVhZChOZGVmTWFwLFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfTkJDKTsKCiAgICAgICAgIC8qIE9mZnNldCA9IEN1cnJlbnQsIGJ1dCB0aGUgcmVhZCBoYXMgcmVhY2hlZCB0aGUgRW5kIG9mIE5CQyBCbG9ja3MgKi8KICAgICAgICBpZigoICggT2Zmc2V0ID09IFBIX0ZSSU5GQ19OREVGTUFQX1NFRUtfQ1VSKSAmJiAoTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gPT0gTmJjKSkgJiYKICAgICAgICAgICAgKE5kZWZNYXAtPkZlbGljYS5Fb2ZDYXJkUmVhY2hlZEZsYWcgPT0gRkVMSUNBX1JEX1dSX0VPRl9DQVJEX1JFQUNIRUQgKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsICBORkNTVEFUVVNfRU9GX05ERUZfQ09OVEFJTkVSX1JFQUNIRUQpOyAKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKCiAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5DdXJyQnl0ZXNSZWFkID0gKChOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObyAqIDE2KS0gTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkpOwogICAgICAgICAgICBzdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFJlYWREYXRhKE5kZWZNYXAsTmRlZk1hcC0+RmVsaWNhLk9mZnNldCk7CgogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAoc3RhdHVzKTsKfQoKLypSZWFkIE9wZXJhdGlvbiBSZWxhdGVkIEhlbHBlciBSb3V0aW5lcyovCgovKiEKICogXGJyaWVmIFVzZWQgaW4gUmVhZCBPcGVhcmF0aW9uLlNldHMgdGhlIFRyeCBCdWZmZXIgTGVuIGNhbGxzIFRyYW5zYyBDbWQuCiAqIEFmdGVyIGEgc3VjY2Vzc2Z1bCByZWFkIG9wZXJhdGlvbiwgZnVuY3Rpb24gZG9lcyBjaGVja3MgdGhlIHVzZXIgYnVmZmVyIHNpemUgCiAqIHNldHMgdGhlIHN0YXR1cyBmbGFncy4KKi8KCnN0YXRpYyBORkNTVEFUVVMgcGhGcmlOZmNfRmVsaWNhX0hSZWFkRGF0YShwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXAsdWludDhfdCBvZmZzZXQpCnsKICAgIE5GQ1NUQVRVUyBzdGF0dXMgPSBORkNTVEFUVVNfUEVORElORzsKICAgIHVpbnQxNl90IE5iYz0wLFRyYW5zY0xlbj0wOwoKICAgIE5iYyA9IHBoRnJpTmZjX0ZlbGljYV9IR2V0TWF4aW11bUJsa3NUb1JlYWQoTmRlZk1hcCxQSF9ORkNGUklfTkRFRk1BUF9GRUxJX05CQyk7CiAgICBpZiggKCAoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSA+IDApICYmIChOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObyA8IE5iYyApKQogICAgewogICAgICAgIC8qIGlmIGRhdGEgaXMgcHJlc2VudCBpbiB0aGUgaW50ZXJuYWwgYnVmZmVyKi8KICAgICAgICBpZiAoTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgPiAwICkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGNvcHkgZGF0YSB0byBleHRlcm5hbCBidWZmZXIqLwogICAgICAgICAgICBwaEZyaU5mY19GZWxpY2FfSEFmdGVyUmVhZF9Db3B5RGF0YVRvQnVmZihOZGVmTWFwKTsKICAgICAgICAgICAgLypDaGVjayB0aGUgc2l6ZSBvZiB1c2VyIGJ1ZmZlciovCiAgICAgICAgICAgIHN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IQ2hrQXBkdUJ1ZmZfU2l6ZShOZGVmTWFwKTsKICAgICAgICAgICAgaWYgKCAoc3RhdHVzICE9IE5GQ1NUQVRVU19TVUNDRVNTKSAmJiAoTmRlZk1hcC0+RmVsaWNhLkludGVybWVkaWF0ZVJkRmxhZyA9PSBUUlVFICkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIHNldCB0aGUgdHJhbnNjIGxlbiBhbmQgY2FsbCB0cmFuc2MgY21kKi8KICAgICAgICAgICAgICAgIFRyYW5zY0xlbiA9IHBoRnJpTmZjX0ZlbGljYV9IU2V0VHJ4TGVuKE5kZWZNYXAsTmJjKTsKICAgICAgICAgICAgICAgIHN0YXR1cz0gcGhGcmlOZmNfRmVsaWNhX0hTZXRUcmFuc2NlaXZlRm9yUmVhZChOZGVmTWFwLFRyYW5zY0xlbixvZmZzZXQpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogTm90aGluZyB0byBiZSBkb25lICwgaWYgSW50ZXJtZWRpYXRlUmRGbGFnIGlzIHNldCB0byB6ZXJvKi8KICAgICAgICAgICAgICAgIDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBzZXQgdGhlIHRyYW5zYyBsZW4gYW5kIGNhbGwgdHJhbnNjIGNtZCovCiAgICAgICAgICAgIFRyYW5zY0xlbiA9IHBoRnJpTmZjX0ZlbGljYV9IU2V0VHJ4TGVuKE5kZWZNYXAsTmJjKTsKICAgICAgICAgICAgc3RhdHVzPSBwaEZyaU5mY19GZWxpY2FfSFNldFRyYW5zY2VpdmVGb3JSZWFkKE5kZWZNYXAsVHJhbnNjTGVuLG9mZnNldCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qIENoayB0aGUgQnVmZmVyIHNpemUqLwogICAgICAgIHN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IQ2hrQXBkdUJ1ZmZfU2l6ZShOZGVmTWFwKTsKICAgICAgICBpZiAoIChzdGF0dXMgIT0gTkZDU1RBVFVTX1NVQ0NFU1MpICYmIChOZGVmTWFwLT5GZWxpY2EuSW50ZXJtZWRpYXRlUmRGbGFnID09IFRSVUUgKSkKICAgICAgICB7CiAgICAgICAgICAgIFRyYW5zY0xlbiA9IHBoRnJpTmZjX0ZlbGljYV9IU2V0VHJ4TGVuKE5kZWZNYXAsTmJjKTsKICAgICAgICAgICAgc3RhdHVzPSBwaEZyaU5mY19GZWxpY2FfSFNldFRyYW5zY2VpdmVGb3JSZWFkKE5kZWZNYXAsVHJhbnNjTGVuLG9mZnNldCk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIChzdGF0dXMpOwp9CgovKiEKICogXGJyaWVmIFVzZWQgaW4gUmVhZCBPcGVhcmF0aW9uLlNldHMgdGhlIFRyeCBCdWZmZXIgTGVuLgogKi8KCnN0YXRpYyB1aW50MTZfdCAgICBwaEZyaU5mY19GZWxpY2FfSFNldFRyeExlbihwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXAsdWludDE2X3QgTmJjKQp7CiAgICB1aW50MTZfdCBUcmFuc2NMZW4gPSAwLEJsb2Nrc1RvUmVhZD0wOwoKICAgIGlmKCAoIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpJSAxNikgPT0gMCkKICAgIHsKICAgICAgICBCbG9ja3NUb1JlYWQgPSAodWludDE2X3QpKCAoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KS8xNiApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIEJsb2Nrc1RvUmVhZCA9ICh1aW50MTZfdCkoKChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpLzE2KSArMSk7CiAgICB9CiAgICBpZiAoIChCbG9ja3NUb1JlYWQgPiBOYmMpIHx8KCAoQmxvY2tzVG9SZWFkKSA+ICggTmJjIC0gTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8pKSApCiAgICB7CiAgICAgICAgQmxvY2tzVG9SZWFkID0gTmJjIC0gTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm87CiAgICB9CgoKICAgIGlmICggQmxvY2tzVG9SZWFkID49IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5icikKICAgIHsKICAgICAgICBpZiggTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJyIDwgTmJjICkKICAgICAgICB7CiAgICAgICAgICAgIFRyYW5zY0xlbiA9ICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5OYnIqMTY7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFRyYW5zY0xlbiA9IE5iYyoxNjsKICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkxhc3RCbGtSZWFjaGVkRmxhZyA9MTsKICAgICAgICB9CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKEJsb2Nrc1RvUmVhZCA8PSBOYmMgKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCAoIEJsb2Nrc1RvUmVhZCAqIDE2KSA9PSAoKE5iYyAqMTYpIC0gIChOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObyAqIDE2KSkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5MYXN0QmxrUmVhY2hlZEZsYWcgPTE7CgogICAgICAgICAgICB9CiAgICAgICAgICAgIFRyYW5zY0xlbiA9IEJsb2Nrc1RvUmVhZCoxNjsKCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFRyYW5zY0xlbiA9IE5iYyoxNjsKICAgICAgICB9CiAgICB9CiAgICAvKiBBcyBDdXIgQmxrIGNoYW5nZXMsIHRvIHJlbWVtYmVyIHRoZSBleGFjdCBsZW4gd2hhdCB3ZSBoYWQgc2V0IAogICAgaW4gdGhlIGJlZ2luaW5nIG9mIGVhY2ggcmVhZCBvcGVyYXRpb24qLwogICAgTmRlZk1hcC0+RmVsaWNhLlRyeExlbiA9IFRyYW5zY0xlbjsKICAgIHJldHVybiAoVHJhbnNjTGVuKTsKfQoKLyohCiAqIFxicmllZiBVc2VkIGluIFJlYWQgT3BlYXJhdGlvbi5BZnRlciBhIHN1Y2Nlc3NmdWwgcmVhZCBvcGVyYXRpb24sCiAqICAgQ29waWVzIHRoZSBkYXRhIHRvIHVzZXIgYnVmZmVyLgogKi8KCnN0YXRpYyB2b2lkICAgIHBoRnJpTmZjX0ZlbGljYV9IQWZ0ZXJSZWFkX0NvcHlEYXRhVG9CdWZmKHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCkKewogICAgdWludDhfdCBSZXNldEZsYWcgPSBGQUxTRSwgRXh0ckJ5dGVzVG9DcHkgPSBGQUxTRTsKICAgIHVpbnQxNl90IE5iYz0wOwogICAgdWludDMyX3QgRGF0YUxlbj0wOwogICAgICAgICAgICAgICAgIAogICAgTmJjID0gcGhGcmlOZmNfRmVsaWNhX0hHZXRNYXhpbXVtQmxrc1RvUmVhZChOZGVmTWFwLFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfTkJDICk7CgogICAgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9DQUxfTEVOX0JZVEVTKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTGVuQnl0ZXNbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1syXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGFMZW4pOwogICAgLyogSW50ZXJuYWwgQnVmZmVyIGhhcyBzb21lIG9sZCByZWFkIGJ5dGVzIHRvIGNweSB0byB1c2VyIGJ1ZmZlciovCiAgICBpZiggTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgPiAwICkKICAgIHsKICAgICAgICBpZiAoIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpIDwgTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgKQogICAgICAgIHsKICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5IC09ICh1aW50OF90KShOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpOwogICAgICAgICAgICAKICAgICAgICAgICAgICAgIGlmIChOZGVmTWFwLT5GZWxpY2EuSW50ZXJtZWRpYXRlQ3B5RmxhZyA9PSBUUlVFICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKkNvcHkgZGF0YSBmcm9tIHRoZSBpbnRlcm5hbCBidWZmZXIgdG8gdXNlciBidWZmZXIqLwogICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCYoTmRlZk1hcC0+RmVsaWNhLlJkX0J5dGVzVG9Db3B5QnVmZltOZGVmTWFwLT5GZWxpY2EuSW50ZXJtZWRpYXRlQ3B5TGVuXSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSk7CgogICAgICAgICAgICAgICAgICAgICAgCgogICAgICAgICAgICAgICAgICAgIC8qIFN0b3JlIG51bWJlciBvZiBieXRlcyBjb3BpZWQgZnJtIGludGVybmFsIGJ1ZmZlciB0byBVc2VyIEJ1ZmZlciAqLwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5JbnRlcm1lZGlhdGVDcHlMZW4gKz0gKHVpbnQ4X3QpKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkludGVybWVkaWF0ZUNweUZsYWcgPSAxOyAgICAgICAgICAgICAgICAKCiAgICAgICAgICAgICAgICAgICAgLyogY2hlY2sgZG8gd2UgcmVhY2ggbGVuIGJ5dGVzIGFueSBjaGFuY2UqLwogICAgICAgICAgICAgICAgICAgIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfQ0FMX0xFTl9CWVRFUyhOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1swXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1syXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhTGVuKTsKICAgICAgICAgICAgICAgICAgICAvKiBJbnRlcm5hbCBidWZmZXIgaGFzIHplcm8gYnl0ZXMgZm9yIGNvcHkgb3BlcmF0aW9uKi8KICAgICAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5ID09IDApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnID1GRUxJQ0FfUkRfV1JfRU9GX0NBUkRfUkVBQ0hFRDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLypDb3B5IGRhdGEgZnJvbSB0aGUgaW50ZXJuYWwgYnVmZmVyIHRvIGFwZHUgYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCAoJihOZGVmTWFwLT5BcGR1QnVmZmVyW05kZWZNYXAtPkFwZHVCdWZmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9CeXRlc1RvQ29weUJ1ZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggKz0gKHVpbnQ4X3QpKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCk7CiAgICAgICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAoIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpID09IE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5ICkKICAgICAgICB7CiAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLkludGVybWVkaWF0ZUNweUZsYWcgPT0gVFJVRSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qQ29weSBkYXRhIGludGVybmFsIGJ1ZmYgdG8gYXBkdWJ1ZmZlciovCiAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCAoJihOZGVmTWFwLT5BcGR1QnVmZmVyW05kZWZNYXAtPkFwZHVCdWZmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5GZWxpY2EuUmRfQnl0ZXNUb0NvcHlCdWZmW05kZWZNYXAtPkZlbGljYS5JbnRlcm1lZGlhdGVDcHlMZW5dKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUmRfTm9CeXRlc1RvQ29weSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKkNvcHkgZGF0YSBpbnRlcm5hbCBidWZmIHRvIGFwZHVidWZmZXIqLwogICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggKCYoTmRlZk1hcC0+QXBkdUJ1ZmZlcltOZGVmTWFwLT5BcGR1QnVmZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9CeXRlc1RvQ29weUJ1ZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKmluY3JlbWVudCB0aGUgaW5kZXgsaW50ZXJuYWwgYnVmZmVyIGxlbiovCiAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggKz0gTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHk7CiAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5IC09ICh1aW50OF90KShOZGVmTWFwLT5BcGR1QnVmZkluZGV4KTsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qIFRvIHJlc2V0IHRoZSBwYXJhbWV0ZXJzKi8KICAgICAgICAgICAgUmVzZXRGbGFnID0gVFJVRTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogRXh0cmEgQnl0ZXMgdG8gQ29weSBmcm9tIGludGVybmFsIGJ1ZmZlciB0byBleHRlcm5hbCBidWZmZXIqLwogICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5JbnRlcm1lZGlhdGVDcHlGbGFnID09IFRSVUUgKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKkNvcHkgZGF0YSBpbnRlcm5hbCBidWZmIHRvIGFwZHVidWZmZXIqLwogICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggKCYoTmRlZk1hcC0+QXBkdUJ1ZmZlcltOZGVmTWFwLT5BcGR1QnVmZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCYoTmRlZk1hcC0+RmVsaWNhLlJkX0J5dGVzVG9Db3B5QnVmZltOZGVmTWFwLT5GZWxpY2EuSW50ZXJtZWRpYXRlQ3B5TGVuXSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLypDb3B5IGRhdGEgaW50ZXJuYWwgYnVmZiB0byBhcGR1YnVmZmVyKi8KICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUmRfQnl0ZXNUb0NvcHlCdWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5KTsKICAgICAgICAgICAgfQogICAgICAgICAgICAvKmluY3JlbWVudCB0aGUgaW5kZXgqLwogICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ICs9IE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5OwoKICAgICAgICAgICAgLyogVG8gcmVzZXQgdGhlIHBhcmFtZXRlcnMqLwogICAgICAgICAgICBSZXNldEZsYWcgPSBUUlVFOwogICAgICAgIH0KICAgIH0vKkVuZCBvZiBJbnRlcm5hbCBCdWZmZXIgaGFzIHNvbWUgb2xkIHJlYWQgYnl0ZXMgdG8gY3B5IHRvIHVzZXIgYnVmZmVyKi8KICAgIGVsc2UKICAgIHsgICAgICAgCiAgICAgICAgLyogY2hlY2sgaWYgbGFzdCBibG9jayBpcyByZWFjaGVkKi8KICAgICAgICBpZiAoICgoTmRlZk1hcC0+RmVsaWNhLkxhc3RCbGtSZWFjaGVkRmxhZyA9PSAxKSAmJiAoKCBOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpID49IDE2KSkgKQogICAgICAgIHsKICAgICAgICAgICAgLyogZ3JlYXRlciB0aGFuIDE2IGJ1dCBsZXNzIHRoYW4gdGhlIGRhdGEgbGVuIHNpemUqLwogICAgICAgICAgICBpZiAoKCBOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpID49IERhdGFMZW4pCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5DdXJyQnl0ZXNSZWFkID0gKHVpbnQxNl90KSgoRGF0YUxlbikgLSAoTmRlZk1hcC0+RmVsaWNhLkN1cnJCeXRlc1JlYWQgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpKTsKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggKCYoTmRlZk1hcC0+QXBkdUJ1ZmZlcltOZGVmTWFwLT5BcGR1QnVmZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMTNdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkN1cnJCeXRlc1JlYWQpOwoKICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggKz0gTmRlZk1hcC0+RmVsaWNhLkN1cnJCeXRlc1JlYWQ7CiAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggPT0gRGF0YUxlbikKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBSZXNldEZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogbmVlZCB0byBjaGVjayBleGFjdCBuby4gb2YgYnl0ZXMgdG8gY29weSB0byBidWZmZXIqLwogICAgICAgICAgICAgICAgaWYoICggKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCkgPD0gTmRlZk1hcC0+RmVsaWNhLlRyeExlbiApfHwKICAgICAgICAgICAgICAgICAgICAoKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCkgPD0gRGF0YUxlbiApKQogICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICBFeHRyQnl0ZXNUb0NweSA9IFRSVUU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgPSAodWludDhfdCkoMTYtKCggTmJjICogMTYpIC0gKERhdGFMZW4pKSk7CgogICAgICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgPiAoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qUmVkdWNlIGFscmVhZHkgY29waWVkIGJ5dGVzIGZyb20gdGhlIGludGVybmFsIGJ1ZmZlciovCiAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5IC09ICh1aW50OF90KShOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICBFeHRyQnl0ZXNUb0NweSA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEV4dHJCeXRlc1RvQ3B5ID0gRkFMU0U7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCBFeHRyQnl0ZXNUb0NweSA9PSBUUlVFICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuQ3VyckJ5dGVzUmVhZCA9ICh1aW50MTZfdCkoKERhdGFMZW4pLSAoTmRlZk1hcC0+RmVsaWNhLkN1cnJCeXRlc1JlYWQgKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpKTsKCiAgICAgICAgICAgICAgICAgICAgaWYoTmRlZk1hcC0+RmVsaWNhLkN1cnJCeXRlc1JlYWQgPCAKICAgICAgICAgICAgICAgICAgICAgICAgKHVpbnQxNl90KShOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIAogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMTNdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5DdXJyQnl0ZXNSZWFkKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggKCYoIE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCYoIE5kZWZNYXAtPlNlbmRSZWN2QnVmWzEzXSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVpbnQxNl90KShOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpKTsKICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLkxhc3RCbGtSZWFjaGVkRmxhZyA9PSAxICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5ID0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1aW50OF90KSgoTmRlZk1hcC0+RmVsaWNhLkN1cnJCeXRlc1JlYWQgPiAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVpbnQxNl90KShOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpKT8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5kZWZNYXAtPkZlbGljYS5DdXJyQnl0ZXNSZWFkIC0gCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1aW50MTZfdCkoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSk6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgUmVzZXRGbGFnID0gKChOZGVmTWFwLT5GZWxpY2EuUmRfTm9CeXRlc1RvQ29weSA9PSAwKT9UUlVFOkZBTFNFKTsKCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5ID0gKHVpbnQ4X3QpKCBOZGVmTWFwLT5GZWxpY2EuVHJ4TGVuIC0gKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCkpOwogICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgLyogQ29weSByZW1haW5lZCBieXRlcyBiYWNrIGludG8gaW50ZXJuYWwgYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCAgIE5kZWZNYXAtPkZlbGljYS5SZF9CeXRlc1RvQ29weUJ1ZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZltQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1JFU1BfSEVBREVSX0xFTisoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KV0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5KTsKCiAgICAgICAgICAgICAgICAgICAgLyogc2V0IHRoZSBpbnRlcm1lZGlhdGUgZmxhZyA6IFRoaXMgZmxhZyByZW1lbWJlcnMgdGhhdCB0aGVyZSBhcmUgc3RpbGwgWCBuby4gYnl0ZXMgcmVtYWluZWQgaW4KICAgICAgICAgICAgICAgICAgICBJbnRlcm5hbCBCdWZmZXIgRXg6IFVzZXIgaGFzIGdpdmVuIG9ubHkgb25lIGJ5dGUgYnVmZmVyLG5lZWRzIHRvIGNweSBvbmUgYnl0ZSBhdCBhIHRpbWUqLwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5JbnRlcm1lZGlhdGVDcHlGbGFnID0gVFJVRTsKCiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCArPSAoKE5kZWZNYXAtPkZlbGljYS5DdXJyQnl0ZXNSZWFkIDwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1aW50MTZfdCkoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCkpPwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuQ3VyckJ5dGVzUmVhZDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVpbnQxNl90KShOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSk7IAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSAKICAgICAgICAgICAgICAgIHsgICAKICAgICAgICAgICAgICAgICAgICAvKkNvcHkgZGF0YSBmcm9tIHRoZSBpbnRlcm5hbCBidWZmZXIgdG8gdXNlciBidWZmZXIqLwogICAgICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggKCYoIE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxM10pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUmRfTm9CeXRlc1RvQ29weSk7CgogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggKz0gTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHk7CiAgICAgICAgICAgICAgICAgICAgUmVzZXRGbGFnID0gVFJVRTsgCgogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9ICAgIAogICAgCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmICgoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSA8IE5kZWZNYXAtPkZlbGljYS5UcnhMZW4gKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBDYWxjdWxhdGUgZXhhY3RseSByZW1haW5lZCBieXRlcyB0byBjb3B5IHRvIGludGVybmFsIGJ1ZmZlciBhbmQgc2V0IGl0Ki8KICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLkxhc3RCbGtSZWFjaGVkRmxhZyA9PSAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5ID0gKHVpbnQ4X3QpKDE2LSgoIE5iYyAqIDE2KSAtIERhdGFMZW4pKTsKCiAgICAgICAgICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5GZWxpY2EuUmRfTm9CeXRlc1RvQ29weSA+IChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLypSZWR1Y2UgYWxyZWFkeSBjb3BpZWQgYnl0ZXMgZnJvbSB0aGUgaW50ZXJuYWwgYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgLT0gKHVpbnQ4X3QpKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCk7CiAgICAgICAgICAgICAgICAgICAgICAgIEV4dHJCeXRlc1RvQ3B5ID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgPSAodWludDhfdCkoTmRlZk1hcC0+RmVsaWNhLlRyeExlbiAtIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpKTsKICAgICAgICAgICAgICAgICAgICBFeHRyQnl0ZXNUb0NweSA9IFRSVUU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoIEV4dHJCeXRlc1RvQ3B5ID09IFRSVUUgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qQ29weSB0aGUgcmVhZCBkYXRhIGZyb20gdHJ4IGJ1ZmZlciB0byBhcGR1IG9mIHNpemUgYXBkdSovCiAgICAgICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggKCYoTmRlZk1hcC0+QXBkdUJ1ZmZlcltOZGVmTWFwLT5BcGR1QnVmZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmWzEzXSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpOwoKICAgICAgICAgICAgICAgICAgICAvKmNvcHkgYnl0ZXNUb0NvcHkgdG8gaW50ZXJuYWwgYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCBOZGVmTWFwLT5GZWxpY2EuUmRfQnl0ZXNUb0NvcHlCdWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMTMrKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCldKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5KTsKCiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkludGVybWVkaWF0ZUNweUZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggKz0gKHVpbnQxNl90KU5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsgICAKICAgICAgICAgICAgICAgICAgICAvKkNvcHkgZGF0YSBmcm9tIHRoZSBpbnRlcm5hbCBidWZmZXIgdG8gdXNlciBidWZmZXIqLwogICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxM10pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkpOwoKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ICs9IE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5OwogICAgICAgICAgICAgICAgICAgIFJlc2V0RmxhZyA9IFRSVUU7IAogICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCBEYXRhTGVuIDw9IChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZyA9RkVMSUNBX1JEX1dSX0VPRl9DQVJEX1JFQUNIRUQ7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSBpZiAoKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCkgPT0gTmRlZk1hcC0+RmVsaWNhLlRyeExlbiApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qQ29weSBleGFjdGx5IHJlbWFpbmVkIGxhc3QgYnl0ZXMgdG8gdXNlciBidWZmZXIgYW5kIGluY3JlbWVudCB0aGUgaW5kZXgqLwogICAgICAgICAgICAgICAgLyoxMyA6IDErMTIgOiAxc3QgYnl0ZSBlbnRpcmUgcGt0IGxlbmd0aCArIDEyIGJ5dGVzIHRvIHNraXAgbWFudWYgZGV0YWlscyovCiAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCAoJihOZGVmTWFwLT5BcGR1QnVmZmVyW05kZWZNYXAtPkFwZHVCdWZmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxM10pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChOZGVmTWFwLT5GZWxpY2EuVHJ4TGVuICkpOwoKICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggKz0gTmRlZk1hcC0+RmVsaWNhLlRyeExlbjsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSA+IE5kZWZNYXAtPkZlbGljYS5UcnhMZW4gKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKkNvcHkgdGhlIGRhdGEgdG8gYXBkdSBidWZmZXIgYW5kIGluY3JlbWVudCB0aGUgaW5kZXggKi8KICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggKCYoTmRlZk1hcC0+QXBkdUJ1ZmZlcltOZGVmTWFwLT5BcGR1QnVmZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZltQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1JFU1BfSEVBREVSX0xFTl0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5UcnhMZW4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCArPSAodWludDE2X3QpTmRlZk1hcC0+RmVsaWNhLlRyeExlbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmICggUmVzZXRGbGFnID09IFRSVUUgKQogICAgewogICAgICAgIC8qIHJlc2V0IHRoZSBpbnRlcm5hbCBidWZmZXIgdmFyaWFibGVzKi8KICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUmRfTm9CeXRlc1RvQ29weSA9MDsKICAgICAgICBOZGVmTWFwLT5GZWxpY2EuSW50ZXJtZWRpYXRlQ3B5TGVuID0wOwogICAgICAgIE5kZWZNYXAtPkZlbGljYS5JbnRlcm1lZGlhdGVDcHlGbGFnID1GQUxTRTsKICAgIH0KICAgIHJldHVybjsKfQoKCi8qIQogKiBcYnJpZWYgVXNlZCBpbiBSZWFkIE9wZWFyYXRpb24uQWZ0ZXIgYSBzdWNjZXNzZnVsIHJlYWQgb3BlcmF0aW9uLAogICAgQ2hlY2tzIHRoZSByZWxhdmVudCBidWZmZXIgc2l6ZXMgYW5kIHNldCB0aGUgc3RhdHVzLkZvbGxvd2luZyBmdW5jdGlvbiBpcyB1c2VkCiAgICB3aGVuIHdlIHJlYWQgdGhlIE5tYXhiIGJsb2Nrcy4gUmV0YWluZWQgZm9yIGZ1dHVyZSBwdXJwb3NlLgogKi8KCnN0YXRpYyBORkNTVEFUVVMgcGhGcmlOZmNfRmVsaWNhX0hDaGtBcGR1QnVmZl9TaXplKCBwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXApCnsKICAgIE5GQ1NUQVRVUyBzdGF0dXMgPSBORkNTVEFUVVNfUEVORElORzsKICAgIHVpbnQ4X3QgUmVzZXRGbGFnID0gRkFMU0U7CiAgICB1aW50MzJfdCBOYmMgPSAwOwoKICAgIE5iYyA9IHBoRnJpTmZjX0ZlbGljYV9IR2V0TWF4aW11bUJsa3NUb1JlYWQoTmRlZk1hcCxQSF9ORkNGUklfTkRFRk1BUF9GRUxJX05CQyk7CgogICAgLyogc2V0IHN0YXR1cyB0byBTdWNjZXNzIDogVXNlciBCdWZmZXIgaXMgZnVsbCBhbmQgQ3VyYmxrIDwgbm1heGIqLwogICAgaWYgKCAoKCBOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZS1OZGVmTWFwLT5BcGR1QnVmZkluZGV4ICk9PSAwKSAmJiAKICAgICAgICAgKE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vIDwgTmJjICkpCiAgICB7CiAgICAgICAgc3RhdHVzID0gUEhORkNTVFZBTChDSURfTkZDX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5GQ1NUQVRVU19TVUNDRVNTKTsKICAgICAgICAvKlJlc2V0IHRoZSBpbmRleCwgaW50ZXJuYWwgYnVmZmVyIGNvdW50ZXJzIGJhY2sgdG8gemVybyovCiAgICAgICAgKk5kZWZNYXAtPk51bU9mQnl0ZXNSZWFkID0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleDsKICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ID0gMDsKICAgICAgICAgICAgICAgIAogICAgfS8qaWYoIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZS1OZGVmTWFwLT5BcGR1QnVmZkluZGV4ICk9PSAwICYmIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vIDwgTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGIgKSovCiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKCggKCBOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZS1OZGVmTWFwLT5BcGR1QnVmZkluZGV4ICk9PSAwKSAmJgogICAgICAgICAgICAgKE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vID09IE5iYyApKQogICAgICAgIHsKICAgICAgICAgICAgc3RhdHVzID0gUEhORkNTVFZBTChDSURfTkZDX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5GQ1NUQVRVU19TVUNDRVNTKTsKICAgICAgICAgICAgCiAgICAgICAgICAgIFJlc2V0RmxhZyA9ICgoTmRlZk1hcC0+RmVsaWNhLlJkX05vQnl0ZXNUb0NvcHkgPiAwICk/CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBGQUxTRToKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUpOwogICAgICAgICAgICBpZiggUmVzZXRGbGFnPT0gRkFMU0UpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICpOZGVmTWFwLT5OdW1PZkJ5dGVzUmVhZCA9IE5kZWZNYXAtPkFwZHVCdWZmSW5kZXg7CiAgICAgICAgICAgICAgICAvKlJlc2V0IHRoZSBpbmRleCwgaW50ZXJuYWwgYnVmZmVyIGNvdW50ZXJzIGJhY2sgdG8gemVybyovCiAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0vKmlmICgoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUtTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCApPT0gMCAmJiBOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObyA9PSBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YiApKi8KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiByZWFjaGVkIHJlYWRpbmcgYWxsIHRoZSBibGtzIGF2YWlsYWJsZSBpbiB0aGUgY2FyZDogc2V0IEVPRiBmbGFnKi8KICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ID09IChOYmMqMTYpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9ORkNfTk9ORSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX1NVQ0NFU1MpOwogICAgICAgICAgICAgICAgUmVzZXRGbGFnID0gVFJVRTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICgoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUtTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCApPiAwICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vID09IE5iYyApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKiBieXRlcyBwZW5kaW5nIGluIGludGVybmFsIGJ1ZmZlciAsIE5vIFNwYWNlIGluIFVzZXIgQnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5GZWxpY2EuUmRfTm9CeXRlc1RvQ29weSA+IDApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZyA9PSBUUlVFICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9ORkNfTk9ORSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfU1VDQ0VTUyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKk5kZWZNYXAtPk51bU9mQnl0ZXNSZWFkID0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4PTA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hBZnRlclJlYWRfQ29weURhdGFUb0J1ZmYoTmRlZk1hcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5ID4gMCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9ORkNfTk9ORSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5GQ1NUQVRVU19TVUNDRVNTKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKk5kZWZNYXAtPk51bU9mQnl0ZXNSZWFkID0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleD0wOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeyAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBFT0YgQ2FyZCBSZWFjaGVkIHNldCB0aGUgaW50ZXJuYWwgRU9GIEZsYWcqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9ORkNfTk9ORSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX1NVQ0NFU1MpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzZXRGbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLyogQWxsIGJ5dGVzIGZyb20gaW50ZXJuYWwgYnVmZmVyIGFyZSBjb3BpZWQgYW5kIHNldCBlb2YgZmxhZyovCiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gUEhORkNTVFZBTChDSURfTkZDX05PTkUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX1NVQ0NFU1MpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVzZXRGbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBmbGFnIGlzIHNldCB0byBlbnN1cmUgdGhhdCwgbmVlZCBvZiBSZWFkIE9wZWFyYXRpb24KICAgICAgICAgICAgICAgICAgICAgICAgd2UgY29tcGxldGVkIGNveWluZyB0aGUgZGF0YSBmcm9tIGludGVybmFsIGJ1ZmZlciB0byBleHRlcm5hbCBidWZmZXIKICAgICAgICAgICAgICAgICAgICAgICAgbGVmdCBzb21lIG1vcmUgYnl0ZXMsaW4gVXNlciBidWZlciBzbyBpbml0aWF0ZSB0aGUgcmVhZCBvcGVyYXRpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkludGVybWVkaWF0ZVJkRmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX05GQ19OT05FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfU1VDQ0VTUyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgaWYgKCBSZXNldEZsYWcgPT0gVFJVRSkKICAgICAgICB7CiAgICAgICAgICAgICpOZGVmTWFwLT5OdW1PZkJ5dGVzUmVhZCA9IE5kZWZNYXAtPkFwZHVCdWZmSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypSZXNldCB0aGUgaW5kZXgsIGludGVybmFsIGJ1ZmZlciBjb3VudGVycyBiYWNrIHRvIHplcm8qLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5SZF9Ob0J5dGVzVG9Db3B5PTA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZz1GRUxJQ0FfUkRfV1JfRU9GX0NBUkRfUkVBQ0hFRDsKCiAgICAgICAgfQogICAgICAgIAogICAgfQogICAgcmV0dXJuKCBzdGF0dXMpOwp9CgovKiEKICogXGJyaWVmIFVzZWQgaW4gUmVhZCBPcGVhcmF0aW9uLlNldHMgdGhlIHRyYW5zY2VpdmUgQ29tbWFuZCBmb3IgcmVhZC4KICovCnN0YXRpYyBORkNTVEFUVVMgICBwaEZyaU5mY19GZWxpY2FfSFNldFRyYW5zY2VpdmVGb3JSZWFkKHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCx1aW50MTZfdCBUcnhMZW4sdWludDhfdCBPZmZzZXQpCnsKICAgIE5GQ1NUQVRVUyBUcnhTdGF0dXMgPSAgTkZDU1RBVFVTX1BFTkRJTkc7CiAgICB1aW50MTZfdCBCdWZJbmRleD0wLGk9MDsKICAgCiAgICAvKiBzZXQgdGhlIGZlbGljYSBjbWQgKi8KI2lmZGVmIFBIX0hBTDRfRU5BQkxFCiAgICBOZGVmTWFwLT5DbWQuRmVsQ21kID0gcGhIYWxfZUZlbGljYV9SYXc7CiNlbHNlCiAgICBOZGVmTWFwLT5DbWQuRmVsQ21kID0gcGhIYWxfZUZlbGljYUNtZExpc3RGZWxpY2FDbWQ7CiNlbmRpZiAvKiAjaWZkZWYgUEhfSEFMNF9FTkFCTEUgKi8KCiAgICAvKkNoYW5nZSB0aGUgc3RhdGUgdG8gUmVhZCAqLwogICAgTmRlZk1hcC0+U3RhdGUgPSBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1NUQVRFX1JEX0JMT0NLOyAgICAKCiAgICAvKiBzZXQgdGhlIGNvbXBsaXRpb24gcm91dGluZXMgZm9yIHRoZSBtaWZhcmUgb3BlcmF0aW9ucyAqLwogICAgTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8uQ29tcGxldGlvblJvdXRpbmUgPSBwaEZyaU5mY19GZWxpY2FfUHJvY2VzczsKICAgIE5kZWZNYXAtPk1hcENvbXBsZXRpb25JbmZvLkNvbnRleHQgPSBOZGVmTWFwOwoKICAgIC8qc2V0IHRoZSBhZGRpdGlvbmFsIGluZm9ybWF0aW9ucyBmb3IgdGhlIGRhdGEgZXhjaGFuZ2UqLwogICAgTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mby5EZXBGbGFncy5NZXRhQ2hhaW5pbmcgPSAwOwogICAgTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mby5EZXBGbGFncy5OQURQcmVzZW50ID0gMDsKCiAgICAvKiBwa3QgbGVuIDogdXBkYXRlZCBhdCB0aGUgZW5kKi8KICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwMDsgCiAgICBCdWZJbmRleCArKzsKCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4MDY7CiAgICBCdWZJbmRleCsrOwoKICAgIC8qIElEbSAtIE1hbnVmYWN0dXJlciBJZCA6IDhieXRlcyovCiNpZmRlZiBQSF9IQUw0X0VOQUJMRQogICAgKHZvaWQpbWVtY3B5KCgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAodm9pZCAqICkoJihOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uSURtKSksCiAgICAgICAgICAgICAgICAgICA4KTsKI2Vsc2UKICAgICAodm9pZCltZW1jcHkoKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICh2b2lkICogKSgmKE5kZWZNYXAtPnBzUmVtb3RlRGV2SW5mby0+UmVtb3RlRGV2SW5mby5DYXJkSW5mbzIxMl80MjQuU3RhcnR1cDIxMl80MjQuTkZDSUQydCkpLAogICAgICAgICAgICAgICAgICAgOCk7CiNlbmRpZiAgLyogI2lmZGVmIFBIX0hBTDRfRU5BQkxFICovCgogICAgQnVmSW5kZXgrPTg7CgogICAgLypOdW1iZXIgb2YgU2VydmljZXMgKG49MSA9PT4gMHg4MCkqLwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDAxOyAgIAogICAgQnVmSW5kZXgrKzsKCiAgICAvKlNlcnZpY2UgQ29kZSBMaXN0Ki8KICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwQjsgIAogICAgQnVmSW5kZXgrKzsKCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4MDA7IAogICAgQnVmSW5kZXgrKzsKCiAgICAvKk51bWJlciBvZiBCbG9ja3MgdG8gcmVhZCovCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgKHVpbnQ4X3QpKFRyeExlbi8xNik7ICAKICAgIEJ1ZkluZGV4Kys7CiAgICAvKiBTZXQgdGhlIEJsayBudW1iZXJzIGFzIHBlciB0aGUgb2Zmc2V0IHNldCBieSB0aGUgdXNlciA6IEJsb2NrIExpc3QqLwogICAgaWYgKCBPZmZzZXQgPT0gUEhfRlJJTkZDX05ERUZNQVBfU0VFS19CRUdJTiApCiAgICB7CiAgICAgICAgZm9yICggaT0wO2k8KFRyeExlbi8xNik7aSsrKQogICAgICAgIHsKICAgICAgICAgICAgLyoxc3QgU2VydmljZSBDb2RlIGxpc3QgOiBieXRlIDEqLwogICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4ODA7ICAKICAgICAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgICAgIC8qIE5vLiBPZiBCbG9ja3MqLwogICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgICh1aW50OF90KShpICsgMSk7IAogICAgICAgICAgICBCdWZJbmRleCsrOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBmb3IgKCBpPSAxO2k8PShUcnhMZW4vMTYpO2krKykKICAgICAgICB7CiAgICAgICAgICAgIC8qMXN0IFNlcnZpY2UgQ29kZSBsaXN0IDogYnl0ZSAxKi8KICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDgwOwogICAgICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAgICAgLyogTm8uIE9mIEJsb2NrcyovCiAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgKHVpbnQ4X3QpKE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vICsgaSk7CiAgICAgICAgICAgIEJ1ZkluZGV4Kys7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKiBsZW4gb2YgZW50aXJlIHBrdCovCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1BLVF9MRU5fSU5ERVhdICAgICAgICAgID0gICh1aW50OF90KSBCdWZJbmRleDsKCiAgICAvKiBTZXQgdGhlIFBrdCBMZW4qLwogICAgTmRlZk1hcC0+U2VuZExlbmd0aCA9IEJ1ZkluZGV4OwoKICAgICpOZGVmTWFwLT5TZW5kUmVjdkxlbmd0aCA9IE5kZWZNYXAtPlRlbXBSZWNlaXZlTGVuZ3RoOwoKICAgIFRyeFN0YXR1cyA9IHBoRnJpTmZjX092ckhhbF9UcmFuc2NlaXZlKE5kZWZNYXAtPkxvd2VyRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk5kZWZNYXAtPk1hcENvbXBsZXRpb25JbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+cHNSZW1vdGVEZXZJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+Q21kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJk5kZWZNYXAtPnBzRGVwQWRkaXRpb25hbEluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2TGVuZ3RoKTsKICAgIHJldHVybiAoVHJ4U3RhdHVzKTsKfQoKLyohCiAqIFxicmllZiBJbml0aWF0ZXMgV3JpdGluZyBvZiBOREVGIGluZm9ybWF0aW9uIHRvIHRoZSBSZW1vdGUgRGV2aWNlLgogKgogKiBUaGUgZnVuY3Rpb24gaW5pdGlhdGVzIHRoZSB3cml0aW5nIG9mIE5ERUYgaW5mb3JtYXRpb24gdG8gYSBSZW1vdGUgRGV2aWNlLgogKiBJdCBwZXJmb3JtcyBhIHJlc2V0IG9mIHRoZSBzdGF0ZSBhbmQgc3RhcnRzIHRoZSBhY3Rpb24gKHN0YXRlIG1hY2hpbmUpLgogKiBBIHBlcmlvZGljIGNhbGwgb2YgdGhlIFxyZWYgcGhGcmlOZmNOZGVmTWFwX1Byb2Nlc3MgaGFzIHRvIGJlIGRvbmUgb25jZSB0aGUgYWN0aW9uCiAqIGhhcyBiZWVuIHRyaWdnZXJlZC4KICovCgpORkNTVEFUVVMgcGhGcmlOZmNfRmVsaWNhX1dyTmRlZiggIHBoRnJpTmZjX05kZWZNYXBfdCAgKk5kZWZNYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgICAgICAgICAgICAgKlBhY2tldERhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90ICAgICAgICAgICAgKlBhY2tldERhdGFMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgICAgICAgICAgICAgT2Zmc2V0KQp7CgogICAgTkZDU1RBVFVTIHN0YXR1cyA9IE5GQ1NUQVRVU19QRU5ESU5HOwoKICAgIE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplID0gKlBhY2tldERhdGFMZW5ndGg7CiAgICAvKlN0b3JlIHRoZSBwYWNrZXQgZGF0YSBidWZmZXIqLwogICAgTmRlZk1hcC0+QXBkdUJ1ZmZlciA9IFBhY2tldERhdGE7CgogICAgLyogVG8gVXBkYXRlIHRoZSBBY3V0YWwgd3JpdHRlbiBieXRlcyB0byBjb250ZXh0Ki8KICAgIE5kZWZNYXAtPldyTmRlZlBhY2tldExlbmd0aCA9IFBhY2tldERhdGFMZW5ndGg7CiAgICAqTmRlZk1hcC0+V3JOZGVmUGFja2V0TGVuZ3RoID0gMDsKCgogICAgTmRlZk1hcC0+UHJldk9wZXJhdGlvbiA9IFBIX0ZSSU5GQ19OREVGTUFQX1dSSVRFX09QRTsKICAgIE5kZWZNYXAtPkZlbGljYS5PZmZzZXQgPSBPZmZzZXQ7ICAgIAoKICAgIE5kZWZNYXAtPkZlbGljYS5PcEZsYWcgPSBQSF9GUklORkNfTkRFRk1BUF9GRUxJX1dSX0FUVFJfUkRfT1A7CiAgICBzdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFJkQXR0ckluZm8oTmRlZk1hcCk7CiAgICAvKiBoYW5kbGUgdGhlIGVycm9yIGluIFRyYW5zYyBmdW5jdGlvbiovCiAgICBpZiAoIChzdGF0dXMgJiBQSE5GQ1NUQkxPV0VSKSAhPSAoTkZDU1RBVFVTX1BFTkRJTkcgJiBQSE5GQ1NUQkxPV0VSKSkKICAgIHsKICAgICAgICAvKiBjYWxsIHJlc3BlY3RpdmUgQ1IgKi8KICAgICAgICBwaEZyaU5mY19GZWxpY2FfSENySGFuZGxlcihOZGVmTWFwLFBIX0ZSSU5GQ19OREVGTUFQX0NSX0NIS19OREVGLHN0YXR1cyk7CiAgICB9CiAgICByZXR1cm4gKHN0YXR1cyk7Cn0KCi8qIQogKiBcYnJpZWYgSW5pdGlhdGVzIFdyaXRpbmcgb2YgRW1wdHkgTkRFRiBpbmZvcm1hdGlvbiB0byB0aGUgUmVtb3RlIERldmljZS4KICoKICogVGhlIGZ1bmN0aW9uIGluaXRpYXRlcyB0aGUgd3JpdGluZyBlbXB0eSBvZiBOREVGIGluZm9ybWF0aW9uIHRvIGEgUmVtb3RlIERldmljZS4KICogSXQgcGVyZm9ybXMgYSByZXNldCBvZiB0aGUgc3RhdGUgYW5kIHN0YXJ0cyB0aGUgYWN0aW9uIChzdGF0ZSBtYWNoaW5lKS4KICogQSBwZXJpb2RpYyBjYWxsIG9mIHRoZSBccmVmIHBoRnJpTmZjTmRlZk1hcF9Qcm9jZXNzIGhhcyB0byBiZSBkb25lIG9uY2UgdGhlIGFjdGlvbgogKiBoYXMgYmVlbiB0cmlnZ2VyZWQuCiAqLwoKTkZDU1RBVFVTIHBoRnJpTmZjX0ZlbGljYV9FcmFzZU5kZWYoICBwaEZyaU5mY19OZGVmTWFwX3QgICpOZGVmTWFwKQp7CgogICAgTkZDU1RBVFVTIHN0YXR1cyA9IE5GQ1NUQVRVU19QRU5ESU5HOwogICAgc3RhdGljIHVpbnQzMl90IFBrdER0TGVuZ3RoID0wOwoKICAgIGlmICggTmRlZk1hcC0+Q2FyZFN0YXRlID09IFBIX05ERUZNQVBfQ0FSRF9TVEFURV9JTlZBTElEICkKICAgIHsKICAgICAgICAvKiAgQ2FyZCBpcyBpbiBpbnZhbGlkIHN0YXRlLCBjYW5ub3QgaGF2ZSBhbnkgcmVhZC93cml0ZSAKICAgICAgICBvcGVyYXRpb25zKi8KICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLFwKICAgICAgICAgICAgTkZDU1RBVFVTX0lOVkFMSURfRk9STUFUKTsKICAgIH0KICAgIGVsc2UgaWYgKCBOZGVmTWFwLT5DYXJkU3RhdGUgPT0gUEhfTkRFRk1BUF9DQVJEX1NUQVRFX1JFQURfT05MWSApCiAgICB7CiAgICAgICAgLypDYW4ndCB3cml0ZSB0byB0aGUgY2FyZCA6Tm8gR3JhbnRzICovCiAgICAgICAgc3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCxcCiAgICAgICAgICAgIE5GQ1NUQVRVU19XUklURV9GQUlMRUQpOwogICAgICAgIC8qIHNldCB0aGUgbm8uIGJ5dGVzIHdyaXR0ZW4gaXMgemVybyovCiAgICAgICAgTmRlZk1hcC0+V3JOZGVmUGFja2V0TGVuZ3RoID0gJlBrdER0TGVuZ3RoOwogICAgICAgICpOZGVmTWFwLT5Xck5kZWZQYWNrZXRMZW5ndGggPSAwOwogICAgfQogICAgZWxzZQogICAgewoKICAgICAgICAvKiBzZXQgdGhlIE9wZXJhdGlvbiovCiAgICAgICAgTmRlZk1hcC0+RmVsaWNhLk9wRmxhZyA9IFBIX0ZSSU5GQ19OREVGTUFQX0ZFTElfV1JfRU1QVFlfTVNHX09QOwoKICAgICAgICBzdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFJkQXR0ckluZm8oTmRlZk1hcCk7CiAgICB9CiAgICByZXR1cm4gKHN0YXR1cyk7Cn0KCgovKiEKICogXGJyaWVmIFVzZWQgaW4gV3JpdGUgT3BlYXJhdGlvbi4KICogY2hlY2sgdGhlIHZhbHVlIHNldCBmb3IgdGhlIFdyaXRlIEZsYWcsIGluIGZpcnN0IHdyaXRlIG9wZXJhdGlvbihiZWdpbiksIHNldHMgdGhlCiAqIFdSIGZsYWcgaW4gYXR0cmlidXRlIGJsY2suCiAqIEFmdGVyIGEgc3VjY2Vzc2Z1bCB3cml0ZSBvcGVyYXRpb24sIFRoaXMgZnVuY3Rpb24gc2V0cyB0aGUgV1IgZmxhZyBvZmYgYW5kIHVwZGF0ZXMKICogdGhlIExFTiBieXRlcyBpbiBhdHRyaWJ1dGUgQmxvY2suCiAqLwoKc3RhdGljIE5GQ1NUQVRVUyAgcGhGcmlOZmNfRmVsaWNhX0hVcGRhdGVBdHRyQmxrRm9yV3JPcChwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXAsdWludDhfdCBpc1N0YXJ0ZWQpCnsKICAgIE5GQ1NUQVRVUyAgIHN0YXR1cyA9IE5GQ1NUQVRVU19QRU5ESU5HOwoKICAgIHVpbnQxNl90IENoa1N1bT0wLGluZGV4PTA7CiAgICB1aW50OF90IEJ1ZkluZGV4PTAsIEVyckZsYWcgPSBGQUxTRTsKICAgIHVpbnQzMl90IFRvdE5vV3JpdHRlbkJ5dGVzPTA7CgogICAgLyogV3JpdGUgT3BlcmF0aW9uIDogQmVnaW4vRW5kIENoZWNrKi8KCiAgICBOZGVmTWFwLT5TdGF0ZSA9IAogICAgKCggaXNTdGFydGVkID09IEZFTElDQV9XUklURV9TVEFSVEVEICk/CiAgICBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1NUQVRFX0FUVFJfQkxLX1dSX0JFR0lOOgogICAgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9TVEFURV9BVFRSX0JMS19XUl9FTkQpOwoKICAgIGlmKCAoIE5kZWZNYXAtPlN0YXRlID09IFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfQVRUUl9CTEtfV1JfQkVHSU4pfHwKICAgICAgICAoIE5kZWZNYXAtPlN0YXRlID09IFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfQVRUUl9CTEtfV1JfRU5EKSApCiAgICB7CgogICAgICAgIC8qIFNldCB0aGUgRmVsaWNhIENtZCovCiNpZmRlZiBQSF9IQUw0X0VOQUJMRQogICAgICAgIE5kZWZNYXAtPkNtZC5GZWxDbWQgPSBwaEhhbF9lRmVsaWNhX1JhdzsKI2Vsc2UKICAgICAgICBOZGVmTWFwLT5DbWQuRmVsQ21kID0gcGhIYWxfZUZlbGljYUNtZExpc3RGZWxpY2FDbWQ7CiNlbmRpZiAgLyogI2lmZGVmIFBIX0hBTDRfRU5BQkxFICovCgogICAgICAgIC8qIDFzdCBieXRlIHJlcHJlc2VudHMgdGhlIGxlbmd0aCBvZiB0aGUgY21kIHBhY2tldCovCiAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdID0gMHgwMDsKICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAvKiBXcml0ZS9VcGRhdGUgY29tbWFuZCBjb2RlKi8KICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPSAweDA4OwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIC8qIElEbSAtIE1hbnVmYWN0dXJlciBJZCA6IDhieXRlcyovCiNpZmRlZiBQSF9IQUw0X0VOQUJMRQogICAgICAgICh2b2lkKW1lbWNweSggKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICAgKHZvaWQqKSgmKE5kZWZNYXAtPnBzUmVtb3RlRGV2SW5mby0+UmVtb3RlRGV2SW5mby5GZWxpY2FfSW5mby5JRG0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgOCk7CiNlbHNlCiAgICAgICAgKHZvaWQpbWVtY3B5KCAoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAodm9pZCopKCYoTmRlZk1hcC0+cHNSZW1vdGVEZXZJbmZvLT5SZW1vdGVEZXZJbmZvLkNhcmRJbmZvMjEyXzQyNC5TdGFydHVwMjEyXzQyNC5ORkNJRDJ0KSksCiAgICAgICAgICAgICAgICAgICAgICAgIDgpOwojZW5kaWYgLyogI2lmZGVmIFBIX0hBTDRfRU5BQkxFICovCgogICAgICAgIEJ1ZkluZGV4Kz04OwoKICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4MDE7ICAvKiAgTnVtYmVyIG9mIFNlcnZpY2VzIChuPTEgPT0+IDB4ODApKi8KICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4MDk7ICAvKiAgU2VydmljZSBDb2RlIExpc3QqLwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwMDsgIC8qICBTZXJ2aWNlIENvZGUgTGlzdCovCiAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDAxOyAgLyogIE51bWJlciBvZiBCbG9ja3MgdG8gV3JpdGUqLwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHg4MDsgIC8qICAxc3QgQmxvY2sgRWxlbWVudCA6IGJ5dGUgMSovCiAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDAwOyAgLyogIDFzdCBCbG9jayBFbGVtZW50IDogYnl0ZSAyLCBibG9jayAxKi8KICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAvKiBGaWxsIEF0dHJpYnV0ZSBCbGsgSW5mb3JtYXRpb24qLwogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5WZXJzaW9uOwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5OYnI7CiAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idzsKICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gID0gKHVpbnQ4X3QpKChOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YikgPj4gOCk7CiAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9ICh1aW50OF90KSgoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGIpICYgKDB4MDBmZikpOwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDAwOyAvKlJGVSovCiAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IDB4MDA7IC8qUkZVKi8KICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gID0gMHgwMDsgLypSRlUqLwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDAwOyAvKlJGVSovCiAgICAgICAgQnVmSW5kZXgrKzsKICAgICAgICAKICAgICAgICBpZiAoaXNTdGFydGVkID09IEZFTElDQV9XUklURV9TVEFSVEVEICkKICAgICAgICB7CiAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDBGOyAvKiBXcml0ZSBGbGFnIE1hZGUgT24qLwogICAgICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLlJkV3JGbGFnOyAvKiBSZWFkIHdyaXRlIGZsYWcqLwogICAgICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAgICAgLyogTGVuIEJ5dGVzKi8KICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzBdOwogICAgICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzFdOwogICAgICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzJdOwogICAgICAgICAgICBCdWZJbmRleCsrOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBDYXNlOiBQcmV2aW91cyBXcml0ZSBPcGVyYXRpb24gZmFpbGVkIGFuZCBpbnRlZ3JhdGlvbiBjb250ZXh0IGNvbnRpbnVlcyB3aXRoIHdyaXRlCiAgICAgICAgICAgIG9wZXJhdGlvbiB3aXRoIG9mZnNldCBzZXQgdG8gQ3VycmVudC4gSW4gdGhpcyBjYXNlLCBpZiB3ZSBmaW5kIEludGVybmFsIEJ5dGVzIHJlbWFpbmVkIGluIHRoZSAKICAgICAgICAgICAgZmVsaWNhIGNvbnRleHQgaXMgdHJ1ZSg+MCkgYW5kIGN1cnJlbnQgYmxvY2sgbnVtYmVyIGlzIFplcm8uIFRoZW4gd2Ugc2hvdWxkbid0IGFsbG93IHRoZSBtb2R1bGUKICAgICAgICAgICAgdG8gd3JpdGUgdGhlIGRhdGEgdG8gY2FyZCwgYXMgdGhpcyBpcyBhIGludmFsaWQgY2FzZSovCiAgICAgICAgICAgIGlmICggKE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkID4gMCkgJiYgKE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vID09IDApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgICAgICAgICAgICAgIEVyckZsYWcgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDAwOyAvKiBXcml0ZSBGbGFnIE1hZGUgT2ZmKi8KICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLlJkV3JGbGFnOyAvKiBSZWFkIHdyaXRlIGZsYWcqLwogICAgICAgICAgICAgICAgQnVmSW5kZXgrKzsKICAgICAgICAgICAgCiAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkID4gMCApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVG90Tm9Xcml0dGVuQnl0ZXMgPSAoIChOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObyAqMTYpLSAoMTYgLSAoTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgVG90Tm9Xcml0dGVuQnl0ZXMgPSAoIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vICoxNik7CgogICAgICAgICAgICAgICAgfQogICAgICAgIAogICAgICAgICAgICAgICAgLyogVXBkYXRlIExlbiBCeXRlcyovCiAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gID0gKHVpbnQ4X3QpKCggVG90Tm9Xcml0dGVuQnl0ZXMgJiAweDAwZmYwMDAwKSA+PiAxNik7CiAgICAgICAgICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAodWludDhfdCkoKFRvdE5vV3JpdHRlbkJ5dGVzICYgMHgwMDAwZmYwMCkgPj4gOCk7CiAgICAgICAgICAgICAgICBCdWZJbmRleCsrOwoKICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAodWludDhfdCkoVG90Tm9Xcml0dGVuQnl0ZXMgJiAweDAwMDAwMGZmKTsgCiAgICAgICAgICAgICAgICBCdWZJbmRleCsrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgCiAgICAgICAgaWYgKCBFcnJGbGFnICE9IFRSVUUgKQogICAgICAgIHsKICAgICAgICAgICAgLyogY2hlY2sgc3VtIHVwZGF0ZSovCiAgICAgICAgICAgIGZvciAoIGluZGV4ID0gMTYgOyBpbmRleCA8IDMwIDsgaW5kZXggKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIENoa1N1bSArPSBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltpbmRleF07CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIGZpbGwgY2hlY2sgc3VtIGluIGNvbW1hbmQgcGt0Ki8KICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdID0gKHVpbnQ4X3QpKENoa1N1bSA+PiA4KTsKICAgICAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSA9ICh1aW50OF90ICkoQ2hrU3VtICYgMHgwMGZmKTsKICAgICAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgICAgIC8qIHVwZGF0ZSBsZW5ndGggb2YgdGhlIGNtZCBwa3QqLwogICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1BLVF9MRU5fSU5ERVhdID0gQnVmSW5kZXg7CgogICAgICAgICAgICAqTmRlZk1hcC0+U2VuZFJlY3ZMZW5ndGggPSBOZGVmTWFwLT5UZW1wUmVjZWl2ZUxlbmd0aDsKCiAgICAgICAgICAgIC8qIFVwZGF0ZSB0aGUgU2VuZCBMZW4qLwogICAgICAgICAgICBOZGVmTWFwLT5TZW5kTGVuZ3RoID0gQnVmSW5kZXg7CgogICAgICAgICAgICAvKnNldCB0aGUgY29tcGxldGlvbiByb3V0aW5lcyBmb3IgdGhlIGRlc2ZpcmUgY2FyZCBvcGVyYXRpb25zKi8KICAgICAgICAgICAgTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8uQ29tcGxldGlvblJvdXRpbmUgPSBwaEZyaU5mY19OZGVmTWFwX1Byb2Nlc3M7CiAgICAgICAgICAgIE5kZWZNYXAtPk1hcENvbXBsZXRpb25JbmZvLkNvbnRleHQgPSBOZGVmTWFwOwoKICAgICAgICAgICAgLypzZXQgdGhlIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25zIGZvciB0aGUgZGF0YSBleGNoYW5nZSovCiAgICAgICAgICAgIE5kZWZNYXAtPnBzRGVwQWRkaXRpb25hbEluZm8uRGVwRmxhZ3MuTWV0YUNoYWluaW5nID0gMDsKICAgICAgICAgICAgTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mby5EZXBGbGFncy5OQURQcmVzZW50ID0gMDsKCiAgICAgICAgICAgIC8qQ2FsbCB0aGUgT3ZlcmxhcHBlZCBIQUwgVHJhbnNjZWl2ZSBmdW5jdGlvbiAqLyAKICAgICAgICAgICAgc3RhdHVzID0gcGhGcmlOZmNfT3ZySGFsX1RyYW5zY2VpdmUoIE5kZWZNYXAtPkxvd2VyRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPnBzUmVtb3RlRGV2SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+Q21kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRMZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkxlbmd0aCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX0lOVkFMSURfUEFSQU1FVEVSKTsKICAgIAogICAgfQogICAgcmV0dXJuIChzdGF0dXMpOwp9CgpzdGF0aWMgTkZDU1RBVFVTICBwaEZyaU5mY19GZWxpY2FfSFdyRW1wdHlNc2cocGhGcmlOZmNfTmRlZk1hcF90ICpOZGVmTWFwKQp7CiAgICBORkNTVEFUVVMgICBzdGF0dXMgPSBORkNTVEFUVVNfUEVORElORzsKCiAgICB1aW50MTZfdCBDaGtTdW09MCxpbmRleD0wOwogICAgdWludDhfdCBCdWZJbmRleD0wOwoKICAgIC8qIFdyaXRlIE9wZXJhdGlvbiA6IFRvIEVyYXNlIHRoZSBwcmVzZW50IE5ERUYgRGF0YSovCgogICAgTmRlZk1hcC0+U3RhdGUgPSBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1NUQVRFX1dSX0VNUFRZX01TRzsKCiAgICAvKiBTZXQgdGhlIEZlbGljYSBDbWQqLwojaWZkZWYgUEhfSEFMNF9FTkFCTEUKICAgIE5kZWZNYXAtPkNtZC5GZWxDbWQgPSBwaEhhbF9lRmVsaWNhX1JhdzsKI2Vsc2UKICAgIE5kZWZNYXAtPkNtZC5GZWxDbWQgPSBwaEhhbF9lRmVsaWNhQ21kTGlzdEZlbGljYUNtZDsKI2VuZGlmICAvKiAjaWZkZWYgUEhfSEFMNF9FTkFCTEUgKi8KCiAgICAvKiAxc3QgYnl0ZSByZXByZXNlbnRzIHRoZSBsZW5ndGggb2YgdGhlIGNtZCBwYWNrZXQqLwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdID0gMHgwMDsKICAgIEJ1ZkluZGV4Kys7CgogICAgLyogV3JpdGUvVXBkYXRlIGNvbW1hbmQgY29kZSovCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPSAweDA4OwogICAgQnVmSW5kZXgrKzsKCiAgICAvKiBJRG0gLSBNYW51ZmFjdHVyZXIgSWQgOiA4Ynl0ZXMqLwojaWZkZWYgUEhfSEFMNF9FTkFCTEUKICAgICh2b2lkKW1lbWNweSggKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAodm9pZCopKCYoTmRlZk1hcC0+cHNSZW1vdGVEZXZJbmZvLT5SZW1vdGVEZXZJbmZvLkZlbGljYV9JbmZvLklEbSkpLAogICAgICAgICAgICAgICAgICAgIDgpOyAKI2Vsc2UKICAgICh2b2lkKW1lbWNweSggKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAodm9pZCopKCYoTmRlZk1hcC0+cHNSZW1vdGVEZXZJbmZvLT5SZW1vdGVEZXZJbmZvLkNhcmRJbmZvMjEyXzQyNC5TdGFydHVwMjEyXzQyNC5ORkNJRDJ0KSksCiAgICAgICAgICAgICAgICAgICAgOCk7CiNlbmRpZiAgLyogI2lmZGVmIFBIX0hBTDRfRU5BQkxFICovCgoKICAgIEJ1ZkluZGV4Kz04OwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwMTsgIC8qICBOdW1iZXIgb2YgU2VydmljZXMgKG49MSA9PT4gMHg4MCkqLwogICAgQnVmSW5kZXgrKzsKCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4MDk7ICAvKiAgU2VydmljZSBDb2RlIExpc3QqLwogICAgQnVmSW5kZXgrKzsKCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4MDA7ICAvKiAgU2VydmljZSBDb2RlIExpc3QqLwogICAgQnVmSW5kZXgrKzsKCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4MDE7ICAvKiAgTnVtYmVyIG9mIEJsb2NrcyB0byBXcml0ZSovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHg4MDsgIC8qICAxc3QgQmxvY2sgRWxlbWVudCA6IGJ5dGUgMSovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwMDsgIC8qICAxc3QgQmxvY2sgRWxlbWVudCA6IGJ5dGUgMiwgYmxvY2sgMSovCiAgICBCdWZJbmRleCsrOwoKICAgIC8qIEZpbGwgQXR0cmlidXRlIEJsayBJbmZvcm1hdGlvbiovCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gID0gTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uVmVyc2lvbjsKICAgIEJ1ZkluZGV4Kys7CgogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5icjsKICAgIEJ1ZkluZGV4Kys7CgogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idzsKICAgIEJ1ZkluZGV4Kys7CgogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9ICh1aW50OF90KSgoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGIpID4+IDgpOwogICAgQnVmSW5kZXgrKzsKCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gID0gKHVpbnQ4X3QpKChOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YikgJiAoMHgwMGZmKSk7CiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDAwOyAvKlJGVSovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDAwOyAvKlJGVSovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDAwOyAvKlJGVSovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDAwOyAvKlJGVSovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5Xcml0ZUZsYWc7IAogICAgQnVmSW5kZXgrKzsKCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gID0gTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uUmRXckZsYWc7IC8qIFJlYWQgd3JpdGUgZmxhZyovCiAgICBCdWZJbmRleCsrOwoKICAgIC8qIExlbiBCeXRlcyBhcmUgc2V0IHRvIDAgOiBFbXB0eSBNc2cqLwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICA9IDB4MDA7CiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgPSAweDAwOwogICAgQnVmSW5kZXgrKzsKCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gID0gMHgwMDsKICAgIEJ1ZkluZGV4Kys7CiAgICAKICAgIC8qIGNoZWNrIHN1bSB1cGRhdGUqLwogICAgZm9yICggaW5kZXggPSAxNiA7IGluZGV4IDwgMzAgOyBpbmRleCArKykKICAgIHsKICAgICAgICBDaGtTdW0gKz0gTmRlZk1hcC0+U2VuZFJlY3ZCdWZbaW5kZXhdOwogICAgfQoKICAgIC8qIGZpbGwgY2hlY2sgc3VtIGluIGNvbW1hbmQgcGt0Ki8KICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSA9ICh1aW50OF90KShDaGtTdW0gPj4gOCk7CiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSA9ICh1aW50OF90ICkoQ2hrU3VtICYgMHgwMGZmKTsKICAgIEJ1ZkluZGV4Kys7CgogICAgLyogdXBkYXRlIGxlbmd0aCBvZiB0aGUgY21kIHBrdCovCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1BLVF9MRU5fSU5ERVhdID0gQnVmSW5kZXg7CgogICAgKk5kZWZNYXAtPlNlbmRSZWN2TGVuZ3RoID0gTmRlZk1hcC0+VGVtcFJlY2VpdmVMZW5ndGg7CgogICAgLyogVXBkYXRlIHRoZSBTZW5kIExlbiovCiAgICBOZGVmTWFwLT5TZW5kTGVuZ3RoID0gQnVmSW5kZXg7CgogICAgLypzZXQgdGhlIGNvbXBsZXRpb24gcm91dGluZXMgZm9yIHRoZSBkZXNmaXJlIGNhcmQgb3BlcmF0aW9ucyovCiAgICBOZGVmTWFwLT5NYXBDb21wbGV0aW9uSW5mby5Db21wbGV0aW9uUm91dGluZSA9IHBoRnJpTmZjX05kZWZNYXBfUHJvY2VzczsKICAgIE5kZWZNYXAtPk1hcENvbXBsZXRpb25JbmZvLkNvbnRleHQgPSBOZGVmTWFwOwoKICAgIC8qc2V0IHRoZSBhZGRpdGlvbmFsIGluZm9ybWF0aW9ucyBmb3IgdGhlIGRhdGEgZXhjaGFuZ2UqLwogICAgTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mby5EZXBGbGFncy5NZXRhQ2hhaW5pbmcgPSAwOwogICAgTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mby5EZXBGbGFncy5OQURQcmVzZW50ID0gMDsKCiAgICAvKkNhbGwgdGhlIE92ZXJsYXBwZWQgSEFMIFRyYW5zY2VpdmUgZnVuY3Rpb24gKi8gCiAgICBzdGF0dXMgPSBwaEZyaU5mY19PdnJIYWxfVHJhbnNjZWl2ZSggTmRlZk1hcC0+TG93ZXJEZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5wc1JlbW90ZURldkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5DbWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZExlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZMZW5ndGgpOwogICAgCiAgICByZXR1cm4gKHN0YXR1cyk7Cn0KCgoKCi8qIQogKiBcYnJpZWYgVXNlZCBpbiBXcml0ZSBPcGVhcmF0aW9uLgogKiAgVGhpcyBGdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgYSBzdWNjZXNzZnVsIHZhbGlkYXRpb24gYW5kIHN0b3Jpbmcgb2YgYXR0cmlidXRpb24gYmxvY2sgCiAqICBjb250ZW50IGluIHRvIGNvbnRleHQuCiAqICBJZiB0aGUgd3JpdGUgb3BlcmF0aW9uIGlzIGluaXRpYXRlZCB3aXRoIGJlZ2luLGZ1bmN0aW9uIGluaXRpYXRlcyB0aGUgd3JpdGUgb3BlcmF0aW9uIHdpdGggCiAqICBSZFdyIGZsYWcuCiAqICBJZiB0aGUgT2Zmc2V0IGlzIHNldCB0byBDdXJyZW50LCBDaGVja3MgZm9yIHRoZSBFT0YgY2FyZCByZWFjaGVkIHN0YXR1cyBhbmQgd3JpdGVzIGRhdGEgdG8KICogIFRoZSBDYXJkCiAqLwoKc3RhdGljIE5GQ1NUQVRVUyAgIHBoRnJpTmZjX0ZlbGljYV9IQ2hrQXR0ckJsa0ZvcldyT3AocGhGcmlOZmNfTmRlZk1hcF90ICAqTmRlZk1hcCkKewogICAgTkZDU1RBVFVTICAgc3RhdHVzID0gTkZDU1RBVFVTX1BFTkRJTkc7CiAgICB1aW50MzJfdCBEYXRhTGVuPTA7CgogICAgLypjaGVjayBSVyBGbGFnIEFjY2VzcyBSaWdodHMqLwogICAgLyogc2V0IHRvIHJlYWQgb25seSBjYW5ub3Qgd3JpdGUqLwogICAgaWYgKCBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5SZFdyRmxhZyA9PSAweDAwKQogICAgICAgICAKICAgIHsKICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfSU5WQUxJRF9ERVZJQ0VfUkVRVUVTVCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaWYgKCAoIE5kZWZNYXAtPkZlbGljYS5PZmZzZXQgPT0gUEhfRlJJTkZDX05ERUZNQVBfU0VFS19CRUdJTikgfHwgCiAgICAgICAgICAgICAgICAoICggTmRlZk1hcC0+UHJldk9wZXJhdGlvbiA9PSBQSF9GUklORkNfTkRFRk1BUF9SRUFEX09QRSkgJiYgCiAgICAgICAgICAgICAgICAgICAoTmRlZk1hcC0+RmVsaWNhLk9mZnNldCAhPSBQSF9GUklORkNfTkRFRk1BUF9TRUVLX0JFR0lOICkgKSkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGNoZWNrIGFsbHJlYWR5IHdyaXR0ZW4gbnVtYmVyIG9mIGJ5dGVzIGFuZCBhcGR1IGJ1ZmZlciBzaXplKi8KICAgICAgICAgICAgaWYgKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplID4gKHVpbnQzMl90KShOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YiAqMTYpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnID0gRkVMSUNBX0VPRl9SRUFDSEVEX1dSX1dJVEhfQkVHSU5fT0ZGU0VUOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZyA9IEZBTFNFOwogICAgICAgICAgICB9CgogICAgICAgICAgICAKICAgICAgICAgICAgLyogcmVzZXQgdGhlIGludGVybmFsIHZhcmlhYmxlcyBpbml0aWF0ZSB0b3VwZGF0ZSB0aGUgYXR0cmlidXRlIGJsayovCiAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkID0gMDsKICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gPSAwOwogICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuTm9CbG9ja3NXcml0dGVuID0gMDsKICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hJbml0SW50ZXJuYWxCdWYoTmRlZk1hcC0+RmVsaWNhLldyX1JlbWFpbmVkQnl0ZXNCdWZmKTsKICAgICAgICAgICAgc3RhdHVzPSBwaEZyaU5mY19GZWxpY2FfSFVwZGF0ZUF0dHJCbGtGb3JXck9wKE5kZWZNYXAsRkVMSUNBX1dSSVRFX1NUQVJURUQpOwogICAgICAgICAgICAKICAgICAgICB9CiAgICAgICAgZWxzZSAKICAgICAgICB7CiAgICAgICAgICAgIGlmIChOZGVmTWFwLT5GZWxpY2EuT2Zmc2V0ID09IFBIX0ZSSU5GQ19OREVGTUFQX1NFRUtfQ1VSICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogQ2FsY3VsYXRlIHRoZSBBbGxyZWFkeSBXcml0dGVuIE5vLiBPZiBCbG9ja3MqLwogICAgICAgICAgICAgICAgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9DQUxfTEVOX0JZVEVTKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTGVuQnl0ZXNbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1syXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERhdGFMZW4pOwoKICAgICAgICAgICAgICAgIGlmICgoIE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplICsgKERhdGFMZW4gKSkgPiAKICAgICAgICAgICAgICAgICAgICAgICAgKHVpbnQzMl90KSggTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGIgKjE2KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBpZigoIERhdGFMZW4gKSA9PSAgKHVpbnQzMl90KShOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YiAqMTYpICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfRU9GX05ERUZfQ09OVEFJTkVSX1JFQUNIRUQpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewoKICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZyA9RkVMSUNBX0VPRl9SRUFDSEVEX1dSX1dJVEhfQ1VSUl9PRkZTRVQ7CiAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggPTA7CiAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Ob0Jsb2Nrc1dyaXR0ZW4gPSAwOwogICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXM9IHBoRnJpTmZjX0ZlbGljYV9IVXBkYXRlQXR0ckJsa0ZvcldyT3AoTmRlZk1hcCxGRUxJQ0FfV1JJVEVfU1RBUlRFRCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggPTA7CiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLk5vQmxvY2tzV3JpdHRlbiA9IDA7CiAgICAgICAgICAgICAgICAgICAgc3RhdHVzPSBwaEZyaU5mY19GZWxpY2FfSFVwZGF0ZUF0dHJCbGtGb3JXck9wKE5kZWZNYXAsRkVMSUNBX1dSSVRFX1NUQVJURUQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9LyppZiAoTmRlZk1hcC0+RmVsaWNhLk9mZnNldCA9PSBQSF9GUklORkNfTkRFRk1BUF9TRUVLX0NVUiApKi8KICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gKHN0YXR1cyk7Cn0KCi8qIQogKiBcYnJpZWYgVXNlZCBpbiBSZWFkIE9wZWFyYXRpb24uCiAqICBUaGlzIEZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciBhIHN1Y2Nlc3NmdWwgdmFsaWRhdGlvbiBhbmQgc3RvcmluZyBvZiBhdHRyaWJ1dGlvbiBibG9jayAKICogIGNvbnRlbnQgaW4gdG8gY29udGV4dC4KICogIFdoaWxlIE9mZnNldCBpcyBzZXQgdG8gQ3VycmVudCwgQ2hlY2tzIGZvciB0aGUgRU9GIGNhcmQgcmVhY2hlZCBzdGF0dXMgYW5kIHJlYWRzIGRhdGEgZnJvbQogKiAgVGhlIENhcmQKICovCgpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hDaGtBdHRyQmxrRm9yUmRPcChwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQzMl90IE5kZWZMZW4pCnsKICAgIE5GQ1NUQVRVUyAgIHN0YXR1cyA9IE5GQ1NUQVRVU19QRU5ESU5HOwoKICAgIC8qY2hlY2sgV1IgRmxhZyBBY2Nlc3MgUmlnaHRzKi8KICAgIC8qIHNldCB0byBzdGlsbCB3cml0aW5nIGRhdGEgc3RhdGUgb25seSBjYW5ub3QgUmVhZCovCiAgICBpZiAoIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLldyaXRlRmxhZyA9PSAweDBGICkKICAgIHsKICAgICAgICAgc3RhdHVzID0gIFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsTkZDU1RBVFVTX1JFQURfRkFJTEVEKTsKICAgICAgICAgLyogQXMgd2UgYXJlIG5vdCBhYmxlIHRvIGNvbnRpbnVlIHdpdGggcmVhZGluZyBkYXRhCiAgICAgICAgICAgIGJ5dGVzIHJlYWQgc2V0IHRvIHplcm8qLwogICAgICAgICAqTmRlZk1hcC0+TnVtT2ZCeXRlc1JlYWQgPSAwOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN0YXR1cyA9IHBoRnJpTmZjX01hcFRvb2xfU2V0Q2FyZFN0YXRlKCBOZGVmTWFwLE5kZWZMZW4pOwogICAgICAgIGlmICggc3RhdHVzID09IE5GQ1NUQVRVU19TVUNDRVNTKQogICAgICAgIHsKICAgICAgICAgICAgLyogUmVhZCBkYXRhIEZyb20gdGhlIGNhcmQqLwogICAgICAgICAgICBzdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFJlYWREYXRhKE5kZWZNYXAsTmRlZk1hcC0+RmVsaWNhLk9mZnNldCk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAoc3RhdHVzKTsKfQoKLyohCiAqIFxicmllZiBVc2VkIGluIFdyaXRlIE9wZWFyYXRpb24uCiAqIFRoaXMgZnVuY3Rpb24gd3JpdGVzIHRoZSBkYXRhIGluIHRlcm1zIG9mIGJsb2Nrcy4KICogRWFjaCB3cml0ZSBvcGVyYXRpb24gc3VwcG9ydHMsbWluaW11bSBOYncgYmxvY2tzIG9mIGJ5dGVzLgogKiBBbHNvIGNoZWNrcyBmb3IgdGhlIEVPRiw+PU5CVyw8TkJXIGV0YwogKi8Kc3RhdGljIE5GQ1NUQVRVUyAgIHBoRnJpTmZjX0ZlbGljYV9IVXBkYXRlRGF0YShwaEZyaU5mY19OZGVmTWFwX3QgKk5kZWZNYXApCnsKICAgIE5GQ1NUQVRVUyBzdGF0dXMgPSBORkNTVEFUVVNfUEVORElORzsKCiAgICB1aW50OF90IEJ1ZkluZGV4PTAsCiAgICAgICAgICAgIGk9MCwKICAgICAgICAgICAgQmxrTm89MCwKICAgICAgICAgICAgUGFkQnl0ZXM9MCwKICAgICAgICAgICAgQ3VyQmxrPTEsCiAgICAgICAgICAgIE5vT2ZCbGtzPTAsCiAgICAgICAgICAgIE5id0NoZWNrPTAsCiAgICAgICAgICAgIFRvdE5vQmxrcz0wOwoKICAgIHVpbnQzMl90IEJ5dGVzUmVtYWluZWRJbkNhcmQ9MCwKICAgICAgICAgICAgIEJ5dGVzUmVtYWluZWQ9MCwKICAgICAgICAgICAgIFRvdE5vV3JpdHRlbkJ5dGVzPTA7CgogICAgaWYoIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSA+IDAgKQogICAgewogICAgICAgIC8qIFByZXBhcmUgdGhlIHdyaXRlIGNtZCBwa3QgZm9yIGZlbGljYSovCiAgICAgICAgLyogMXN0IGJ5dGUgcmVwcmVzZW50cyB0aGUgbGVuZ3RoIG9mIHRoZSBjbWQgcGFja2V0Ki8KICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPSAweDAwOwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIC8qIFdyaXRlL1VwZGF0ZSBjb21tYW5kIGNvZGUqLwogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSA9IDB4MDg7CiAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgLyogSURtIC0gTWFudWZhY3R1cmVyIElkIDogOGJ5dGVzKi8KI2lmZGVmIFBIX0hBTDRfRU5BQkxFCiAgICAgICAgKHZvaWQpbWVtY3B5KCgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uSURtKSksCiAgICAgICAgICAgICAgICAgICAgICA4KTsKI2Vsc2UKICAgICAgICAgKHZvaWQpbWVtY3B5KCgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uQ2FyZEluZm8yMTJfNDI0LlN0YXJ0dXAyMTJfNDI0Lk5GQ0lEMnQpKSwKICAgICAgICAgICAgICAgICAgICAgIDgpOwojZW5kaWYgIC8qICNpZmRlZiBQSF9IQUw0X0VOQUJMRSAqLwoKICAgICAgICBCdWZJbmRleCs9ODsKCiAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDAxOyAgIC8qICBOdW1iZXIgb2YgU2VydmljZXMgKG49MSA9PT4gMHg4MCkqLwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwOTsgICAvKiAgU2VydmljZSBDb2RlIExpc3QqLwogICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwMDsgICAvKiBTZXJ2aWNlIENvZGUgTGlzdCovCiAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgaWYgKCBOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnID09IEZFTElDQV9FT0ZfUkVBQ0hFRF9XUl9XSVRIX0JFR0lOX09GRlNFVCkKICAgICAgICB7CiAgICAgICAgICAgIC8qIGNoZWNrIGZvciB0aGUgZW9mIGNhcmQgcmVhY2hlZCBmbGFnLk5lZWQgdG8gd3JpdGUgb25seSBtYW14aW11bSBieXRlcyhtZW1vcnkpdG8gY2FyZC4KICAgICAgICAgICAgVXNlZCB3aGVuLCBvZmZzZXQgc2V0IHRvIGJlZ2luIGNhc2UqLwogICAgICAgICAgICBCeXRlc1JlbWFpbmVkSW5DYXJkPSAoIChOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YioxNikgLSAoTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gKiAxNikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICAvKiBPZmZzZXQgOiBDdXVyZW50Ki8KICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnID09IEZFTElDQV9FT0ZfUkVBQ0hFRF9XUl9XSVRIX0NVUlJfT0ZGU0VUICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAvKiBjYWN1bGF0ZSBwcmV2aW91c2x5IHdyaXR0ZW4gTmRlZiBibGtzKi8KICAgICAgICAgICAgICAgICAodm9pZClwaEZyaU5mY19GZWxpY2FfSEdldE1heGltdW1CbGtzVG9SZWFkKE5kZWZNYXAsUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9OQkMpOwoKICAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkICApCiAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRvdE5vV3JpdHRlbkJ5dGVzID0gKCAoTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gKjE2KS0gKDE2IC0gKE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkKSkpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIFRvdE5vV3JpdHRlbkJ5dGVzID0gKCBOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObyAqMTYpOwogICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAvKiBEZXRlcm1pbmUgZXhhY3RseSwgaG93IG1hbnkgYnl0ZXMgd2UgY2FuIHdyaXRlKi8KICAgICAgICAgICAgICAgICBCeXRlc1JlbWFpbmVkSW5DYXJkID0gKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5tYXhiKjE2IC0gKFRvdE5vV3JpdHRlbkJ5dGVzKSk7CiAgICAgICAgICAgIH0KICAgICAgICAKICAgICAgICB9CiAgICAgICAgLyogV3JpdGUgRGF0YSBQZW5kaW5nIGluIHRoZSBJbnRlcm5hbCBCdWZmZXIqLwogICAgICAgIGlmKE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkID4gMCkKICAgICAgICB7CiAgICAgICAgICAgIC8qIHVwZGF0ZSB0aGUgbnVtYmVyIG9mIGJsb2NrcyB0byB3cml0ZSB3aXRoIHRoZSBibG9jayBsaXN0IGVsZW1lbnRzKi8KICAgICAgICAgICAgLyogVG90YWwgTnVtYmVyIG9mIGJsb2NrcyB0byB3cml0ZSovCiAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMDsKICAgICAgICAgICAgQnVmSW5kZXgrKzsKCiAgICAgICAgICAgIC8qIFVwZGF0ZSB0aGlzIFRvdGFsIG5vLiBCbG9rcyBsYXRlciovCiAgICAgICAgICAgIE5vT2ZCbGtzID0gQnVmSW5kZXg7CgogICAgICAgICAgICAvKiBBcyB3ZSBhcmUgd3JpdGluZyBhdGxlYXN0IG9uZSBibG9jayovCiAgICAgICAgICAgIFRvdE5vQmxrcyA9IDE7IAoKICAgICAgICAgICAgLyogY2hlY2sgZG8gd2UgaGF2ZSBzb21lIGV4dHJhIGJ5dGVzIHRvIHdyaXRlPyBpbiBVc2VyIEJ1ZmZlciovCiAgICAgICAgICAgIGlmICggTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgPih1aW50MzJfdCkgKDE2IC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBIYXZlIHdlIHJlYWNoZWQgRU9GPyovCiAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5Fb2ZDYXJkUmVhY2hlZEZsYWcgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIEJ5dGVzUmVtYWluZWQgPSBCeXRlc1JlbWFpbmVkSW5DYXJkOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIFRoaXMgdmFsdWUgdGVsbHMgaG93IG1hbnkgZXh0cmEgYnl0ZXMgd2UgY2FuIHdyaXRlIG90aGVyIHRoYW4gaW50ZXJuYWwgYnVmZmVyIGJ5dGVzKi8KICAgICAgICAgICAgICAgICAgICBCeXRlc1JlbWFpbmVkID0gKHVpbnQ4X3QpTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSAoMTYgLSBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCk7CiAgICAgICAgICAgICAgICB9ICAKICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgaWYgKCBCeXRlc1JlbWFpbmVkICkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBOb3QgcmVhY2hlZCBFT0YqLwogICAgICAgICAgICAgICAgICAgIGlmICghTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZykgCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgIC8qIENhbGN1bGF0ZSBIb3cgbWFueSBibGtzIHdlIG5lZWQgdG8gd3JpdGUqLwogICAgICAgICAgICAgICAgICAgICAgICBCbGtObyA9KCh1aW50OF90KSggQnl0ZXNSZW1haW5lZCApLzE2KTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNoZWNrIGJsb2NrcyB0byB3cml0ZSBleGNlZWRzIG5idyovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggQmxrTm8gPj0gTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJ3ICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQmxrTm8gPSBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5OYnc7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBOby4gQmxrcyB0byB3cml0ZSBhcmUgbW9yZSB0aGFuIE5idyovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOYndDaGVjayA9IDE7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgICgoKCBCeXRlc1JlbWFpbmVkICUxNikgPT0gMCkmJiAoQmxrTm8gPT0gMCApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJsa05vPTE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgLyogY2hlY2sgZG8gd2UgbmVlZCBwYWQgYnl0ZXM/Ki8KICAgICAgICAgICAgICAgICAgICAgICAgaWYoICghTmJ3Q2hlY2sgJiYgKHVpbnQ4X3QpKCBCeXRlc1JlbWFpbmVkKSUxNikgIT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQmxrTm8rKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhZEJ5dGVzID0gKEJsa05vICogMTYpIC0gKHVpbnQ4X3QpKCBCeXRlc1JlbWFpbmVkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5QYWRCeXRlRmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuTm9CbG9ja3NXcml0dGVuID0gQmxrTm87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUb3ROb0Jsa3MgKz0gQmxrTm87CgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBOYndDaGVjayApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYXMgd2UgaGF2ZSB0byB3cml0ZSBvbmx5IDggYmxvY2tzIGFuZCBhbHJlYWR5IHdlIGhhdmUgcGFkIGJ5dGVzIHNvIHdlIGhhdmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byBzdHJhdCBmcm9tIHByZXZpb3VzIGJsb2NrKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUb3ROb0Jsa3MgKz0gQmxrTm8gLSAxOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Ob0Jsb2Nrc1dyaXR0ZW4gPSBUb3ROb0Jsa3MtMTsgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAhKEJ5dGVzUmVtYWluZWQgLSAoMTYgLU5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkKT09IDAgKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRvdE5vQmxrcyArPSBCbGtObzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5QYWRCeXRlRmxhZyApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuTm9CbG9ja3NXcml0dGVuID0gVG90Tm9CbGtzLTE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgLyogd2UgaGF2ZSByZWFjaGVkIHRoZSBlb2YgY2FyZCAmIGh2IGJ5dGVzIHRvIHdyaXRlKi8KICAgICAgICAgICAgICAgICAgICAgICAgQmxrTm8gPSh1aW50OF90KSgoIEJ5dGVzUmVtYWluZWQgLSAoKDE2IC1OZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCkpICkvMTYpOwoKICAgICAgICAgICAgICAgICAgICAgICAgLyogY2hlY2sgYXJlIHdlIGV4Y2VlZGluZyB0aGUgTkJXIGxpbWl0LCB3aGlsZSBhIHdyaXRlPyovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggQmxrTm8gPj0gTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJ3ICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQmxrTm8gPSBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5OYnc7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTm8uIEJsa3MgdG8gd3JpdGUgYXJlIG1vcmUgdGhhbiBOYncqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmJ3Q2hlY2sgPSAxOwoKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICAoKCggQnl0ZXNSZW1haW5lZCAlMTYpID09IDApJiYgKEJsa05vID09IDAgKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBCbGtObz0xOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgICAgICAgICAvKmNoZWNrIFRvdGFsIGhvdyBtYW55IGJsb2NrcyB0byB3cml0ZSovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmKCgoIU5id0NoZWNrKSAmJiggQnl0ZXNSZW1haW5lZC0gKDE2IC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKSUxNikgIT0gMCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQmxrTm8rKzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBhZEJ5dGVzID0gKEJsa05vICogMTYpIC0gKHVpbnQ4X3QpKCBCeXRlc1JlbWFpbmVkKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5QYWRCeXRlRmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuTm9CbG9ja3NXcml0dGVuID0gQmxrTm87CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBUb3ROb0Jsa3MgKz0gQmxrTm87CgogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBOYndDaGVjayApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYXMgd2UgaGF2ZSB0byB3cml0ZSBvbmx5IDggYmxvY2tzIGFuZCBhbHJlYWR5IHdlIGhhdmUgcGFkIGJ5dGVzIHNvIHdlIGhhdmUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0byBzdHJhdCBmcm9tIHByZXZpb3VzIGxhc3QgYmxvY2sqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRvdE5vQmxrcyArPSBCbGtObyAtIDE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLk5vQmxvY2tzV3JpdHRlbiA9IFRvdE5vQmxrcy0xOyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB3ZSBuZWVkIHRvIHdyaXRlIG9ubHkgb25lIGJsb2NrICggYnl0ZXNyZW1hbmluZCArIGludGVybmFsIGJ1ZmZlciBzaXplID0gMTYpKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICEoQnl0ZXNSZW1haW5lZCAtICgxNiAtTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpPT0gMCApKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG90Tm9CbGtzICs9IEJsa05vOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7Lyogd2UgYXJlIG5vdCBpbmNyZW1lbnRpbmcgdGhlIFRvdGFsIG5vLiBvZiBibG9ja3MgdG8gd3JpdGUqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5GZWxpY2EuUGFkQnl0ZUZsYWcgKSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Ob0Jsb2Nrc1dyaXR0ZW4gPSBUb3ROb0Jsa3MgLTE7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0vKmlmICggQnl0ZXNSZW1haW5lZCApKi8KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIDsgLypOb3RoaW5nIHRvIHByb2Nlc3MgaGVyZSovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0vKmlmICggTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgPih1aW50MzJfdCkgKDE2IC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKSovCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogTm8gbmV3IGJsa3MgdG8gd3JpdGUqLwogICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLk5vQmxvY2tzV3JpdHRlbiA9IDA7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogUHJlcGFyZSB0aGUgQmxrIExpc3QgZm9yIFdyaXRlIE9wZXJhdGlvbiovCiAgICAgICAgICAgIC8qIEJsb2NrIExpc3QgZm9yIE5CdyA6IDFzdCBieXRlIDogdHdvIGJ5dGUgbGVuIGxpc3Q6IDJuZCBieXRlIGlzIHRoZSBibG9jayBudW1iZXIqLwogICAgICAgICAgICBmb3IgKCBpPTA7IGk8IFRvdE5vQmxrczsgaSsrKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIDB4ODA7ICAKICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CiAgICAgICAgICAgICAgICAvKiByZW1lbWJlciB0aGUgcHJldmlvdXMgQmxrIG5vIGFuZCBjb250aW51ZSBmcm9tIHRoZXJlKi8KICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLlBhZEJ5dGVGbGFnID09IFRSVUUgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gKyBpOyAgCiAgICAgICAgICAgICAgICAgICAgQnVmSW5kZXgrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UgICAgCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQ3VyQmxrID0gTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gKzE7CiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICBDdXJCbGsgKyBpOyAgCiAgICAgICAgICAgICAgICAgICAgQnVmSW5kZXgrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBDb3B5IHJlbGV2YW50IGRhdGEgdG8gVHJhbnNjIGJ1ZmZlciovICAgICAgICAgICAgCiAgICAgICAgICAgIGlmKChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpID49ICh1aW50MzJfdCkoMTYgLSBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCkpCiAgICAgICAgICAgIHsKCiAgICAgICAgICAgICAgICAvKkNvcHkgdGhlIFJlbWFpbmVkIGJ5dGVzIGZyb20gdGhlIGludGVybmFsIGJ1ZmZlciB0byAgdHJ4YnVmZmVyICovCiAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoICgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Xcl9SZW1haW5lZEJ5dGVzQnVmZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCk7CgogICAgICAgICAgICAgICAgLypJbmNyZW1lbnQgdGhlIGJ1ZmYgaW5kZXgqLwogICAgICAgICAgICAgICAgQnVmSW5kZXggKz0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQ7CgogICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8qYXBwZW5kIGNvcHkgMTYtYnl0ZXNUb1BhZCB0byB0cnhCdWZmZXIqLwogICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCAoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoMTYgLSBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCkpOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAvKiBVcGRhdGUgTnVtYmVyIE9mIEJ5dGVzIFdyaXR0ZW5lZCovCiAgICAgICAgICAgICAgICBOZGVmTWFwLT5OdW1PZkJ5dGVzV3JpdHRlbiA9IDE2IC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQ7CgogICAgICAgICAgICAgICAgLyogaW5jcmVtZW50IHRoZSBpbmRleCovCiAgICAgICAgICAgICAgICBCdWZJbmRleCArPSAxNiAtIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkOwoKICAgICAgICAgICAgICAgIGlmICggQnl0ZXNSZW1haW5lZCApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCFOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogY2hlY2sgbmJ3IGxpbWl0Ki8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBOYndDaGVjayAhPSAxICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQ29weSBFeHRyYSBCeXRlcyBvdGhlciB0aGFuIHRoZSBpbnRlcm5hbCBidWZmZXIgYnl0ZXMqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCAoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbKDE2IC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpXSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gKDE2IC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKSk7CgoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFVwZGF0ZSBOdW1iZXIgT2YgQnl0ZXMgV3JpdHRlbmVkKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPk51bU9mQnl0ZXNXcml0dGVuICs9ICh1aW50MTZfdCkoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSAoMTYgLSBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCkpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4ICs9ICh1aW50OF90KShOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtICgxNiAtIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBQYWRCeXRlcyApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGk9IDA7IGk8IFBhZEJ5dGVzOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPTB4MDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5vIG9mIGJ5dGVzIHJlbWFpbmVkIGNvcHkqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkID0gKHVpbnQ4X3QpKDE2IC0gUGFkQnl0ZXMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKmNvcHkgdGhlIGRhdGEgdG8gaW50ZXJuYWwgYnVmZmVyIDogQnl0ZXMgcmVtYWluZWQqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggTmRlZk1hcC0+RmVsaWNhLldyX1JlbWFpbmVkQnl0ZXNCdWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCYoIE5kZWZNYXAtPkFwZHVCdWZmZXJbKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpXSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCkpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5vIEJ5dGVzIGluIEludGVybmFsIGJ1ZmZlciovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgLypDb3B5IE5idyoxNiBieXRlcyBvZiBkYXRhIHRvIHRoZSB0cnggYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoICgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCYoTmRlZk1hcC0+QXBkdUJ1ZmZlclsoMTYgLSBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCldKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idyAtIDEpICogMTYpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGluY3JlbWVudCB0aGUgQnVmZmluZGV4Ki8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4ICs9ICgoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJ3IC0gMSApKjE2KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5OdW1PZkJ5dGVzV3JpdHRlbis9ICgoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJ3IC0xKSoxNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUGFkQnl0ZUZsYWcgPUZBTFNFOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfS8qaWYgKCFOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnKSovCiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNoZWNrIG5idyBsaW1pdCovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggTmJ3Q2hlY2sgIT0gMSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGhhbmRsZSBFT0YgY2FyZCByZWFjaGVkIGNhc2UqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCAoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCYoTmRlZk1hcC0+QXBkdUJ1ZmZlclsoMTYgLSBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCldKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICggQnl0ZXNSZW1haW5lZCAtICgoMTYgLU5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkKSApKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogVXBkYXRlIE51bWJlciBPZiBCeXRlcyBXcml0dGVuZWQqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+TnVtT2ZCeXRlc1dyaXR0ZW4gKz0gKHVpbnQxNl90KSggQnl0ZXNSZW1haW5lZCAtICgxNiAtTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBCdWZJbmRleCArPSAodWludDhfdCkoIEJ5dGVzUmVtYWluZWQgLSAoMTYgLU5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkKSk7CgogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBQYWRCeXRlcyApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9yKGk9IDA7IGk8IFBhZEJ5dGVzOyBpKyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPTB4MDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5vIG9mIGJ5dGVzIHJlbWFpbmVkIGNvcHkqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkID0gKHVpbnQ4X3QpKDE2IC0gUGFkQnl0ZXMpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKmNvcHkgdGhlIGRhdGEgdG8gaW50ZXJuYWwgYnVmZmVyIDogQnl0ZXMgcmVtYWluZWQqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweShOZGVmTWFwLT5GZWxpY2EuV3JfUmVtYWluZWRCeXRlc0J1ZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpXSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKkNvcHkgTmJ3KjE2IGJ5dGVzIG9mIGRhdGEgdG8gdGhlIHRyeCBidWZmZXIqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5BcGR1QnVmZmVyWygxNiAtIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkKV0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idyAtIDEpICogMTYpOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGluY3JlbWVudCB0aGUgQnVmZmluZGV4Ki8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4ICs9ICgoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJ3IC0gMSApKjE2KTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5OdW1PZkJ5dGVzV3JpdHRlbis9ICgoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJ3IC0xKSoxNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5QYWRCeXRlRmxhZyA9RkFMU0U7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LyppZiAoIEJ5dGVzUmVtYWluZWQgKSovCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQgPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLyogVXBkYXRlIFRvdGFsIE5vLiBvZiBibG9ja3Mgd3JpdHRlbmVkKi8KICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW05vT2ZCbGtzIC0xIF09VG90Tm9CbGtzOwogICAgICAgICAgICB9LyppZigoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSA+PSAodWludDMyX3QpKDE2IC0gTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKSovCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLypjb3B5IHRoZSBpbnRlcm5hbCBidWZmZXIgZGF0YSB0byAgIHRyeCBidWZmZXIqLwogICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuV3JfUmVtYWluZWRCeXRlc0J1ZmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkKSk7CiAgICAKICAgICAgICAgICAgICAgIC8qIGluY3JlbWVudCB0aGUgaW5kZXgqLwogICAgICAgICAgICAgICAgQnVmSW5kZXgrPU5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkOwoKICAgICAgICAgICAgICAgIC8qYXBwZW5kIHRoZSBhcGR1c2l6ZSBkYXRhIHRvIHRoZSB0cnggYnVmZmVyKi8KICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSgoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplKTsKCiAgICAgICAgICAgICAgICAgLyogSW5kZXggaW5jcmVtZW50Ki8KICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kz0gKHVpbnQ4X3QpTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemU7CgogICAgICAgICAgICAgICAgLyogVGVsbHMgaG93IG1hbnkgYnl0ZXMgcHJlc2VudCBpbiB0aGUgaW50ZXJuYWwgYnVmZmVyKi8KICAgICAgICAgICAgICAgIEJ5dGVzUmVtYWluZWQgPSBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCArIE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplOwoKICAgICAgICAgICAgICAgIFBhZEJ5dGVzID0gKHVpbnQ4X3QpKDE2LUJ5dGVzUmVtYWluZWQpOwoKICAgICAgICAgICAgICAgIC8qIFBhZCBlbXB0eSBieXRlcyB3aXRoIFplcm9lcyB0byBjb21wbGV0ZSAxNiBieXRlcyovCiAgICAgICAgICAgICAgICBmb3IoaT0gMDsgaTwgUGFkQnl0ZXM7IGkrKykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPTB4MDA7CiAgICAgICAgICAgICAgICAgICAgQnVmSW5kZXgrKzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKiBVcGRhdGUgTnVtYmVyIE9mIEJ5dGVzIFdyaXR0ZW5lZCovCiAgICAgICAgICAgICAgICBOZGVmTWFwLT5OdW1PZkJ5dGVzV3JpdHRlbiA9ICh1aW50MTZfdClOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZTsKCiAgICAgICAgICAgICAgICAvKiBGbGFnIHNldCB0byB1bmRlcnN0YW5kIHRoYXQgLCB3ZSBoYXZlIHJlY2VpdmVkIGxlc3Mgbm8uIG9mIGJ5dGVzIHRoYW4gCiAgICAgICAgICAgICAgICBwcmVzZW50IGluIHRoZSBpbnRlcm5hbCBidWZmZXIqLwogICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkludGVybWVkaWF0ZVdyRmxhZyA9IFRSVUU7CgogICAgICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5GZWxpY2EuUGFkQnl0ZUZsYWcgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Ob0Jsb2Nrc1dyaXR0ZW4gPSAwOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgogICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1BLVF9MRU5fSU5ERVhdID0gQnVmSW5kZXg7CiAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRMZW5ndGggPSBCdWZJbmRleDsKICAgICAgICAgICAgLyogVXBkYXRlIFRvdGFsIE5vLiBvZiBibG9ja3Mgd3JpdHRlbmVkKi8KICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbTm9PZkJsa3MgLTEgXT1Ub3ROb0Jsa3M7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIC8qRnJlc2ggd3JpdGUsIHN0YXJ0aW5nIGZyb20gYSBuZXcgYmxvY2sqLwogICAgICAgICAgICBpZiAoIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpID49ICh1aW50MzJfdCkoMTYqIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idyApKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBjaGVjayBmb3IgdGhlIGNhcmQgc2l6ZSBhbmQgd3JpdGUgTmJ3IEJsa3MqLwogICAgICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YiAtIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vID49IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiB1cGRhdGUgdGhlIG51bWJlciBvZiBibG9ja3MgdG8gd3JpdGUgd2l0aCB0aGUgYmxvY2sgbGlzdCBlbGVtZW50cyovCiAgICAgICAgICAgICAgICAgICAgLyogVG90YWwgTnVtYmVyIG9mIGJsb2NrcyB0byB3cml0ZSovCiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5OYnc7IAogICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgICAgICAgICAgICAgIC8qIEJsb2NrIExpc3QgZm9yIE5CdyA6IDFzdCBieXRlIDogdHdvIGJ5dGUgbGVuIGxpc3Q6IDJuZCBieXRlIGlzIHRoZSBibG9jayBudW1iZXIqLwogICAgICAgICAgICAgICAgICAgIGZvciAoIGk9MTsgaTw9IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idzsgaSsrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDgwOyAgCiAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gICAgPSAgIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vICsgaTsgIAogICAgICAgICAgICAgICAgICAgICAgICBCdWZJbmRleCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAvKkNvcHkgTmJ3KjE2IGJ5dGVzIG9mIGRhdGEgdG8gdGhlIHRyeCBidWZmZXIqLwoKICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJ3ICogMTYpOwoKICAgICAgICAgICAgICAgICAgICAvKiBpbmNyZW1lbnQgdGhlIEJ1ZmZpbmRleCovCiAgICAgICAgICAgICAgICAgICAgQnVmSW5kZXggKz0gKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idyoxNik7CgogICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSB0aGUgbGVuZ3RoKi8KICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1BLVF9MRU5fSU5ERVhdID0gQnVmSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkID0gMDsKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5OdW1PZkJ5dGVzV3JpdHRlbiA9IChOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5OYncqMTYpOwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Ob0Jsb2Nrc1dyaXR0ZW4gPSBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5OYnc7CgogICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSB0aGUgU2VuZCBsZW5ndGgqLwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRMZW5ndGggPSBCdWZJbmRleDsKCiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlBhZEJ5dGVGbGFnID0gRkFMU0U7CiAgICAgICAgICAgICAgICB9LyppZiAoIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5tYXhiIC0gTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gPj0gTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJ3KSovCiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogd2UgbmVlZCB0byB3cml0ZSBsZXNzIHRoYW4gbmJ3IGJsa3MqLwogICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSB0aGUgbnVtYmVyIG9mIGJsb2NrcyB0byB3cml0ZSB3aXRoIHRoZSBibG9jayBsaXN0IGVsZW1lbnRzKi8KICAgICAgICAgICAgICAgICAgICAvKiBUb3RhbCBOdW1iZXIgb2YgYmxvY2tzIHRvIHdyaXRlKi8KICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPSAodWludDhfdCkoIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5tYXhiIC0gTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8pOwogICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgICAgICAgICAgICAgIC8qIEJsb2NrIExpc3QgZm9yIE5CdyA6IDFzdCBieXRlIDogdHdvIGJ5dGUgbGVuIGxpc3Q6IDJuZCBieXRlIGlzIHRoZSBibG9jayBudW1iZXIqLwogICAgICAgICAgICAgICAgICAgIGZvciAoIGk9MTsgaTw9IChOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YiAtIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vKTsgaSsrKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDgwOyAgCiAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gKyBpOyAgCiAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgLypDb3B5IE5idyoxNiBieXRlcyBvZiBkYXRhIHRvIHRoZSB0cnggYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5tYXhiIC0gTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8pKjE2KTsKCiAgICAgICAgICAgICAgICAgICAgLyogaW5jcmVtZW50IHRoZSBCdWZmaW5kZXgqLwogICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4ICs9ICh1aW50OF90KSgoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGIgLSBOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObyApKjE2KTsKCiAgICAgICAgICAgICAgICAgICAgLyogdXBkYXRlIHRoZSBsZW5ndGgqLwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW1BIX05GQ0ZSSV9OREVGTUFQX0ZFTElfUEtUX0xFTl9JTkRFWF0gPSBCdWZJbmRleDsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5OdW1PZkJ5dGVzV3JpdHRlbiA9ICgoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGIgLSBOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObykqMTYpOwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Ob0Jsb2Nrc1dyaXR0ZW4gPSAodWludDhfdCkoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGIgLSBOZGVmTWFwLT5GZWxpY2EuQ3VyQmxvY2tObyk7CgogICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSB0aGUgU2VuZCBsZW5ndGgqLwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRMZW5ndGggPSBCdWZJbmRleDsKCiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLlBhZEJ5dGVGbGFnID1GQUxTRTsKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0vKiBpZiAoIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpID49ICh1aW50MzJfdCkoMTYqIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idyApKSAqLwogICAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qY2hrIGVvZiByZWFjaGVkKi8KICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBCbGtObyA9KCh1aW50OF90KShCeXRlc1JlbWFpbmVkSW5DYXJkICkvMTYpOwogICAgICAgICAgICAgICAgICAgIGlmKCgodWludDhfdCkoIEJ5dGVzUmVtYWluZWRJbkNhcmQgKSUxNikgIT0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEJsa05vKys7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhZEJ5dGVzID0gKChCbGtObyAqIDE2KSAtICh1aW50OF90KShCeXRlc1JlbWFpbmVkSW5DYXJkICkpOwogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUGFkQnl0ZUZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAKICAgICAgICAgICAgICAgICAgICBCbGtObyA9KCh1aW50OF90KSggTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KS8xNik7CiAgICAgICAgICAgICAgICAgICAgaWYoKCh1aW50OF90KSggTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KSUxNikgIT0gMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIEJsa05vKys7CiAgICAgICAgICAgICAgICAgICAgICAgIFBhZEJ5dGVzID0gKEJsa05vICogMTYpIC0gKHVpbnQ4X3QpKCBOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpOwogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUGFkQnl0ZUZsYWcgPSBUUlVFOwogICAgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSB0aGUgbnVtYmVyIG9mIGJsb2NrcyB0byB3cml0ZSB3aXRoIHRoZSBibG9jayBsaXN0IGVsZW1lbnRzKi8KICAgICAgICAgICAgICAgIC8qIFRvdGFsIE51bWJlciBvZiBibG9ja3MgdG8gd3JpdGUqLwogICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gIEJsa05vOyAKICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CgogICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLk5vQmxvY2tzV3JpdHRlbiA9IEJsa05vOwoKICAgICAgICAgICAgICAgIC8qIEJsb2NrIExpc3QgZm9yIE5CdyA6IDFzdCBieXRlIDogdHdvIGJ5dGUgbGVuIGxpc3Q6IDJuZCBieXRlIGlzIHRoZSBibG9jayBudW1iZXIqLwogICAgICAgICAgICAgICAgZm9yICggaT0wOyBpPCBCbGtObzsgaSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHg4MDsKICAgICAgICAgICAgICAgICAgICBCdWZJbmRleCsrOwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgQ3VyQmxrID0gTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gKzE7CiAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgQ3VyQmxrICsgaTsgIAogICAgICAgICAgICAgICAgICAgICAgICBCdWZJbmRleCsrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZyApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLypDb3B5IGxhc3QgZGF0YSB0byB0aGUgdHJ4IGJ1ZmZlciovCiAgICAgICAgICAgICAgICAgICAgKHZvaWQpbWVtY3B5KCgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5BcGR1QnVmZmVyW05kZWZNYXAtPkFwZHVCdWZmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEJ5dGVzUmVtYWluZWRJbkNhcmQgKTsKCiAgICAgICAgICAgICAgICAgICAgLyogaW5jcmVtZW50IHRoZSBidWZpbmRleCBhbmQgYnl0ZXMgd3JpdHRlbiovCiAgICAgICAgICAgICAgICAgICAgQnVmSW5kZXggKz0gKHVpbnQ4X3QgKUJ5dGVzUmVtYWluZWRJbkNhcmQgOwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPk51bU9mQnl0ZXNXcml0dGVuID0gKHVpbnQxNl90KUJ5dGVzUmVtYWluZWRJbkNhcmQgOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qQ29weSBkYXRhIHRvIHRoZSB0cnggYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgmKE5kZWZNYXAtPkFwZHVCdWZmZXJbTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplIC0gTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCkpOwoKICAgICAgICAgICAgICAgICAgICAvKiBpbmNyZW1lbnQgdGhlIGJ1ZmluZGV4IGFuZCBieXRlcyB3cml0dGVuKi8KICAgICAgICAgICAgICAgICAgICBCdWZJbmRleCArPSAodWludDhfdCkoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4KTsKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5OdW1PZkJ5dGVzV3JpdHRlbiA9ICh1aW50OF90KShOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCBQYWRCeXRlcyApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZm9yKGk9IDA7IGk8IFBhZEJ5dGVzOyBpKyspCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPTB4MDA7CiAgICAgICAgICAgICAgICAgICAgICAgIEJ1ZkluZGV4Kys7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIC8qbm8gb2YgYnl0ZXMgcmVtYWluZWQgY29weSovCiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQgPSAodWludDhfdCkoMTYgLSBQYWRCeXRlcyk7CgogICAgICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLkVvZkNhcmRSZWFjaGVkRmxhZyApCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKmNvcHkgdGhlIGRhdGEgdG8gaW50ZXJuYWwgYnVmZmVyIDogQnl0ZXMgcmVtYWluZWQqLwogICAgICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoTmRlZk1hcC0+RmVsaWNhLldyX1JlbWFpbmVkQnl0ZXNCdWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5BcGR1QnVmZmVyWygoQnl0ZXNSZW1haW5lZEluQ2FyZCAtIChCeXRlc1JlbWFpbmVkSW5DYXJkICUgMTYpKSldKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICggTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQpKTsKCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qY29weSB0aGUgZGF0YSB0byBpbnRlcm5hbCBidWZmZXIgOiBCeXRlcyByZW1haW5lZCovCiAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKW1lbWNweSggTmRlZk1hcC0+RmVsaWNhLldyX1JlbWFpbmVkQnl0ZXNCdWZmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoJihOZGVmTWFwLT5BcGR1QnVmZmVyWygoTmRlZk1hcC0+QXBkdUJ1ZmZlclNpemUgLSBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCkpXSkpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCkpOwoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LyppZiAoIFBhZEJ5dGVzICkqLwogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5Xcl9CeXRlc1JlbWFpbmVkID0gMDsKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUGFkQnl0ZUZsYWcgPSBGQUxTRTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSB0aGUgcGt0IGxlbiovCiAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1BLVF9MRU5fSU5ERVhdID0gQnVmSW5kZXg7CiAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kTGVuZ3RoID0gQnVmSW5kZXg7CiAgICAgICAgICAgIH0KICAgICAgICB9LyogZWxzZSBvZiBpZiAoIChOZGVmTWFwLT5BcGR1QnVmZmVyU2l6ZSAtIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXgpID49ICh1aW50MzJfdCkoMTYqIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5idyApKSAqLwogICAgICAgIHN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IV3JpdGVEYXRhQmxrKE5kZWZNYXApOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIC8qMCByZXByZXNlbnRzIHRoZSB3cml0ZSBvcGVyYXRpb24gZW5kZWQqLwogICAgICAgIHN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IVXBkYXRlQXR0ckJsa0ZvcldyT3AoTmRlZk1hcCxGRUxJQ0FfV1JJVEVfRU5ERUQpOwogICAgfQogICAgcmV0dXJuIChzdGF0dXMpOwp9CgoKLyohCiAqIFxicmllZiBVc2VkIGluIFdyaXRlIE9wZWFyYXRpb24uCiAqIFRoaXMgZnVuY3Rpb24gcHJlcGFyZXMgYW5kIHNlbmRzIHRyYW5zY2MgQ21kIFBrdC4KICovCgpzdGF0aWMgTkZDU1RBVFVTIHBoRnJpTmZjX0ZlbGljYV9IV3JpdGVEYXRhQmxrKHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCkKewogICAgTkZDU1RBVFVTIHN0YXR1cyA9IE5GQ1NUQVRVU19QRU5ESU5HOwoKICAgIC8qc2V0IHRoZSBhZGRpdGlvbmFsIGluZm9ybWF0aW9ucyBmb3IgdGhlIGRhdGEgZXhjaGFuZ2UqLwogICAgTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mby5EZXBGbGFncy5NZXRhQ2hhaW5pbmcgPSAwOwogICAgTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mby5EZXBGbGFncy5OQURQcmVzZW50ID0gMDsKCiAgICAvKlNldCB0aGUgSVNPMTQ0MzQgY29tbWFuZCovCiNpZmRlZiBQSF9IQUw0X0VOQUJMRQogICAgTmRlZk1hcC0+Q21kLkZlbENtZCA9IHBoSGFsX2VGZWxpY2FfUmF3OyAgICAKI2Vsc2UKICAgIE5kZWZNYXAtPkNtZC5GZWxDbWQgPSBwaEhhbF9lRmVsaWNhQ21kTGlzdEZlbGljYUNtZDsKI2VuZGlmICAvKiAjaWZkZWYgUEhfSEFMNF9FTkFCTEUgKi8KCiAgICAvKiBzZXQgdGhlIHN0YXRlKi8KICAgIE5kZWZNYXAtPlN0YXRlID0gUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9TVEFURV9XUl9CTE9DSzsKCiAgICAvKiBzZXQgc2VuZCByZWNlaXZlIGxlbmd0aCovCiAgICAqTmRlZk1hcC0+U2VuZFJlY3ZMZW5ndGggPSBOZGVmTWFwLT5UZW1wUmVjZWl2ZUxlbmd0aDsgCgogICAgIC8qQ2FsbCB0aGUgT3ZlcmxhcHBlZCBIQUwgVHJhbnNjZWl2ZSBmdW5jdGlvbiAqLyAKICAgIHN0YXR1cyA9IHBoRnJpTmZjX092ckhhbF9UcmFuc2NlaXZlKCBOZGVmTWFwLT5Mb3dlckRldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+cHNSZW1vdGVEZXZJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkNtZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2TGVuZ3RoKTsKICAgIHJldHVybiAoc3RhdHVzKTsKfQoKLyohCiAqIFxicmllZiBDaGVjayB3aGV0aGVyIGEgcGFydGljdWxhciBSZW1vdGUgRGV2aWNlIGlzIE5ERUYgY29tcGxpYW50LgogKiBUaGUgZnVuY3Rpb24gY2hlY2tzIHdoZXRoZXIgdGhlIHBlZXIgZGV2aWNlIGlzIE5ERUYgY29tcGxpYW50LgogKi8KCk5GQ1NUQVRVUyBwaEZyaU5mY19GZWxpY2FfQ2hrTmRlZiggcGhGcmlOZmNfTmRlZk1hcF90ICAgICAqTmRlZk1hcCkKewogICAgTkZDU1RBVFVTIHN0YXR1cyA9IE5GQ1NUQVRVU19QRU5ESU5HOwogICAgdWludDhfdCBzeXNDb2RlWzJdOwoKICAgIC8qIHNldCB0aGUgc3lzdGVtIGNvZGUgZm9yIHNlbGVjdGluZyB0aGUgd2lsZCBjYXJkKi8KICAgIHN5c0NvZGVbMF0gPSAweDEyOwogICAgc3lzQ29kZVsxXSA9IDB4RkM7CgogICAgc3RhdHVzID0gcGhGcmlOZmNfRmVsaWNhX0hQb2xsQ2FyZCggTmRlZk1hcCxzeXNDb2RlLFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfU0VMRUNUX05ERUZfQVBQKTsKCiAgICByZXR1cm4gKHN0YXR1cyk7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAovKiEKICogXGJyaWVmIENoZWNrIHdoZXRoZXIgYSBwYXJ0aWN1bGFyIFJlbW90ZSBEZXZpY2UgaXMgTkRFRiBjb21wbGlhbnQuCiAqIHNlbGVjdHMgdGhlIHN5c0NvZGUgYW5kIHRoZW4gTkZDIEZvcnVtIFJlZmVyZW5jZSBBcHBsaWNhdGlvbnMKICovCiNpZmRlZiBQSF9IQUw0X0VOQUJMRQpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hQb2xsQ2FyZCggIHBoRnJpTmZjX05kZWZNYXBfdCAgICAgKk5kZWZNYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB1aW50OF90IHN5c0NvZGVbXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3Qgc3RhdGUpCnsKICAgIE5GQ1NUQVRVUyBzdGF0dXMgPSBORkNTVEFUVVNfUEVORElORzsKCiAgICAvKkZvcm1hdCB0aGUgUG9sbCBQYWNrZXQgZm9yIHNlbGVjdGluZyB0aGUgc3lzdGVtIGNvZGUgcGFzc2VkIGFzIHBhcmFtZXRlciAqLwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMF0gPSAweDA2OwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMV0gPSAweDAwOwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMl0gPSBzeXNDb2RlWzBdOwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbM10gPSBzeXNDb2RlWzFdOwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbNF0gPSAweDAxOwogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbNV0gPSAweDAzOwoKICAgIE5kZWZNYXAtPlNlbmRMZW5ndGggPSA2OwoKICAgICAvKnNldCB0aGUgY29tcGxldGlvbiByb3V0aW5lcyBmb3IgdGhlIGZlbGljYSBjYXJkIG9wZXJhdGlvbnMqLwogICAgTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8uQ29tcGxldGlvblJvdXRpbmUgPSBwaEZyaU5mY19GZWxpY2FfUHJvY2VzczsKICAgIE5kZWZNYXAtPk1hcENvbXBsZXRpb25JbmZvLkNvbnRleHQgPSBOZGVmTWFwOwoKICAgIC8qU2V0IE5kZWYgU3RhdGUqLwogICAgTmRlZk1hcC0+U3RhdGUgPSBzdGF0ZTsKCiAgICAvKiBzZXQgdGhlIGZlbGljYSBjbWQgKi8KICAgIE5kZWZNYXAtPkNtZC5GZWxDbWQgPSBwaEhhbF9lRmVsaWNhX1JhdzsKCiAgICAvKnNldCB0aGUgYWRkaXRpb25hbCBpbmZvcm1hdGlvbnMgZm9yIHRoZSBkYXRhIGV4Y2hhbmdlKi8KICAgIE5kZWZNYXAtPnBzRGVwQWRkaXRpb25hbEluZm8uRGVwRmxhZ3MuTWV0YUNoYWluaW5nID0gMDsKICAgIE5kZWZNYXAtPnBzRGVwQWRkaXRpb25hbEluZm8uRGVwRmxhZ3MuTkFEUHJlc2VudCA9IDA7CgogICAgc3RhdHVzID0gcGhGcmlOZmNfT3ZySGFsX1RyYW5zY2VpdmUoTmRlZk1hcC0+TG93ZXJEZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5wc1JlbW90ZURldkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5DbWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZExlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+U2VuZFJlY3ZMZW5ndGgpOwogICAgcmV0dXJuIChzdGF0dXMpOwp9CiNlbmRpZgoKCiNpZm5kZWYgUEhfSEFMNF9FTkFCTEUKc3RhdGljIE5GQ1NUQVRVUyAgIHBoRnJpTmZjX0ZlbGljYV9IUG9sbENhcmQoICBwaEZyaU5mY19OZGVmTWFwX3QgICAgICpOZGVmTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdWludDhfdCAgICAgICAgICAgICAgICAgc3lzQ29kZVtdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdWludDhfdCAgICAgICAgICAgICAgICAgc3RhdGUpCnsKICAgIE5GQ1NUQVRVUyBzdGF0dXMgPSBORkNTVEFUVVNfUEVORElORzsKICAgIAogICAgLypGb3JtYXQgdGhlIFBvbGwgUGFja2V0IGZvciBzZWxlY3RpbmcgdGhlIHdpbGQgY2FyZCAiMHhmZiAweGZmIGFzIHN5c3RlbSBjb2RlKi8KICAgIE5kZWZNYXAtPkZlbGljYVBvbGxEZXRhaWxzLkRldklucHV0UGFyYW0tPkZlbGljYVBvbGxQYXlsb2FkWzBdICAgPSAgIDB4MDA7CiAgICBOZGVmTWFwLT5GZWxpY2FQb2xsRGV0YWlscy5EZXZJbnB1dFBhcmFtLT5GZWxpY2FQb2xsUGF5bG9hZFsxXSAgID0gICBzeXNDb2RlWzBdOwogICAgTmRlZk1hcC0+RmVsaWNhUG9sbERldGFpbHMuRGV2SW5wdXRQYXJhbS0+RmVsaWNhUG9sbFBheWxvYWRbMl0gICA9ICAgc3lzQ29kZVsxXTsKICAgIE5kZWZNYXAtPkZlbGljYVBvbGxEZXRhaWxzLkRldklucHV0UGFyYW0tPkZlbGljYVBvbGxQYXlsb2FkWzNdICAgPSAgIDB4MDE7CiAgICBOZGVmTWFwLT5GZWxpY2FQb2xsRGV0YWlscy5EZXZJbnB1dFBhcmFtLT5GZWxpY2FQb2xsUGF5bG9hZFs0XSAgID0gICAweDAzOyAKCiAgICAvKiBzZXQgdGhlIGxlbmd0aCB0byB6ZXJvKi8KICAgIE5kZWZNYXAtPkZlbGljYVBvbGxEZXRhaWxzLkRldklucHV0UGFyYW0tPkdlbmVyYWxCeXRlTGVuZ3RoID0weDAwOwoKICAgIE5kZWZNYXAtPk5vT2ZEZXZpY2VzID0gUEhfRlJJTkZDX05ERUZNQVBfRkVMSV9OVU1fREVWSUNFX1RPX0RFVEVDVDsKCiAgICAgLypzZXQgdGhlIGNvbXBsZXRpb24gcm91dGluZXMgZm9yIHRoZSBmZWxpY2EgY2FyZCBvcGVyYXRpb25zKi8KICAgIE5kZWZNYXAtPk1hcENvbXBsZXRpb25JbmZvLkNvbXBsZXRpb25Sb3V0aW5lID0gcGhGcmlOZmNfRmVsaWNhX1Byb2Nlc3M7CiAgICBOZGVmTWFwLT5NYXBDb21wbGV0aW9uSW5mby5Db250ZXh0ID0gTmRlZk1hcDsKCiAgICAvKlNldCBOZGVmIFN0YXRlKi8KICAgIE5kZWZNYXAtPlN0YXRlID0gc3RhdGU7CgogICAgLyogIEhhcnNoYTogVGhpcyBpcyBhIHNwZWNpYWwgY2FzZSBmb3IgZmVsaWNhLiAKICAgICAgICBNYWtlIGEgY29weSBvZiB0aGUgcmVtb3RlIGRldmljZSBpbmZvcm1hdGlvbiBhbmQgc2VuZCBpdCBmb3IKICAgICAgICBwb2xsaW5nLiBSZXR1cm4gdGhlIG9yaWdpbmFsIHJlbW90ZSBkZXZpY2UgaW5mb3JtYXRpb24gdG8gdGhlCiAgICAgICAgY2FsbGVyLiBUaGUgdXNlciBkb2VzIG5vdCBuZWVkIHRoZSB1cGRhdGVkIHJlc3VsdHMgb2YgdGhlIHBvbGwKICAgICAgICB0aGF0IHdlIGFyZSBnb2luZyB0byBjYWxsIG5vdy4gVGhpcyBpcyBvbmx5IHVzZWQgZm9yIGNoZWNraW5nCiAgICAgICAgd2hldGhlciB0aGUgZmVsaWNhIGNhcmQgaXMgTkRFRiBjb21wbGlhbnQgb3Igbm90LiAqLyAKICAgICAodm9pZCkgbWVtY3B5KCAmTmRlZk1hcC0+RmVsaWNhUG9sbERldGFpbHMucHNUZW1wUmVtb3RlRGV2SW5mbywKICAgICAgICAgICAgTmRlZk1hcC0+cHNSZW1vdGVEZXZJbmZvLAogICAgICAgICAgICBzaXplb2YocGhIYWxfc1JlbW90ZURldkluZm9ybWF0aW9uX3QpKTsKCiAgICAvKiAgUmVzZXQgdGhlIHNlc3Npb24gb3BlbmVkIGZsYWcgKi8KICAgIE5kZWZNYXAtPkZlbGljYVBvbGxEZXRhaWxzLnBzVGVtcFJlbW90ZURldkluZm8uU2Vzc2lvbk9wZW5lZCA9IDB4MDA7CgogICAgLypDYWxsIHRoZSBPdmVybGFwcGVkIEhBTCBQT0xMIGZ1bmN0aW9uICovCiAgICBzdGF0dXMgPSAgcGhGcmlOZmNfT3ZySGFsX1BvbGwoIE5kZWZNYXAtPkxvd2VyRGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPk9wTW9kZVR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZOZGVmTWFwLT5GZWxpY2FQb2xsRGV0YWlscy5wc1RlbXBSZW1vdGVEZXZJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+Tm9PZkRldmljZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYVBvbGxEZXRhaWxzLkRldklucHV0UGFyYW0pOwoKICAgIHJldHVybiAoc3RhdHVzKTsKfQojZW5kaWYgLyogI2lmbmRlZiBQSF9IQUw0X0VOQUJMRSAqLwovKiEKICogXGJyaWVmIENoZWNrcyB2YWxpZGl0eSBvZiBzeXN0ZW0gY29kZSBzZW50IGZyb20gdGhlIGxvd2VyIGRldmljZSwgZHVyaW5nIHBvbGwgb3BlcmF0aW9uLgogKi8KCnN0YXRpYyBORkNTVEFUVVMgICBwaEZyaU5mY19GZWxpY2FfSFVwZGF0ZU1hbnVmSWREZXRhaWxzKGNvbnN0IHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCkKewogICAgTkZDU1RBVFVTIHN0YXR1cyA9IE5GQ1NUQVRVU19QRU5ESU5HOwoKICAgIC8qIEdldCB0aGUgZGV0YWlscyBmcm9tIFBvbGwgUmVzcG9uc2UgcGFja2V0ICovCiAgICBpZiAoTmRlZk1hcC0+U2VuZFJlY3ZMZW5ndGggPj0gMjApCiAgICB7CiAgICAgICAgKHZvaWQpbWVtY3B5KCAgKHVpbnQ4X3QgKilOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uSURtLAogICAgICAgICAgICAgICAgICAgICAgICh1aW50OF90ICopJk5kZWZNYXAtPlNlbmRSZWN2QnVmWzJdLCA4KTsKICAgICAgICAodm9pZCltZW1jcHkoICAodWludDhfdCAqKU5kZWZNYXAtPnBzUmVtb3RlRGV2SW5mby0+UmVtb3RlRGV2SW5mby5GZWxpY2FfSW5mby5QTW0sCiAgICAgICAgICAgICAgICAgICAgICAgKHVpbnQ4X3QgKikmTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMTBdLCA4KTsKICAgICAgICBOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uU3lzdGVtQ29kZVsxXSA9IE5kZWZNYXAtPlNlbmRSZWN2QnVmWzE4XTsKICAgICAgICBOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uU3lzdGVtQ29kZVswXSA9IE5kZWZNYXAtPlNlbmRSZWN2QnVmWzE5XTsKICAgICAgICBOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uSURtTGVuZ3RoID0gODsKCiAgICAgICAgLyogY29weSB0aGUgSURtIGFuZCBQTW0gaW4gTWFudWZhY3R1cmUgRGV0YWlscyBTdHJ1Y3R1cmUqLwogICAgICAgICh2b2lkKW1lbWNweSggKHVpbnQ4X3QgKikoTmRlZk1hcC0+RmVsaWNhTWFudWZEZXRhaWxzLk1hbnVmSUQpLAogICAgICAgICAgICAgICAgICAgICAgKHVpbnQ4X3QgKilOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uSURtLAogICAgICAgICAgICAgICAgICAgICAgOCk7CiAgICAgICAgKHZvaWQpbWVtY3B5KCAodWludDhfdCAqKShOZGVmTWFwLT5GZWxpY2FNYW51ZkRldGFpbHMuTWFudWZQYXJhbWV0ZXIpLAogICAgICAgICAgICAgICAgICAgICAgKHVpbnQ4X3QgKilOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uUE1tLAogICAgICAgICAgICAgICAgICAgICAgOCk7CiAgICAgICAgaWYoKE5kZWZNYXAtPnBzUmVtb3RlRGV2SW5mby0+UmVtb3RlRGV2SW5mby5GZWxpY2FfSW5mby5TeXN0ZW1Db2RlWzFdID09IDB4MTIpCiAgICAgICAgICAgICYmIChOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uU3lzdGVtQ29kZVswXSA9PSAweEZDKSkKICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX05GQ19OT05FLCBORkNTVEFUVVNfU1VDQ0VTUyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX05PX05ERUZfU1VQUE9SVCk7CiAgICAgICAgfQogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfTk9fTkRFRl9TVVBQT1JUKTsKICAgIH0KCiAgICByZXR1cm4gKHN0YXR1cyk7Cn0KCgovKiEKICogXGJyaWVmIENvbXBsZXRpb24gUm91dGluZSwgUHJvY2Vzc2luZyBmdW5jdGlvbiwgbmVlZGVkIHRvIGF2b2lkIGxvbmcgYmxvY2tpbmcuCiAqIFxub3RlIFRoZSBsb3dlciAoT3ZlcmxhcHBlZCBIQUwpIGxheWVyIG11c3QgcmVnaXN0ZXIgYSBwb2ludGVyIHRvIHRoaXMgZnVuY3Rpb24gYXMgYSBDb21wbGV0aW9uCiAqIFJvdXRpbmUgaW4gb3JkZXIgdG8gYmUgYWJsZSB0byBub3RpZnkgdGhlIGNvbXBvbmVudCB0aGF0IGFuIEkvTyBoYXMgZmluaXNoZWQgYW5kIGRhdGEgYXJlCiAqIHJlYWR5IHRvIGJlIHByb2Nlc3NlZC4KICovCgp2b2lkIHBoRnJpTmZjX0ZlbGljYV9Qcm9jZXNzKHZvaWQgICAgICAgKkNvbnRleHQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTICAgU3RhdHVzKQp7CiAgICB1aW50OF90ICBDUkZsYWcgPSBGQUxTRTsKICAgIHVpbnQxNl90IFJlY3ZUeExlbiA9IDAsCiAgICAgICAgICAgICBCeXRlc1RvUmVjdiA9IDAsCiAgICAgICAgICAgICBOYmMgPSAwOwogICAgdWludDMyX3QgVG90Tm9Xcml0dGVuQnl0ZXMgPSAwLAogICAgICAgICAgICAgTkRFRkxlbj0wOwoKICAgIC8qU2V0IHRoZSBjb250ZXh0IHRvIE1hcCBNb2R1bGUqLwogICAgcGhGcmlOZmNfTmRlZk1hcF90ICAgICAgKk5kZWZNYXAgPSAocGhGcmlOZmNfTmRlZk1hcF90ICopQ29udGV4dDsKICAgIAogICAgaWYgKCBTdGF0dXMgPT0gTkZDU1RBVFVTX1NVQ0NFU1MgKQogICAgewogICAgICAgIHN3aXRjaCAoTmRlZk1hcC0+U3RhdGUpCiAgICAgICAgewogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfU0VMRUNUX05ERUZfQVBQOgoKICAgICAgICAgICAgICAgICAgICAvKiBjaGVjayB0aGUgbmRlZiBjb21wbGllbmN5IHdpdGggdGhlIHN5c3RlbSBjb2RlIHJlZWNpdmVkIGluIHRoZSBSZW1vdGVEZXZJbmZvKi8KICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFVwZGF0ZU1hbnVmSWREZXRhaWxzKE5kZWZNYXApOwoKICAgICAgICAgICAgICAgICAgICBpZiAoU3RhdHVzID09IE5GQ1NUQVRVU19TVUNDRVNTKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogTWFudGlzIElEIDogNjQ1Ki8KICAgICAgICAgICAgICAgICAgICAgICAgLyogc2V0IHRoZSBvcGVyYXRpb24gdHlwZSB0byBDaGVjayBuZGVmIHR5cGUqLwogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuT3BGbGFnID0gUEhfRlJJTkZDX05ERUZNQVBfRkVMSV9DSEtfTkRFRl9PUDsKICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gcGhGcmlOZmNfRmVsaWNhX0hSZEF0dHJJbmZvKE5kZWZNYXApOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBoYW5kbGUgdGhlIGVycm9yIGluIFRyYW5zYyBmdW5jdGlvbiovCiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggKFN0YXR1cyAmIFBITkZDU1RCTE9XRVIpICE9IChORkNTVEFUVVNfUEVORElORyAmIFBITkZDU1RCTE9XRVIpKQogICAgICAgICAgICAgICAgICAgICAgICB7ICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JGbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAgICAgfSAgICAgCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIENSRmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGlmICggQ1JGbGFnID09IFRSVUUgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogY2FsbCByZXNwZWN0aXZlIENSICovCiAgICAgICAgICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsUEhfRlJJTkZDX05ERUZNQVBfQ1JfQ0hLX05ERUYsU3RhdHVzKTsKCiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfUkRfQVRUUjoKICAgICAgICAgICAgIC8qIGNoZWNrIGZvciB0aGUgc3RhdHVzIGZsYWcxIGFuZCBzdGF0dXMgZmxhZzJmb3IgdGhlIHN1Y2Nlc3NmdWwgcmVhZCBvcGVyYXRpb24qLwogICAgICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxMF0gPT0gMHgwMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBjaGVjayB0aGUgTWFudWYgSWQgaW4gdGhlIHJlY2VpdmUgYnVmZmVyKi8KICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSENoZWNrTWFudWZJZChOZGVmTWFwKTsKICAgICAgICAgICAgICAgICAgICBpZiAoIFN0YXR1cyA9PSBORkNTVEFUVVNfU1VDQ0VTUykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFVwZGF0ZSB0aGUgQXR0cmlidXRlIEluZm9ybWF0aW9uIGluIHRvIHRoZSBjb250ZXh0IHN0cnVjdHVyZSovCiAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IVXBkYXRlQXR0ckluZm8oTmRlZk1hcCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggU3RhdHVzID09IE5GQ1NUQVRVU19TVUNDRVNTICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9DQUxfTEVOX0JZVEVTKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzBdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTGVuQnl0ZXNbMV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1syXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5ERUZMZW4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLk9wRmxhZyA9PSBQSF9GUklORkNfTkRFRk1BUF9GRUxJX1dSX0FUVFJfUkRfT1AgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIFByb2NlZWQgV2l0aCBXcml0ZSBGdW5jdGluYWxpdHkqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IQ2hrQXR0ckJsa0ZvcldyT3AoTmRlZk1hcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaGFuZGxlIHRoZSBlcnJvciBpbiBUcmFuc2MgZnVuY3Rpb24qLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggKFN0YXR1cyAmIFBITkZDU1RCTE9XRVIpICE9IChORkNTVEFUVVNfUEVORElORyAmIFBITkZDU1RCTE9XRVIpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY2FsbCByZXNwZWN0aXZlIENSICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsUEhfRlJJTkZDX05ERUZNQVBfQ1JfV1JfTkRFRixTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYoIE5kZWZNYXAtPkZlbGljYS5PcEZsYWcgPT0gUEhfRlJJTkZDX05ERUZNQVBfRkVMSV9SRF9BVFRSX1JEX09QICkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBQcm9jZWVkIFdpdGggUmVhZCBGdW5jdGluYWxpdHkqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IQ2hrQXR0ckJsa0ZvclJkT3AoTmRlZk1hcCxOREVGTGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIChTdGF0dXMgJiBQSE5GQ1NUQkxPV0VSKSAhPSAoTkZDU1RBVFVTX1BFTkRJTkcgJiBQSE5GQ1NUQkxPV0VSKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNhbGwgcmVzcGVjdGl2ZSBDUiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaEZyaU5mY19GZWxpY2FfSENySGFuZGxlcihOZGVmTWFwLFBIX0ZSSU5GQ19OREVGTUFQX0NSX1JEX05ERUYsU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmKCBOZGVmTWFwLT5GZWxpY2EuT3BGbGFnID09IFBIX0ZSSU5GQ19OREVGTUFQX0ZFTElfQ0hLX05ERUZfT1AgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1cyA9IHBoRnJpTmZjX01hcFRvb2xfU2V0Q2FyZFN0YXRlKCBOZGVmTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOREVGTGVuKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjaGVjayBzdGF0dXMgdmFsdWUqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkNhcmRUeXBlID0gUEhfRlJJTkZDX05ERUZNQVBfRkVMSUNBX1NNQVJUX0NBUkQ7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypyZXNldCB0aGUgYnVmZmVyIGluZGV4Ki8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzZXQgdGhlIE5leHQgb3BlcmF0aW9uIEZsYWcgdG8gaW5kaWNhdGUgbmVlZCBvZiByZWFkaW5nIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLk9wRmxhZyA9IFBIX0ZSSU5GQ19OREVGTUFQX0ZFTElfT1BfTk9ORTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjYWxsIHJlc3BlY3RpdmUgQ1IgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaEZyaU5mY19GZWxpY2FfSENySGFuZGxlcihOZGVmTWFwLFBIX0ZSSU5GQ19OREVGTUFQX0NSX0NIS19OREVGLFN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICggTmRlZk1hcC0+RmVsaWNhLk9wRmxhZyA9PSBQSF9GUklORkNfTkRFRk1BUF9GRUxJX1dSX0VNUFRZX01TR19PUCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogUHJvY2VlZCBXaXRoIFdyaXRlIEZ1bmN0aW5hbGl0eSovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gcGhGcmlOZmNfRmVsaWNhX0hXckVtcHR5TXNnKE5kZWZNYXApOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGhhbmRsZSB0aGUgZXJyb3IgaW4gVHJhbnNjIGZ1bmN0aW9uKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIChTdGF0dXMgJiBQSE5GQ1NUQkxPV0VSKSAhPSAoTkZDU1RBVFVTX1BFTkRJTkcgJiBQSE5GQ1NUQkxPV0VSKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNhbGwgcmVzcGVjdGl2ZSBDUiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaEZyaU5mY19GZWxpY2FfSENySGFuZGxlcihOZGVmTWFwLFBIX0ZSSU5GQ19OREVGTUFQX0NSX0VSQVNFX05ERUYsU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaW52YWxpZCBvcGVyYXRpb24gb2NjdXJlZCovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfSU5WQUxJRF9ERVZJQ0VfUkVRVUVTVCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JGbGFnID1UUlVFIDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIENSRmxhZyA9VFJVRSA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgQ1JGbGFnID1UUlVFIDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgQ1JGbGFnID1UUlVFOwogICAgICAgICAgICAgICAgICAgIC8qaGFuZGxlIHRoZSAgRXJyb3IgY2FzZSovCiAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfUkVBRF9GQUlMRUQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKCBDUkZsYWcgPT0gVFJVRSApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogY2FsbCByZXNwZWN0aXZlIENSICovCiAgICAgICAgICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hDckhhbmRsZXIoTmRlZk1hcCxQSF9GUklORkNfTkRFRk1BUF9DUl9SRF9OREVGLFN0YXR1cyk7ICAgCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9TVEFURV9BVFRSX0JMS19XUl9CRUdJTjoKICAgICAgICAgICAgICAgICAgICAvKiBjaGsgdGhlIHN0YXR1cyBmbGFncyAxIGFuZCAyKi8KICAgICAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPlNlbmRSZWN2QnVmWzEwXSA9PSAweDAwICkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFVwZGF0ZSBEYXRhIENhbGwqLwogICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPXBoRnJpTmZjX0ZlbGljYV9IVXBkYXRlRGF0YShOZGVmTWFwKTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAoU3RhdHVzICYgUEhORkNTVEJMT1dFUikgIT0gKE5GQ1NUQVRVU19QRU5ESU5HICYgUEhORkNTVEJMT1dFUikpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNhbGwgcmVzcGVjdGl2ZSBDUiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hDckhhbmRsZXIoTmRlZk1hcCxQSF9GUklORkNfTkRFRk1BUF9DUl9XUl9OREVGLFN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLypoYW5kbGUgdGhlICBFcnJvciBjYXNlKi8KICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX1dSSVRFX0ZBSUxFRCk7CiAgICAgICAgICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsUEhfRlJJTkZDX05ERUZNQVBfQ1JfV1JfTkRFRixTdGF0dXMpOyAgIAoKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1NUQVRFX0FUVFJfQkxLX1dSX0VORDoKCiAgICAgICAgICAgICAgICAgICAgLyogY2hrIHRoZSBzdGF0dXMgZmxhZ3MgMSBhbmQgMiovCiAgICAgICAgICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxMF0gPT0gMHgwMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVudGlyZSBXcml0ZSBPcGVyYXRpb24gaXMgY29tcGxldGUqLwogICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9ORkNfTk9ORSxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX1NVQ0NFU1MpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgLypoYW5kbGUgdGhlICBFcnJvciBjYXNlKi8KICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX1dSSVRFX0ZBSUxFRCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsUEhfRlJJTkZDX05ERUZNQVBfQ1JfV1JfTkRFRixTdGF0dXMpOyAgIAogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfV1JfRU1QVFlfTVNHIDoKCiAgICAgICAgICAgICAgICAgICAgLyogY2hrIHRoZSBzdGF0dXMgZmxhZ3MgMSBhbmQgMiovCiAgICAgICAgICAgICAgICAgICAgaWYgKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxMF0gPT0gMHgwMCkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIEVudGlyZSBXcml0ZSBPcGVyYXRpb24gaXMgY29tcGxldGUqLwogICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9ORkNfTk9ORSxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX1NVQ0NFU1MpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgLypoYW5kbGUgdGhlICBFcnJvciBjYXNlKi8KICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCxcCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX1dSSVRFX0ZBSUxFRCk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsUEhfRlJJTkZDX05ERUZNQVBfQ1JfV1JfTkRFRixTdGF0dXMpOyAgIAogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfV1JfQkxPQ0sgOgogICAgICAgICAgICAgICAgaWYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMV0gPT0gUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9XUl9SRVNQX0JZVEUgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIGNoayB0aGUgc3RhdHVzIGZsYWdzIDEgYW5kIDIqLwogICAgICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMTBdID09IDB4MDAgKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogVGhpcyBpcyB1c2VkIHdoZW4gd2UgaGF2ZSBieXRlcyBsZXNzIHRoYW4gMTYgYnl0ZXMqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5JbnRlcm1lZGlhdGVXckZsYWcgPT0gVFJVRSApCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGFmdGVyIFN1Y2Nlc3NmdWwgd3JpdGUgY29weSB0aGUgbGFzdCB3cml0dGVuZWQgYnl0ZXMgYmFjayB0byB0aGUKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludGVybmFsIGJ1ZmZlciovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCltZW1jcHkoICgmKE5kZWZNYXAtPkZlbGljYS5Xcl9SZW1haW5lZEJ5dGVzQnVmZltOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZF0pKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZmVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPk51bU9mQnl0ZXNXcml0dGVuKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuV3JfQnl0ZXNSZW1haW5lZCArPQogICAgICAgICAgICAgICAgICAgICAgICAgICAodWludDhfdCkoIE5kZWZNYXAtPk51bU9mQnl0ZXNXcml0dGVuKTsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBJbmNyZW1lbnQgdGhlIFNlbmQgQnVmZmVyIGluZGV4ICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ICs9IAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPk51bU9mQnl0ZXNXcml0dGVuOwoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICpOZGVmTWFwLT5Xck5kZWZQYWNrZXRMZW5ndGggPSBOZGVmTWFwLT5BcGR1QnVmZkluZGV4OwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLkludGVybWVkaWF0ZVdyRmxhZyA9IEZBTFNFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQ2FsbCBVcGRhdGUgRGF0YSgpKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IVXBkYXRlRGF0YShOZGVmTWFwKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHVwZGF0ZSB0aGUgaW5kZXggYW5kIGJ5dGVzIHdyaXR0ZW5lZCovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4ICs9IE5kZWZNYXAtPk51bU9mQnl0ZXNXcml0dGVuOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKk5kZWZNYXAtPldyTmRlZlBhY2tldExlbmd0aCA9IE5kZWZNYXAtPkFwZHVCdWZmSW5kZXg7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPkZlbGljYS5Fb2ZDYXJkUmVhY2hlZEZsYWcgKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gPCBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YikKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vICs9IE5kZWZNYXAtPkZlbGljYS5Ob0Jsb2Nrc1dyaXR0ZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICgoIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vID09IE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5tYXhiKSAmJgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoIE5kZWZNYXAtPkFwZHVCdWZmSW5kZXggPT0gKE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLk5tYXhiKjE2KSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnID0gRkVMSUNBX1JEX1dSX0VPRl9DQVJEX1JFQUNIRUQgOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKjAgcmVwcmVzZW50cyB0aGUgd3JpdGUgZW5kZWQqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFVwZGF0ZUF0dHJCbGtGb3JXck9wKE5kZWZNYXAsRkVMSUNBX1dSSVRFX0VOREVEKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoIChTdGF0dXMgJiBQSE5GQ1NUQkxPV0VSKSAhPSAoTkZDU1RBVFVTX1BFTkRJTkcgJiBQSE5GQ1NUQkxPV0VSKSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogY2FsbCByZXNwZWN0aXZlIENSICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwaEZyaU5mY19GZWxpY2FfSENySGFuZGxlcihOZGVmTWFwLFBIX0ZSSU5GQ19OREVGTUFQX0NSX1dSX05ERUYsU3RhdHVzKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX0NBTF9MRU5fQllURVMoTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTGVuQnl0ZXNbMF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1sxXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzJdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgVG90Tm9Xcml0dGVuQnl0ZXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoICggTmRlZk1hcC0+RmVsaWNhLkN1ckJsb2NrTm8gPT0gTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTm1heGIpICYmCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoKFRvdE5vV3JpdHRlbkJ5dGVzICsgTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCkgPT0gKHVpbnQzMl90KShOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YioxNikpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnID1GRUxJQ0FfUkRfV1JfRU9GX0NBUkRfUkVBQ0hFRDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qMCByZXByZXNlbnRzIHRoZSB3cml0ZSBlbmRlZCovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFVwZGF0ZUF0dHJCbGtGb3JXck9wKE5kZWZNYXAsRkVMSUNBX1dSSVRFX0VOREVEKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggKFN0YXR1cyAmIFBITkZDU1RCTE9XRVIpICE9IChORkNTVEFUVVNfUEVORElORyAmIFBITkZDU1RCTE9XRVIpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNhbGwgcmVzcGVjdGl2ZSBDUiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsUEhfRlJJTkZDX05ERUZNQVBfQ1JfV1JfTkRFRixTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQ2FsbCBVcGRhdGUgRGF0YSgpKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFN0YXR1cyA9IHBoRnJpTmZjX0ZlbGljYV9IVXBkYXRlRGF0YShOZGVmTWFwKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggKFN0YXR1cyAmIFBITkZDU1RCTE9XRVIpICE9IChORkNTVEFUVVNfUEVORElORyAmIFBITkZDU1RCTE9XRVIpKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNhbGwgcmVzcGVjdGl2ZSBDUiAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsUEhfRlJJTkZDX05ERUZNQVBfQ1JfV1JfTkRFRixTdGF0dXMpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfS8qaWYgKCBOZGVmTWFwLT5GZWxpY2EuRW9mQ2FyZFJlYWNoZWRGbGFnICkqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vICs9IE5kZWZNYXAtPkZlbGljYS5Ob0Jsb2Nrc1dyaXR0ZW47CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogQ2FsbCBVcGRhdGUgRGF0YSgpKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFVwZGF0ZURhdGEoTmRlZk1hcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAoU3RhdHVzICYgUEhORkNTVEJMT1dFUikgIT0gKE5GQ1NUQVRVU19QRU5ESU5HICYgUEhORkNTVEJMT1dFUikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBjYWxsIHJlc3BlY3RpdmUgQ1IgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hDckhhbmRsZXIoTmRlZk1hcCxQSF9GUklORkNfTkRFRk1BUF9DUl9XUl9OREVGLFN0YXR1cyk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfS8qaWYgKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxMF0gPT0gMHgwMCApKi8KICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAvKmhhbmRsZSB0aGUgIEVycm9yIGNhc2UqLwogICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfV1JJVEVfRkFJTEVEKTsKICAgICAgICAgICAgICAgICAgICAgICAgQ1JGbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9LyppZihOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxXSA9PSBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1dSX1JFU1BfQllURSApKi8KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgIC8qcmV0dXJuIEVycm9yICJJbnZhbGlkIFdyaXRlIFJlc3BvbnNlIENvZGUiKi8KICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfV1JJVEVfRkFJTEVEKTsKICAgICAgICAgICAgICAgICAgICBDUkZsYWcgPSBUUlVFOwoKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmICggQ1JGbGFnID09IFRSVUUgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIFJlc2V0IGZvbGxvd2luZyBwYXJhbWV0ZXJzKi8KICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4PTA7CiAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhLldyX0J5dGVzUmVtYWluZWQgPSAwOwogICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkFwZHVCdWZmZXJTaXplID0gMDsKICAgICAgICAgICAgICAgICAgICBwaEZyaU5mY19GZWxpY2FfSENySGFuZGxlcihOZGVmTWFwLFBIX0ZSSU5GQ19OREVGTUFQX0NSX1dSX05ERUYsU3RhdHVzKTsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgICAgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9TVEFURV9SRF9CTE9DSyA6CgogICAgICAgICAgICAvKiBjaGVjayB0aGUgTWFudWYgSWQgaW4gdGhlIHJlY2VpdmUgYnVmZmVyKi8KICAgICAgICAgICAgU3RhdHVzID0gcGhGcmlOZmNfRmVsaWNhX0hDaGVja01hbnVmSWQoTmRlZk1hcCk7CiAgICAgICAgICAgIGlmICggU3RhdHVzID09IE5GQ1NUQVRVU19TVUNDRVNTICkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMV0gPT0gUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9SRF9SRVNQX0JZVEUgKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIGNhbGN1bGF0ZSB0aGUgTm1heGIqLwogICAgICAgICAgICAgICAgICAgIE5iYyA9IHBoRnJpTmZjX0ZlbGljYV9IR2V0TWF4aW11bUJsa3NUb1JlYWQoTmRlZk1hcCxQSF9ORkNGUklfTkRFRk1BUF9GRUxJX05CQyk7CiAgICAgICAgICAgICAgICAgICAgLypnZXQgUmVjZWl2ZSBsZW5ndGggZnJvbSB0aGUgY2FyZCBmb3IgY29yc3MgdmVyaWZpY2F0aW9ucyovCiAgICAgICAgICAgICAgICAgICAgUmVjdlR4TGVuPSBwaEZyaU5mY19GZWxpY2FfSFNldFRyeExlbihOZGVmTWFwLE5iYyk7CiAgICAgICAgICAgICAgICAgICAgQnl0ZXNUb1JlY3YgPSBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxMl0qMTY7CgogICAgICAgICAgICAgICAgICAgIC8qIGNoayB0aGUgc3RhdHVzIGZsYWdzIDEgKi8KICAgICAgICAgICAgICAgICAgICBpZiAoIE5kZWZNYXAtPlNlbmRSZWN2QnVmWzEwXSA9PSAweDAwKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCBSZWN2VHhMZW4gPT0gQnl0ZXNUb1JlY3YpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYS5DdXJCbG9ja05vICs9ICh1aW50OF90KShSZWN2VHhMZW4vMTYpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hBZnRlclJlYWRfQ29weURhdGFUb0J1ZmYoTmRlZk1hcCk7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBwaEZyaU5mY19GZWxpY2FfSFJlYWREYXRhKE5kZWZNYXAsUEhfRlJJTkZDX05ERUZNQVBfU0VFS19DVVIpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogaGFuZGxlIHRoZSBlcnJvciBpbiBUcmFuc2MgZnVuY3Rpb24qLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCAoU3RhdHVzICYgUEhORkNTVEJMT1dFUikgIT0gKE5GQ1NUQVRVU19QRU5ESU5HICYgUEhORkNTVEJMT1dFUikpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JGbGFnID1UUlVFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JGbGFnID1UUlVFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX0lOVkFMSURfUkVDRUlWRV9MRU5HVEgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgLypzZXQgdGhlIGJ1ZmZlciBpbmRleCBiYWNrIHRvIHplcm8qLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2EuUmRfTm9CeXRlc1RvQ29weSA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+QXBkdUJ1ZmZJbmRleD0wOwogICAgICAgICAgICAgICAgICAgICAgICAvKmhhbmRsZSB0aGUgIEVycm9yIGNhc2UqLwogICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLFwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfUkVBRF9GQUlMRUQpOwogICAgICAgICAgICAgICAgICAgICAgICBDUkZsYWcgPVRSVUU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIENSRmxhZyA9VFJVRTsKICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5BcGR1QnVmZkluZGV4PTA7CiAgICAgICAgICAgICAgICAgICAgLypyZXR1cm4gRXJyb3IgIkludmFsaWQgUmVhZCBSZXNwb25zZSBDb2RlIiovCiAgICAgICAgICAgICAgICAgICAgU3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfUkVBRF9GQUlMRUQpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgQ1JGbGFnID1UUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICggQ1JGbGFnID09VFJVRSApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIC8qIGNhbGwgcmVzcGVjdGl2ZSBDUiAqLwogICAgICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hDckhhbmRsZXIoTmRlZk1hcCxQSF9GUklORkNfTkRFRk1BUF9DUl9SRF9OREVGLFN0YXR1cyk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIFN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVNfSU5WQUxJRF9ERVZJQ0VfUkVRVUVTVCk7CiAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsIFBIX0ZSSU5GQ19OREVGTUFQX0NSX0lOVkFMSURfT1BFLCBTdGF0dXMpOwogICAgICAgICAgICBicmVhazsKCgogICAgICAgIH0KICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBDYWxsIENSIGZvciB1bmtub3duIEVycm9yJ3MqLwogICAgICAgIHN3aXRjaCAoIE5kZWZNYXAtPlN0YXRlKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBQSF9GUklORkNfTkRFRk1BUF9GRUxJX1NUQVRFX0NIS19OREVGIDoKICAgICAgICAgICAgY2FzZSBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1NUQVRFX1NFTEVDVF9XSUxEX0NBUkQgOgogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfU0VMRUNUX05ERUZfQVBQIDoKICAgICAgICAgICAgY2FzZSBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1NUQVRFX1JEX0FUVFIgOgogICAgICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hDckhhbmRsZXIoTmRlZk1hcCwgUEhfRlJJTkZDX05ERUZNQVBfQ1JfQ0hLX05ERUYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfV1JfQkxPQ0sgOgogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfQVRUUl9CTEtfV1JfQkVHSU4gOgogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfQVRUUl9CTEtfV1JfRU5EIDoKICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsIFBIX0ZSSU5GQ19OREVGTUFQX0NSX1dSX05ERUYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RhdHVzKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfU1RBVEVfUkRfQkxPQ0sgOgogICAgICAgICAgICAgICAgcGhGcmlOZmNfRmVsaWNhX0hDckhhbmRsZXIoTmRlZk1hcCwgUEhfRlJJTkZDX05ERUZNQVBfQ1JfUkRfTkRFRiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGF0dXMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGRlZmF1bHQgOiAKICAgICAgICAgICAgICAgIC8qc2V0IHRoZSBpbnZhbGlkIHN0YXRlKi8KICAgICAgICAgICAgICAgIFN0YXR1cyA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsIE5GQ1NUQVRVU19JTlZBTElEX0RFVklDRV9SRVFVRVNUKTsKICAgICAgICAgICAgICAgIHBoRnJpTmZjX0ZlbGljYV9IQ3JIYW5kbGVyKE5kZWZNYXAsIFBIX0ZSSU5GQ19OREVGTUFQX0NSX0lOVkFMSURfT1BFLCBTdGF0dXMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKfQoKLyohCiAqIFxicmllZiBQcmVwYXJlcyBDbWQgUGt0IGZvciByZWFkaW5nIGF0dHJpYnV0ZSBCbGsgaW5mb3JtYXRpb24uCiAqLwpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hSZEF0dHJJbmZvKHBoRnJpTmZjX05kZWZNYXBfdCAqTmRlZk1hcCkKewoKICAgIE5GQ1NUQVRVUyAgIHN0YXR1cyA9IE5GQ1NUQVRVU19QRU5ESU5HOwogICAgdWludDhfdCBCdWZJbmRleCA9IDA7CgogICAgLyogU2V0IHRoZSBGZWxpY2EgQ21kKi8KI2lmZGVmIFBIX0hBTDRfRU5BQkxFCiAgICBOZGVmTWFwLT5DbWQuRmVsQ21kID0gcGhIYWxfZUZlbGljYV9SYXc7CiNlbHNlCiAgICBOZGVmTWFwLT5DbWQuRmVsQ21kID0gcGhIYWxfZUZlbGljYUNtZExpc3RGZWxpY2FDbWQ7CiNlbmRpZiAgLyogI2lmZGVmIFBIX0hBTDRfRU5BQkxFICovCgogICAgLypzZXQgdGhlIGFkZGl0aW9uYWwgaW5mb3JtYXRpb25zIGZvciB0aGUgZGF0YSBleGNoYW5nZSovCiAgICBOZGVmTWFwLT5wc0RlcEFkZGl0aW9uYWxJbmZvLkRlcEZsYWdzLk1ldGFDaGFpbmluZyA9IDA7CiAgICBOZGVmTWFwLT5wc0RlcEFkZGl0aW9uYWxJbmZvLkRlcEZsYWdzLk5BRFByZXNlbnQgPSAwOwoKICAgIC8qIDFzdCBieXRlIHJlcHJlc2VudHMgdGhlIGxlbmd0aCBvZiB0aGUgY21kIHBhY2tldCovCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPSAweDAwOwogICAgQnVmSW5kZXgrKzsKCiAgICAvKiBSZWFkL2NoZWNrIGNvbW1hbmQgY29kZSovCiAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0gPSAweDA2OwogICAgQnVmSW5kZXgrKzsKCiAgICAvKiBJRG0gLSBNYW51ZmFjdHVyZXIgSWQgOiA4Ynl0ZXMqLwojaWZkZWYgUEhfSEFMNF9FTkFCTEUKICAgICh2b2lkKW1lbWNweSgoJihOZGVmTWFwLT5TZW5kUmVjdkJ1ZltCdWZJbmRleF0pKSwKICAgICAgICAgICAgICAgICh2b2lkICogKSZOZGVmTWFwLT5wc1JlbW90ZURldkluZm8tPlJlbW90ZURldkluZm8uRmVsaWNhX0luZm8uSURtLAogICAgICAgICAgICAgICAgOCk7CiNlbHNlCiAgICAodm9pZCltZW1jcHkoKCYoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdKSksCiAgICAgICAgICAgICAgICAodm9pZCAqICkmTmRlZk1hcC0+cHNSZW1vdGVEZXZJbmZvLT5SZW1vdGVEZXZJbmZvLkNhcmRJbmZvMjEyXzQyNC5TdGFydHVwMjEyXzQyNC5ORkNJRDJ0LAogICAgICAgICAgICAgICAgOCk7CiAgICAgICAgCiNlbmRpZiAgLyogI2lmZGVmIFBIX0hBTDRfRU5BQkxFICovCgogICAgQnVmSW5kZXgrPTg7CgogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDAxOyAgLyogIE51bWJlciBvZiBTZXJ2aWNlcyAobj0xID09PiAweDgwKSovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwQjsgIC8qICBTZXJ2aWNlIENvZGUgTGlzdCovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwMDsgIC8qICBTZXJ2aWNlIENvZGUgTGlzdCovCiAgICBCdWZJbmRleCsrOwoKICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmW0J1ZkluZGV4XSAgICA9ICAgMHgwMTsgIC8qICBOdW1iZXIgb2YgQmxvY2tzIHRvIHJlYWQpKi8KICAgIEJ1ZkluZGV4Kys7CgogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDgwOyAgLyogIDFzdCBCbG9jayBFbGVtZW50IDogYnl0ZSAxKi8KICAgIEJ1ZkluZGV4Kys7CgogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbQnVmSW5kZXhdICAgID0gICAweDAwOyAgLyogIDFzdCBCbG9jayBFbGVtZW50IDogYnl0ZSAyLCBibG9jayAxKi8KICAgIEJ1ZkluZGV4Kys7CgogICAgTmRlZk1hcC0+U2VuZFJlY3ZCdWZbUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9QS1RfTEVOX0lOREVYXSAgICAgICAgICAgICA9ICAgQnVmSW5kZXg7CgogICAgKk5kZWZNYXAtPlNlbmRSZWN2TGVuZ3RoID0gTmRlZk1hcC0+VGVtcFJlY2VpdmVMZW5ndGg7CgogICAgLyogVXBkYXRlIHRoZSBTZW5kIExlbiovCiAgICBOZGVmTWFwLT5TZW5kTGVuZ3RoID0gQnVmSW5kZXg7CgogICAgLyogQ2hhbmdlIHRoZSBzdGF0ZSB0byAgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9TVEFURV9SRF9BVFRSICovCiAgICBOZGVmTWFwLT5TdGF0ZSA9ICBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1NUQVRFX1JEX0FUVFI7CgogICAgLypzZXQgdGhlIGNvbXBsZXRpb24gcm91dGluZXMgZm9yIHRoZSBkZXNmaXJlIGNhcmQgb3BlcmF0aW9ucyovCiAgICBOZGVmTWFwLT5NYXBDb21wbGV0aW9uSW5mby5Db21wbGV0aW9uUm91dGluZSA9IHBoRnJpTmZjX05kZWZNYXBfUHJvY2VzczsKICAgIE5kZWZNYXAtPk1hcENvbXBsZXRpb25JbmZvLkNvbnRleHQgPSBOZGVmTWFwOwoKICAgIC8qQ2FsbCB0aGUgT3ZlcmxhcHBlZCBIQUwgVHJhbnNjZWl2ZSBmdW5jdGlvbiAqLyAKICAgIHN0YXR1cyA9IHBoRnJpTmZjX092ckhhbF9UcmFuc2NlaXZlKCBOZGVmTWFwLT5Mb3dlckRldmljZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+TWFwQ29tcGxldGlvbkluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+cHNSZW1vdGVEZXZJbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkNtZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmTmRlZk1hcC0+cHNEZXBBZGRpdGlvbmFsSW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kTGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2QnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPlNlbmRSZWN2TGVuZ3RoKTsKICAgICAgcmV0dXJuIChzdGF0dXMpOwogICAgCn0KCi8qIQogKiBcYnJpZWYgVmFsaWRhdGVkIG1hbnVmYWN0dXJlciBEZXRhaWxzLCBkdXJpbmcgdGhlIHJlYWQvd3JpdGUgb3BlcmF0aW9ucy4KICovCgpzdGF0aWMgTkZDU1RBVFVTICAgcGhGcmlOZmNfRmVsaWNhX0hDaGVja01hbnVmSWQoY29uc3QgcGhGcmlOZmNfTmRlZk1hcF90ICpOZGVmTWFwKQp7CiAgICBORkNTVEFUVVMgc3RhdHVzID0gTkZDU1RBVFVTX1BFTkRJTkc7CgogICAgdWludDhfdCByZXN1bHQgPSAwOwoKICAgIC8qIGNoZWNrIHRoZSBzdG9yZWQgbWFudWZhY3R1cmUgaWQgd2l0aCB0aGUgcmVjZWl2ZWQgbWFudWZhY3R1cmUgaWQqLwogICAgcmVzdWx0ID0gKHVpbnQ4X3QpKHBoRnJpTmZjX0ZlbGljYV9NZW1Db21wYXJlKCAodm9pZCAqKSgmKE5kZWZNYXAtPlNlbmRSZWN2QnVmWzJdKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKU5kZWZNYXAtPkZlbGljYU1hbnVmRGV0YWlscy5NYW51ZklELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOCkpOwoKICAgIGlmICggcmVzdWx0ICE9IDApCiAgICB7CiAgICAgICAgc3RhdHVzID0gUEhORkNTVFZBTChDSURfRlJJX05GQ19OREVGX01BUCwgTkZDU1RBVFVTX0lOVkFMSURfUkVNT1RFX0RFVklDRSk7CiAgICAgICAgCiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgc3RhdHVzID0gUEhORkNTVFZBTChDSURfTkZDX05PTkUsTkZDU1RBVFVTX1NVQ0NFU1MpOwogICAgICAgIAogICAgfQogICAgcmV0dXJuIChzdGF0dXMpOwp9CgpzdGF0aWMgTkZDU1RBVFVTIHBoRnJpTmZjX0ZlbGljYV9IQ2FsQ2hlY2tTdW0oY29uc3QgdWludDhfdCAqVGVtcEJ1ZmZlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgU3RhcnRJbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVpbnQ4X3QgRW5kSW5kZXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50MTZfdCBSZWN2Q2hrU3VtKQp7CiAgICBORkNTVEFUVVMgICBSZXN1bHQgPSBORkNTVEFUVVNfU1VDQ0VTUzsKICAgIHVpbnQxNl90IENoZWNrU3VtPTAsCiAgICAgICAgICAgICBCdWZJbmRleD0wOwoKICAgIGZvcihCdWZJbmRleCA9IFN0YXJ0SW5kZXg7QnVmSW5kZXggPD1FbmRJbmRleDtCdWZJbmRleCsrKQogICAgewogICAgICAgIENoZWNrU3VtICs9IFRlbXBCdWZmZXJbQnVmSW5kZXhdOwogICAgfQogICAgaWYoIFJlY3ZDaGtTdW0gIT0gQ2hlY2tTdW0gKQogICAgewogICAgICAgICAgIFJlc3VsdCA9IFBITkZDU1RWQUwoQ0lEX0ZSSV9ORkNfTkRFRl9NQVAsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgTkZDU1RBVFVTX0lOVkFMSURfRk9STUFUKTsKICAgIH0KICAgIHJldHVybiAoUmVzdWx0KTsKfQoKCgoKCgoKCgoKCi8qIQogKiBcYnJpZWYgT24gc3VjY2Vzc2Z1bCByZWFkIGF0dHJpYnV0ZSBibGsgaW5mb3JtYXRpb24sIHRoaXMgZnVuY3Rpb24gdmFsaWRhdGVzIGFuZCBzdG9yZXMgdGhlCiAqIEF0dHJpYnV0ZSBpbmZvcm1hdGlvbnMgaW4gdG8gdGhlIGNvbnRleHQuCiAqLyAgICAKc3RhdGljIE5GQ1NUQVRVUyAgIHBoRnJpTmZjX0ZlbGljYV9IVXBkYXRlQXR0ckluZm8ocGhGcmlOZmNfTmRlZk1hcF90ICpOZGVmTWFwKQp7CiAgICBORkNTVEFUVVMgc3RhdHVzID0gTkZDU1RBVFVTX1BFTkRJTkc7CiAgICB1aW50OF90ICAgQ1JGbGFnID0gRkFMU0UsCiAgICAgICAgICAgICAgTm1heGIxLCBObWF4YjIgPSAwLAogICAgICAgICAgICAgIENoa1N1bTEgPSAwLCBDaGtTdW0yPTA7CgogICAgdWludDE2X3QgIE5tYXhibGsgPSAwLAogICAgICAgICAgICAgIFJlY3ZDaGtTdW09MCwKICAgICAgICAgICAgICBOZGVmQmxrID0gMDsKICAgIHVpbnQzMl90ICBEYXRhTGVuID0wOwogICAgICAgICAgICAgICAgCgogICAgLyogVmFsaWRhdGUgVDNWTm8gYW5kIE5GQ0RldlZObyAqLwogICAgc3RhdHVzID0gcGhGcmlOZmNfTWFwVG9vbF9DaGtTcGNWZXIoTmRlZk1hcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBIX05GQ0ZSSV9OREVGTUFQX0ZFTElfVkVSU0lPTl9JTkRFWCk7CiAgICBpZiAoIHN0YXR1cyAhPSBORkNTVEFUVVNfU1VDQ0VTUyApCiAgICB7CiAgICAgICAgQ1JGbGFnID0gVFJVRTsKICAgIH0KICAgIGVsc2UgCiAgICB7CiAgICAgICAgLyogZ2V0IHRoZSBObWF4YiBmcm9tIHRoZSByZWNlaXZlIGJ1ZmZlciovCiAgICAgICAgTm1heGIxID0gTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMTZdOwogICAgICAgIE5tYXhiMiA9IE5kZWZNYXAtPlNlbmRSZWN2QnVmWzE3XTsKCiAgICAgICAgTm1heGJsayA9ICgoKHVpbnQxNl90KU5tYXhiMSA8PCA4KSB8IChObWF4YjIgJiAweDAwZmYpKTsKCiAgICAgICAgaWYgKCBObWF4YmxrICE9IDAgKQogICAgICAgIHsKICAgICAgICAgICAgLyogY2hlY2sgdGhlIE5iciBhZ2FpbnN0IHRoZSBObWF4YiovCiAgICAgICAgICAgIGlmICggTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMTRdID4gTm1heGJsayApIAogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBDUkZsYWcgPSBUUlVFOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgeyAgIAogICAgICAgICAgICAgICAgLypjaGVjayBOYncgPiBObWF4YiovCiAgICAgICAgICAgICAgICAvKmNoZWNrIHRoZSB3cml0ZSBmbGFnIHZhbGlkaXR5Ki8KICAgICAgICAgICAgICAgIC8qY2hlY2sgZm9yIHRoZSBSRlUgYnl0ZXMgdmFsaWRpdHkqLwogICAgICAgICAgICAgICAgIGlmICggKE5kZWZNYXAtPlNlbmRSZWN2QnVmWzE1XSA+IE5tYXhibGspIHx8CiAgICAgICAgICAgICAgICAgICAgICgoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMjJdICE9IDB4MDApICYmIChOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyMl0gIT0weDBmICkpfHwKICAgICAgICAgICAgICAgICAgICAgKCAoTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMjNdICE9IDB4MDApICYmIChOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyM10gIT0weDAxICkpfHwKICAgICAgICAgICAgICAgICAgICAgKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxOF0gIT0gMHgwMCkgfHwKICAgICAgICAgICAgICAgICAgICAgKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxOV0gIT0gMHgwMCkgfHwKICAgICAgICAgICAgICAgICAgICAgKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyMF0gIT0gMHgwMCkgfHwKICAgICAgICAgICAgICAgICAgICAgKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyMV0gIT0gMHgwMCkpCgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIENSRmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogY2hlY2sgdGhlIHZhbGlkaXR5IG9mIHRoZSBhY3R1YWwgbmRlZiBkYXRhIGxlbiovCiAgICAgICAgICAgICAgICAgICAgUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9DQUxfTEVOX0JZVEVTKCBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyNF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyNV0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyNl0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEYXRhTGVuKTsKCgogICAgICAgICAgICAgICAgICAgIC8qIENhbGN1bGF0ZSBOYmMqLwogICAgICAgICAgICAgICAgICAgIE5kZWZCbGsgPSAodWludDE2X3QgKSgoKCBEYXRhTGVuICUgMTYpID09IDAgKSA/IChEYXRhTGVuID4+IDQpIDogKChEYXRhTGVuID4+IDQpICsxKSk7CgogICAgICAgICAgICAgICAgICAgIC8qIGNoZWNrIE5iYyBhZ2FpbnN0IE5tYXhiKi8KICAgICAgICAgICAgICAgICAgICBpZiAoKE5kZWZCbGsgPiBObWF4YmxrKSkKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIENSRmxhZyA9IFRSVUU7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qU3RvcmUgdGhlIGF0dHJpYnV0ZSBpbmZvcm1hdGlvbiBpbiBwaEZyaU5mY19GZWxpY2FfQXR0ckluZm8qLwogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5WZXJzaW9uID0gTmRlZk1hcC0+U2VuZFJlY3ZCdWZbUEhfTkZDRlJJX05ERUZNQVBfRkVMSV9WRVJTSU9OX0lOREVYXTsKICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTmJyID0gTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMTRdOwogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5OYncgPSBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsxNV07CgogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5ObWF4YiA9IE5tYXhibGs7CgogICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5Xcml0ZUZsYWcgPSBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyMl07CiAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLlJkV3JGbGFnID0gTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMjNdOwoKICAgICAgICAgICAgICAgICAgICAgICAgLyogR2V0IENoZWNrU3VtKi8KICAgICAgICAgICAgICAgICAgICAgICAgQ2hrU3VtMSA9IE5kZWZNYXAtPlNlbmRSZWN2QnVmWzI3XTsKICAgICAgICAgICAgICAgICAgICAgICAgQ2hrU3VtMiA9IE5kZWZNYXAtPlNlbmRSZWN2QnVmWzI4XTsKCiAgICAgICAgICAgICAgICAgICAgICAgIFJlY3ZDaGtTdW0gPSAoKCh1aW50MTZfdClDaGtTdW0xIDw8IDgpIHwgKENoa1N1bTIgJiAweDAwZmYpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIC8qIENoZWNrIHRoZSBjaGVjayBzdW0gdmFsaWRpdHk/Ki8KICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzID0gcGhGcmlOZmNfRmVsaWNhX0hDYWxDaGVja1N1bShOZGVmTWFwLT5TZW5kUmVjdkJ1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQSF9ORkNGUklfTkRFRk1BUF9GRUxJX1ZFUlNJT05fSU5ERVgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMjYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUmVjdkNoa1N1bSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICggc3RhdHVzICE9IE5GQ1NUQVRVU19TVUNDRVNTICkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1JGbGFnID0gVFJVRTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qY2hlY2sgUlcgRmxhZyBBY2Nlc3MgUmlnaHRzKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNldCB0byByZWFkIG9ubHkgY2Fubm90IHdyaXRlKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICggTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uUmRXckZsYWcgPT0gMHgwMCApCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+Q2FyZFN0YXRlID0gUEhfTkRFRk1BUF9DQVJEX1NUQVRFX1JFQURfT05MWTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5SZFdyRmxhZyA9PSAweDAxICkgLy8gYWRkaXRpb25hbCBjaGVjayBmb3IgUi9XIGFjY2VzcwogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkNhcmRTdGF0ZSA9IFBIX05ERUZNQVBfQ0FSRF9TVEFURV9SRUFEX1dSSVRFOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSAvLyBvdGhlcndpc2UgaW52YWxpZAogICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkNhcmRTdGF0ZSA9IFBIX05ERUZNQVBfQ0FSRF9TVEFURV9JTlZBTElEOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBOZGVmTWFwLT5GZWxpY2FBdHRySW5mby5MZW5CeXRlc1swXSA9IE5kZWZNYXAtPlNlbmRSZWN2QnVmWzI0XTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5kZWZNYXAtPkZlbGljYUF0dHJJbmZvLkxlbkJ5dGVzWzFdID0gTmRlZk1hcC0+U2VuZFJlY3ZCdWZbMjVdOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgTmRlZk1hcC0+RmVsaWNhQXR0ckluZm8uTGVuQnl0ZXNbMl0gPSBOZGVmTWFwLT5TZW5kUmVjdkJ1ZlsyNl07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXMgPSBQSE5GQ1NUVkFMKENJRF9ORkNfTk9ORSxORkNTVEFUVVNfU1VDQ0VTUyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgQ1JGbGFnID0gVFJVRTsKICAgICAgICB9CiAgICB9CiAgICBpZiAoIChzdGF0dXMgPT0gTkZDU1RBVFVTX0lOVkFMSURfRk9STUFUICkgJiYgKENSRmxhZyA9PSBUUlVFICkpCiAgICB7CiAgICAgICAgTmRlZk1hcC0+Q2FyZFN0YXRlID0gUEhfTkRFRk1BUF9DQVJEX1NUQVRFX0lOVkFMSUQ7CiAgICB9CiAgICBpZiAoIENSRmxhZyA9PSBUUlVFICkKICAgIHsKICAgICAgICAvKlJldHVybiBTdGF0dXMgRXJyb3IgkyBJbnZhbGlkIEZvcm1hdJQqLwogICAgICAgIHN0YXR1cyA9ICBQSE5GQ1NUVkFMKENJRF9GUklfTkZDX05ERUZfTUFQLE5GQ1NUQVRVU19JTlZBTElEX0ZPUk1BVCk7CiAgICB9CgogICAgcmV0dXJuIChzdGF0dXMpOwp9CgovKiEKICogXGJyaWVmIHRoaXMgc2hhbGwgbm90aWZ5IHRoZSBpbnRlZ3JhdGlvbiBzb2Z0d2FyZSB3aXRoIHJlc3BlY3RpdmUKICogIHN1Y2Nlc3MvZXJyb3Igc3RhdHVzIGFsb25nIHdpdGggdGhlIGNvbXBsZXRpb24gcm91dGluZXMuCiAqLwpzdGF0aWMgdm9pZCBwaEZyaU5mY19GZWxpY2FfSENySGFuZGxlcihwaEZyaU5mY19OZGVmTWFwX3QgICpOZGVmTWFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1aW50OF90ICAgICAgICAgICAgICBDckluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORkNTVEFUVVMgICAgICAgICAgICBTdGF0dXMpCnsKICAgIC8qIHNldCB0aGUgc3RhdGUgYmFjayB0byB0aGUgUmVzZXRfSW5pdCBzdGF0ZSovCiAgICBOZGVmTWFwLT5TdGF0ZSA9ICBQSF9GUklORkNfTkRFRk1BUF9TVEFURV9SRVNFVF9JTklUOwoKICAgIC8qIHNldCB0aGUgY29tcGxldGlvbiByb3V0aW5lKi8KICAgIE5kZWZNYXAtPkNvbXBsZXRpb25Sb3V0aW5lW0NySW5kZXhdLgogICAgICAgIENvbXBsZXRpb25Sb3V0aW5lKE5kZWZNYXAtPkNvbXBsZXRpb25Sb3V0aW5lLT5Db250ZXh0LCBTdGF0dXMpOwp9CgovKiEKICogXGJyaWVmIHRoaXMgc2hhbGwgaW5pdGlhbGlzZSB0aGUgaW50ZXJuYWwgYnVmZmVyIGRhdGEgdG8gemVyby4KICovCnN0YXRpYyB2b2lkIHBoRnJpTmZjX0ZlbGljYV9ISW5pdEludGVybmFsQnVmKHVpbnQ4X3QgKkJ1ZmZlcikKewogICAgdWludDhfdCBpbmRleD0wOwoKICAgIGZvciggaW5kZXggPSAwOyBpbmRleDwgMTYgOyBpbmRleCsrKQogICAgewogICAgICAgIEJ1ZmZlcltpbmRleF0gPSAwOwogICAgfQp9CgpzdGF0aWMgaW50IHBoRnJpTmZjX0ZlbGljYV9NZW1Db21wYXJlICggdm9pZCAqczEsIHZvaWQgKnMyLCB1bnNpZ25lZCBpbnQgbiApCnsKICAgIGludDhfdCAgIGRpZmYgPSAwOwogICAgaW50OF90ICpjaGFyXzEgID0oaW50OF90ICopczE7CiAgICBpbnQ4X3QgKmNoYXJfMiAgPShpbnQ4X3QgKilzMjsKICAgIGlmKE5VTEwgPT0gczEgfHwgTlVMTCA9PSBzMikKICAgIHsKICAgICAgICBQSERCR19DUklUSUNBTF9FUlJPUigiTlVMTCBwb2ludGVyIHBhc3NlZCB0byBtZW1jb21wYXJlIik7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgZm9yKDsoKG4+MCkmJihkaWZmPT0wKSk7bi0tLGNoYXJfMSsrLGNoYXJfMisrKQogICAgICAgIHsKICAgICAgICAgICAgZGlmZiA9ICpjaGFyXzEgLSAqY2hhcl8yOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAoaW50KWRpZmY7Cn0KCgojaWZkZWYgVU5JVF9URVNUCiNpbmNsdWRlIDxwaFVuaXRUZXN0TmZjX0ZlbGljYV9zdGF0aWMuYz4KI2VuZGlmCgojZW5kaWYgIC8qIFBIX0ZSSU5GQ19NQVBfRkVMSUNBX0RJU0FCTEVEICovCg==