LyogRGlyZWN0RHJhd0dhbW1hQ29udHJvbCBpbXBsZW1lbnRhdGlvbgogKgogKiBDb3B5cmlnaHQgMjAwMSBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMgSW5jLgogKiBDb3B5cmlnaHQgMjAwNiBTdGVmYW4gRPZzaW5nZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkbGliLmg+CgojZGVmaW5lIENPQkpNQUNST1MKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5nZGkuaCIKI2luY2x1ZGUgIndpbmUvZXhjZXB0aW9uLmgiCgojaW5jbHVkZSAiZGRyYXcuaCIKI2luY2x1ZGUgImQzZC5oIgoKI2luY2x1ZGUgImRkcmF3X3ByaXZhdGUuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGRkcmF3KTsKV0lORV9ERUNMQVJFX0RFQlVHX0NIQU5ORUwoZGRyYXdfdGh1bmspOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVVua25vd24gcGFydHMgZm9sbG93CiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdHYW1tYUNvbnRyb2w6OlF1ZXJ5SW50ZXJmYWNlCiAqCiAqIFF1ZXJ5SW50ZXJmYWNlLCB0aHVua3MgdG8gSURpcmVjdERyYXdTdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIHJpaWQ6IEludGVyZmFjZSBpZCBxdWVyaWVkIGZvcgogKiAgb2JqOiBSZXR1cm5zIHRoZSBpbnRlcmZhY2UgcG9pbnRlcgogKgogKiBSZXR1cm5zOgogKiAgU19PSyBvciBFX05PSU5URVJGQUNFOiBTZWUgSURpcmVjdERyYXdTdXJmYWNlNzo6UXVlcnlJbnRlcmZhY2UKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0dhbW1hQ29udHJvbEltcGxfUXVlcnlJbnRlcmZhY2UoSURpcmVjdERyYXdHYW1tYUNvbnRyb2wgKmlmYWNlLCBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKipvYmopCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3R2FtbWFDb250cm9sLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oJXMsJXApOiBUaHVua2luZyB0byBJRGlyZWN0RHJhd1N1cmZhY2U3XG4iLCBUaGlzLCBkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBvYmopOwoKICAgIHJldHVybiBJRGlyZWN0RHJhd1N1cmZhY2U3X1F1ZXJ5SW50ZXJmYWNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9iaik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElEaXJlY3REcmF3R2FtbWFDb250cm9sOjpBZGRSZWYKICoKICogQWRkcmVmLCB0aHVua3MgdG8gSURpcmVjdERyYXdTdXJmYWNlCiAqCiAqIFJldHVybnM6CiAqICBUaGUgbmV3IHJlZmNvdW50CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdGF0aWMgVUxPTkcgV0lOQVBJCklEaXJlY3REcmF3R2FtbWFDb250cm9sSW1wbF9BZGRSZWYoSURpcmVjdERyYXdHYW1tYUNvbnRyb2wgKmlmYWNlKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCwgaWZhY2UpOwogICAgVFJBQ0VfKGRkcmF3X3RodW5rKSgiKCVwKS0+KCkgVGh1bmtpbmcgdG8gSURpcmVjdERyYXdTdXJmYWNlN1xuIiwgVGhpcyk7CgogICAgcmV0dXJuIElEaXJlY3REcmF3U3VyZmFjZTdfQWRkUmVmKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdHYW1tYUNvbnRyb2w6OlJlbGVhc2UKICoKICogUmVsZWFzZSwgdGh1bmtzIHRvIElEaXJlY3REcmF3U3VyZmFjZQogKgogKiBSZXR1cm5zOgogKiAgVGhlIG5ldyByZWZjb3VudAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIFVMT05HIFdJTkFQSQpJRGlyZWN0RHJhd0dhbW1hQ29udHJvbEltcGxfUmVsZWFzZShJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCAqaWZhY2UpCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3R2FtbWFDb250cm9sLCBpZmFjZSk7CiAgICBUUkFDRV8oZGRyYXdfdGh1bmspKCIoJXApLT4oKSBUaHVua2luZyB0byBJRGlyZWN0RHJhd1N1cmZhY2U3XG4iLCBUaGlzKTsKCiAgICByZXR1cm4gSURpcmVjdERyYXdTdXJmYWNlN19SZWxlYXNlKElDT01fSU5URVJGQUNFKFRoaXMsIElEaXJlY3REcmF3U3VyZmFjZTcpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdHYW1tYUNvbnRyb2wKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbDo6R2V0R2FtbWFSYW1wCiAqCiAqIFJldHVybnMgdGhlIGN1cnJlbnQgZ2FtbWEgcmFtcCBmb3IgYSBzdXJmYWNlCiAqCiAqIFBhcmFtczoKICogIEZsYWdzOiBJZ25vcmVkCiAqICBHYW1tYVJhbXA6IEFkZHJlc3MgdG8gd3JpdGUgdGhlIHJhbXAgdG8KICoKICogUmV0dXJuczoKICogIEREX09LIG9uIHN1Y2Nlc3MKICogIERERVJSX0lOVkFMSURQQVJBTVMgaWYgR2FtbWFSYW1wIGlzIE5VTEwKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCnN0YXRpYyBIUkVTVUxUIFdJTkFQSQpJRGlyZWN0RHJhd0dhbW1hQ29udHJvbEltcGxfR2V0R2FtbWFSYW1wKElEaXJlY3REcmF3R2FtbWFDb250cm9sICppZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEREdBTU1BUkFNUCAqR2FtbWFSYW1wKQp7CiAgICBJQ09NX1RISVNfRlJPTShJRGlyZWN0RHJhd1N1cmZhY2VJbXBsLCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbCwgaWZhY2UpOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKVxuIiwgVGhpcyxGbGFncyxHYW1tYVJhbXApOwoKICAgIC8qIFRoaXMgbG9va3Mgc2FuZSAqLwogICAgaWYoIUdhbW1hUmFtcCkKICAgIHsKICAgICAgICBFUlIoIiglcCkgR2FtbWFSYW1wIGlzIE5VTEwsIHJldHVybmluZyBEREVSUl9JTlZBTElEUEFSQU1TXG4iLCBUaGlzKTsKICAgICAgICByZXR1cm4gRERFUlJfSU5WQUxJRFBBUkFNUzsKICAgIH0KCiAgICBpZihUaGlzLT5zdXJmYWNlX2Rlc2MuZGRzQ2Fwcy5kd0NhcHMgJiBERFNDQVBTX1BSSU1BUllTVVJGQUNFKQogICAgewogICAgICAgIC8qIE5vdGU6IERER0FNTUFSQU1QIGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNER0FNTUFSQU1QICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfR2V0R2FtbWFSYW1wKFRoaXMtPmRkcmF3LT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFN3YXBjaGFpbiAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFdJTkVEM0RHQU1NQVJBTVAgKikgR2FtbWFSYW1wKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBFUlIoIiglcCkgVW5pbXBsZW1lbnRlZCBmb3Igbm9uLXByaW1hcnkgc3VyZmFjZXNcbiIsIFRoaXMpOwogICAgfQoKICAgIHJldHVybiBERF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSURpcmVjdERyYXdHYW1tYUNvbnRyb2w6OlNldEdhbW1hUmFtcAogKgogKiBTZXRzIHRoZSByZWQsIGdyZWVuIGFuZCBibHVlIGdhbW1hIHJhbXBzIGZvcgogKgogKiBQYXJhbXM6CiAqICBGbGFnczogQ2FuIGJlIEREU0dSX0NBTElCUkFURSB0byByZXF1ZXN0IGNhbGlicmF0aW9uCiAqICBHYW1tYVJhbXA6IFN0cnVjdHVyZSBjb250YWluaW5nIHRoZSBuZXcgZ2FtbWEgcmFtcAogKgogKiBSZXR1cm5zOgogKiAgRERfT0sgb24gc3VjY2VzcwogKiAgRERFUlJfSU5WQUxJRFBBUkFNUyBpZiBHYW1tYVJhbXAgaXMgTlVMTAogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQgV0lOQVBJCklEaXJlY3REcmF3R2FtbWFDb250cm9sSW1wbF9TZXRHYW1tYVJhbXAoSURpcmVjdERyYXdHYW1tYUNvbnRyb2wgKmlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIEZsYWdzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERER0FNTUFSQU1QICpHYW1tYVJhbXApCnsKICAgIElDT01fVEhJU19GUk9NKElEaXJlY3REcmF3U3VyZmFjZUltcGwsIElEaXJlY3REcmF3R2FtbWFDb250cm9sLCBpZmFjZSk7CiAgICBUUkFDRSgiKCVwKS0+KCUwOHgsJXApXG4iLCBUaGlzLEZsYWdzLEdhbW1hUmFtcCk7CgogICAgLyogVGhpcyBsb29rcyBzYW5lICovCiAgICBpZighR2FtbWFSYW1wKQogICAgewogICAgICAgIEVSUigiKCVwKSBHYW1tYVJhbXAgaXMgTlVMTCwgcmV0dXJuaW5nIERERVJSX0lOVkFMSURQQVJBTVNcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBEREVSUl9JTlZBTElEUEFSQU1TOwogICAgfQoKICAgIGlmKFRoaXMtPnN1cmZhY2VfZGVzYy5kZHNDYXBzLmR3Q2FwcyAmIEREU0NBUFNfUFJJTUFSWVNVUkZBQ0UpCiAgICB7CgogICAgICAgIC8qIE5vdGU6IERER0FNTUFSQU1QIGlzIGNvbXBhdGlibGUgd2l0aCBXSU5FRDNER0FNTUFSQU1QICovCiAgICAgICAgSVdpbmVEM0REZXZpY2VfU2V0R2FtbWFSYW1wKFRoaXMtPmRkcmF3LT53aW5lRDNERGV2aWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwIC8qIFN3YXBjaGFpbiAqLywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChXSU5FRDNER0FNTUFSQU1QICopIEdhbW1hUmFtcCk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgRVJSKCIoJXApIFVuaW1wbGVtZW50ZWQgZm9yIG5vbi1wcmltYXJ5IHN1cmZhY2VzXG4iLCBUaGlzKTsKICAgIH0KCiAgICByZXR1cm4gRERfT0s7Cn0KCmNvbnN0IElEaXJlY3REcmF3R2FtbWFDb250cm9sVnRibCBJRGlyZWN0RHJhd0dhbW1hQ29udHJvbF9WdGJsID0KewogICAgSURpcmVjdERyYXdHYW1tYUNvbnRyb2xJbXBsX1F1ZXJ5SW50ZXJmYWNlLAogICAgSURpcmVjdERyYXdHYW1tYUNvbnRyb2xJbXBsX0FkZFJlZiwKICAgIElEaXJlY3REcmF3R2FtbWFDb250cm9sSW1wbF9SZWxlYXNlLAogICAgSURpcmVjdERyYXdHYW1tYUNvbnRyb2xJbXBsX0dldEdhbW1hUmFtcCwKICAgIElEaXJlY3REcmF3R2FtbWFDb250cm9sSW1wbF9TZXRHYW1tYVJhbXAKfTsK