LyogRGlyZWN0M0QgVGV4dHVyZQogKiBDb3B5cmlnaHQgKGMpIDE5OTggTGlvbmVsIFVMTUVSCiAqIENvcHlyaWdodCAoYykgMjAwNiBTdGVmYW4gRNZTSU5HRVIKICoKICogVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBpbXBsZW1lbnRhdGlvbiBvZiBpbnRlcmZhY2UgRGlyZWN0M0RUZXh0dXJlMi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKI2RlZmluZSBOT05BTUVMRVNTVU5JT04KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZDcpOwpXSU5FX0RFQ0xBUkVfREVCVUdfQ0hBTk5FTChkZHJhd190aHVuayk7CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVVua25vd24gaW50ZXJmYWNlcy4gVGhleSBhcmUgdGh1bmtzIHRvIElEaXJlY3REcmF3U3VyZmFjZTcKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKVGh1bmtfSURpcmVjdDNEVGV4dHVyZUltcGxfMl9RdWVyeUludGVyZmFjZShJRGlyZWN0M0RUZXh0dXJlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKm9iaikKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZTIsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXMsJXApIHRodW5raW5nIHRvIElEaXJlY3REcmF3U3VyZmFjZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgb2JqKTsKICAgIHJldHVybiBJRGlyZWN0RHJhd1N1cmZhY2U3X1F1ZXJ5SW50ZXJmYWNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaik7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0RUZXh0dXJlSW1wbF8xX1F1ZXJ5SW50ZXJmYWNlKElEaXJlY3QzRFRleHR1cmUgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJXMsJXApIHRodW5raW5nIHRvIElEaXJlY3REcmF3U3VyZmFjZTcgaW50ZXJmYWNlLlxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgb2JqKTsKCiAgICByZXR1cm4gSURpcmVjdERyYXdTdXJmYWNlN19RdWVyeUludGVyZmFjZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmopOwp9CgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRFRleHR1cmVJbXBsXzJfQWRkUmVmKElEaXJlY3QzRFRleHR1cmUyICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZTIsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oKSB0aHVua2luZyB0byBJRGlyZWN0RHJhd1N1cmZhY2U3IGludGVyZmFjZS5cbiIsIFRoaXMpOwoKICAgIHJldHVybiBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZihJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkKVGh1bmtfSURpcmVjdDNEVGV4dHVyZUltcGxfMV9BZGRSZWYoSURpcmVjdDNEVGV4dHVyZSAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oKSB0aHVua2luZyB0byBJRGlyZWN0RHJhd1N1cmZhY2U3IGludGVyZmFjZS5cbiIsIFRoaXMpOwoKICAgIHJldHVybiBJRGlyZWN0RHJhd1N1cmZhY2U3X0FkZFJlZihDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpKTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSQpUaHVua19JRGlyZWN0M0RUZXh0dXJlSW1wbF8yX1JlbGVhc2UoSURpcmVjdDNEVGV4dHVyZTIgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0M0RUZXh0dXJlMiwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3REcmF3U3VyZmFjZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CgogICAgcmV0dXJuIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSk7Cn0KCgpzdGF0aWMgVUxPTkcgV0lOQVBJClRodW5rX0lEaXJlY3QzRFRleHR1cmVJbXBsXzFfUmVsZWFzZShJRGlyZWN0M0RUZXh0dXJlICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPigpIHRodW5raW5nIHRvIElEaXJlY3REcmF3U3VyZmFjZTcgaW50ZXJmYWNlLlxuIiwgVGhpcyk7CgogICAgcmV0dXJuIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgSURpcmVjdERyYXdTdXJmYWNlNywgaWZhY2UpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRFRleHR1cmUgaW50ZXJmYWNlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0RUZXh0dXJlMTo6SW5pdGlhbGl6ZQogKgogKiBUaGUgc2RrIHNheXMgaXQncyBub3QgaW1wbGVtZW50ZWQKICoKICogUGFyYW1zOgogKiAgPwogKgogKiBSZXR1cm5zCiAqICBEREVSUl9VTlNVUFBPUlRFRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0RUZXh0dXJlSW1wbF8xX0luaXRpYWxpemUoSURpcmVjdDNEVGV4dHVyZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0REZXZpY2UgKkRpcmVjdDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdERyYXdTdXJmYWNlICpERFN1cmZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUsIGlmYWNlKTsKICAgIElEaXJlY3QzRERldmljZUltcGwgKmQzZCA9IElDT01fT0JKRUNUKElEaXJlY3QzRERldmljZUltcGwsIElEaXJlY3QzRERldmljZSwgRGlyZWN0M0REZXZpY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3VyZiA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3U3VyZmFjZTMsIEREU3VyZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwLCVwKSBOb3QgaW1wbGVtZW50ZWRcbiIsIFRoaXMsIGQzZCwgc3VyZik7CiAgICByZXR1cm4gRERFUlJfVU5TVVBQT1JURUQ7IC8qIFVuY2hlY2tlZCAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNEVGV4dHVyZTI6OlBhbGV0dGVDaGFuZ2VkCiAqCiAqIEluZm9ybXMgdGhlIHRleHR1cmUgYWJvdXQgYSBwYWxldHRlIGNoYW5nZQogKgogKiBQYXJhbXM6CiAqICBTdGFydDogU3RhcnQgaW5kZXggb2YgdGhlIGNoYW5nZQogKiAgQ291bnQ6IFRoZSBudW1iZXIgb2YgY2hhbmdlZCBlbnRyaWVzCiAqCiAqIFJldHVybnMKICogIEQzRF9PSywgYmVjYXVzZSBpdCdzIGEgc3R1YgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0RUZXh0dXJlSW1wbF9QYWxldHRlQ2hhbmdlZChJRGlyZWN0M0RUZXh0dXJlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQ291bnQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUyLCBpZmFjZSk7CiAgICBGSVhNRSgiKCVwKS0+KCUwOHgsJTA4eCk6IHN0dWIhXG4iLCBUaGlzLCBTdGFydCwgQ291bnQpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRFRleHR1cmVJbXBsXzFfUGFsZXR0ZUNoYW5nZWQoSURpcmVjdDNEVGV4dHVyZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgU3RhcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgQ291bnQpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUsIGlmYWNlKTsKICAgIFRSQUNFKCIoJXApLT4oJTA4eCwlMDh4KSB0aHVua2luZyB0byBJRGlyZWN0M0RUZXh0dXJlMiBpbnRlcmZhY2UuXG4iLCBUaGlzLCBTdGFydCwgQ291bnQpOwoKICAgIHJldHVybiBJRGlyZWN0M0RUZXh0dXJlMl9QYWxldHRlQ2hhbmdlZChDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgSURpcmVjdDNEVGV4dHVyZTIsIGlmYWNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTdGFydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBDb3VudCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdDNEVGV4dHVyZTo6VW5sb2FkCiAqCiAqIERYNSBTREs6ICJUaGUgSURpcmVjdDNEVGV4dHVyZTI6OlVubG9hZCBtZXRob2QgaXMgbm90IGltcGxlbWVudGVkCiAqCiAqCiAqIFJldHVybnM6CiAqICBEREVSUl9VTlNVUFBPUlRFRAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0M0RUZXh0dXJlSW1wbF8xX1VubG9hZChJRGlyZWN0M0RUZXh0dXJlICppZmFjZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPigpOiBub3QgaW1wbGVtZW50ZWQhXG4iLCBUaGlzKTsKICAgIHJldHVybiBEREVSUl9VTlNVUFBPUlRFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3QzRFRleHR1cmUyOjpHZXRIYW5kbGUKICoKICogUmV0dXJucyBoYW5kbGUgZm9yIHRoZSB0ZXh0dXJlLiBBdCB0aGUgbW9tZW50LCB0aGUgaW50ZXJmYWNlCiAqIHRvIHRoZSBJV2luZUQzRFRleHR1cmUgaXMgdXNlZC4KICoKICogUGFyYW1zOgogKiAgRGlyZWN0M0REZXZpY2UyOiBEZXZpY2UgdGhpcyBoYW5kbGUgaXMgYXNzaWduZWQgdG8KICogIEhhbmRsZTogQWRkcmVzcyB0byBzdG9yZSB0aGUgaGFuZGxlIGF0LgogKgogKiBSZXR1cm5zOgogKiAgRDNEX09LCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3QzRFRleHR1cmVJbXBsX0dldEhhbmRsZShJRGlyZWN0M0RUZXh0dXJlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElEaXJlY3QzRERldmljZTIgKkRpcmVjdDNERGV2aWNlMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRDNEVEVYVFVSRUhBTkRMRSAqbHBIYW5kbGUpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUyLCBpZmFjZSk7CiAgICBJRGlyZWN0M0REZXZpY2VJbXBsICpkM2QgPSBJQ09NX09CSkVDVChJRGlyZWN0M0REZXZpY2VJbXBsLCBJRGlyZWN0M0REZXZpY2UyLCBEaXJlY3QzRERldmljZTIpOwoKICAgIFRSQUNFKCIoJXApLT4oJXAsJXApXG4iLCBUaGlzLCBkM2QsIGxwSGFuZGxlKTsKCiAgICBFbnRlckNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgaWYoIVRoaXMtPkhhbmRsZSkKICAgIHsKICAgICAgICBUaGlzLT5IYW5kbGUgPSBJRGlyZWN0M0REZXZpY2VJbXBsX0NyZWF0ZUhhbmRsZShkM2QpOwogICAgICAgIGlmKFRoaXMtPkhhbmRsZSkKICAgICAgICB7CiAgICAgICAgICAgIGQzZC0+SGFuZGxlc1tUaGlzLT5IYW5kbGUgLSAxXS5wdHIgPSBUaGlzOwogICAgICAgICAgICBkM2QtPkhhbmRsZXNbVGhpcy0+SGFuZGxlIC0gMV0udHlwZSA9IEREcmF3SGFuZGxlX1RleHR1cmU7CiAgICAgICAgfQogICAgfQogICAgKmxwSGFuZGxlID0gVGhpcy0+SGFuZGxlOwoKICAgIFRSQUNFKCIgcmV0dXJuaW5nIGhhbmRsZSAlMDh4LlxuIiwgKmxwSGFuZGxlKTsKCiAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgcmV0dXJuIEQzRF9PSzsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJClRodW5rX0lEaXJlY3QzRFRleHR1cmVJbXBsXzFfR2V0SGFuZGxlKElEaXJlY3QzRFRleHR1cmUgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUERJUkVDVDNEREVWSUNFIGxwRGlyZWN0M0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQRDNEVEVYVFVSRUhBTkRMRSBscEhhbmRsZSkKewogICAgSUNPTV9USElTX0ZST00oSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgaWZhY2UpOwogICAgSURpcmVjdDNERGV2aWNlSW1wbCAqZDNkID0gSUNPTV9PQkpFQ1QoSURpcmVjdDNERGV2aWNlSW1wbCwgSURpcmVjdDNERGV2aWNlLCBscERpcmVjdDNERGV2aWNlKTsKICAgIFRSQUNFXyhkZHJhd190aHVuaykoIiglcCktPiglcCwlcCkgdGh1bmtpbmcgdG8gSURpcmVjdDNEVGV4dHVyZTIgaW50ZXJmYWNlLlxuIiwgVGhpcywgZDNkLCBscEhhbmRsZSk7CgogICAgcmV0dXJuIElEaXJlY3QzRFRleHR1cmUyX0dldEhhbmRsZShJQ09NX0lOVEVSRkFDRShUaGlzLCBJRGlyZWN0M0RUZXh0dXJlMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElDT01fSU5URVJGQUNFKGQzZCwgSURpcmVjdDNERGV2aWNlMiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxwSGFuZGxlKTsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBnZXRfc3ViX21pbWFwbGV2ZWwKICoKICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyB0aGUgbmV4dCBtaXBtYXAgbGV2ZWwKICoKICogdGV4X3B0cjogU3VyZmFjZSBvZiB3aGljaCB0byByZXR1cm4gdGhlIG5leHQgbGV2ZWwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqCmdldF9zdWJfbWltYXBsZXZlbChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICp0ZXhfcHRyKQp7CiAgICAvKiBOb3cgZ28gZG93biB0aGUgbWlwbWFwIGNoYWluIHRvIHRoZSBuZXh0IHN1cmZhY2UgKi8KICAgIHN0YXRpYyBERFNDQVBTMiBtaXBtYXBfY2FwcyA9IHsgRERTQ0FQU19NSVBNQVAgfCBERFNDQVBTX1RFWFRVUkUsIDAsIDAsIDAgfTsKICAgIExQRElSRUNURFJBV1NVUkZBQ0U3IG5leHRfbGV2ZWw7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpzdXJmX3B0cjsKICAgIEhSRVNVTFQgaHI7CgogICAgaHIgPSBJRGlyZWN0RHJhd1N1cmZhY2U3X0dldEF0dGFjaGVkU3VyZmFjZShJQ09NX0lOVEVSRkFDRSh0ZXhfcHRyLCBJRGlyZWN0RHJhd1N1cmZhY2U3KSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm1pcG1hcF9jYXBzLCAmbmV4dF9sZXZlbCk7CiAgICBpZiAoRkFJTEVEKGhyKSkgcmV0dXJuIE5VTEw7CgogICAgc3VyZl9wdHIgPSBJQ09NX09CSkVDVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd1N1cmZhY2U3LCBuZXh0X2xldmVsKTsKICAgIElEaXJlY3REcmF3U3VyZmFjZTdfUmVsZWFzZShuZXh0X2xldmVsKTsKCiAgICByZXR1cm4gc3VyZl9wdHI7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0M0RUZXh0dXJlMjo6TG9hZAogKgogKiBMb2FkcyBhIHRleHR1cmUgY3JlYXRlZCB3aXRoIHRoZSBERFNDQVBTX0FMTE9DT05MT0FECiAqCiAqIFRoaXMgZnVuY3Rpb24gaXNuJ3QgcmVsYXllZCB0byBXaW5lRDNEIGJlY2F1c2UgdGhlIHdob2xlIGludGVyZmFjZSBpcwogKiBpbXBsZW1lbnRlZCBpbiBERHJhdyBvbmx5LiBGb3Igc3BlZWQgaW1wcm92ZW1lbnRzIGEgaW1wbGVtZW50YXRpb24gd2hpY2gKICogdGFrZXMgT3BlbkdMIG1vcmUgaW50byBhY2NvdW50IGNvdWxkIGJlIHBsYWNlZCBpbnRvIFdpbmVEM0QuCiAqCiAqIFBhcmFtczoKICogIEQzRFRleHR1cmUyOiBBZGRyZXNzIG9mIHRoZSB0ZXh0dXJlIHRvIGxvYWQKICoKICogUmV0dXJuczoKICogIEQzRF9PSyBvbiBzdWNjZXNzCiAqICBEM0RFUlJfVEVYVFVSRV9MT0FEX0ZBSUxFRC4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgSFJFU1VMVCBXSU5BUEkKSURpcmVjdDNEVGV4dHVyZUltcGxfTG9hZChJRGlyZWN0M0RUZXh0dXJlMiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgSURpcmVjdDNEVGV4dHVyZTIgKkQzRFRleHR1cmUyKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0M0RUZXh0dXJlMiwgaWZhY2UpOwogICAgSURpcmVjdERyYXdTdXJmYWNlSW1wbCAqc3JjX3B0ciA9IElDT01fT0JKRUNUKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3QzRFRleHR1cmUyLCBEM0RUZXh0dXJlMik7CiAgICBIUkVTVUxUIHJldF92YWx1ZSA9IEQzRF9PSzsKICAgIGlmKHNyY19wdHIgPT0gVGhpcykKICAgIHsKICAgICAgICBUUkFDRSgiY29weWluZyBzdXJmYWNlICVwIHRvIHN1cmZhY2UgJXAsIHdoeT9cbiIsIHNyY19wdHIsIFRoaXMpOwogICAgICAgIHJldHVybiByZXRfdmFsdWU7CiAgICB9CgogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIHNyY19wdHIpOwogICAgRW50ZXJDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKCiAgICBpZiAoKChzcmNfcHRyLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkgIT0gKFRoaXMtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfTUlQTUFQKSkgfHwKICAgICAgICAoc3JjX3B0ci0+c3VyZmFjZV9kZXNjLnUyLmR3TWlwTWFwQ291bnQgIT0gVGhpcy0+c3VyZmFjZV9kZXNjLnUyLmR3TWlwTWFwQ291bnQpKQogICAgewogICAgICAgIEVSUigiVHJ5aW5nIHRvIGxvYWQgc3VyZmFjZXMgd2l0aCBkaWZmZXJlbnQgbWlwLW1hcCBjb3VudHMgIVxuIik7CiAgICB9CgogICAgd2hpbGUoMSkKICAgIHsKICAgICAgICBJV2luZUQzRFBhbGV0dGUgKndpbmVfcGFsLCAqd2luZV9wYWxfc3JjOwogICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZSAqcGFsID0gTlVMTCwgKnBhbF9zcmMgPSBOVUxMOwogICAgICAgIEREU1VSRkFDRURFU0MgKnNyY19kLCAqZHN0X2Q7CgogICAgICAgIFRSQUNFKCIgY29weWluZyBzdXJmYWNlICVwIHRvIHN1cmZhY2UgJXAgKG1pcG1hcCBsZXZlbCAlZClcbiIsIHNyY19wdHIsIFRoaXMsIHNyY19wdHItPm1pcG1hcF9sZXZlbCk7CgogICAgICAgIC8qIFN1cHByZXNzIHRoZSBBTExPQ09OTE9BRCBmbGFnICovCiAgICAgICAgVGhpcy0+c3VyZmFjZV9kZXNjLmRkc0NhcHMuZHdDYXBzICY9IH5ERFNDQVBTX0FMTE9DT05MT0FEOwoKICAgICAgICAvKiBHZXQgdGhlIHBhbGV0dGVzICovCiAgICAgICAgcmV0X3ZhbHVlID0gSVdpbmVEM0RTdXJmYWNlX0dldFBhbGV0dGUoVGhpcy0+V2luZUQzRFN1cmZhY2UsICZ3aW5lX3BhbCk7CiAgICAgICAgaWYoIHJldF92YWx1ZSAhPSBEM0RfT0spCiAgICAgICAgewogICAgICAgICAgICBFUlIoIklXaW5lRDNEU3VyZmFjZTo6R2V0UGFsZXR0ZSBmYWlsZWQhIFRoaXMgaXMgdW5leHBlY3RlZFxuIik7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEM0RFUlJfVEVYVFVSRV9MT0FEX0ZBSUxFRDsKICAgICAgICB9CiAgICAgICAgaWYod2luZV9wYWwpCiAgICAgICAgewogICAgICAgICAgICByZXRfdmFsdWUgPSBJV2luZUQzRFBhbGV0dGVfR2V0UGFyZW50KHdpbmVfcGFsLCAoSVVua25vd24gKiopICZwYWwpOwogICAgICAgICAgICBpZihyZXRfdmFsdWUgIT0gRDNEX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFUlIoIklXaW5lRDNEUGFsZXR0ZTo6R2V0UGFyZW50IGZhaWxlZCEgVGhpcyBpcyB1bmV4cGVjdGVkXG4iKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRDNERVJSX1RFWFRVUkVfTE9BRF9GQUlMRUQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIHJldF92YWx1ZSA9IElXaW5lRDNEU3VyZmFjZV9HZXRQYWxldHRlKHNyY19wdHItPldpbmVEM0RTdXJmYWNlLCAmd2luZV9wYWxfc3JjKTsKICAgICAgICBpZiggcmV0X3ZhbHVlICE9IEQzRF9PSykKICAgICAgICB7CiAgICAgICAgICAgIEVSUigiSVdpbmVEM0RTdXJmYWNlOjpHZXRQYWxldHRlIGZhaWxlZCEgVGhpcyBpcyB1bmV4cGVjdGVkXG4iKTsKICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgcmV0dXJuIEQzREVSUl9URVhUVVJFX0xPQURfRkFJTEVEOwogICAgICAgIH0KICAgICAgICBpZih3aW5lX3BhbF9zcmMpCiAgICAgICAgewogICAgICAgICAgICByZXRfdmFsdWUgPSBJV2luZUQzRFBhbGV0dGVfR2V0UGFyZW50KHdpbmVfcGFsX3NyYywgKElVbmtub3duICoqKSAmcGFsX3NyYyk7CiAgICAgICAgICAgIGlmKHJldF92YWx1ZSAhPSBEM0RfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEVSUigiSVdpbmVEM0RQYWxldHRlOjpHZXRQYXJlbnQgZmFpbGVkISBUaGlzIGlzIHVuZXhwZWN0ZWRcbiIpOwogICAgICAgICAgICAgICAgaWYgKHBhbCkgSURpcmVjdERyYXdQYWxldHRlX1JlbGVhc2UocGFsKTsKICAgICAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgICAgICByZXR1cm4gRDNERVJSX1RFWFRVUkVfTE9BRF9GQUlMRUQ7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChwYWxfc3JjICE9IE5VTEwpCiAgICAgICAgewogICAgICAgICAgICBQQUxFVFRFRU5UUlkgcGFsZW50WzI1Nl07CgogICAgICAgICAgICBpZiAocGFsID09IE5VTEwpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZV9SZWxlYXNlKHBhbF9zcmMpOwogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEREVSUl9OT1BBTEVUVEVBVFRBQ0hFRDsKICAgICAgICAgICAgfQogICAgICAgICAgICBJRGlyZWN0RHJhd1BhbGV0dGVfR2V0RW50cmllcyhwYWxfc3JjLCAwLCAwLCAyNTYsIHBhbGVudCk7CiAgICAgICAgICAgIElEaXJlY3REcmF3UGFsZXR0ZV9TZXRFbnRyaWVzKHBhbCwgMCwgMCwgMjU2LCBwYWxlbnQpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHBhbCkgSURpcmVjdERyYXdQYWxldHRlX1JlbGVhc2UocGFsKTsKICAgICAgICBpZiAocGFsX3NyYykgSURpcmVjdERyYXdQYWxldHRlX1JlbGVhc2UocGFsX3NyYyk7CgogICAgICAgIC8qIENvcHkgb25lIHN1cmZhY2Ugb24gdGhlIG90aGVyICovCiAgICAgICAgZHN0X2QgPSAoRERTVVJGQUNFREVTQyAqKSYoVGhpcy0+c3VyZmFjZV9kZXNjKTsKICAgICAgICBzcmNfZCA9IChERFNVUkZBQ0VERVNDICopJihzcmNfcHRyLT5zdXJmYWNlX2Rlc2MpOwoKICAgICAgICBpZiAoKHNyY19kLT5kd1dpZHRoICE9IGRzdF9kLT5kd1dpZHRoKSB8fCAoc3JjX2QtPmR3SGVpZ2h0ICE9IGRzdF9kLT5kd0hlaWdodCkpCiAgICAgICAgewogICAgICAgICAgICAvKiBTaG91bGQgYWxzbyBjaGVjayBmb3Igc2FtZSBwaXhlbCBmb3JtYXQsIHUxLmxQaXRjaCwgLi4uICovCiAgICAgICAgICAgIEVSUigiRXJyb3IgaW4gc3VyZmFjZSBzaXplc1xuIik7CiAgICAgICAgICAgIExlYXZlQ3JpdGljYWxTZWN0aW9uKCZkZHJhd19jcyk7CiAgICAgICAgICAgIHJldHVybiBEM0RFUlJfVEVYVFVSRV9MT0FEX0ZBSUxFRDsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgV0lORUQzRExPQ0tFRF9SRUNUIHBTcmNSZWN0LCBwRHN0UmVjdDsKCiAgICAgICAgICAgIC8qIExQRElSRUNUM0RERVZJQ0UyIGQzZGQgPSAoTFBESVJFQ1QzRERFVklDRTIpIFRoaXMtPkQzRGRldmljZTsgKi8KICAgICAgICAgICAgLyogSSBzaG91bGQgcHV0IGEgbWFjcm8gZm9yIHRoZSBjYWxjdWx1cyBvZiBicHAgKi8KCiAgICAgICAgICAgIC8qIENvcHkgYWxzbyB0aGUgQ29sb3JLZXlpbmcgc3R1ZmYgKi8KICAgICAgICAgICAgaWYgKHNyY19kLT5kd0ZsYWdzICYgRERTRF9DS1NSQ0JMVCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZHN0X2QtPmR3RmxhZ3MgfD0gRERTRF9DS1NSQ0JMVDsKICAgICAgICAgICAgICAgIGRzdF9kLT5kZGNrQ0tTcmNCbHQuZHdDb2xvclNwYWNlTG93VmFsdWUgPSBzcmNfZC0+ZGRja0NLU3JjQmx0LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgZHN0X2QtPmRkY2tDS1NyY0JsdC5kd0NvbG9yU3BhY2VIaWdoVmFsdWUgPSBzcmNfZC0+ZGRja0NLU3JjQmx0LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgLyogQ29weSB0aGUgbWFpbiBtZW1vcnkgdGV4dHVyZSBpbnRvIHRoZSBzdXJmYWNlIHRoYXQgY29ycmVzcG9uZHMgdG8gdGhlIE9wZW5HTAogICAgICAgICAgICAgIHRleHR1cmUgb2JqZWN0LiAqLwoKICAgICAgICAgICAgcmV0X3ZhbHVlID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KHNyY19wdHItPldpbmVEM0RTdXJmYWNlLCAmcFNyY1JlY3QsIE5VTEwsIDApOwogICAgICAgICAgICBpZihyZXRfdmFsdWUgIT0gRDNEX09LKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBFUlIoIiAoJXApIExvY2tpbmcgdGhlIHNvdXJjZSBzdXJmYWNlIGZhaWxlZFxuIiwgVGhpcyk7CiAgICAgICAgICAgICAgICBMZWF2ZUNyaXRpY2FsU2VjdGlvbigmZGRyYXdfY3MpOwogICAgICAgICAgICAgICAgcmV0dXJuIEQzREVSUl9URVhUVVJFX0xPQURfRkFJTEVEOwogICAgICAgICAgICB9CgogICAgICAgICAgICByZXRfdmFsdWUgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoVGhpcy0+V2luZUQzRFN1cmZhY2UsICZwRHN0UmVjdCwgTlVMTCwgMCk7CiAgICAgICAgICAgIGlmKHJldF92YWx1ZSAhPSBEM0RfT0spCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIEVSUigiICglcCkgTG9ja2luZyB0aGUgZGVzdGluYXRpb24gc3VyZmFjZSBmYWlsZWRcbiIsIFRoaXMpOwogICAgICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3Qoc3JjX3B0ci0+V2luZUQzRFN1cmZhY2UpOwogICAgICAgICAgICAgICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgICAgICAgICAgICAgIHJldHVybiBEM0RFUlJfVEVYVFVSRV9MT0FEX0ZBSUxFRDsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKFRoaXMtPnN1cmZhY2VfZGVzYy51NC5kZHBmUGl4ZWxGb3JtYXQuZHdGbGFncyAmIEREUEZfRk9VUkNDKQogICAgICAgICAgICAgICAgbWVtY3B5KHBEc3RSZWN0LnBCaXRzLCBwU3JjUmVjdC5wQml0cywgc3JjX3B0ci0+c3VyZmFjZV9kZXNjLnUxLmR3TGluZWFyU2l6ZSk7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIG1lbWNweShwRHN0UmVjdC5wQml0cywgcFNyY1JlY3QucEJpdHMsIHBTcmNSZWN0LlBpdGNoICogc3JjX2QtPmR3SGVpZ2h0KTsKCiAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KHNyY19wdHItPldpbmVEM0RTdXJmYWNlKTsKICAgICAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoVGhpcy0+V2luZUQzRFN1cmZhY2UpOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNyY19wdHItPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfTUlQTUFQKQogICAgICAgIHsKICAgICAgICAgICAgc3JjX3B0ciA9IGdldF9zdWJfbWltYXBsZXZlbChzcmNfcHRyKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgc3JjX3B0ciA9IE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX01JUE1BUCkKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMgPSBnZXRfc3ViX21pbWFwbGV2ZWwoVGhpcyk7CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIFRoaXMgPSBOVUxMOwogICAgICAgIH0KCiAgICAgICAgaWYgKChzcmNfcHRyID09IE5VTEwpIHx8IChUaGlzID09IE5VTEwpKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHNyY19wdHIgIT0gVGhpcykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgRVJSKCIgTG9hZGluZyBzdXJmYWNlIHdpdGggZGlmZmVyZW50IG1pcG1hcCBzdHJ1Y3R1cmUgISEhXG4iKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CgogICAgTGVhdmVDcml0aWNhbFNlY3Rpb24oJmRkcmF3X2NzKTsKICAgIHJldHVybiByZXRfdmFsdWU7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpUaHVua19JRGlyZWN0M0RUZXh0dXJlSW1wbF8xX0xvYWQoSURpcmVjdDNEVGV4dHVyZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBJRGlyZWN0M0RUZXh0dXJlICpEM0RUZXh0dXJlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0M0RUZXh0dXJlLCBpZmFjZSk7CiAgICBJRGlyZWN0RHJhd1N1cmZhY2VJbXBsICpUZXh0dXJlID0gSUNPTV9PQkpFQ1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgRDNEVGV4dHVyZSk7CiAgICBUUkFDRSgiKCVwKS0+KCVwKSB0aHVua2luZyB0byBJRGlyZWN0M0RUZXh0dXJlMiBpbnRlcmZhY2UuXG4iLCBUaGlzLCBUZXh0dXJlKTsKCiAgICByZXR1cm4gSURpcmVjdDNEVGV4dHVyZTJfTG9hZChDT01fSU5URVJGQUNFX0NBU1QoSURpcmVjdERyYXdTdXJmYWNlSW1wbCwgSURpcmVjdDNEVGV4dHVyZSwgSURpcmVjdDNEVGV4dHVyZTIsIGlmYWNlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIENPTV9JTlRFUkZBQ0VfQ0FTVChJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0M0RUZXh0dXJlLCBJRGlyZWN0M0RUZXh0dXJlMiwgRDNEVGV4dHVyZSkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogVGhlIFZUYWJsZXMKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpjb25zdCBJRGlyZWN0M0RUZXh0dXJlMlZ0YmwgSURpcmVjdDNEVGV4dHVyZTJfVnRibCA9CnsKICAgIFRodW5rX0lEaXJlY3QzRFRleHR1cmVJbXBsXzJfUXVlcnlJbnRlcmZhY2UsCiAgICBUaHVua19JRGlyZWN0M0RUZXh0dXJlSW1wbF8yX0FkZFJlZiwKICAgIFRodW5rX0lEaXJlY3QzRFRleHR1cmVJbXBsXzJfUmVsZWFzZSwKICAgIElEaXJlY3QzRFRleHR1cmVJbXBsX0dldEhhbmRsZSwKICAgIElEaXJlY3QzRFRleHR1cmVJbXBsX1BhbGV0dGVDaGFuZ2VkLAogICAgSURpcmVjdDNEVGV4dHVyZUltcGxfTG9hZCwKfTsKCgpjb25zdCBJRGlyZWN0M0RUZXh0dXJlVnRibCBJRGlyZWN0M0RUZXh0dXJlMV9WdGJsID0KewogICAgVGh1bmtfSURpcmVjdDNEVGV4dHVyZUltcGxfMV9RdWVyeUludGVyZmFjZSwKICAgIFRodW5rX0lEaXJlY3QzRFRleHR1cmVJbXBsXzFfQWRkUmVmLAogICAgVGh1bmtfSURpcmVjdDNEVGV4dHVyZUltcGxfMV9SZWxlYXNlLAogICAgSURpcmVjdDNEVGV4dHVyZUltcGxfMV9Jbml0aWFsaXplLAogICAgVGh1bmtfSURpcmVjdDNEVGV4dHVyZUltcGxfMV9HZXRIYW5kbGUsCiAgICBUaHVua19JRGlyZWN0M0RUZXh0dXJlSW1wbF8xX1BhbGV0dGVDaGFuZ2VkLAogICAgVGh1bmtfSURpcmVjdDNEVGV4dHVyZUltcGxfMV9Mb2FkLAogICAgSURpcmVjdDNEVGV4dHVyZUltcGxfMV9VbmxvYWQsCn07Cg==