LyoKICogQ09NIHByb3h5L3N0dWIgZmFjdG9yeSAoQ1N0ZFBTRmFjdG9yeSkgaW1wbGVtZW50YXRpb24KICoKICogQ29weXJpZ2h0IDIwMDEgT3ZlIEvldmVuLCBUcmFuc0dhbWluZyBUZWNobm9sb2dpZXMKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAgMDIxMTEtMTMwNyAgVVNBCiAqLwoKI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmVycm9yLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKCiNpbmNsdWRlICJvYmpiYXNlLmgiCgojaW5jbHVkZSAicnBjcHJveHkuaCIKCiNpbmNsdWRlICJ3aW5lL2RlYnVnLmgiCgojaW5jbHVkZSAiY3BzZi5oIgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwob2xlKTsKCnN0YXRpYyBCT09MIEZpbmRQcm94eUluZm8oY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUZpbGVMaXN0LCBSRUZJSUQgcmlpZCwgY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUluZm8sIGludCAqcEluZGV4KQp7CiAgd2hpbGUgKCpwUHJveHlGaWxlTGlzdCkgewogICAgaWYgKCgqcFByb3h5RmlsZUxpc3QpLT5wSUlETG9va3VwUnRuKHJpaWQsIHBJbmRleCkpIHsKICAgICAgKnBQcm94eUluZm8gPSAqcFByb3h5RmlsZUxpc3Q7CiAgICAgIFRSQUNFKCJmb3VuZDogUHJveHlJbmZvICVwIEluZGV4ICVkXG4iLCAqcFByb3h5SW5mbywgKnBJbmRleCk7CiAgICAgIHJldHVybiBUUlVFOwogICAgfQogICAgcFByb3h5RmlsZUxpc3QrKzsKICB9CiAgVFJBQ0UoIm5vdCBmb3VuZFxuIik7CiAgcmV0dXJuIEZBTFNFOwp9CgpzdGF0aWMgSFJFU1VMVCBXSU5BUEkgQ1N0ZFBTRmFjdG9yeV9RdWVyeUludGVyZmFjZShMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUZJSUQgcmlpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKm9iaikKewogIElDT01fVEhJUyhDU3RkUFNGYWN0b3J5QnVmZmVyLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+UXVlcnlJbnRlcmZhY2UoJXMsJXApXG4iLGlmYWNlLGRlYnVnc3RyX2d1aWQocmlpZCksb2JqKTsKICBpZiAoSXNFcXVhbEdVSUQoJklJRF9JVW5rbm93bixyaWlkKSB8fAogICAgICBJc0VxdWFsR1VJRCgmSUlEX0lQU0ZhY3RvcnlCdWZmZXIscmlpZCkpIHsKICAgICpvYmogPSBUaGlzOwogICAgVGhpcy0+UmVmQ291bnQrKzsKICAgIHJldHVybiBTX09LOwogIH0KICByZXR1cm4gRV9OT0lOVEVSRkFDRTsKfQoKc3RhdGljIFVMT05HIFdJTkFQSSBDU3RkUFNGYWN0b3J5X0FkZFJlZihMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSkKewogIElDT01fVEhJUyhDU3RkUFNGYWN0b3J5QnVmZmVyLGlmYWNlKTsKICBUUkFDRSgiKCVwKS0+QWRkUmVmKClcbiIsaWZhY2UpOwogIHJldHVybiArKyhUaGlzLT5SZWZDb3VudCk7Cn0KCnN0YXRpYyBVTE9ORyBXSU5BUEkgQ1N0ZFBTRmFjdG9yeV9SZWxlYXNlKExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlKQp7CiAgSUNPTV9USElTKENTdGRQU0ZhY3RvcnlCdWZmZXIsaWZhY2UpOwogIFRSQUNFKCIoJXApLT5SZWxlYXNlKClcbiIsaWZhY2UpOwogIHJldHVybiAtLShUaGlzLT5SZWZDb3VudCk7Cn0KCnN0YXRpYyBIUkVTVUxUIFdJTkFQSSBDU3RkUFNGYWN0b3J5X0NyZWF0ZVByb3h5KExQUFNGQUNUT1JZQlVGRkVSIGlmYWNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVU5LTk9XTiBwVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBSUENQUk9YWUJVRkZFUiAqcHBQcm94eSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKnBwdikKewogIElDT01fVEhJUyhDU3RkUFNGYWN0b3J5QnVmZmVyLGlmYWNlKTsKICBjb25zdCBQcm94eUZpbGVJbmZvICpQcm94eUluZm87CiAgaW50IEluZGV4OwogIFRSQUNFKCIoJXApLT5DcmVhdGVQcm94eSglcCwlcywlcCwlcClcbiIsaWZhY2UscFVua091dGVyLAogICAgICAgZGVidWdzdHJfZ3VpZChyaWlkKSxwcFByb3h5LHBwdik7CiAgaWYgKCFGaW5kUHJveHlJbmZvKFRoaXMtPnBQcm94eUZpbGVMaXN0LHJpaWQsJlByb3h5SW5mbywmSW5kZXgpKQogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CiAgcmV0dXJuIFN0ZFByb3h5X0NvbnN0cnVjdChyaWlkLCBwVW5rT3V0ZXIsIFByb3h5SW5mby0+cE5hbWVzQXJyYXlbSW5kZXhdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgUHJveHlJbmZvLT5wUHJveHlWdGJsTGlzdFtJbmRleF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm94eUluZm8tPnBTdHViVnRibExpc3RbSW5kZXhdLCBpZmFjZSwgcHBQcm94eSwgcHB2KTsKfQoKc3RhdGljIEhSRVNVTFQgV0lOQVBJIENTdGRQU0ZhY3RvcnlfQ3JlYXRlU3R1YihMUFBTRkFDVE9SWUJVRkZFUiBpZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBVTktOT1dOIHBVbmtTZXJ2ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUFJQQ1NUVUJCVUZGRVIgKnBwU3R1YikKewogIElDT01fVEhJUyhDU3RkUFNGYWN0b3J5QnVmZmVyLGlmYWNlKTsKICBjb25zdCBQcm94eUZpbGVJbmZvICpQcm94eUluZm87CiAgaW50IEluZGV4OwogIFRSQUNFKCIoJXApLT5DcmVhdGVTdHViKCVzLCVwLCVwKVxuIixpZmFjZSxkZWJ1Z3N0cl9ndWlkKHJpaWQpLAogICAgICAgcFVua1NlcnZlcixwcFN0dWIpOwogIGlmICghRmluZFByb3h5SW5mbyhUaGlzLT5wUHJveHlGaWxlTGlzdCxyaWlkLCZQcm94eUluZm8sJkluZGV4KSkKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwogIHJldHVybiBDU3RkU3R1YkJ1ZmZlcl9Db25zdHJ1Y3QocmlpZCwgcFVua1NlcnZlciwgUHJveHlJbmZvLT5wTmFtZXNBcnJheVtJbmRleF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQcm94eUluZm8tPnBTdHViVnRibExpc3RbSW5kZXhdLCBpZmFjZSwgcHBTdHViKTsKfQoKc3RhdGljIElDT01fVlRBQkxFKElQU0ZhY3RvcnlCdWZmZXIpIENTdGRQU0ZhY3RvcnlfVnRibCA9CnsKICBJQ09NX01TVlRBQkxFX0NPTVBBVF9EdW1teVJUVElWQUxVRQogIENTdGRQU0ZhY3RvcnlfUXVlcnlJbnRlcmZhY2UsCiAgQ1N0ZFBTRmFjdG9yeV9BZGRSZWYsCiAgQ1N0ZFBTRmFjdG9yeV9SZWxlYXNlLAogIENTdGRQU0ZhY3RvcnlfQ3JlYXRlUHJveHksCiAgQ1N0ZFBTRmFjdG9yeV9DcmVhdGVTdHViCn07CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckRsbEdldENsYXNzT2JqZWN0IFtSUENSVDQuQF0KICovCkhSRVNVTFQgV0lOQVBJIE5kckRsbEdldENsYXNzT2JqZWN0KFJFRkNMU0lEIHJjbHNpZCwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHJveHlGaWxlSW5mbyAqKnBQcm94eUZpbGVMaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IENMU0lEICpwY2xzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ1N0ZFBTRmFjdG9yeUJ1ZmZlciAqcFBTRmFjdG9yeUJ1ZmZlcikKewogICpwcHYgPSBOVUxMOwogIGlmICghcFBTRmFjdG9yeUJ1ZmZlci0+bHBWdGJsKSB7CiAgICBwUFNGYWN0b3J5QnVmZmVyLT5scFZ0YmwgPSAmQ1N0ZFBTRmFjdG9yeV9WdGJsOwogICAgcFBTRmFjdG9yeUJ1ZmZlci0+UmVmQ291bnQgPSAwOwogICAgcFBTRmFjdG9yeUJ1ZmZlci0+cFByb3h5RmlsZUxpc3QgPSBwUHJveHlGaWxlTGlzdDsKICB9CiAgaWYgKElzRXF1YWxHVUlEKHJjbHNpZCwgcGNsc2lkKSkKICAgIHJldHVybiBJUFNGYWN0b3J5QnVmZmVyX1F1ZXJ5SW50ZXJmYWNlKChMUFBTRkFDVE9SWUJVRkZFUilwUFNGYWN0b3J5QnVmZmVyLCBpaWQsIHBwdik7CiAgcmV0dXJuIENMQVNTX0VfQ0xBU1NOT1RBVkFJTEFCTEU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyRGxsQ2FuVW5sb2FkTm93IFtSUENSVDQuQF0KICovCkhSRVNVTFQgV0lOQVBJIE5kckRsbENhblVubG9hZE5vdyhDU3RkUFNGYWN0b3J5QnVmZmVyICpwUFNGYWN0b3J5QnVmZmVyKQp7CiAgcmV0dXJuICEocFBTRmFjdG9yeUJ1ZmZlci0+UmVmQ291bnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICAgICAgIE5kckRsbFJlZ2lzdGVyUHJveHkgW1JQQ1JUNC5AXQogKi8KSFJFU1VMVCBXSU5BUEkgTmRyRGxsUmVnaXN0ZXJQcm94eShITU9EVUxFIGhEbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQcm94eUZpbGVJbmZvICoqcFByb3h5RmlsZUxpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBDTFNJRCAqcGNsc2lkKQp7CiAgTFBTVFIgY2xzaWQ7CiAgY2hhciBrZXluYW1lWzEyMF0sIG1vZHVsZVsxMjBdOwogIEhLRVkga2V5LCBzdWJrZXk7CgogIFRSQUNFKCIoJXAsJXAsJXMpXG4iLCBoRGxsLCBwUHJveHlGaWxlTGlzdCwgZGVidWdzdHJfZ3VpZChwY2xzaWQpKTsKICBVdWlkVG9TdHJpbmdBKChVVUlEKilwY2xzaWQsICh1bnNpZ25lZCBjaGFyKiopJmNsc2lkKTsKCiAgLyogcmVnaXN0ZXIgaW50ZXJmYWNlcyB0byBwb2ludCB0byBjbHNpZCAqLwogIHdoaWxlICgqcFByb3h5RmlsZUxpc3QpIHsKICAgIHVuc2lnbmVkIHU7CiAgICBmb3IgKHU9MDsgdTwoKnBQcm94eUZpbGVMaXN0KS0+VGFibGVTaXplOyB1KyspIHsKICAgICAgQ0ludGVyZmFjZVN0dWJWdGJsICpwcm94eSA9ICgqcFByb3h5RmlsZUxpc3QpLT5wU3R1YlZ0YmxMaXN0W3VdOwogICAgICBQQ0ludGVyZmFjZU5hbWUgbmFtZSA9ICgqcFByb3h5RmlsZUxpc3QpLT5wTmFtZXNBcnJheVt1XTsKICAgICAgTFBTVFIgaWlkOwoKICAgICAgVFJBQ0UoInJlZ2lzdGVyaW5nICVzICVzID0+ICVzXG4iLCBuYW1lLCBkZWJ1Z3N0cl9ndWlkKHByb3h5LT5oZWFkZXIucGlpZCksIGNsc2lkKTsKCiAgICAgIFV1aWRUb1N0cmluZ0EoKFVVSUQqKXByb3h5LT5oZWFkZXIucGlpZCwgKHVuc2lnbmVkIGNoYXIqKikmaWlkKTsKICAgICAgc25wcmludGYoa2V5bmFtZSwgc2l6ZW9mKGtleW5hbWUpLCAiSW50ZXJmYWNlXFx7JXN9IiwgaWlkKTsKICAgICAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmaWlkKTsKICAgICAgaWYgKFJlZ0NyZWF0ZUtleUV4QShIS0VZX0NMQVNTRVNfUk9PVCwga2V5bmFtZSwgMCwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfV1JJVEUsIE5VTEwsICZrZXksIE5VTEwpID09IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgICBpZiAobmFtZSkKICAgICAgICAgIFJlZ1NldFZhbHVlRXhBKGtleSwgTlVMTCwgMCwgUkVHX1NaLCBuYW1lLCBzdHJsZW4obmFtZSkpOwogICAgICAgIGlmIChSZWdDcmVhdGVLZXlFeEEoa2V5LCAiUHJveHlTdHViQ2xzaWQzMiIsIDAsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBLRVlfV1JJVEUsIE5VTEwsICZzdWJrZXksIE5VTEwpID09IEVSUk9SX1NVQ0NFU1MpIHsKICAgICAgICAgIHNucHJpbnRmKG1vZHVsZSwgc2l6ZW9mKG1vZHVsZSksICJ7JXN9IiwgY2xzaWQpOwogICAgICAgICAgUmVnU2V0VmFsdWVFeEEoc3Via2V5LCBOVUxMLCAwLCBSRUdfU1osIG1vZHVsZSwgc3RybGVuKG1vZHVsZSkpOwogICAgICAgICAgUmVnQ2xvc2VLZXkoc3Via2V5KTsKICAgICAgICB9CiAgICAgICAgUmVnQ2xvc2VLZXkoa2V5KTsKICAgICAgfQogICAgfQogICAgcFByb3h5RmlsZUxpc3QrKzsKICB9CgogIC8qIHJlZ2lzdGVyIGNsc2lkIHRvIHBvaW50IHRvIG1vZHVsZSAqLwogIHNucHJpbnRmKGtleW5hbWUsIHNpemVvZihrZXluYW1lKSwgIkNMU0lEXFx7JXN9IiwgY2xzaWQpOwogIEdldE1vZHVsZUZpbGVOYW1lQShoRGxsLCBtb2R1bGUsIHNpemVvZihtb2R1bGUpKTsKICBUUkFDRSgicmVnaXN0ZXJpbmcgQ0xTSUQgJXMgPT4gJXNcbiIsIGNsc2lkLCBtb2R1bGUpOwogIGlmIChSZWdDcmVhdGVLZXlFeEEoSEtFWV9DTEFTU0VTX1JPT1QsIGtleW5hbWUsIDAsIE5VTEwsIDAsCiAgICAgICAgICAgICAgICAgICAgICBLRVlfV1JJVEUsIE5VTEwsICZrZXksIE5VTEwpID09IEVSUk9SX1NVQ0NFU1MpIHsKICAgICBpZiAoUmVnQ3JlYXRlS2V5RXhBKGtleSwgIkluUHJvY1NlcnZlcjMyIiwgMCwgTlVMTCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIEtFWV9XUklURSwgTlVMTCwgJnN1YmtleSwgTlVMTCkgPT0gRVJST1JfU1VDQ0VTUykgewogICAgICAgUmVnU2V0VmFsdWVFeEEoc3Via2V5LCBOVUxMLCAwLCBSRUdfU1osIG1vZHVsZSwgc3RybGVuKG1vZHVsZSkpOwogICAgICAgUmVnQ2xvc2VLZXkoc3Via2V5KTsKICAgICB9CiAgICAgUmVnQ2xvc2VLZXkoa2V5KTsKICB9CgogIC8qIGRvbmUgKi8KICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZjbHNpZCk7CiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgTmRyRGxsVW5yZWdpc3RlclByb3h5IFtSUENSVDQuQF0KICovCkhSRVNVTFQgV0lOQVBJIE5kckRsbFVucmVnaXN0ZXJQcm94eShITU9EVUxFIGhEbGwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFByb3h5RmlsZUluZm8gKipwUHJveHlGaWxlTGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgQ0xTSUQgKnBjbHNpZCkKewogIExQU1RSIGNsc2lkOwogIGNoYXIga2V5bmFtZVsxMjBdLCBtb2R1bGVbMTIwXTsKCiAgVFJBQ0UoIiglcCwlcCwlcylcbiIsIGhEbGwsIHBQcm94eUZpbGVMaXN0LCBkZWJ1Z3N0cl9ndWlkKHBjbHNpZCkpOwogIFV1aWRUb1N0cmluZ0EoKFVVSUQqKXBjbHNpZCwgKHVuc2lnbmVkIGNoYXIqKikmY2xzaWQpOwoKICAvKiB1bnJlZ2lzdGVyIGludGVyZmFjZXMgKi8KICB3aGlsZSAoKnBQcm94eUZpbGVMaXN0KSB7CiAgICB1bnNpZ25lZCB1OwogICAgZm9yICh1PTA7IHU8KCpwUHJveHlGaWxlTGlzdCktPlRhYmxlU2l6ZTsgdSsrKSB7CiAgICAgIENJbnRlcmZhY2VTdHViVnRibCAqcHJveHkgPSAoKnBQcm94eUZpbGVMaXN0KS0+cFN0dWJWdGJsTGlzdFt1XTsKICAgICAgUENJbnRlcmZhY2VOYW1lIG5hbWUgPSAoKnBQcm94eUZpbGVMaXN0KS0+cE5hbWVzQXJyYXlbdV07CiAgICAgIExQU1RSIGlpZDsKCiAgICAgIFRSQUNFKCJ1bnJlZ2lzdGVyaW5nICVzICVzIDw9ICVzXG4iLCBuYW1lLCBkZWJ1Z3N0cl9ndWlkKHByb3h5LT5oZWFkZXIucGlpZCksIGNsc2lkKTsKCiAgICAgIFV1aWRUb1N0cmluZ0EoKFVVSUQqKXByb3h5LT5oZWFkZXIucGlpZCwgKHVuc2lnbmVkIGNoYXIqKikmaWlkKTsKICAgICAgc25wcmludGYoa2V5bmFtZSwgc2l6ZW9mKGtleW5hbWUpLCAiSW50ZXJmYWNlXFx7JXN9IiwgaWlkKTsKICAgICAgUnBjU3RyaW5nRnJlZUEoKHVuc2lnbmVkIGNoYXIqKikmaWlkKTsKICAgICAgUmVnRGVsZXRlS2V5QShIS0VZX0NMQVNTRVNfUk9PVCwga2V5bmFtZSk7CiAgICB9CiAgICBwUHJveHlGaWxlTGlzdCsrOwogIH0KCiAgLyogdW5yZWdpc3RlciBjbHNpZCAqLwogIHNucHJpbnRmKGtleW5hbWUsIHNpemVvZihrZXluYW1lKSwgIkNMU0lEXFx7JXN9IiwgY2xzaWQpOwogIEdldE1vZHVsZUZpbGVOYW1lQShoRGxsLCBtb2R1bGUsIHNpemVvZihtb2R1bGUpKTsKICBUUkFDRSgidW5yZWdpc3RlcmluZyBDTFNJRCAlcyA8PSAlc1xuIiwgY2xzaWQsIG1vZHVsZSk7CiAgUmVnRGVsZXRlS2V5QShIS0VZX0NMQVNTRVNfUk9PVCwga2V5bmFtZSk7CgogIC8qIGRvbmUgKi8KICBScGNTdHJpbmdGcmVlQSgodW5zaWduZWQgY2hhcioqKSZjbHNpZCk7CiAgcmV0dXJuIFNfT0s7Cn0K