LyoKICogSVdpbmVEM0RTdXJmYWNlIEltcGxlbWVudGF0aW9uIG9mIG1hbmFnZW1lbnQobm9uLXJlbmRlcmluZykgZnVuY3Rpb25zCiAqCiAqIENvcHlyaWdodCAxOTk4IExpb25lbCBVbG1lcgogKiBDb3B5cmlnaHQgMjAwMC0yMDAxIFRyYW5zR2FtaW5nIFRlY2hub2xvZ2llcyBJbmMuCiAqIENvcHlyaWdodCAyMDAyLTIwMDUgSmFzb24gRWRtZWFkZXMKICogQ29weXJpZ2h0IDIwMDItMjAwMyBSYXBoYWVsIEp1bnF1ZWlyYQogKiBDb3B5cmlnaHQgMjAwNCBDaHJpc3RpYW4gQ29zdGEKICogQ29weXJpZ2h0IDIwMDUgT2xpdmVyIFN0aWViZXIKICogQ29weXJpZ2h0IDIwMDYtMjAwOCBTdGVmYW4gRPZzaW5nZXIgZm9yIENvZGVXZWF2ZXJzCiAqIENvcHlyaWdodCAyMDA3IEhlbnJpIFZlcmJlZXQKICogQ29weXJpZ2h0IDIwMDYtMjAwNyBSb2RlcmljayBDb2xlbmJyYW5kZXIKICoKICogVGhpcyBsaWJyYXJ5IGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKiBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlcgogKiB2ZXJzaW9uIDIuMSBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBsaWJyYXJ5IGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGUgR05VCiAqIExlc3NlciBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgbGlicmFyeTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1MSBGcmFua2xpbiBTdCwgRmlmdGggRmxvb3IsIEJvc3RvbiwgTUEgMDIxMTAtMTMwMSwgVVNBCiAqLwoKI2luY2x1ZGUgImNvbmZpZy5oIgojaW5jbHVkZSAid2luZS9wb3J0LmgiCiNpbmNsdWRlICJ3aW5lZDNkX3ByaXZhdGUuaCIKCiNpbmNsdWRlIDxhc3NlcnQuaD4KCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGQzZF9zdXJmYWNlKTsKCi8qIERvIE5PVCBkZWZpbmUgR0xJTkZPX0xPQ0FUSU9OIGluIHRoaXMgZmlsZS4gVEhJUyBDT0RFIE1VU1QgTk9UIFVTRSBJVCAqLwoKLyogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVVua25vd24gcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfUXVlcnlJbnRlcmZhY2UoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVGSUlEIHJpaWQsIExQVk9JRCAqcHBvYmopCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwogICAgLyogV2FybiAsYnV0IGJlIG5pY2UgYWJvdXQgdGhpbmdzICovCiAgICBUUkFDRSgiKCVwKS0+KCVzLCVwKVxuIiwgVGhpcyxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwb2JqKTsKCiAgICBpZiAoSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JVW5rbm93bikKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEQmFzZSkKICAgICAgICB8fCBJc0VxdWFsR1VJRChyaWlkLCAmSUlEX0lXaW5lRDNEUmVzb3VyY2UpCiAgICAgICAgfHwgSXNFcXVhbEdVSUQocmlpZCwgJklJRF9JV2luZUQzRFN1cmZhY2UpKSB7CiAgICAgICAgSVVua25vd25fQWRkUmVmKChJVW5rbm93biopaWZhY2UpOwogICAgICAgICpwcG9iaiA9IFRoaXM7CiAgICAgICAgcmV0dXJuIFNfT0s7CiAgICAgICAgfQogICAgICAgICpwcG9iaiA9IE5VTEw7CiAgICAgICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7Cn0KClVMT05HIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9BZGRSZWYoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBVTE9ORyByZWYgPSBJbnRlcmxvY2tlZEluY3JlbWVudCgmVGhpcy0+cmVzb3VyY2UucmVmKTsKICAgIFRSQUNFKCIoJXApIDogQWRkUmVmIGluY3JlYXNpbmcgZnJvbSAlZFxuIiwgVGhpcyxyZWYgLSAxKTsKICAgIHJldHVybiByZWY7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICAgSVdpbmVEM0RTdXJmYWNlIElXaW5lRDNEUmVzb3VyY2UgcGFydHMgZm9sbG93CiAgICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGV2aWNlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNERGV2aWNlKiogcHBEZXZpY2UpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXREZXZpY2UoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcHBEZXZpY2UpOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQsIENPTlNUIHZvaWQqIHBEYXRhLCBEV09SRCBTaXplT2ZEYXRhLCBEV09SRCBGbGFncykgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX1NldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBTaXplT2ZEYXRhLCBGbGFncyk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFByaXZhdGVEYXRhKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFJFRkdVSUQgcmVmZ3VpZCwgdm9pZCogcERhdGEsIERXT1JEKiBwU2l6ZU9mRGF0YSkgewogICAgcmV0dXJuIElXaW5lRDNEUmVzb3VyY2VJbXBsX0dldFByaXZhdGVEYXRhKChJV2luZUQzRFJlc291cmNlICopaWZhY2UsIHJlZmd1aWQsIHBEYXRhLCBwU2l6ZU9mRGF0YSk7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0ZyZWVQcml2YXRlRGF0YShJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBSRUZHVUlEIHJlZmd1aWQpIHsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9GcmVlUHJpdmF0ZURhdGEoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcmVmZ3VpZCk7Cn0KCkRXT1JEICAgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFByaW9yaXR5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIFByaW9yaXR5TmV3KSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfU2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgUHJpb3JpdHlOZXcpOwp9CgpEV09SRCAgIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQcmlvcml0eShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0UHJpb3JpdHkoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSk7Cn0KCldJTkVEM0RSRVNPVVJDRVRZUEUgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldFR5cGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgVFJBQ0UoIiglcCkgOiBjYWxsaW5nIHJlc291cmNlaW1wbF9HZXRUeXBlXG4iLCBpZmFjZSk7CiAgICByZXR1cm4gSVdpbmVEM0RSZXNvdXJjZUltcGxfR2V0VHlwZSgoSVdpbmVEM0RSZXNvdXJjZSAqKWlmYWNlKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UGFyZW50KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElVbmtub3duICoqcFBhcmVudCkgewogICAgVFJBQ0UoIiglcCkgOiBjYWxsaW5nIHJlc291cmNlaW1wbF9HZXRQYXJlbnRcbiIsIGlmYWNlKTsKICAgIHJldHVybiBJV2luZUQzRFJlc291cmNlSW1wbF9HZXRQYXJlbnQoKElXaW5lRDNEUmVzb3VyY2UgKilpZmFjZSwgcFBhcmVudCk7Cn0KCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogICBJV2luZUQzRFN1cmZhY2UgSVdpbmVEM0RTdXJmYWNlIHBhcnRzIGZvbGxvdwogICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiogKi8KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldENvbnRhaW5lcihJV2luZUQzRFN1cmZhY2UqIGlmYWNlLCBSRUZJSUQgcmlpZCwgdm9pZCoqIHBwQ29udGFpbmVyKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIElXaW5lRDNEQmFzZSAqY29udGFpbmVyID0gMDsKCiAgICBUUkFDRSgiKFRoaXMgJXAsIHJpaWQgJXMsIHBwQ29udGFpbmVyICVwKVxuIiwgVGhpcywgZGVidWdzdHJfZ3VpZChyaWlkKSwgcHBDb250YWluZXIpOwoKICAgIGlmICghcHBDb250YWluZXIpIHsKICAgICAgICBFUlIoIkNhbGxlZCB3aXRob3V0IGEgdmFsaWQgcHBDb250YWluZXIuXG4iKTsKICAgIH0KCiAgICAvKiogRnJvbSBNU0ROOgogICAgICogSWYgdGhlIHN1cmZhY2UgaXMgY3JlYXRlZCB1c2luZyBDcmVhdGVJbWFnZVN1cmZhY2UvQ3JlYXRlT2Zmc2NyZWVuUGxhaW5TdXJmYWNlLCBDcmVhdGVSZW5kZXJUYXJnZXQsCiAgICAgKiBvciBDcmVhdGVEZXB0aFN0ZW5jaWxTdXJmYWNlLCB0aGUgc3VyZmFjZSBpcyBjb25zaWRlcmVkIHN0YW5kIGFsb25lLiBJbiB0aGlzIGNhc2UsCiAgICAgKiBHZXRDb250YWluZXIgd2lsbCByZXR1cm4gdGhlIERpcmVjdDNEIGRldmljZSB1c2VkIHRvIGNyZWF0ZSB0aGUgc3VyZmFjZS4KICAgICAqLwogICAgaWYgKFRoaXMtPmNvbnRhaW5lcikgewogICAgICAgIGNvbnRhaW5lciA9IFRoaXMtPmNvbnRhaW5lcjsKICAgIH0gZWxzZSB7CiAgICAgICAgY29udGFpbmVyID0gKElXaW5lRDNEQmFzZSAqKVRoaXMtPnJlc291cmNlLndpbmVEM0REZXZpY2U7CiAgICB9CgogICAgVFJBQ0UoIlJlbGF5aW5nIHRvIFF1ZXJ5SW50ZXJmYWNlXG4iKTsKICAgIHJldHVybiBJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb250YWluZXIsIHJpaWQsIHBwQ29udGFpbmVyKTsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0RGVzYyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBXSU5FRDNEU1VSRkFDRV9ERVNDICpwRGVzYykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiBjb3B5aW5nIGludG8gJXBcbiIsIFRoaXMsIHBEZXNjKTsKICAgIGlmKHBEZXNjLT5Gb3JtYXQgIT0gTlVMTCkgICAgICAgICAgICAgKihwRGVzYy0+Rm9ybWF0KSA9IFRoaXMtPnJlc291cmNlLmZvcm1hdDsKICAgIGlmKHBEZXNjLT5UeXBlICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+VHlwZSkgICA9IFRoaXMtPnJlc291cmNlLnJlc291cmNlVHlwZTsKICAgIGlmKHBEZXNjLT5Vc2FnZSAhPSBOVUxMKSAgICAgICAgICAgICAgKihwRGVzYy0+VXNhZ2UpICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnVzYWdlOwogICAgaWYocERlc2MtPlBvb2wgIT0gTlVMTCkgICAgICAgICAgICAgICAqKHBEZXNjLT5Qb29sKSAgICAgICAgICAgICAgID0gVGhpcy0+cmVzb3VyY2UucG9vbDsKICAgIGlmKHBEZXNjLT5TaXplICE9IE5VTEwpICAgICAgICAgICAgICAgKihwRGVzYy0+U2l6ZSkgICAgICAgICAgICAgICA9IFRoaXMtPnJlc291cmNlLnNpemU7ICAgLyogZHg4IG9ubHkgKi8KICAgIGlmKHBEZXNjLT5NdWx0aVNhbXBsZVR5cGUgIT0gTlVMTCkgICAgKihwRGVzYy0+TXVsdGlTYW1wbGVUeXBlKSAgICA9IFRoaXMtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlVHlwZTsKICAgIGlmKHBEZXNjLT5NdWx0aVNhbXBsZVF1YWxpdHkgIT0gTlVMTCkgKihwRGVzYy0+TXVsdGlTYW1wbGVRdWFsaXR5KSA9IFRoaXMtPmN1cnJlbnREZXNjLk11bHRpU2FtcGxlUXVhbGl0eTsKICAgIGlmKHBEZXNjLT5XaWR0aCAhPSBOVUxMKSAgICAgICAgICAgICAgKihwRGVzYy0+V2lkdGgpICAgICAgICAgICAgICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgaWYocERlc2MtPkhlaWdodCAhPSBOVUxMKSAgICAgICAgICAgICAqKHBEZXNjLT5IZWlnaHQpICAgICAgICAgICAgID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0OwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldEJsdFN0YXR1cyhJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBEV09SRCBGbGFncykgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCV4KVxuIiwgVGhpcywgRmxhZ3MpOwoKICAgIHN3aXRjaCAoRmxhZ3MpCiAgICB7CiAgICAgICAgY2FzZSBXSU5FRERHQlNfQ0FOQkxUOgogICAgICAgIGNhc2UgV0lORURER0JTX0lTQkxURE9ORToKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRGbGlwU3RhdHVzKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzKSB7CiAgICAvKiBYWFg6IERERVJSX0lOVkFMSURTVVJGQUNFVFlQRSAqLwoKICAgIFRSQUNFKCIoJXApLT4oJTA4eClcbiIsaWZhY2UsRmxhZ3MpOwogICAgc3dpdGNoIChGbGFncykgewogICAgICAgIGNhc2UgV0lORURER0ZTX0NBTkZMSVA6CiAgICAgICAgY2FzZSBXSU5FRERHRlNfSVNGTElQRE9ORToKICAgICAgICAgICAgcmV0dXJuIFdJTkVEM0RfT0s7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX0lOVkFMSURDQUxMOwogICAgfQp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9Jc0xvc3QoSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIEQzRDggYW5kIDkgbG9vc2UgZnVsbCBkZXZpY2VzLCBkZHJhdyBvbmx5IHN1cmZhY2VzICovCiAgICByZXR1cm4gVGhpcy0+RmxhZ3MgJiBTRkxBR19MT1NUID8gV0lORUQzREVSUl9ERVZJQ0VMT1NUIDogV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfUmVzdG9yZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKVxuIiwgVGhpcyk7CgogICAgLyogU28gZmFyIHdlIGRvbid0IGxvc2UgYW55dGhpbmcgOikgKi8KICAgIFRoaXMtPkZsYWdzICY9IH5TRkxBR19MT1NUOwogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldFBhbGV0dGUoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RQYWxldHRlICpQYWwpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEUGFsZXR0ZUltcGwgKlBhbEltcGwgPSAoSVdpbmVEM0RQYWxldHRlSW1wbCAqKSBQYWw7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgUGFsKTsKCiAgICBpZihUaGlzLT5wYWxldHRlID09IFBhbEltcGwpIHsKICAgICAgICBUUkFDRSgiTm9wIHBhbGV0dGUgY2hhbmdlXG4iKTsKICAgICAgICByZXR1cm4gV0lORUQzRF9PSzsKICAgIH0KCiAgICBpZihUaGlzLT5wYWxldHRlICE9IE5VTEwpCiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKQogICAgICAgICAgICBUaGlzLT5wYWxldHRlLT5GbGFncyAmPSB+V0lORUREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CgogICAgVGhpcy0+cGFsZXR0ZSA9IFBhbEltcGw7CgogICAgaWYoUGFsSW1wbCAhPSBOVUxMKSB7CiAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfUkVOREVSVEFSR0VUKSB7CiAgICAgICAgICAgIChQYWxJbXBsKS0+RmxhZ3MgfD0gV0lORUREUENBUFNfUFJJTUFSWVNVUkZBQ0U7CiAgICAgICAgfQoKICAgICAgICByZXR1cm4gSVdpbmVEM0RTdXJmYWNlX1JlYWxpemVQYWxldHRlKGlmYWNlKTsKICAgIH0KICAgIGVsc2UgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldENvbG9yS2V5KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBXSU5FRERDT0xPUktFWSAqQ0tleSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglMDh4LCVwKVxuIiwgVGhpcywgRmxhZ3MsIENLZXkpOwoKICAgIGlmICgoRmxhZ3MgJiBXSU5FRERDS0VZX0NPTE9SU1BBQ0UpICE9IDApIHsKICAgICAgICBGSVhNRSgiIGNvbG9ya2V5IHZhbHVlIG5vdCBzdXBwb3J0ZWQgKCUwOHgpICFcbiIsIEZsYWdzKTsKICAgICAgICByZXR1cm4gV0lORUQzREVSUl9JTlZBTElEQ0FMTDsKICAgIH0KCiAgICAvKiBEaXJ0aWZ5IHRoZSBzdXJmYWNlLCBidXQgb25seSBpZiBhIGtleSB3YXMgY2hhbmdlZCAqLwogICAgaWYoQ0tleSkgewogICAgICAgIHN3aXRjaCAoRmxhZ3MgJiB+V0lORUREQ0tFWV9DT0xPUlNQQUNFKSB7CiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9ERVNUQkxUOgogICAgICAgICAgICAgICAgVGhpcy0+RGVzdEJsdENLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBXSU5FRERTRF9DS0RFU1RCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9ERVNUT1ZFUkxBWToKICAgICAgICAgICAgICAgIFRoaXMtPkRlc3RPdmVybGF5Q0tleSA9ICpDS2V5OwogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzIHw9IFdJTkVERFNEX0NLREVTVE9WRVJMQVk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+U3JjT3ZlcmxheUNLZXkgPSAqQ0tleTsKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyB8PSBXSU5FRERTRF9DS1NSQ09WRVJMQVk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9TUkNCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5TcmNCbHRDS2V5ID0gKkNLZXk7CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgfD0gV0lORUREU0RfQ0tTUkNCTFQ7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBlbHNlIHsKICAgICAgICBzd2l0Y2ggKEZsYWdzICYgfldJTkVERENLRVlfQ09MT1JTUEFDRSkgewogICAgICAgICAgICBjYXNlIFdJTkVERENLRVlfREVTVEJMVDoKICAgICAgICAgICAgICAgIFRoaXMtPkNLZXlGbGFncyAmPSB+V0lORUREU0RfQ0tERVNUQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CgogICAgICAgICAgICBjYXNlIFdJTkVERENLRVlfREVTVE9WRVJMQVk6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfldJTkVERFNEX0NLREVTVE9WRVJMQVk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9TUkNPVkVSTEFZOgogICAgICAgICAgICAgICAgVGhpcy0+Q0tleUZsYWdzICY9IH5XSU5FRERTRF9DS1NSQ09WRVJMQVk7CiAgICAgICAgICAgICAgICBicmVhazsKCiAgICAgICAgICAgIGNhc2UgV0lORUREQ0tFWV9TUkNCTFQ6CiAgICAgICAgICAgICAgICBUaGlzLT5DS2V5RmxhZ3MgJj0gfldJTkVERFNEX0NLU1JDQkxUOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9HZXRQYWxldHRlKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIElXaW5lRDNEUGFsZXR0ZSAqKlBhbCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgVFJBQ0UoIiglcCktPiglcClcbiIsIFRoaXMsIFBhbCk7CgogICAgKlBhbCA9IChJV2luZUQzRFBhbGV0dGUgKikgVGhpcy0+cGFsZXR0ZTsKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpEV09SRCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0UGl0Y2goSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgRFdPUkQgcmV0OwogICAgVFJBQ0UoIiglcClcbiIsIFRoaXMpOwoKICAgIC8qIERYVG4gZm9ybWF0cyBkb24ndCBoYXZlIGV4YWN0IHBpdGNoZXMgYXMgdGhleSBhcmUgdG8gdGhlIG5ldyByb3cgb2YgYmxvY2tzLAogICAgd2hlcmUgZWFjaCBibG9jayBpcyA0eDQgcGl4ZWxzLCA4IGJ5dGVzIChkeHQxKSBhbmQgMTYgYnl0ZXMgKGR4dDIvMy80LzUpCiAgICBpZSBwaXRjaCA9ICh3aWR0aC80KSAqIGJ5dGVzIHBlciBibG9jayAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpIC8qIERYVDEgaXMgOCBieXRlcyBwZXIgYmxvY2sgKi8KICAgICAgICByZXQgPSAoKFRoaXMtPmN1cnJlbnREZXNjLldpZHRoICsgMykgPj4gMikgPDwgMzsKICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBUaGlzLT5yZXNvdXJjZS5mb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSAvKiBEWFQyLzMvNC81IGlzIDE2IGJ5dGVzIHBlciBibG9jayAqLwogICAgICAgIHJldCA9ICgoVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKyAzKSA+PiAyKSA8PCA0OwogICAgZWxzZSB7CiAgICAgICAgdW5zaWduZWQgY2hhciBhbGlnbm1lbnQgPSBUaGlzLT5yZXNvdXJjZS53aW5lRDNERGV2aWNlLT5zdXJmYWNlX2FsaWdubWVudDsKICAgICAgICByZXQgPSBUaGlzLT5ieXRlc1BlclBpeGVsICogVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7ICAvKiBCeXRlcyAvIHJvdyAqLwogICAgICAgIHJldCA9IChyZXQgKyBhbGlnbm1lbnQgLSAxKSAmIH4oYWxpZ25tZW50IC0gMSk7CiAgICB9CiAgICBUUkFDRSgiKCVwKSBSZXR1cm5pbmcgJWRcbiIsIFRoaXMsIHJldCk7CiAgICByZXR1cm4gcmV0Owp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRPdmVybGF5UG9zaXRpb24oSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgTE9ORyBYLCBMT05HIFkpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKCiAgICBGSVhNRSgiKCVwKS0+KCVkLCVkKSBTdHViIVxuIiwgVGhpcywgWCwgWSk7CgogICAgaWYoIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKTogTm90IGFuIG92ZXJsYXkgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0dldE92ZXJsYXlQb3NpdGlvbihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBMT05HICpYLCBMT05HICpZKSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CgogICAgRklYTUUoIiglcCktPiglcCwlcCkgU3R1YiFcbiIsIFRoaXMsIFgsIFkpOwoKICAgIGlmKCEoVGhpcy0+cmVzb3VyY2UudXNhZ2UgJiBXSU5FRDNEVVNBR0VfT1ZFUkxBWSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCk6IE5vdCBhbiBvdmVybGF5IHN1cmZhY2VcbiIsIFRoaXMpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfTk9UQU9WRVJMQVlTVVJGQUNFOwogICAgfQoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9VcGRhdGVPdmVybGF5Wk9yZGVyKElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIERXT1JEIEZsYWdzLCBJV2luZUQzRFN1cmZhY2UgKlJlZikgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqUmVmSW1wbCA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFJlZjsKCiAgICBGSVhNRSgiKCVwKS0+KCUwOHgsJXApIFN0dWIhXG4iLCBUaGlzLCBGbGFncywgUmVmSW1wbCk7CgogICAgaWYoIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKTogTm90IGFuIG92ZXJsYXkgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1VwZGF0ZU92ZXJsYXkoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgUkVDVCAqU3JjUmVjdCwgSVdpbmVEM0RTdXJmYWNlICpEc3RTdXJmYWNlLCBSRUNUICpEc3RSZWN0LCBEV09SRCBGbGFncywgV0lORURET1ZFUkxBWUZYICpGWCkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqRHN0ID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgRHN0U3VyZmFjZTsKICAgIEZJWE1FKCIoJXApLT4oJXAsICVwLCAlcCwgJTA4eCwgJXApXG4iLCBUaGlzLCBTcmNSZWN0LCBEc3QsIERzdFJlY3QsIEZsYWdzLCBGWCk7CgogICAgaWYoIShUaGlzLT5yZXNvdXJjZS51c2FnZSAmIFdJTkVEM0RVU0FHRV9PVkVSTEFZKSkKICAgIHsKICAgICAgICBUUkFDRSgiKCVwKTogTm90IGFuIG92ZXJsYXkgc3VyZmFjZVxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9OT1RBT1ZFUkxBWVNVUkZBQ0U7CiAgICB9CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX1NldENsaXBwZXIoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RDbGlwcGVyICpjbGlwcGVyKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgY2xpcHBlcik7CgogICAgVGhpcy0+Y2xpcHBlciA9IGNsaXBwZXI7CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfR2V0Q2xpcHBlcihJV2luZUQzRFN1cmZhY2UgKmlmYWNlLCBJV2luZUQzRENsaXBwZXIgKipjbGlwcGVyKQp7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgaWZhY2U7CiAgICBUUkFDRSgiKCVwKS0+KCVwKVxuIiwgVGhpcywgY2xpcHBlcik7CgogICAgKmNsaXBwZXIgPSBUaGlzLT5jbGlwcGVyOwogICAgaWYoKmNsaXBwZXIpIHsKICAgICAgICBJV2luZUQzRENsaXBwZXJfQWRkUmVmKCpjbGlwcGVyKTsKICAgIH0KICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9TZXRDb250YWluZXIoSVdpbmVEM0RTdXJmYWNlICppZmFjZSwgSVdpbmVEM0RCYXNlICpjb250YWluZXIpIHsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKWlmYWNlOwoKICAgIFRSQUNFKCJUaGlzICVwLCBjb250YWluZXIgJXBcbiIsIFRoaXMsIGNvbnRhaW5lcik7CgogICAgLyogV2UgY2FuJ3Qga2VlcCBhIHJlZmVyZW5jZSB0byB0aGUgY29udGFpbmVyLCBzaW5jZSB0aGUgY29udGFpbmVyIGFscmVhZHkga2VlcHMgYSByZWZlcmVuY2UgdG8gdXMuICovCgogICAgVFJBQ0UoIlNldHRpbmcgY29udGFpbmVyIHRvICVwIGZyb20gJXBcbiIsIGNvbnRhaW5lciwgVGhpcy0+Y29udGFpbmVyKTsKICAgIFRoaXMtPmNvbnRhaW5lciA9IGNvbnRhaW5lcjsKCiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKSFJFU1VMVCBXSU5BUEkgSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfU2V0Rm9ybWF0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RGT1JNQVQgZm9ybWF0KSB7CiAgICBJV2luZUQzRFN1cmZhY2VJbXBsICpUaGlzID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKilpZmFjZTsKICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqZm9ybWF0RW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoZm9ybWF0LCBOVUxMLCBOVUxMKTsKCiAgICBpZiAoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ICE9IFdJTkVEM0RGTVRfVU5LTk9XTikgewogICAgICAgIEZJWE1FKCIoJXApIDogVGhlIGZvcm1hdCBvZiB0aGUgc3VyZmFjZSBtdXN0IGJlIFdJTkVEM0RGT1JNQVRfVU5LTk9XTlxuIiwgVGhpcyk7CiAgICAgICAgcmV0dXJuIFdJTkVEM0RFUlJfSU5WQUxJRENBTEw7CiAgICB9CgogICAgVFJBQ0UoIiglcCkgOiBTZXR0aW5nIHRleHR1cmUgZm9ybWF0IHRvICglZCwlcylcbiIsIFRoaXMsIGZvcm1hdCwgZGVidWdfZDNkZm9ybWF0KGZvcm1hdCkpOwogICAgaWYgKGZvcm1hdCA9PSBXSU5FRDNERk1UX1VOS05PV04pIHsKICAgICAgICBUaGlzLT5yZXNvdXJjZS5zaXplID0gMDsKICAgIH0gZWxzZSBpZiAoZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMSkgewogICAgICAgIC8qIERYVDEgaXMgaGFsZiBieXRlIHBlciBwaXhlbCAqLwogICAgICAgIFRoaXMtPnJlc291cmNlLnNpemUgPSAoKG1heChUaGlzLT5wb3cyV2lkdGgsIDQpICogZm9ybWF0RW50cnktPmJwcCkgKiBtYXgoVGhpcy0+cG93MkhlaWdodCwgNCkpID4+IDE7CgogICAgfSBlbHNlIGlmIChmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQyIHx8IGZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDMgfHwKICAgICAgICAgICAgICAgZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNCB8fCBmb3JtYXQgPT0gV0lORUQzREZNVF9EWFQ1KSB7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgobWF4KFRoaXMtPnBvdzJXaWR0aCwgNCkgKiBmb3JtYXRFbnRyeS0+YnBwKSAqIG1heChUaGlzLT5wb3cySGVpZ2h0LCA0KSk7CiAgICB9IGVsc2UgewogICAgICAgIHVuc2lnbmVkIGNoYXIgYWxpZ25tZW50ID0gVGhpcy0+cmVzb3VyY2Uud2luZUQzRERldmljZS0+c3VyZmFjZV9hbGlnbm1lbnQ7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSA9ICgoVGhpcy0+cG93MldpZHRoICogZm9ybWF0RW50cnktPmJwcCkgKyBhbGlnbm1lbnQgLSAxKSAmIH4oYWxpZ25tZW50IC0gMSk7CiAgICAgICAgVGhpcy0+cmVzb3VyY2Uuc2l6ZSAqPSBUaGlzLT5wb3cySGVpZ2h0OwogICAgfQoKICAgIGlmIChmb3JtYXQgIT0gV0lORUQzREZNVF9VTktOT1dOKSB7CiAgICAgICAgVGhpcy0+Ynl0ZXNQZXJQaXhlbCA9IGZvcm1hdEVudHJ5LT5icHA7CiAgICB9IGVsc2UgewogICAgICAgIFRoaXMtPmJ5dGVzUGVyUGl4ZWwgPSAwOwogICAgfQoKICAgIFRoaXMtPkZsYWdzIHw9IChXSU5FRDNERk1UX0QxNl9MT0NLQUJMRSA9PSBmb3JtYXQpID8gU0ZMQUdfTE9DS0FCTEUgOiAwOwoKICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9IGZvcm1hdDsKCiAgICBUUkFDRSgiKCVwKSA6IFNpemUgJWQsIGJ5dGVzUGVyUGl4ZWwgJWRcbiIsIFRoaXMsIFRoaXMtPnJlc291cmNlLnNpemUsIFRoaXMtPmJ5dGVzUGVyUGl4ZWwpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9CgpIUkVTVUxUIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0NyZWF0ZURJQlNlY3Rpb24oSVdpbmVEM0RTdXJmYWNlICppZmFjZSkgewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CiAgICBpbnQgZXh0cmFsaW5lID0gMDsKICAgIFNZU1RFTV9JTkZPIHN5c0luZm87CiAgICBCSVRNQVBJTkZPKiBiX2luZm87CiAgICBIREMgZGRjOwogICAgRFdPUkQgKm1hc2tzOwogICAgY29uc3QgU3RhdGljUGl4ZWxGb3JtYXREZXNjICpmb3JtYXRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShUaGlzLT5yZXNvdXJjZS5mb3JtYXQsIE5VTEwsIE5VTEwpOwogICAgVUlOVCB1c2FnZTsKCiAgICBzd2l0Y2ggKFRoaXMtPmJ5dGVzUGVyUGl4ZWwpIHsKICAgICAgICBjYXNlIDI6CiAgICAgICAgY2FzZSA0OgogICAgICAgICAgICAvKiBBbGxvY2F0ZSBleHRyYSBzcGFjZSB0byBzdG9yZSB0aGUgUkdCIGJpdCBtYXNrcy4gKi8KICAgICAgICAgICAgYl9pbmZvID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSArIDMgKiBzaXplb2YoRFdPUkQpKTsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgYl9pbmZvID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIEhFQVBfWkVST19NRU1PUlksIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAvKiBBbGxvY2F0ZSBleHRyYSBzcGFjZSBmb3IgYSBwYWxldHRlLiAqLwogICAgICAgICAgICBiX2luZm8gPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgSEVBUF9aRVJPX01FTU9SWSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihCSVRNQVBJTkZPSEVBREVSKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzaXplb2YoUkdCUVVBRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogKDEgPDwgKFRoaXMtPmJ5dGVzUGVyUGl4ZWwgKiA4KSkpOwogICAgICAgICAgICBicmVhazsKICAgIH0KCiAgICBpZiAoIWJfaW5mbykKICAgICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICAgICAgLyogU29tZSBhcHBzIGFjY2VzcyB0aGUgc3VyZmFjZSBpbiB2aWEgRFdPUkRzLCBhbmQgZG8gbm90IHRha2UgdGhlIG5lY2Vzc2FyeSBjYXJlIGF0IHRoZSBlbmQgb2YgdGhlCiAgICAqIHN1cmZhY2UuIFNvIHdlIG5lZWQgYXQgbGVhc3QgZXh0cmEgNCBieXRlcyBhdCB0aGUgZW5kIG9mIHRoZSBzdXJmYWNlLiBDaGVjayBhZ2FpbnN0IHRoZSBwYWdlIHNpemUsCiAgICAqIGlmIHRoZSBsYXN0IHBhZ2UgdXNlZCBmb3IgdGhlIHN1cmZhY2UgaGFzIGF0IGxlYXN0IDQgc3BhcmUgYnl0ZXMgd2UncmUgc2FmZSwgb3RoZXJ3aXNlCiAgICAqIGFkZCBhbiBleHRyYSBsaW5lIHRvIHRoZSBkaWIgc2VjdGlvbgogICAgICAgICovCiAgICBHZXRTeXN0ZW1JbmZvKCZzeXNJbmZvKTsKICAgIGlmKCAoKFRoaXMtPnJlc291cmNlLnNpemUgKyAzKSAlIHN5c0luZm8uZHdQYWdlU2l6ZSkgPCA0KSB7CiAgICAgICAgZXh0cmFsaW5lID0gMTsKICAgICAgICBUUkFDRSgiQWRkaW5nIGFuIGV4dHJhIGxpbmUgdG8gdGhlIGRpYiBzZWN0aW9uXG4iKTsKICAgIH0KCiAgICBiX2luZm8tPmJtaUhlYWRlci5iaVNpemUgPSBzaXplb2YoQklUTUFQSU5GT0hFQURFUik7CiAgICAvKiBUT0RPOiBJcyB0aGVyZSBhIG5pY2VyIHdheSB0byBmb3JjZSBhIHNwZWNpZmljIGFsaWdubWVudD8gKDggYnl0ZSBmb3IgZGRyYXcpICovCiAgICBiX2luZm8tPmJtaUhlYWRlci5iaVdpZHRoID0gSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKGlmYWNlKSAvIFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICBiX2luZm8tPmJtaUhlYWRlci5iaUhlaWdodCA9IC1UaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgLWV4dHJhbGluZTsKICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpU2l6ZUltYWdlID0gKCBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQgKyBleHRyYWxpbmUpICogSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKGlmYWNlKTsKICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpUGxhbmVzID0gMTsKICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQml0Q291bnQgPSBUaGlzLT5ieXRlc1BlclBpeGVsICogODsKCiAgICBiX2luZm8tPmJtaUhlYWRlci5iaVhQZWxzUGVyTWV0ZXIgPSAwOwogICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlZUGVsc1Blck1ldGVyID0gMDsKICAgIGJfaW5mby0+Ym1pSGVhZGVyLmJpQ2xyVXNlZCA9IDA7CiAgICBiX2luZm8tPmJtaUhlYWRlci5iaUNsckltcG9ydGFudCA9IDA7CgogICAgLyogR2V0IHRoZSBiaXQgbWFza3MgKi8KICAgIG1hc2tzID0gKERXT1JEICopICYoYl9pbmZvLT5ibWlDb2xvcnMpOwogICAgc3dpdGNoIChUaGlzLT5yZXNvdXJjZS5mb3JtYXQpIHsKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjhHOEI4OgogICAgICAgICAgICB1c2FnZSA9IERJQl9SR0JfQ09MT1JTOwogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUNvbXByZXNzaW9uID0gQklfUkdCOwogICAgICAgICAgICBicmVhazsKCiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1gxUjVHNUI1OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMVI1RzVCNToKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQTRSNEc0QjQ6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g0UjRHNEI0OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9SM0czQjI6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX0E4UjNHM0IyOgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMkIxMEcxMFIxMDoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfQThCOEc4Ujg6CiAgICAgICAgY2FzZSBXSU5FRDNERk1UX1g4QjhHOFI4OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMlIxMEcxMEIxMDoKICAgICAgICBjYXNlIFdJTkVEM0RGTVRfUjVHNkI1OgogICAgICAgIGNhc2UgV0lORUQzREZNVF9BMTZCMTZHMTZSMTY6CiAgICAgICAgICAgIHVzYWdlID0gMDsKICAgICAgICAgICAgYl9pbmZvLT5ibWlIZWFkZXIuYmlDb21wcmVzc2lvbiA9IEJJX0JJVEZJRUxEUzsKICAgICAgICAgICAgbWFza3NbMF0gPSBmb3JtYXRFbnRyeS0+cmVkTWFzazsKICAgICAgICAgICAgbWFza3NbMV0gPSBmb3JtYXRFbnRyeS0+Z3JlZW5NYXNrOwogICAgICAgICAgICBtYXNrc1syXSA9IGZvcm1hdEVudHJ5LT5ibHVlTWFzazsKICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIC8qIERvbid0IGtub3cgcGFsZXR0ZSAqLwogICAgICAgICAgICBiX2luZm8tPmJtaUhlYWRlci5iaUNvbXByZXNzaW9uID0gQklfUkdCOwogICAgICAgICAgICB1c2FnZSA9IDA7CiAgICAgICAgICAgIGJyZWFrOwogICAgfQoKICAgIGRkYyA9IEdldERDKDApOwogICAgaWYgKGRkYyA9PSAwKSB7CiAgICAgICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgYl9pbmZvKTsKICAgICAgICByZXR1cm4gSFJFU1VMVF9GUk9NX1dJTjMyKEdldExhc3RFcnJvcigpKTsKICAgIH0KCiAgICBUUkFDRSgiQ3JlYXRpbmcgYSBESUIgc2VjdGlvbiB3aXRoIHNpemUgJWR4JWR4JWQsIHNpemU9JWRcbiIsIGJfaW5mby0+Ym1pSGVhZGVyLmJpV2lkdGgsIGJfaW5mby0+Ym1pSGVhZGVyLmJpSGVpZ2h0LCBiX2luZm8tPmJtaUhlYWRlci5iaUJpdENvdW50LCBiX2luZm8tPmJtaUhlYWRlci5iaVNpemVJbWFnZSk7CiAgICBUaGlzLT5kaWIuRElCc2VjdGlvbiA9IENyZWF0ZURJQlNlY3Rpb24oZGRjLCBiX2luZm8sIHVzYWdlLCAmVGhpcy0+ZGliLmJpdG1hcF9kYXRhLCAwIC8qIEhhbmRsZSAqLywgMCAvKiBPZmZzZXQgKi8pOwogICAgUmVsZWFzZURDKDAsIGRkYyk7CgogICAgaWYgKCFUaGlzLT5kaWIuRElCc2VjdGlvbikgewogICAgICAgIEVSUigiQ3JlYXRlRElCU2VjdGlvbiBmYWlsZWQhXG4iKTsKICAgICAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwogICAgICAgIHJldHVybiBIUkVTVUxUX0ZST01fV0lOMzIoR2V0TGFzdEVycm9yKCkpOwogICAgfQoKICAgIFRSQUNFKCJESUJTZWN0aW9uIGF0IDogJXBcbiIsIFRoaXMtPmRpYi5iaXRtYXBfZGF0YSk7CiAgICAvKiBjb3B5IHRoZSBleGlzdGluZyBzdXJmYWNlIHRvIHRoZSBkaWIgc2VjdGlvbiAqLwogICAgaWYoVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KSB7CiAgICAgICAgbWVtY3B5KFRoaXMtPmRpYi5iaXRtYXBfZGF0YSwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5LCAgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0ICogSVdpbmVEM0RTdXJmYWNlX0dldFBpdGNoKGlmYWNlKSk7CiAgICB9IGVsc2UgewogICAgICAgIC8qIFRoaXMgaXMgdG8gbWFrZSBMb2NrUmVjdCByZWFkIHRoZSBnbCBUZXh0dXJlIGFsdGhvdWdoIG1lbW9yeSBpcyBhbGxvY2F0ZWQgKi8KICAgICAgICBUaGlzLT5GbGFncyAmPSB+U0ZMQUdfSU5TWVNNRU07CiAgICB9CiAgICBUaGlzLT5kaWIuYml0bWFwX3NpemUgPSBiX2luZm8tPmJtaUhlYWRlci5iaVNpemVJbWFnZTsKCiAgICBIZWFwRnJlZShHZXRQcm9jZXNzSGVhcCgpLCAwLCBiX2luZm8pOwoKICAgIC8qIE5vdyBhbGxvY2F0ZSBhIEhEQyAqLwogICAgVGhpcy0+aERDID0gQ3JlYXRlQ29tcGF0aWJsZURDKDApOwogICAgVGhpcy0+ZGliLmhvbGRiaXRtYXAgPSBTZWxlY3RPYmplY3QoVGhpcy0+aERDLCBUaGlzLT5kaWIuRElCc2VjdGlvbik7CiAgICBUUkFDRSgidXNpbmcgd2luZWQzZCBwYWxldHRlICVwXG4iLCBUaGlzLT5wYWxldHRlKTsKICAgIFNlbGVjdFBhbGV0dGUoVGhpcy0+aERDLAogICAgICAgICAgICAgICAgICBUaGlzLT5wYWxldHRlID8gVGhpcy0+cGFsZXR0ZS0+aHBhbCA6IDAsCiAgICAgICAgICAgICAgICAgIEZBTFNFKTsKCiAgICBUaGlzLT5GbGFncyB8PSBTRkxBR19ESUJTRUNUSU9OOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIFRoaXMtPnJlc291cmNlLmhlYXBNZW1vcnkpOwogICAgVGhpcy0+cmVzb3VyY2UuaGVhcE1lbW9yeSA9IE5VTEw7CgogICAgcmV0dXJuIFdJTkVEM0RfT0s7Cn0KCnZvaWQgY29udmVydF9yMzJmX3IxNmYoQllURSAqc3JjLCBCWVRFICpkc3QsIERXT1JEIHBpdGNoX2luLCBEV09SRCBwaXRjaF9vdXQsIHVuc2lnbmVkIGludCB3LCB1bnNpZ25lZCBpbnQgaCkgewogICAgdW5zaWduZWQgaW50IHgsIHk7CiAgICBmbG9hdCAqc3JjX2Y7CiAgICB1bnNpZ25lZCBzaG9ydCAqZHN0X3M7CgogICAgVFJBQ0UoIkNvbnZlcnRpbmcgJWR4JWQgcGl4ZWxzLCBwaXRjaGVzICVkICVkXG4iLCB3LCBoLCBwaXRjaF9pbiwgcGl0Y2hfb3V0KTsKICAgIGZvcih5ID0gMDsgeSA8IGg7IHkrKykgewogICAgICAgIHNyY19mID0gKGZsb2F0ICopIChzcmMgKyB5ICogcGl0Y2hfaW4pOwogICAgICAgIGRzdF9zID0gKHVuc2lnbmVkIHNob3J0ICopIChkc3QgKyB5ICogcGl0Y2hfb3V0KTsKICAgICAgICBmb3IoeCA9IDA7IHggPCB3OyB4KyspIHsKICAgICAgICAgICAgZHN0X3NbeF0gPSBmbG9hdF8zMl90b18xNihzcmNfZiArIHgpOwogICAgICAgIH0KICAgIH0KfQoKc3RydWN0IGQzZGZtdF9jb252ZXJ0b3JfZGVzYyB7CiAgICBXSU5FRDNERk9STUFUIGZyb20sIHRvOwogICAgdm9pZCAoKmNvbnZlcnQpKEJZVEUgKnNyYywgQllURSAqZHN0LCBEV09SRCBwaXRjaF9pbiwgRFdPUkQgcGl0Y2hfb3V0LCB1bnNpZ25lZCBpbnQgdywgdW5zaWduZWQgaW50IGgpOwp9OwoKc3RydWN0IGQzZGZtdF9jb252ZXJ0b3JfZGVzYyBjb252ZXJ0b3JzW10gPSB7CiAgICB7V0lORUQzREZNVF9SMzJGLCAgICAgICBXSU5FRDNERk1UX1IxNkYsICAgICAgICBjb252ZXJ0X3IzMmZfcjE2Zn0sCn07CgpzdGF0aWMgaW5saW5lIHN0cnVjdCBkM2RmbXRfY29udmVydG9yX2Rlc2MgKmZpbmRfY29udmVydG9yKFdJTkVEM0RGT1JNQVQgZnJvbSwgV0lORUQzREZPUk1BVCB0bykgewogICAgdW5zaWduZWQgaW50IGk7CiAgICBmb3IoaSA9IDA7IGkgPCAoc2l6ZW9mKGNvbnZlcnRvcnMpIC8gc2l6ZW9mKGNvbnZlcnRvcnNbMF0pKTsgaSsrKSB7CiAgICAgICAgaWYoY29udmVydG9yc1tpXS5mcm9tID09IGZyb20gJiYgY29udmVydG9yc1tpXS50byA9PSB0bykgewogICAgICAgICAgICByZXR1cm4gJmNvbnZlcnRvcnNbaV07CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBzdXJmYWNlX2NvbnZlcnRfZm9ybWF0CiAqCiAqIENyZWF0ZXMgYSBkdXBsaWNhdGUgb2YgYSBzdXJmYWNlIGluIGEgZGlmZmVyZW50IGZvcm1hdC4gSXMgdXNlZCBieSBCbHQgdG8KICogYmxpdCBiZXR3ZWVuIHN1cmZhY2VzIHdpdGggZGlmZmVyZW50IGZvcm1hdHMKICoKICogUGFyYW1ldGVycwogKiAgc291cmNlOiBTb3VyY2Ugc3VyZmFjZQogKiAgZm10OiBSZXF1ZXN0ZWQgZGVzdGluYXRpb24gZm9ybWF0CiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSVdpbmVEM0RTdXJmYWNlSW1wbCAqc3VyZmFjZV9jb252ZXJ0X2Zvcm1hdChJV2luZUQzRFN1cmZhY2VJbXBsICpzb3VyY2UsIFdJTkVEM0RGT1JNQVQgdG9fZm10KSB7CiAgICBJV2luZUQzRFN1cmZhY2UgKnJldCA9IE5VTEw7CiAgICBzdHJ1Y3QgZDNkZm10X2NvbnZlcnRvcl9kZXNjICpjb252OwogICAgV0lORUQzRExPQ0tFRF9SRUNUIGxvY2tfc3JjLCBsb2NrX2RzdDsKICAgIEhSRVNVTFQgaHI7CgogICAgY29udiA9IGZpbmRfY29udmVydG9yKHNvdXJjZS0+cmVzb3VyY2UuZm9ybWF0LCB0b19mbXQpOwogICAgaWYoIWNvbnYpIHsKICAgICAgICBGSVhNRSgiQ2Fubm90IGZpbmQgYSBjb252ZXJzaW9uIGZ1bmN0aW9uIGZyb20gZm9ybWF0ICVzIHRvICVzXG4iLAogICAgICAgICAgICAgIGRlYnVnX2QzZGZvcm1hdChzb3VyY2UtPnJlc291cmNlLmZvcm1hdCksIGRlYnVnX2QzZGZvcm1hdCh0b19mbXQpKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBJV2luZUQzRERldmljZV9DcmVhdGVTdXJmYWNlKChJV2luZUQzRERldmljZSAqKSBzb3VyY2UtPnJlc291cmNlLndpbmVEM0REZXZpY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZS0+Y3VycmVudERlc2MuV2lkdGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNvdXJjZS0+Y3VycmVudERlc2MuSGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b19mbXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUsICAvKiBsb2NrYWJsZSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUUlVFLCAgLyogZGlzY2FyZCAgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgICAgIC8qIGxldmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZyZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEM0RSVFlQRV9TVVJGQUNFLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwLCAgICAgLyogdXNhZ2UgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFBPT0xfU0NSQVRDSCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRE1VTFRJU0FNUExFX05PTkUsICAgLyogVE9ETzogTXVsdGlzYW1wbGVkIGNvbnZlcnNpb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCwgICAgIC8qIE11bHRpU2FtcGxlUXVhbGl0eSAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAgLyogU2hhcmVkSGFuZGxlICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZV9HZXRJbXBsVHlwZSgoSVdpbmVEM0RTdXJmYWNlICopIHNvdXJjZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOyAvKiBwYXJlbnQgKi8KICAgIGlmKCFyZXQpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBjcmVhdGUgYSBkZXN0aW5hdGlvbiBzdXJmYWNlIGZvciBjb252ZXJzaW9uXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBtZW1zZXQoJmxvY2tfc3JjLCAwLCBzaXplb2YobG9ja19zcmMpKTsKICAgIG1lbXNldCgmbG9ja19kc3QsIDAsIHNpemVvZihsb2NrX2RzdCkpOwoKICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KChJV2luZUQzRFN1cmZhY2UgKikgc291cmNlLCAmbG9ja19zcmMsIE5VTEwsIFdJTkVEM0RMT0NLX1JFQURPTkxZKTsKICAgIGlmKEZBSUxFRChocikpIHsKICAgICAgICBFUlIoIkZhaWxlZCB0byBsb2NrIHRoZSBzb3VyY2Ugc3VyZmFjZVxuIik7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UocmV0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIGhyID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KHJldCwgJmxvY2tfZHN0LCBOVUxMLCBXSU5FRDNETE9DS19SRUFET05MWSk7CiAgICBpZihGQUlMRUQoaHIpKSB7CiAgICAgICAgRVJSKCJGYWlsZWQgdG8gbG9jayB0aGUgZGVzdCBzdXJmYWNlXG4iKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdCgoSVdpbmVEM0RTdXJmYWNlICopIHNvdXJjZSk7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1JlbGVhc2UocmV0KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBjb252LT5jb252ZXJ0KGxvY2tfc3JjLnBCaXRzLCBsb2NrX2RzdC5wQml0cywgbG9ja19zcmMuUGl0Y2gsIGxvY2tfZHN0LlBpdGNoLAogICAgICAgICAgICAgICAgICBzb3VyY2UtPmN1cnJlbnREZXNjLldpZHRoLCBzb3VyY2UtPmN1cnJlbnREZXNjLkhlaWdodCk7CgogICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QocmV0KTsKICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KChJV2luZUQzRFN1cmZhY2UgKikgc291cmNlKTsKCiAgICByZXR1cm4gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogX0JsdF9Db2xvckZpbGwKICoKICogSGVscGVyIGZ1bmN0aW9uIHRoYXQgZmlsbHMgYSBtZW1vcnkgYXJlYSB3aXRoIGEgc3BlY2lmaWMgY29sb3IKICoKICogUGFyYW1zOgogKiAgYnVmOiBtZW1vcnkgYWRkcmVzcyB0byBzdGFydCBmaWxsaW5nIGF0CiAqICB3aWR0aCwgaGVpZ2h0OiBEaW1lbnNpb25zIG9mIHRoZSBhcmVhIHRvIGZpbGwKICogIGJwcDogQml0IGRlcHRoIG9mIHRoZSBzdXJmYWNlCiAqICBsUGl0Y2g6IHBpdGNoIG9mIHRoZSBzdXJmYWNlCiAqICBjb2xvcjogQ29sb3IgdG8gZmlsbCB3aXRoCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kc3RhdGljIEhSRVNVTFQKICAgICAgICBfQmx0X0NvbG9yRmlsbChCWVRFICpidWYsCiAgICAgICAgICAgICAgICAgICAgICAgaW50IHdpZHRoLCBpbnQgaGVpZ2h0LAogICAgICAgICAgICAgICAgICAgICAgIGludCBicHAsIExPTkcgbFBpdGNoLAogICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGNvbG9yKQp7CiAgICBpbnQgeCwgeTsKICAgIExQQllURSBmaXJzdDsKCiAgICAvKiBEbyBmaXJzdCByb3cgKi8KCiNkZWZpbmUgQ09MT1JGSUxMX1JPVyh0eXBlKSBcCiAgICB7IFwKICAgIHR5cGUgKmQgPSAodHlwZSAqKSBidWY7IFwKICAgIGZvciAoeCA9IDA7IHggPCB3aWR0aDsgeCsrKSBcCiAgICBkW3hdID0gKHR5cGUpIGNvbG9yOyBcCiAgICBicmVhazsgXAp9CiAgICBzd2l0Y2goYnBwKQogICAgewogICAgICAgIGNhc2UgMTogQ09MT1JGSUxMX1JPVyhCWVRFKQogICAgICAgICAgICAgICAgY2FzZSAyOiBDT0xPUkZJTExfUk9XKFdPUkQpCiAgICAgICAgY2FzZSAzOgogICAgICAgIHsKICAgICAgICAgICAgQllURSAqZCA9IGJ1ZjsKICAgICAgICAgICAgZm9yICh4ID0gMDsgeCA8IHdpZHRoOyB4KyssZCs9MykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgZFswXSA9IChjb2xvciAgICApICYgMHhGRjsKICAgICAgICAgICAgICAgIGRbMV0gPSAoY29sb3I+PiA4KSAmIDB4RkY7CiAgICAgICAgICAgICAgICBkWzJdID0gKGNvbG9yPj4xNikgJiAweEZGOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgICAgICBjYXNlIDQ6IENPTE9SRklMTF9ST1coRFdPUkQpCiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgRklYTUUoIkNvbG9yIGZpbGwgbm90IGltcGxlbWVudGVkIGZvciBicHAgJWQhXG4iLCBicHAqOCk7CiAgICAgICAgICAgIHJldHVybiBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgIH0KCiN1bmRlZiBDT0xPUkZJTExfUk9XCgogICAgLyogTm93IGNvcHkgZmlyc3Qgcm93ICovCiAgICBmaXJzdCA9IGJ1ZjsKICAgIGZvciAoeSA9IDE7IHkgPCBoZWlnaHQ7IHkrKykKICAgIHsKICAgICAgICBidWYgKz0gbFBpdGNoOwogICAgICAgIG1lbWNweShidWYsIGZpcnN0LCB3aWR0aCAqIGJwcCk7CiAgICB9CiAgICByZXR1cm4gV0lORUQzRF9PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElXaW5lRDNEU3VyZmFjZTo6Qmx0LCBTVyBlbXVsYXRpb24gdmVyc2lvbgogKgogKiBQZXJmb3JtcyBibGl0cyB0byBhIHN1cmZhY2UsIGVpZ2hlciBmcm9tIGEgc291cmNlIG9mIHNvdXJjZS1sZXNzIGJsdHMKICogVGhpcyBpcyB0aGUgbWFpbiBmdW5jdGlvbmFsaXR5IG9mIERpcmVjdERyYXcKICoKICogUGFyYW1zOgogKiAgRGVzdFJlY3Q6IERlc3RpbmF0aW9uIHJlY3RhbmdsZSB0byB3cml0ZSB0bwogKiAgU3JjU3VyZmFjZTogU291cmNlIHN1cmZhY2UsIGNhbiBiZSBOVUxMCiAqICBTcmNSZWN0OiBTb3VyY2UgcmVjdGFuZ2xlCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KSFJFU1VMVCBXSU5BUEkKSVdpbmVEM0RCYXNlU3VyZmFjZUltcGxfQmx0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBSRUNUICpEZXN0UmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqU3JjU3VyZmFjZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKlNyY1JlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBGbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFdJTkVEREJMVEZYICpEREJsdEZ4LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgV0lORUQzRFRFWFRVUkVGSUxURVJUWVBFIEZpbHRlcikKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIGlmYWNlOwogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqU3JjID0gKElXaW5lRDNEU3VyZmFjZUltcGwgKikgU3JjU3VyZmFjZTsKICAgIFJFQ1QgICAgICAgIHhkc3QseHNyYzsKICAgIEhSRVNVTFQgICAgIHJldCA9IFdJTkVEM0RfT0s7CiAgICBXSU5FRDNETE9DS0VEX1JFQ1QgIGRsb2NrLCBzbG9jazsKICAgIFdJTkVEM0RGT1JNQVQgICAgICAgZGZtdCA9IFdJTkVEM0RGTVRfVU5LTk9XTiwgc2ZtdCA9IFdJTkVEM0RGTVRfVU5LTk9XTjsKICAgIGludCBicHAsIHNyY2hlaWdodCwgc3Jjd2lkdGgsIGRzdGhlaWdodCwgZHN0d2lkdGgsIHdpZHRoOwogICAgaW50IHgsIHk7CiAgICBjb25zdCBTdGF0aWNQaXhlbEZvcm1hdERlc2MgKnNFbnRyeSwgKmRFbnRyeTsKICAgIExQQllURSBkYnVmLCBzYnVmOwogICAgVFJBQ0UoIiglcCktPiglcCwlcCwlcCwleCwlcClcbiIsIFRoaXMsIERlc3RSZWN0LCBTcmMsIFNyY1JlY3QsIEZsYWdzLCBEREJsdEZ4KTsKCiAgICBpZiAoVFJBQ0VfT04oZDNkX3N1cmZhY2UpKQogICAgewogICAgICAgIGlmIChEZXN0UmVjdCkgVFJBQ0UoIlx0ZGVzdHJlY3QgOiVkeCVkLSVkeCVkXG4iLAogICAgICAgICAgICBEZXN0UmVjdC0+bGVmdCwgRGVzdFJlY3QtPnRvcCwgRGVzdFJlY3QtPnJpZ2h0LCBEZXN0UmVjdC0+Ym90dG9tKTsKICAgICAgICBpZiAoU3JjUmVjdCkgVFJBQ0UoIlx0c3JjcmVjdCAgOiVkeCVkLSVkeCVkXG4iLAogICAgICAgICAgICBTcmNSZWN0LT5sZWZ0LCBTcmNSZWN0LT50b3AsIFNyY1JlY3QtPnJpZ2h0LCBTcmNSZWN0LT5ib3R0b20pOwojaWYgMAogICAgICAgIFRSQUNFKCJcdGZsYWdzOiAiKTsKICAgICAgICAgICAgICAgICAgICAgIEREUkFXX2R1bXBfRERCTFQoRmxhZ3MpOwogICAgICAgICAgICAgICAgICAgICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RERlgpCiAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgVFJBQ0UoIlx0YmxpdGZ4OiAiKTsKICAgICAgICAgICAgICAgICAgICAgIEREUkFXX2R1bXBfRERCTFRGWChEREJsdEZ4LT5kd0RERlgpOwogICAgfQojZW5kaWYKICAgIH0KCiAgICBpZiAoIChUaGlzLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkgfHwgKChTcmMgIT0gTlVMTCkgJiYgKFNyYy0+RmxhZ3MgJiBTRkxBR19MT0NLRUQpKSkKICAgIHsKICAgICAgICBXQVJOKCIgU3VyZmFjZSBpcyBidXN5LCByZXR1cm5pbmcgRERFUlJfU1VSRkFDRUJVU1lcbiIpOwogICAgICAgIHJldHVybiBXSU5FRERFUlJfU1VSRkFDRUJVU1k7CiAgICB9CgogICAgaWYoRmlsdGVyICE9IFdJTkVEM0RURVhGX05PTkUgJiYgRmlsdGVyICE9IFdJTkVEM0RURVhGX1BPSU5UKSB7CiAgICAgICAgLyogQ2FuIGhhcHBlbiB3aGVuIGQzZDkgYXBwcyBkbyBhIFN0cmV0Y2hSZWN0IGNhbGwgd2hpY2ggaXNuJ3QgaGFuZGxlZCBpbiBnbCAqLwogICAgICAgIEZJWE1FKCJGaWx0ZXJzIG5vdCBzdXBwb3J0ZWQgaW4gc29mdHdhcmUgYmxpdFxuIik7CiAgICB9CgogICAgaWYgKFNyYyA9PSBUaGlzKQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChpZmFjZSwgJmRsb2NrLCBOVUxMLCAwKTsKICAgICAgICBkZm10ID0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0OwogICAgICAgIHNsb2NrID0gZGxvY2s7CiAgICAgICAgc2ZtdCA9IGRmbXQ7CiAgICAgICAgc0VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KHNmbXQsIE5VTEwsIE5VTEwpOwogICAgICAgIGRFbnRyeSA9IHNFbnRyeTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBkZm10ID0gVGhpcy0+cmVzb3VyY2UuZm9ybWF0OwogICAgICAgIGRFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShkZm10LCBOVUxMLCBOVUxMKTsKICAgICAgICBpZiAoU3JjKQogICAgICAgIHsKICAgICAgICAgICAgaWYoVGhpcy0+cmVzb3VyY2UuZm9ybWF0ICE9IFNyYy0+cmVzb3VyY2UuZm9ybWF0KSB7CiAgICAgICAgICAgICAgICBTcmMgPSBzdXJmYWNlX2NvbnZlcnRfZm9ybWF0KFNyYywgZGZtdCk7CiAgICAgICAgICAgICAgICBpZighU3JjKSB7CiAgICAgICAgICAgICAgICAgICAgLyogVGhlIGNvbnYgZnVuY3Rpb24gd3JpdGVzIGEgRklYTUUgKi8KICAgICAgICAgICAgICAgICAgICBXQVJOKCJDYW5ub3QgY29udmVydCBzb3VyY2Ugc3VyZmFjZSBmb3JtYXQgdG8gZGVzdCBmb3JtYXRcbiIpOwogICAgICAgICAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoKElXaW5lRDNEU3VyZmFjZSAqKSBTcmMsICZzbG9jaywgTlVMTCwgV0lORUQzRExPQ0tfUkVBRE9OTFkpOwogICAgICAgICAgICBzZm10ID0gU3JjLT5yZXNvdXJjZS5mb3JtYXQ7CiAgICAgICAgfQogICAgICAgIHNFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShzZm10LCBOVUxMLCBOVUxMKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsICZkbG9jayxOVUxMLDApOwogICAgfQoKICAgIGlmICghRERCbHRGeCB8fCAhKEREQmx0RngtPmR3RERGWCkpIEZsYWdzICY9IH5XSU5FRERCTFRfRERGWDsKCiAgICBpZiAoc0VudHJ5LT5pc0ZvdXJjYyAmJiBkRW50cnktPmlzRm91cmNjKQogICAgewogICAgICAgIG1lbWNweShkbG9jay5wQml0cywgc2xvY2sucEJpdHMsIFRoaXMtPnJlc291cmNlLnNpemUpOwogICAgICAgIGdvdG8gcmVsZWFzZTsKICAgIH0KCiAgICBpZiAoRGVzdFJlY3QpCiAgICB7CiAgICAgICAgeGRzdCA9ICpEZXN0UmVjdDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICB4ZHN0LnRvcCAgICA9IDA7CiAgICAgICAgeGRzdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgeGRzdC5sZWZ0ICAgPSAwOwogICAgICAgIHhkc3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICB9CgogICAgaWYgKFNyY1JlY3QpCiAgICB7CiAgICAgICAgeHNyYyA9ICpTcmNSZWN0OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIGlmIChTcmMpCiAgICAgICAgewogICAgICAgICAgICB4c3JjLnRvcCAgICA9IDA7CiAgICAgICAgICAgIHhzcmMuYm90dG9tID0gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgICAgIHhzcmMubGVmdCAgID0gMDsKICAgICAgICAgICAgeHNyYy5yaWdodCAgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBtZW1zZXQoJnhzcmMsMCxzaXplb2YoeHNyYykpOwogICAgICAgIH0KICAgIH0KCiAgICAvKiBGaXJzdCBjaGVjayBmb3IgdGhlIHZhbGlkaXR5IG9mIHNvdXJjZSAvIGRlc3RpbmF0aW9uIHJlY3RhbmdsZXMuIFRoaXMgd2FzCiAgICAgKiB2ZXJpZmllZCB1c2luZyBhIHRlc3QgYXBwbGljYXRpb24gKyBieSBNU0ROLgogICAgICovCiAgICBpZiAoKFNyYyAhPSBOVUxMKSAmJgogICAgICAgICAoKHhzcmMuYm90dG9tID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4c3JjLmJvdHRvbSA8IDApIHx8CiAgICAgICAgICh4c3JjLnRvcCAgICAgPiBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwgKHhzcmMudG9wICAgIDwgMCkgfHwKICAgICAgICAgKHhzcmMubGVmdCAgICA+IFNyYy0+Y3VycmVudERlc2MuV2lkdGgpICB8fCAoeHNyYy5sZWZ0ICAgPCAwKSB8fAogICAgICAgICAoeHNyYy5yaWdodCAgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4c3JjLnJpZ2h0ICA8IDApIHx8CiAgICAgICAgICh4c3JjLnJpZ2h0ICAgPCB4c3JjLmxlZnQpICAgICAgICAgICAgICAgfHwgKHhzcmMuYm90dG9tIDwgeHNyYy50b3ApKSkKICAgIHsKICAgICAgICBXQVJOKCJBcHBsaWNhdGlvbiBnYXZlIHVzIGJhZCBzb3VyY2UgcmVjdGFuZ2xlIGZvciBCbHQuXG4iKTsKICAgICAgICByZXQgPSBXSU5FRERFUlJfSU5WQUxJRFJFQ1Q7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQogICAgLyogRm9yIHRoZSBEZXN0aW5hdGlvbiByZWN0LCBpdCBjYW4gYmUgb3V0IG9mIGJvdW5kcyBvbiB0aGUgY29uZGl0aW9uIHRoYXQgYSBjbGlwcGVyCiAgICAgKiBpcyBzZXQgZm9yIHRoZSBnaXZlbiBzdXJmYWNlLgogICAgICovCiAgICBpZiAoKC8qVGhpcy0+Y2xpcHBlciA9PSBOVUxMKi8gVFJVRSkgJiYKICAgICAgICAgKCh4ZHN0LmJvdHRvbSAgPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8ICh4ZHN0LmJvdHRvbSA8IDApIHx8CiAgICAgICAgICh4ZHN0LnRvcCAgICAgID4gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSB8fCAoeGRzdC50b3AgICAgPCAwKSB8fAogICAgICAgICAoeGRzdC5sZWZ0ICAgICA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKSAgfHwgKHhkc3QubGVmdCAgIDwgMCkgfHwKICAgICAgICAgKHhkc3QucmlnaHQgICAgPiBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8ICh4ZHN0LnJpZ2h0ICA8IDApIHx8CiAgICAgICAgICh4ZHN0LnJpZ2h0ICAgIDwgeGRzdC5sZWZ0KSAgICAgICAgICAgICAgICB8fCAoeGRzdC5ib3R0b20gPCB4ZHN0LnRvcCkpKQogICAgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIGdhdmUgdXMgYmFkIGRlc3RpbmF0aW9uIHJlY3RhbmdsZSBmb3IgQmx0IHdpdGhvdXQgYSBjbGlwcGVyIHNldC5cbiIpOwogICAgICAgIHJldCA9IFdJTkVEREVSUl9JTlZBTElEUkVDVDsKICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICB9CgogICAgLyogTm93IGhhbmRsZSBuZWdhdGl2ZSB2YWx1ZXMgaW4gdGhlIHJlY3RhbmdsZXMuIFdhcm5pbmc6IG9ubHkgc3VwcG9ydGVkIGZvciBub3cKICAgIGluIHRoZSAnc2ltcGxlJyBjYXNlcyAoaWUgbm90IGluIGFueSBzdHJldGNoaW5nIC8gcm90YXRpb24gY2FzZXMpLgoKICAgIEZpcnN0LCB0aGUgY2FzZSB3aGVyZSBub3RoaW5nIGlzIHRvIGJlIGRvbmUuCiAgICAqLwogICAgaWYgKCgoeGRzdC5ib3R0b20gPD0gMCkgfHwgKHhkc3QucmlnaHQgPD0gMCkgICAgICAgICB8fAogICAgICAgICAgKHhkc3QudG9wICAgID49IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwKICAgICAgICAgICh4ZHN0LmxlZnQgICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkpIHx8CiAgICAgICAgICAoKFNyYyAhPSBOVUxMKSAmJgogICAgICAgICAgKCh4c3JjLmJvdHRvbSA8PSAwKSB8fCAoeHNyYy5yaWdodCA8PSAwKSAgICAgfHwKICAgICAgICAgICh4c3JjLnRvcCA+PSAoaW50KSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodCkgfHwKICAgICAgICAgICh4c3JjLmxlZnQgPj0gKGludCkgU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkpICApKQogICAgewogICAgICAgIFRSQUNFKCJOb3RoaW5nIHRvIGJlIGRvbmUgIVxuIik7CiAgICAgICAgZ290byByZWxlYXNlOwogICAgfQoKICAgIC8qIFRoZSBlYXN5IGNhc2UgOiB0aGUgc291cmNlLWxlc3MgYmxpdHMuLi4uICovCiAgICBpZiAoU3JjID09IE5VTEwpCiAgICB7CiAgICAgICAgUkVDVCBmdWxsX3JlY3Q7CiAgICAgICAgUkVDVCB0ZW1wX3JlY3Q7IC8qIE5vIGlkZWEgaWYgaW50ZXJzZWN0IHJlY3QgY2FuIGJlIHRoZSBzYW1lIGFzIG9uZSBvZiB0aGUgc291cmNlIHJlY3QgKi8KCiAgICAgICAgZnVsbF9yZWN0LmxlZnQgICA9IDA7CiAgICAgICAgZnVsbF9yZWN0LnRvcCAgICA9IDA7CiAgICAgICAgZnVsbF9yZWN0LnJpZ2h0ICA9IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoOwogICAgICAgIGZ1bGxfcmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CiAgICAgICAgSW50ZXJzZWN0UmVjdCgmdGVtcF9yZWN0LCAmZnVsbF9yZWN0LCAmeGRzdCk7CiAgICAgICAgeGRzdCA9IHRlbXBfcmVjdDsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICAvKiBPbmx5IGhhbmRsZSBjbGlwcGluZyBvbiB0aGUgZGVzdGluYXRpb24gcmVjdGFuZ2xlICovCiAgICAgICAgaW50IGNsaXBfaG9yaXogPSAoeGRzdC5sZWZ0IDwgMCkgfHwgKHhkc3QucmlnaHQgID4gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGggKTsKICAgICAgICBpbnQgY2xpcF92ZXJ0ICA9ICh4ZHN0LnRvcCAgPCAwKSB8fCAoeGRzdC5ib3R0b20gPiAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpOwogICAgICAgIGlmIChjbGlwX3ZlcnQgfHwgY2xpcF9ob3JpeikKICAgICAgICB7CiAgICAgICAgICAgIC8qIE5vdyBjaGVjayBpZiB0aGlzIGlzIGEgc3BlY2lhbCBjYXNlIG9yIG5vdC4uLiAqLwogICAgICAgICAgICBpZiAoKCgoeGRzdC5ib3R0b20gLSB4ZHN0LnRvcCApICE9ICh4c3JjLmJvdHRvbSAtIHhzcmMudG9wICkpICYmIGNsaXBfdmVydCApIHx8CiAgICAgICAgICAgICAgICAgICAoKCh4ZHN0LnJpZ2h0ICAtIHhkc3QubGVmdCkgIT0gKHhzcmMucmlnaHQgIC0geHNyYy5sZWZ0KSkgJiYgY2xpcF9ob3JpeikgfHwKICAgICAgICAgICAgICAgICAgIChGbGFncyAmIFdJTkVEREJMVF9EREZYKSkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgV0FSTigiT3V0IG9mIHNjcmVlbiByZWN0YW5nbGUgaW4gc3BlY2lhbCBjYXNlLiBOb3QgaGFuZGxlZCByaWdodCBub3cuXG4iKTsKICAgICAgICAgICAgICAgIGdvdG8gcmVsZWFzZTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKGNsaXBfaG9yaXopCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGlmICh4ZHN0LmxlZnQgPCAwKSB7IHhzcmMubGVmdCAtPSB4ZHN0LmxlZnQ7IHhkc3QubGVmdCA9IDA7IH0KICAgICAgICAgICAgICAgIGlmICh4ZHN0LnJpZ2h0ID4gVGhpcy0+Y3VycmVudERlc2MuV2lkdGgpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy5yaWdodCAtPSAoeGRzdC5yaWdodCAtIChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLldpZHRoKTsKICAgICAgICAgICAgICAgICAgICB4ZHN0LnJpZ2h0ID0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaWYgKGNsaXBfdmVydCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgaWYgKHhkc3QudG9wIDwgMCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICB4c3JjLnRvcCAtPSB4ZHN0LnRvcDsKICAgICAgICAgICAgICAgICAgICB4ZHN0LnRvcCA9IDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoeGRzdC5ib3R0b20gPiBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgeHNyYy5ib3R0b20gLT0gKHhkc3QuYm90dG9tIC0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICB4ZHN0LmJvdHRvbSA9IChpbnQpIFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICAvKiBBbmQgY2hlY2sgaWYgYWZ0ZXIgY2xpcHBpbmcgc29tZXRoaW5nIGlzIHN0aWxsIHRvIGJlIGRvbmUuLi4gKi8KICAgICAgICAgICAgaWYgKCh4ZHN0LmJvdHRvbSA8PSAwKSAgIHx8ICh4ZHN0LnJpZ2h0IDw9IDApICAgICAgIHx8CiAgICAgICAgICAgICAgICAgKHhkc3QudG9wICAgPj0gKGludCkgVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0KSAgfHwKICAgICAgICAgICAgICAgICAoeGRzdC5sZWZ0ICA+PSAoaW50KSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aCkgICB8fAogICAgICAgICAgICAgICAgICh4c3JjLmJvdHRvbSA8PSAwKSAgIHx8ICh4c3JjLnJpZ2h0IDw9IDApICAgICAgIHx8CiAgICAgICAgICAgICAgICAgKHhzcmMudG9wID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0KSAgICAgfHwKICAgICAgICAgICAgICAgICAoeHNyYy5sZWZ0ID49IChpbnQpIFNyYy0+Y3VycmVudERlc2MuV2lkdGgpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBUUkFDRSgiTm90aGluZyB0byBiZSBkb25lIGFmdGVyIGNsaXBwaW5nICFcbiIpOwogICAgICAgICAgICAgICAgZ290byByZWxlYXNlOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIGJwcCA9IFRoaXMtPmJ5dGVzUGVyUGl4ZWw7CiAgICBzcmNoZWlnaHQgPSB4c3JjLmJvdHRvbSAtIHhzcmMudG9wOwogICAgc3Jjd2lkdGggPSB4c3JjLnJpZ2h0IC0geHNyYy5sZWZ0OwogICAgZHN0aGVpZ2h0ID0geGRzdC5ib3R0b20gLSB4ZHN0LnRvcDsKICAgIGRzdHdpZHRoID0geGRzdC5yaWdodCAtIHhkc3QubGVmdDsKICAgIHdpZHRoID0gKHhkc3QucmlnaHQgLSB4ZHN0LmxlZnQpICogYnBwOwoKICAgIGFzc2VydCh3aWR0aCA8PSBkbG9jay5QaXRjaCk7CgogICAgZGJ1ZiA9IChCWVRFKilkbG9jay5wQml0cysoeGRzdC50b3AqZGxvY2suUGl0Y2gpKyh4ZHN0LmxlZnQqYnBwKTsKCiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfV0FJVCkKICAgIHsKICAgICAgICBGbGFncyAmPSB+V0lORUREQkxUX1dBSVQ7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfQVNZTkMpCiAgICB7CiAgICAgICAgc3RhdGljIEJPT0wgZGlzcGxheWVkID0gRkFMU0U7CiAgICAgICAgaWYgKCFkaXNwbGF5ZWQpCiAgICAgICAgICAgIEZJWE1FKCJDYW4ndCBoYW5kbGUgV0lORUREQkxUX0FTWU5DIGZsYWcgcmlnaHQgbm93LlxuIik7CiAgICAgICAgZGlzcGxheWVkID0gVFJVRTsKICAgICAgICBGbGFncyAmPSB+V0lORUREQkxUX0FTWU5DOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RPTk9UV0FJVCkKICAgIHsKICAgICAgICAvKiBXSU5FRERCTFRfRE9OT1RXQUlUIGFwcGVhcmVkIGluIERYNyAqLwogICAgICAgIHN0YXRpYyBCT09MIGRpc3BsYXllZCA9IEZBTFNFOwogICAgICAgIGlmICghZGlzcGxheWVkKQogICAgICAgICAgICBGSVhNRSgiQ2FuJ3QgaGFuZGxlIFdJTkVEREJMVF9ET05PVFdBSVQgZmxhZyByaWdodCBub3cuXG4iKTsKICAgICAgICBkaXNwbGF5ZWQgPSBUUlVFOwogICAgICAgIEZsYWdzICY9IH5XSU5FRERCTFRfRE9OT1RXQUlUOwogICAgfQoKICAgIC8qIEZpcnN0LCBhbGwgdGhlICdzb3VyY2UtbGVzcycgYmxpdHMgKi8KICAgIGlmIChGbGFncyAmIFdJTkVEREJMVF9DT0xPUkZJTEwpCiAgICB7CiAgICAgICAgcmV0ID0gX0JsdF9Db2xvckZpbGwoZGJ1ZiwgZHN0d2lkdGgsIGRzdGhlaWdodCwgYnBwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRsb2NrLlBpdGNoLCBEREJsdEZ4LT51NS5kd0ZpbGxDb2xvcik7CiAgICAgICAgRmxhZ3MgJj0gfldJTkVEREJMVF9DT0xPUkZJTEw7CiAgICB9CgogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RFUFRIRklMTCkKICAgIHsKICAgICAgICBGSVhNRSgiRERCTFRfREVQVEhGSUxMIG5lZWRzIHRvIGJlIGltcGxlbWVudGVkIVxuIik7CiAgICB9CiAgICBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfUk9QKQogICAgewogICAgICAgIC8qIENhdGNoIHNvbWUgZGVnZW5lcmF0ZSBjYXNlcyBoZXJlICovCiAgICAgICAgc3dpdGNoKEREQmx0RngtPmR3Uk9QKQogICAgICAgIHsKICAgICAgICAgICAgY2FzZSBCTEFDS05FU1M6CiAgICAgICAgICAgICAgICByZXQgPSBfQmx0X0NvbG9yRmlsbChkYnVmLGRzdHdpZHRoLGRzdGhlaWdodCxicHAsZGxvY2suUGl0Y2gsMCk7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgMHhBQTAwMjk6IC8qIE5vLW9wICovCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgV0hJVEVORVNTOgogICAgICAgICAgICAgICAgcmV0ID0gX0JsdF9Db2xvckZpbGwoZGJ1Zixkc3R3aWR0aCxkc3RoZWlnaHQsYnBwLGRsb2NrLlBpdGNoLH4wKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBTUkNDT1BZOiAvKiB3ZWxsLCB3ZSBkbyB0aGF0IGJlbG93ID8gKi8KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgIEZJWE1FKCJVbnN1cHBvcnRlZCByYXN0ZXIgb3A6ICUwOHggIFBhdHRlcm46ICVwXG4iLCBEREJsdEZ4LT5kd1JPUCwgRERCbHRGeC0+dTUubHBERFNQYXR0ZXJuKTsKICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CiAgICAgICAgfQogICAgICAgIEZsYWdzICY9IH5XSU5FRERCTFRfUk9QOwogICAgfQogICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0REUk9QUykKICAgIHsKICAgICAgICBGSVhNRSgiXHREZHJhdyBSYXN0ZXIgT3BzOiAlMDh4ICBQYXR0ZXJuOiAlcFxuIiwgRERCbHRGeC0+ZHdERFJPUCwgRERCbHRGeC0+dTUubHBERFNQYXR0ZXJuKTsKICAgIH0KICAgIC8qIE5vdyB0aGUgJ3dpdGggc291cmNlJyBibGl0cyAqLwogICAgaWYgKFNyYykKICAgIHsKICAgICAgICBMUEJZVEUgc2Jhc2U7CiAgICAgICAgaW50IHN4LCB4aW5jLCBzeSwgeWluYzsKCiAgICAgICAgaWYgKCFkc3R3aWR0aCB8fCAhZHN0aGVpZ2h0KSAvKiBobW0uLi4gc3R1cGlkIHByb2dyYW0gPyAqLwogICAgICAgICAgICBnb3RvIHJlbGVhc2U7CiAgICAgICAgc2Jhc2UgPSAoQllURSopc2xvY2sucEJpdHMrKHhzcmMudG9wKnNsb2NrLlBpdGNoKSt4c3JjLmxlZnQqYnBwOwogICAgICAgIHhpbmMgPSAoc3Jjd2lkdGggPDwgMTYpIC8gZHN0d2lkdGg7CiAgICAgICAgeWluYyA9IChzcmNoZWlnaHQgPDwgMTYpIC8gZHN0aGVpZ2h0OwoKICAgICAgICBpZiAoIUZsYWdzKQogICAgICAgIHsKICAgICAgICAgICAgLyogTm8gZWZmZWN0cywgd2UgY2FuIGNoZWF0IGhlcmUgKi8KICAgICAgICAgICAgaWYgKGRzdHdpZHRoID09IHNyY3dpZHRoKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAoZHN0aGVpZ2h0ID09IHNyY2hlaWdodCkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAvKiBObyBzdHJldGNoaW5nIGluIGVpdGhlciBkaXJlY3Rpb24uIFRoaXMgbmVlZHMgdG8gYmUgYXMKICAgICAgICAgICAgICAgICAgICAqIGZhc3QgYXMgcG9zc2libGUgKi8KICAgICAgICAgICAgICAgICAgICBzYnVmID0gc2Jhc2U7CgogICAgICAgICAgICAgICAgICAgIC8qIGNoZWNrIGZvciBvdmVybGFwcGluZyBzdXJmYWNlcyAqLwogICAgICAgICAgICAgICAgICAgIGlmIChTcmMgIT0gVGhpcyB8fCB4ZHN0LnRvcCA8IHhzcmMudG9wIHx8CiAgICAgICAgICAgICAgICAgICAgICAgIHhkc3QucmlnaHQgPD0geHNyYy5sZWZ0IHx8IHhzcmMucmlnaHQgPD0geGRzdC5sZWZ0KQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogbm8gb3ZlcmxhcCwgb3IgZHN0IGFib3ZlIHNyYywgc28gY29weSBmcm9tIHRvcCBkb3dud2FyZHMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1jcHkoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiArPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoeGRzdC50b3AgPiB4c3JjLnRvcCkgIC8qIGNvcHkgZnJvbSBib3R0b20gdXB3YXJkcyAqLwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgc2J1ZiArPSAoc2xvY2suUGl0Y2gqZHN0aGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiArPSAoZGxvY2suUGl0Y2gqZHN0aGVpZ2h0KTsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzYnVmIC09IHNsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGJ1ZiAtPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZSAvKiBzcmMgYW5kIGRzdCBvdmVybGFwcGluZyBvbiB0aGUgc2FtZSBsaW5lLCB1c2UgbWVtbW92ZSAqLwogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrKQogICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1tb3ZlKGRidWYsIHNidWYsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKiBTdHJldGNoaW5nIGluIFkgZGlyZWN0aW9uIG9ubHkgKi8KICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykgewogICAgICAgICAgICAgICAgICAgICAgICBzYnVmID0gc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCB3aWR0aCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGRidWYgKz0gZGxvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgLyogU3RyZXRjaGluZyBpbiBYIGRpcmVjdGlvbiAqLwogICAgICAgICAgICAgICAgaW50IGxhc3Rfc3kgPSAtMTsKICAgICAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaDsKCiAgICAgICAgICAgICAgICAgICAgaWYgKChzeSA+PiAxNikgPT0gKGxhc3Rfc3kgPj4gMTYpKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgLyogdGhpcyBzb3VyY2Vyb3cgaXMgdGhlIHNhbWUgYXMgbGFzdCBzb3VyY2Vyb3cgLQogICAgICAgICAgICAgICAgICAgICAgICAqIGNvcHkgYWxyZWFkeSBzdHJldGNoZWQgcm93CiAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgICAgIG1lbWNweShkYnVmLCBkYnVmIC0gZGxvY2suUGl0Y2gsIHdpZHRoKTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgIHsKI2RlZmluZSBTVFJFVENIX1JPVyh0eXBlKSB7IFwKICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSAqcyA9ICh0eXBlICopIHNidWYsICpkID0gKHR5cGUgKikgZGJ1ZjsgXAogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSBzeCA9IDA7IHggPCBkc3R3aWR0aDsgeCsrLCBzeCArPSB4aW5jKSBcCiAgICAgICAgICAgICAgICAgICAgICAgIGRbeF0gPSBzW3N4ID4+IDE2XTsgXAogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsgfQoKICAgICAgICAgICAgICAgICAgICAgICAgc3dpdGNoKGJwcCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAxOiBTVFJFVENIX1JPVyhCWVRFKQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IFNUUkVUQ0hfUk9XKFdPUkQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiBTVFJFVENIX1JPVyhEV09SRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgMzoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMUEJZVEUgcyxkID0gZGJ1ZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSBzeCA9IDA7IHggPCBkc3R3aWR0aDsgeCsrLCBzeCs9IHhpbmMpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBwaXhlbDsKCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBzYnVmKzMqKHN4Pj4xNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsID0gc1swXXwoc1sxXTw8OCl8KHNbMl08PDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZFswXSA9IChwaXhlbCAgICApJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbMV0gPSAocGl4ZWw+PiA4KSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkWzJdID0gKHBpeGVsPj4xNikmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZCs9MzsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJWE1FKCJTdHJldGNoZWQgYmxpdCBub3QgaW1wbGVtZW50ZWQgZm9yIGJwcCAlZCFcbiIsIGJwcCo4KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXQgPSBXSU5FRDNERVJSX05PVEFWQUlMQUJMRTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgICAgICAgICAgICAgICAgICB9CiN1bmRlZiBTVFJFVENIX1JPVwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBkYnVmICs9IGRsb2NrLlBpdGNoOwogICAgICAgICAgICAgICAgICAgIGxhc3Rfc3kgPSBzeTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBMT05HIGRzdHlpbmMgPSBkbG9jay5QaXRjaCwgZHN0eGluYyA9IGJwcDsKICAgICAgICAgICAgRFdPUkQga2V5bG93ID0gMHhGRkZGRkZGRiwga2V5aGlnaCA9IDAsIGtleW1hc2sgPSAweEZGRkZGRkZGOwogICAgICAgICAgICBEV09SRCBkZXN0a2V5bG93ID0gMHgwLCBkZXN0a2V5aGlnaCA9IDB4RkZGRkZGRkYsIGRlc3RrZXltYXNrID0gMHhGRkZGRkZGRjsKICAgICAgICAgICAgaWYgKEZsYWdzICYgKFdJTkVEREJMVF9LRVlTUkMgfCBXSU5FRERCTFRfS0VZREVTVCB8IFdJTkVEREJMVF9LRVlTUkNPVkVSUklERSB8IFdJTkVEREJMVF9LRVlERVNUT1ZFUlJJREUpKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAvKiBUaGUgY29sb3Iga2V5aW5nIGZsYWdzIGFyZSBjaGVja2VkIGZvciBjb3JyZWN0bmVzcyBpbiBkZHJhdyAqLwogICAgICAgICAgICAgICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0tFWVNSQykKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBrZXlsb3cgID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICAgICAgICAgIGtleWhpZ2ggPSBTcmMtPlNyY0JsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSAgaWYgKEZsYWdzICYgV0lORUREQkxUX0tFWVNSQ09WRVJSSURFKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGtleWxvdyAgPSBEREJsdEZ4LT5kZGNrU3JjQ29sb3JrZXkuZHdDb2xvclNwYWNlTG93VmFsdWU7CiAgICAgICAgICAgICAgICAgICAga2V5aGlnaCA9IEREQmx0RngtPmRkY2tTcmNDb2xvcmtleS5kd0NvbG9yU3BhY2VIaWdoVmFsdWU7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0tFWURFU1QpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgLyogRGVzdGluYXRpb24gY29sb3Iga2V5cyBhcmUgdGFrZW4gZnJvbSB0aGUgc291cmNlIHN1cmZhY2UgISAqLwogICAgICAgICAgICAgICAgICAgIGRlc3RrZXlsb3cgID0gU3JjLT5EZXN0Qmx0Q0tleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBkZXN0a2V5aGlnaCA9IFNyYy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZSBpZiAoRmxhZ3MgJiBXSU5FRERCTFRfS0VZREVTVE9WRVJSSURFKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRlc3RrZXlsb3cgID0gRERCbHRGeC0+ZGRja0Rlc3RDb2xvcmtleS5kd0NvbG9yU3BhY2VMb3dWYWx1ZTsKICAgICAgICAgICAgICAgICAgICBkZXN0a2V5aGlnaCA9IEREQmx0RngtPmRkY2tEZXN0Q29sb3JrZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgICAgICAgICAgfQoKICAgICAgICAgICAgICAgIGlmKGJwcCA9PSAxKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGtleW1hc2sgPSAweGZmOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGtleW1hc2sgPSBzRW50cnktPnJlZE1hc2sgICB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzRW50cnktPmdyZWVuTWFzayB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzRW50cnktPmJsdWVNYXNrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgRmxhZ3MgJj0gfihXSU5FRERCTFRfS0VZU1JDIHwgV0lORUREQkxUX0tFWURFU1QgfCBXSU5FRERCTFRfS0VZU1JDT1ZFUlJJREUgfCBXSU5FRERCTFRfS0VZREVTVE9WRVJSSURFKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKEZsYWdzICYgV0lORUREQkxUX0RERlgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIExQQllURSBkVG9wTGVmdCwgZFRvcFJpZ2h0LCBkQm90dG9tTGVmdCwgZEJvdHRvbVJpZ2h0LCB0bXA7CiAgICAgICAgICAgICAgICBMT05HIHRtcHh5OwogICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZGJ1ZjsKICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IGRidWYrKChkc3R3aWR0aC0xKSpicHApOwogICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gZFRvcExlZnQrKChkc3RoZWlnaHQtMSkqZGxvY2suUGl0Y2gpOwogICAgICAgICAgICAgICAgZEJvdHRvbVJpZ2h0ID0gZEJvdHRvbUxlZnQrKChkc3R3aWR0aC0xKSpicHApOwoKICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9BUklUSFNUUkVUQ0hZKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2UgbmVlZCB0byBkbyBhbnl0aGluZyBhYm91dCB0aGlzIGZsYWcgKi8KICAgICAgICAgICAgICAgICAgICBXQVJOKCJGbGFncz1EREJMVF9EREZYIG5vdGhpbmcgZG9uZSBmb3IgV0lORUREQkxURlhfQVJJVEhTVFJFVENIWVxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfTUlSUk9STEVGVFJJR0hUKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSBkVG9wTGVmdDsKICAgICAgICAgICAgICAgICAgICBkVG9wTGVmdCAgICAgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICBkc3R4aW5jID0gZHN0eGluYyAqLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfTUlSUk9SVVBET1dOKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIHRtcCAgICAgICAgICA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IGRCb3R0b21MZWZ0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21MZWZ0ICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IHRtcDsKICAgICAgICAgICAgICAgICAgICBkc3R5aW5jID0gZHN0eWluYyAqLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfTk9URUFSSU5HKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2UgbmVlZCB0byBkbyBhbnl0aGluZyBhYm91dCB0aGlzIGZsYWcgKi8KICAgICAgICAgICAgICAgICAgICBXQVJOKCJGbGFncz1EREJMVF9EREZYIG5vdGhpbmcgZG9uZSBmb3IgV0lORUREQkxURlhfTk9URUFSSU5HXG4iKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9ST1RBVEUxODApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRUb3BMZWZ0OwogICAgICAgICAgICAgICAgICAgIGRUb3BMZWZ0ICAgICA9IHRtcDsKICAgICAgICAgICAgICAgICAgICB0bXAgICAgICAgICAgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSBkVG9wUmlnaHQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcFJpZ2h0ICAgID0gdG1wOwogICAgICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R4aW5jICogLTE7CiAgICAgICAgICAgICAgICAgICAgZHN0eWluYyA9IGRzdHlpbmMgKiAtMTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChEREJsdEZ4LT5kd0RERlggJiBXSU5FRERCTFRGWF9ST1RBVEUyNzApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZEJvdHRvbUxlZnQ7CiAgICAgICAgICAgICAgICAgICAgZEJvdHRvbUxlZnQgID0gZEJvdHRvbVJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRCb3R0b21SaWdodCA9IGRUb3BSaWdodDsKICAgICAgICAgICAgICAgICAgICBkVG9wUmlnaHQgICAgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgdG1weHkgICA9IGRzdHhpbmM7CiAgICAgICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHlpbmM7CiAgICAgICAgICAgICAgICAgICAgZHN0eWluYyA9IHRtcHh5OwogICAgICAgICAgICAgICAgICAgIGRzdHhpbmMgPSBkc3R4aW5jICogLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfUk9UQVRFOTApCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgdG1wICAgICAgICAgID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICAgICAgZFRvcExlZnQgICAgID0gZFRvcFJpZ2h0OwogICAgICAgICAgICAgICAgICAgIGRUb3BSaWdodCAgICA9IGRCb3R0b21SaWdodDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tUmlnaHQgPSBkQm90dG9tTGVmdDsKICAgICAgICAgICAgICAgICAgICBkQm90dG9tTGVmdCAgPSB0bXA7CiAgICAgICAgICAgICAgICAgICAgdG1weHkgICA9IGRzdHhpbmM7CiAgICAgICAgICAgICAgICAgICAgZHN0eGluYyA9IGRzdHlpbmM7CiAgICAgICAgICAgICAgICAgICAgZHN0eWluYyA9IHRtcHh5OwogICAgICAgICAgICAgICAgICAgIGRzdHlpbmMgPSBkc3R5aW5jICogLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoRERCbHRGeC0+ZHdEREZYICYgV0lORUREQkxURlhfWkJVRkZFUkJBU0VERVNUKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIC8qIEkgZG9uJ3QgdGhpbmsgd2UgbmVlZCB0byBkbyBhbnl0aGluZyBhYm91dCB0aGlzIGZsYWcgKi8KICAgICAgICAgICAgICAgICAgICBXQVJOKCJGbGFncz1XSU5FRERCTFRfRERGWCBub3RoaW5nIGRvbmUgZm9yIFdJTkVEREJMVEZYX1pCVUZGRVJCQVNFREVTVFxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBkYnVmID0gZFRvcExlZnQ7CiAgICAgICAgICAgICAgICBGbGFncyAmPSB+KFdJTkVEREJMVF9EREZYKTsKICAgICAgICAgICAgfQoKI2RlZmluZSBDT1BZX0NPTE9SS0VZX0ZYKHR5cGUpIHsgXAogICAgICAgICAgICB0eXBlICpzLCAqZCA9ICh0eXBlICopIGRidWYsICpkeCwgdG1wOyBcCiAgICAgICAgICAgIGZvciAoeSA9IHN5ID0gMDsgeSA8IGRzdGhlaWdodDsgeSsrLCBzeSArPSB5aW5jKSB7IFwKICAgICAgICAgICAgcyA9ICh0eXBlKikoc2Jhc2UgKyAoc3kgPj4gMTYpICogc2xvY2suUGl0Y2gpOyBcCiAgICAgICAgICAgIGR4ID0gZDsgXAogICAgICAgICAgICBmb3IgKHggPSBzeCA9IDA7IHggPCBkc3R3aWR0aDsgeCsrLCBzeCArPSB4aW5jKSB7IFwKICAgICAgICAgICAgdG1wID0gc1tzeCA+PiAxNl07IFwKICAgICAgICAgICAgaWYgKCgodG1wICYga2V5bWFzaykgPCBrZXlsb3cgfHwgKHRtcCAmIGtleW1hc2spID4ga2V5aGlnaCkgJiYgXAogICAgICAgICAgICAoKGR4WzBdICYgZGVzdGtleW1hc2spID49IGRlc3RrZXlsb3cgJiYgKGR4WzBdICYgZGVzdGtleW1hc2spIDw9IGRlc3RrZXloaWdoKSkgeyBcCiAgICAgICAgICAgIGR4WzBdID0gdG1wOyBcCiAgICAgICAgfSBcCiAgICAgICAgICAgIGR4ID0gKHR5cGUqKSgoKExQQllURSlkeCkrZHN0eGluYyk7IFwKICAgICAgICB9IFwKICAgICAgICAgICAgZCA9ICh0eXBlKikoKChMUEJZVEUpZCkrZHN0eWluYyk7IFwKICAgICAgICB9IFwKICAgICAgICAgICAgYnJlYWs7IH0KCiAgICAgICAgICAgIHN3aXRjaCAoYnBwKSB7CiAgICAgICAgICAgICAgICBjYXNlIDE6IENPUFlfQ09MT1JLRVlfRlgoQllURSkKICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAyOiBDT1BZX0NPTE9SS0VZX0ZYKFdPUkQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSA0OiBDT1BZX0NPTE9SS0VZX0ZYKERXT1JEKQogICAgICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIExQQllURSBzLGQgPSBkYnVmLCBkeDsKICAgICAgICAgICAgICAgICAgICBmb3IgKHkgPSBzeSA9IDA7IHkgPCBkc3RoZWlnaHQ7IHkrKywgc3kgKz0geWluYykKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIHNidWYgPSBzYmFzZSArIChzeSA+PiAxNikgKiBzbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgICAgICAgICAgZHggPSBkOwogICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHggPSBzeCA9IDA7IHggPCBkc3R3aWR0aDsgeCsrLCBzeCs9IHhpbmMpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIHBpeGVsLCBkcGl4ZWwgPSAwOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHNidWYrMyooc3g+PjE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpeGVsID0gc1swXXwoc1sxXTw8OCl8KHNbMl08PDE2KTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwaXhlbCA9IGR4WzBdfChkeFsxXTw8OCl8KGR4WzJdPDwxNik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoKChwaXhlbCAmIGtleW1hc2spIDwga2V5bG93IHx8IChwaXhlbCAmIGtleW1hc2spID4ga2V5aGlnaCkgJiYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoZHBpeGVsICYga2V5bWFzaykgPj0gZGVzdGtleWxvdyB8fCAoZHBpeGVsICYga2V5bWFzaykgPD0ga2V5aGlnaCkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHhbMF0gPSAocGl4ZWwgICAgKSYweGZmOwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR4WzFdID0gKHBpeGVsPj4gOCkmMHhmZjsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeFsyXSA9IChwaXhlbD4+MTYpJjB4ZmY7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkeCs9IGRzdHhpbmM7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgZCArPSBkc3R5aW5jOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICAgICAgRklYTUUoIiVzIGNvbG9yLWtleWVkIGJsaXQgbm90IGltcGxlbWVudGVkIGZvciBicHAgJWQhXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgIChGbGFncyAmIFdJTkVEREJMVF9LRVlTUkMpID8gIlNvdXJjZSIgOiAiRGVzdGluYXRpb24iLCBicHAqOCk7CiAgICAgICAgICAgICAgICAgICAgcmV0ID0gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKI3VuZGVmIENPUFlfQ09MT1JLRVlfRlgKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCmVycm9yOgogICAgaWYgKEZsYWdzICYmIEZJWE1FX09OKGQzZF9zdXJmYWNlKSkKICAgIHsKICAgICAgICBGSVhNRSgiXHRVbnN1cHBvcnRlZCBmbGFnczogJTA4eFxuIiwgRmxhZ3MpOwogICAgfQoKcmVsZWFzZToKICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKICAgIGlmIChTcmMgJiYgU3JjICE9IFRoaXMpIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KChJV2luZUQzRFN1cmZhY2UgKikgU3JjKTsKICAgIC8qIFJlbGVhc2UgdGhlIGNvbnZlcnRlZCBzdXJmYWNlIGlmIGFueSAqLwogICAgaWYgKFNyYyAmJiBTcmNTdXJmYWNlICE9IChJV2luZUQzRFN1cmZhY2UgKikgU3JjKSBJV2luZUQzRFN1cmZhY2VfUmVsZWFzZSgoSVdpbmVEM0RTdXJmYWNlICopIFNyYyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogSVdpbmVEM0RTdXJmYWNlOjpCbHRGYXN0LCBTVyBlbXVsYXRpb24gdmVyc2lvbgogKgogKiBUaGlzIGlzIHRoZSBzb2Z0d2FyZSBpbXBsZW1lbnRhdGlvbiBvZiBCbHRGYXN0LCBhcyB1c2VkIGJ5IEdESSBzdXJmYWNlcwogKiBhbmQgYXMgYSBmYWxsYmFjayBmb3IgT3BlbkdMIHN1cmZhY2VzLiBUaGlzIGNvZGUgaXMgdGFrZW4gZnJvbSB0aGUgb2xkCiAqIERpcmVjdERyYXcgY29kZSwgYW5kIHdhcyBvcmlnaW5hbGx5IHdyaXR0ZW4gYnkgVHJhbnNHYW1pbmcuCiAqCiAqIFBhcmFtczoKICogIGRzdHg6CiAqICBkc3R5OgogKiAgU291cmNlOiBTb3VyY2Ugc3VyZmFjZSB0byBjb3B5IGZyb20KICogIHJzcmM6IFNvdXJjZSByZWN0YW5nbGUKICogIHRyYW5zOiBTb21lIEZsYWdzCiAqCiAqIFJldHVybnM6CiAqICBXSU5FRDNEX09LIG9uIHN1Y2Nlc3MKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpIUkVTVUxUIFdJTkFQSQpJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CbHRGYXN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHN0eCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkc3R5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIElXaW5lRDNEU3VyZmFjZSAqU291cmNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFQ1QgKnJzcmMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgdHJhbnMpCnsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlRoaXMgPSAoSVdpbmVEM0RTdXJmYWNlSW1wbCAqKSBpZmFjZTsKICAgIElXaW5lRDNEU3VyZmFjZUltcGwgKlNyYyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopIFNvdXJjZTsKCiAgICBpbnQgICAgICAgICAgICAgICAgIGJwcCwgdywgaCwgeCwgeTsKICAgIFdJTkVEM0RMT0NLRURfUkVDVCAgZGxvY2ssc2xvY2s7CiAgICBIUkVTVUxUICAgICAgICAgICAgIHJldCA9IFdJTkVEM0RfT0s7CiAgICBSRUNUICAgICAgICAgICAgICAgIHJzcmMyOwogICAgUkVDVCAgICAgICAgICAgICAgICBsb2NrX3NyYywgbG9ja19kc3QsIGxvY2tfdW5pb247CiAgICBCWVRFICAgICAgICAgICAgICAgICpzYnVmLCAqZGJ1ZjsKICAgIGNvbnN0IFN0YXRpY1BpeGVsRm9ybWF0RGVzYyAqc0VudHJ5LCAqZEVudHJ5OwoKICAgIGlmIChUUkFDRV9PTihkM2Rfc3VyZmFjZSkpCiAgICB7CiAgICAgICAgVFJBQ0UoIiglcCktPiglZCwlZCwlcCwlcCwlMDh4KVxuIiwgVGhpcyxkc3R4LGRzdHksU3JjLHJzcmMsdHJhbnMpOwoKICAgICAgICBpZiAocnNyYykKICAgICAgICB7CiAgICAgICAgICAgIFRSQUNFKCJcdHNyY3JlY3Q6ICVkeCVkLSVkeCVkXG4iLHJzcmMtPmxlZnQscnNyYy0+dG9wLAogICAgICAgICAgICAgICAgICByc3JjLT5yaWdodCxyc3JjLT5ib3R0b20pOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBUUkFDRSgiIHNyY3JlY3Q6IE5VTExcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoKFRoaXMtPkZsYWdzICYgU0ZMQUdfTE9DS0VEKSB8fAogICAgICAgICAoKFNyYyAhPSBOVUxMKSAmJiAoU3JjLT5GbGFncyAmIFNGTEFHX0xPQ0tFRCkpKQogICAgewogICAgICAgIFdBUk4oIiBTdXJmYWNlIGlzIGJ1c3ksIHJldHVybmluZyBEREVSUl9TVVJGQUNFQlVTWVxuIik7CiAgICAgICAgcmV0dXJuIFdJTkVEREVSUl9TVVJGQUNFQlVTWTsKICAgIH0KCiAgICBpZiAoIXJzcmMpCiAgICB7CiAgICAgICAgV0FSTigicnNyYyBpcyBOVUxMIVxuIik7CiAgICAgICAgcnNyYyA9ICZyc3JjMjsKICAgICAgICByc3JjLT5sZWZ0ID0gMDsKICAgICAgICByc3JjLT50b3AgPSAwOwogICAgICAgIHJzcmMtPnJpZ2h0ID0gU3JjLT5jdXJyZW50RGVzYy5XaWR0aDsKICAgICAgICByc3JjLT5ib3R0b20gPSBTcmMtPmN1cnJlbnREZXNjLkhlaWdodDsKICAgIH0KCiAgICAvKiBDaGVjayBzb3VyY2UgcmVjdCBmb3IgdmFsaWRpdHkuIENvcGllZCBmcm9tIG5vcm1hbCBCbHQuIEZpeGVzIEJhbGR1cidzIEdhdGUuKi8KICAgIGlmICgocnNyYy0+Ym90dG9tID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8IChyc3JjLT5ib3R0b20gPCAwKSB8fAogICAgICAgICAocnNyYy0+dG9wICAgID4gU3JjLT5jdXJyZW50RGVzYy5IZWlnaHQpIHx8IChyc3JjLT50b3AgICAgPCAwKSB8fAogICAgICAgICAocnNyYy0+bGVmdCAgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8IChyc3JjLT5sZWZ0ICAgPCAwKSB8fAogICAgICAgICAocnNyYy0+cmlnaHQgID4gU3JjLT5jdXJyZW50RGVzYy5XaWR0aCkgIHx8IChyc3JjLT5yaWdodCAgPCAwKSB8fAogICAgICAgICAocnNyYy0+cmlnaHQgIDwgcnNyYy0+bGVmdCkgICAgICAgICAgICAgIHx8IChyc3JjLT5ib3R0b20gPCByc3JjLT50b3ApKQogICAgewogICAgICAgIFdBUk4oIkFwcGxpY2F0aW9uIGdhdmUgdXMgYmFkIHNvdXJjZSByZWN0YW5nbGUgZm9yIEJsdEZhc3QuXG4iKTsKICAgICAgICByZXR1cm4gV0lORURERVJSX0lOVkFMSURSRUNUOwogICAgfQoKICAgIGggPSByc3JjLT5ib3R0b20gLSByc3JjLT50b3A7CiAgICBpZiAoaCA+IFRoaXMtPmN1cnJlbnREZXNjLkhlaWdodC1kc3R5KSBoID0gVGhpcy0+Y3VycmVudERlc2MuSGVpZ2h0LWRzdHk7CiAgICBpZiAoaCA+IFNyYy0+Y3VycmVudERlc2MuSGVpZ2h0LXJzcmMtPnRvcCkgaD1TcmMtPmN1cnJlbnREZXNjLkhlaWdodC1yc3JjLT50b3A7CiAgICBpZiAoaCA8PSAwKSByZXR1cm4gV0lORURERVJSX0lOVkFMSURSRUNUOwoKICAgIHcgPSByc3JjLT5yaWdodCAtIHJzcmMtPmxlZnQ7CiAgICBpZiAodyA+IFRoaXMtPmN1cnJlbnREZXNjLldpZHRoLWRzdHgpIHcgPSBUaGlzLT5jdXJyZW50RGVzYy5XaWR0aC1kc3R4OwogICAgaWYgKHcgPiBTcmMtPmN1cnJlbnREZXNjLldpZHRoLXJzcmMtPmxlZnQpIHcgPSBTcmMtPmN1cnJlbnREZXNjLldpZHRoLXJzcmMtPmxlZnQ7CiAgICBpZiAodyA8PSAwKSByZXR1cm4gV0lORURERVJSX0lOVkFMSURSRUNUOwoKICAgIC8qIE5vdyBjb21wdXRlIHRoZSBsb2NraW5nIHJlY3RhbmdsZS4uLiAqLwogICAgbG9ja19zcmMubGVmdCA9IHJzcmMtPmxlZnQ7CiAgICBsb2NrX3NyYy50b3AgPSByc3JjLT50b3A7CiAgICBsb2NrX3NyYy5yaWdodCA9IGxvY2tfc3JjLmxlZnQgKyB3OwogICAgbG9ja19zcmMuYm90dG9tID0gbG9ja19zcmMudG9wICsgaDsKCiAgICBsb2NrX2RzdC5sZWZ0ID0gZHN0eDsKICAgIGxvY2tfZHN0LnRvcCA9IGRzdHk7CiAgICBsb2NrX2RzdC5yaWdodCA9IGRzdHggKyB3OwogICAgbG9ja19kc3QuYm90dG9tID0gZHN0eSArIGg7CgogICAgYnBwID0gVGhpcy0+Ynl0ZXNQZXJQaXhlbDsKCiAgICAvKiBXZSBuZWVkIHRvIGxvY2sgdGhlIHN1cmZhY2VzLCBvciB3ZSB3b24ndCBnZXQgcmVmcmVzaGVzIHdoZW4gZG9uZS4gKi8KICAgIGlmIChTcmMgPT0gVGhpcykKICAgIHsKICAgICAgICBpbnQgcGl0Y2g7CgogICAgICAgIFVuaW9uUmVjdCgmbG9ja191bmlvbiwgJmxvY2tfc3JjLCAmbG9ja19kc3QpOwoKICAgICAgICAvKiBMb2NrIHRoZSB1bmlvbiBvZiB0aGUgdHdvIHJlY3RhbmdsZXMgKi8KICAgICAgICByZXQgPSBJV2luZUQzRFN1cmZhY2VfTG9ja1JlY3QoaWZhY2UsICZkbG9jaywgJmxvY2tfdW5pb24sIDApOwogICAgICAgIGlmKHJldCAhPSBXSU5FRDNEX09LKSBnb3RvIGVycm9yOwoKICAgICAgICBwaXRjaCA9IGRsb2NrLlBpdGNoOwogICAgICAgIHNsb2NrLlBpdGNoID0gZGxvY2suUGl0Y2g7CgogICAgICAgIC8qIFNpbmNlIHNsb2NrIHdhcyBvcmlnaW5hbGx5IGNvcGllZCBmcm9tIHRoaXMgc3VyZmFjZSdzIGRlc2NyaXB0aW9uLCB3ZSBjYW4ganVzdCByZXVzZSBpdCAqLwogICAgICAgIGFzc2VydChUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgIT0gTlVMTCk7CiAgICAgICAgc2J1ZiA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIGxvY2tfc3JjLnRvcCAqIHBpdGNoICsgbG9ja19zcmMubGVmdCAqIGJwcDsKICAgICAgICBkYnVmID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsgbG9ja19kc3QudG9wICogcGl0Y2ggKyBsb2NrX2RzdC5sZWZ0ICogYnBwOwogICAgICAgIHNFbnRyeSA9IGdldEZvcm1hdERlc2NFbnRyeShTcmMtPnJlc291cmNlLmZvcm1hdCwgTlVMTCwgTlVMTCk7CiAgICAgICAgZEVudHJ5ID0gc0VudHJ5OwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIHJldCA9IElXaW5lRDNEU3VyZmFjZV9Mb2NrUmVjdChTb3VyY2UsICZzbG9jaywgJmxvY2tfc3JjLCBXSU5FRDNETE9DS19SRUFET05MWSk7CiAgICAgICAgaWYocmV0ICE9IFdJTkVEM0RfT0spIGdvdG8gZXJyb3I7CiAgICAgICAgcmV0ID0gSVdpbmVEM0RTdXJmYWNlX0xvY2tSZWN0KGlmYWNlLCAmZGxvY2ssICZsb2NrX2RzdCwgMCk7CiAgICAgICAgaWYocmV0ICE9IFdJTkVEM0RfT0spIGdvdG8gZXJyb3I7CgogICAgICAgIHNidWYgPSBzbG9jay5wQml0czsKICAgICAgICBkYnVmID0gZGxvY2sucEJpdHM7CiAgICAgICAgVFJBQ0UoIkRzdCBpcyBhdCAlcCwgU3JjIGlzIGF0ICVwXG4iLCBkYnVmLCBzYnVmKTsKCiAgICAgICAgc0VudHJ5ID0gZ2V0Rm9ybWF0RGVzY0VudHJ5KFNyYy0+cmVzb3VyY2UuZm9ybWF0LCBOVUxMLCBOVUxMKTsKICAgICAgICBkRW50cnkgPSBnZXRGb3JtYXREZXNjRW50cnkoVGhpcy0+cmVzb3VyY2UuZm9ybWF0LCBOVUxMLCBOVUxMKTsKICAgIH0KCiAgICAvKiBIYW5kbGUgZmlyc3QgdGhlIEZPVVJDQyBzdXJmYWNlcy4uLiAqLwogICAgaWYgKHNFbnRyeS0+aXNGb3VyY2MgJiYgZEVudHJ5LT5pc0ZvdXJjYykKICAgIHsKICAgICAgICBUUkFDRSgiRm91cmNjIC0+IEZvdXJjYyBjb3B5XG4iKTsKICAgICAgICBpZiAodHJhbnMpCiAgICAgICAgICAgIEZJWE1FKCJ0cmFucyBhcmcgbm90IHN1cHBvcnRlZCB3aGVuIGEgRk9VUkNDIHN1cmZhY2UgaXMgaW52b2x2ZWRcbiIpOwogICAgICAgIGlmIChkc3R4IHx8IGRzdHkpCiAgICAgICAgICAgIEZJWE1FKCJvZmZzZXQgZm9yIGRlc3RpbmF0aW9uIHN1cmZhY2UgaXMgbm90IHN1cHBvcnRlZFxuIik7CiAgICAgICAgaWYgKFNyYy0+cmVzb3VyY2UuZm9ybWF0ICE9IFRoaXMtPnJlc291cmNlLmZvcm1hdCkKICAgICAgICB7CiAgICAgICAgICAgIEZJWE1FKCJGT1VSQ0MtPkZPVVJDQyBjb3B5IG9ubHkgc3VwcG9ydGVkIGZvciB0aGUgc2FtZSB0eXBlIG9mIHN1cmZhY2VcbiIpOwogICAgICAgICAgICByZXQgPSBXSU5FRDNERVJSX1dST05HVEVYVFVSRUZPUk1BVDsKICAgICAgICAgICAgZ290byBlcnJvcjsKICAgICAgICB9CiAgICAgICAgLyogRklYTUU6IFdhdGNoIG91dCB0aGF0IHRoZSBzaXplIGlzIGNvcnJlY3QgZm9yIEZPVVJDQyBzdXJmYWNlcyAqLwogICAgICAgIG1lbWNweShkYnVmLCBzYnVmLCBUaGlzLT5yZXNvdXJjZS5zaXplKTsKICAgICAgICBnb3RvIGVycm9yOwogICAgfQogICAgaWYgKHNFbnRyeS0+aXNGb3VyY2MgJiYgIWRFbnRyeS0+aXNGb3VyY2MpCiAgICB7CiAgICAgICAgLyogVE9ETzogVXNlIHRoZSBsaWJ0eGNfZHh0bi5zbyBzaGFyZWQgbGlicmFyeSB0byBkbwogICAgICAgICAqIHNvZnR3YXJlIGRlY29tcHJlc3Npb24KICAgICAgICAgKi8KICAgICAgICBFUlIoIkRYVEMgZGVjb21wcmVzc2lvbiBub3Qgc3VwcG9ydGVkIGJ5IG5vd1xuIik7CiAgICAgICAgZ290byBlcnJvcjsKICAgIH0KCiAgICBpZiAodHJhbnMgJiAoV0lORUREQkxURkFTVF9TUkNDT0xPUktFWSB8IFdJTkVEREJMVEZBU1RfREVTVENPTE9SS0VZKSkKICAgIHsKICAgICAgICBEV09SRCBrZXlsb3csIGtleWhpZ2g7CiAgICAgICAgVFJBQ0UoIkNvbG9yIGtleWVkIGNvcHlcbiIpOwogICAgICAgIGlmICh0cmFucyAmIFdJTkVEREJMVEZBU1RfU1JDQ09MT1JLRVkpCiAgICAgICAgewogICAgICAgICAgICBrZXlsb3cgID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICBrZXloaWdoID0gU3JjLT5TcmNCbHRDS2V5LmR3Q29sb3JTcGFjZUhpZ2hWYWx1ZTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgLyogSSdtIG5vdCBzdXJlIGlmIHRoaXMgaXMgY29ycmVjdCAqLwogICAgICAgICAgICBGSVhNRSgiV0lORUREQkxURkFTVF9ERVNUQ09MT1JLRVkgbm90IGZ1bGx5IHN1cHBvcnRlZCB5ZXQuXG4iKTsKICAgICAgICAgICAga2V5bG93ICA9IFRoaXMtPkRlc3RCbHRDS2V5LmR3Q29sb3JTcGFjZUxvd1ZhbHVlOwogICAgICAgICAgICBrZXloaWdoID0gVGhpcy0+RGVzdEJsdENLZXkuZHdDb2xvclNwYWNlSGlnaFZhbHVlOwogICAgICAgIH0KCiNkZWZpbmUgQ09QWUJPWF9DT0xPUktFWSh0eXBlKSB7IFwKICAgICAgICB0eXBlICpkLCAqcywgdG1wOyBcCiAgICAgICAgcyA9ICh0eXBlICopIHNidWY7IFwKICAgICAgICBkID0gKHR5cGUgKikgZGJ1ZjsgXAogICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspIHsgXAogICAgICAgIGZvciAoeCA9IDA7IHggPCB3OyB4KyspIHsgXAogICAgICAgIHRtcCA9IHNbeF07IFwKICAgICAgICBpZiAodG1wIDwga2V5bG93IHx8IHRtcCA+IGtleWhpZ2gpIGRbeF0gPSB0bXA7IFwKICAgIH0gXAogICAgICAgIHMgPSAodHlwZSAqKSgoQllURSAqKXMgKyBzbG9jay5QaXRjaCk7IFwKICAgICAgICBkID0gKHR5cGUgKikoKEJZVEUgKilkICsgZGxvY2suUGl0Y2gpOyBcCiAgICB9IFwKICAgICAgICBicmVhazsgXAogICAgfQoKICAgICAgICBzd2l0Y2ggKGJwcCkgewogICAgICAgICAgICBjYXNlIDE6IENPUFlCT1hfQ09MT1JLRVkoQllURSkKICAgICAgICAgICAgICAgICAgICBjYXNlIDI6IENPUFlCT1hfQ09MT1JLRVkoV09SRCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgNDogQ09QWUJPWF9DT0xPUktFWShEV09SRCkKICAgICAgICAgICAgY2FzZSAzOgogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBCWVRFICpkLCAqczsKICAgICAgICAgICAgICAgIERXT1JEIHRtcDsKICAgICAgICAgICAgICAgIHMgPSBzYnVmOwogICAgICAgICAgICAgICAgZCA9IGRidWY7CiAgICAgICAgICAgICAgICBmb3IgKHkgPSAwOyB5IDwgaDsgeSsrKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGZvciAoeCA9IDA7IHggPCB3ICogMzsgeCArPSAzKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgdG1wID0gKERXT1JEKXNbeF0gKyAoKERXT1JEKXNbeCArIDFdIDw8IDgpICsgKChEV09SRClzW3ggKyAyXSA8PCAxNik7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0bXAgPCBrZXlsb3cgfHwgdG1wID4ga2V5aGlnaCkKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZFt4ICsgMF0gPSBzW3ggKyAwXTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRbeCArIDFdID0gc1t4ICsgMV07CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkW3ggKyAyXSA9IHNbeCArIDJdOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIHMgKz0gc2xvY2suUGl0Y2g7CiAgICAgICAgICAgICAgICAgICAgZCArPSBkbG9jay5QaXRjaDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgICAgICBGSVhNRSgiU291cmNlIGNvbG9yIGtleSBibGl0dGluZyBub3Qgc3VwcG9ydGVkIGZvciBicHAgJWRcbiIsYnBwKjgpOwogICAgICAgICAgICAgICAgcmV0ID0gV0lORUQzREVSUl9OT1RBVkFJTEFCTEU7CiAgICAgICAgICAgICAgICBnb3RvIGVycm9yOwogICAgICAgIH0KI3VuZGVmIENPUFlCT1hfQ09MT1JLRVkKICAgICAgICBUUkFDRSgiQ29weSBEb25lXG4iKTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpbnQgd2lkdGggPSB3ICogYnBwOwogICAgICAgIElOVCBzYnVmcGl0Y2gsIGRidWZwaXRjaDsKCiAgICAgICAgVFJBQ0UoIk5PIGNvbG9yIGtleSBjb3B5XG4iKTsKICAgICAgICAvKiBIYW5kbGUgb3ZlcmxhcHBpbmcgc3VyZmFjZXMgKi8KICAgICAgICBpZiAoc2J1ZiA8IGRidWYpCiAgICAgICAgewogICAgICAgICAgICBzYnVmICs9IChoIC0gMSkgKiBzbG9jay5QaXRjaDsKICAgICAgICAgICAgZGJ1ZiArPSAoaCAtIDEpICogZGxvY2suUGl0Y2g7CiAgICAgICAgICAgIHNidWZwaXRjaCA9IC1zbG9jay5QaXRjaDsKICAgICAgICAgICAgZGJ1ZnBpdGNoID0gLWRsb2NrLlBpdGNoOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgewogICAgICAgICAgICBzYnVmcGl0Y2ggPSBzbG9jay5QaXRjaDsKICAgICAgICAgICAgZGJ1ZnBpdGNoID0gZGxvY2suUGl0Y2g7CiAgICAgICAgfQogICAgICAgIGZvciAoeSA9IDA7IHkgPCBoOyB5KyspCiAgICAgICAgewogICAgICAgICAgICAvKiBUaGlzIGlzIHByZXR0eSBlYXN5LCBhIGxpbmUgZm9yIGxpbmUgbWVtY3B5ICovCiAgICAgICAgICAgIG1lbW1vdmUoZGJ1Ziwgc2J1Ziwgd2lkdGgpOwogICAgICAgICAgICBzYnVmICs9IHNidWZwaXRjaDsKICAgICAgICAgICAgZGJ1ZiArPSBkYnVmcGl0Y2g7CiAgICAgICAgfQogICAgICAgIFRSQUNFKCJDb3B5IGRvbmVcbiIpOwogICAgfQoKZXJyb3I6CiAgICBpZiAoU3JjID09IFRoaXMpCiAgICB7CiAgICAgICAgSVdpbmVEM0RTdXJmYWNlX1VubG9ja1JlY3QoaWZhY2UpOwogICAgfQogICAgZWxzZQogICAgewogICAgICAgIElXaW5lRDNEU3VyZmFjZV9VbmxvY2tSZWN0KGlmYWNlKTsKICAgICAgICBJV2luZUQzRFN1cmZhY2VfVW5sb2NrUmVjdChTb3VyY2UpOwogICAgfQoKICAgIHJldHVybiByZXQ7Cn0KCkhSRVNVTFQgV0lOQVBJIElXaW5lRDNEQmFzZVN1cmZhY2VJbXBsX0xvY2tSZWN0KElXaW5lRDNEU3VyZmFjZSAqaWZhY2UsIFdJTkVEM0RMT0NLRURfUkVDVCogcExvY2tlZFJlY3QsIENPTlNUIFJFQ1QqIHBSZWN0LCBEV09SRCBGbGFncykKewogICAgSVdpbmVEM0RTdXJmYWNlSW1wbCAqVGhpcyA9IChJV2luZUQzRFN1cmZhY2VJbXBsICopaWZhY2U7CgogICAgVFJBQ0UoIiglcCkgOiByZWN0QCVwIGZsYWdzKCUwOHgpLCBvdXRwdXQgbG9ja2VkUmVjdEAlcCwgbWVtb3J5QCVwXG4iLAogICAgICAgICAgVGhpcywgcFJlY3QsIEZsYWdzLCBwTG9ja2VkUmVjdCwgVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5KTsKCiAgICBwTG9ja2VkUmVjdC0+UGl0Y2ggPSBJV2luZUQzRFN1cmZhY2VfR2V0UGl0Y2goaWZhY2UpOwoKICAgIGlmIChOVUxMID09IHBSZWN0KQogICAgewogICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeTsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IDA7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC50b3AgICAgPSAwOwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QucmlnaHQgID0gVGhpcy0+Y3VycmVudERlc2MuV2lkdGg7CiAgICAgICAgVGhpcy0+bG9ja2VkUmVjdC5ib3R0b20gPSBUaGlzLT5jdXJyZW50RGVzYy5IZWlnaHQ7CgogICAgICAgIFRSQUNFKCJMb2NrZWQgUmVjdCAoJXApID0gbCAlZCwgdCAlZCwgciAlZCwgYiAlZFxuIiwKICAgICAgICAgICAgICAmVGhpcy0+bG9ja2VkUmVjdCwgVGhpcy0+bG9ja2VkUmVjdC5sZWZ0LCBUaGlzLT5sb2NrZWRSZWN0LnRvcCwKICAgICAgICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0LCBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgVFJBQ0UoIkxvY2sgUmVjdCAoJXApID0gbCAlZCwgdCAlZCwgciAlZCwgYiAlZFxuIiwKICAgICAgICAgICAgICBwUmVjdCwgcFJlY3QtPmxlZnQsIHBSZWN0LT50b3AsIHBSZWN0LT5yaWdodCwgcFJlY3QtPmJvdHRvbSk7CgogICAgICAgIC8qIERYVG4gdGV4dHVyZXMgYXJlIGJhc2VkIG9uIGNvbXByZXNzZWQgYmxvY2tzIG9mIDR4NCBwaXhlbHMsIGVhY2gKICAgICAgICAgKiAxNiBieXRlcyBsYXJnZSAoOCBieXRlcyBpbiBjYXNlIG9mIERYVDEpLiBCZWNhdXNlIG9mIHRoYXQgUGl0Y2ggaGFzCiAgICAgICAgICogc2xpZ2h0bHkgZGlmZmVyZW50IG1lYW5pbmcgY29tcGFyZWQgdG8gcmVndWxhciB0ZXh0dXJlcy4gRm9yIERYVG4KICAgICAgICAgKiB0ZXh0dXJlcyBQaXRjaCBpcyB0aGUgc2l6ZSBvZiBhIHJvdyBvZiBibG9ja3MsIDQgaGlnaCBhbmQgIndpZHRoIgogICAgICAgICAqIGxvbmcuIFRoZSB4IG9mZnNldCBpcyBjYWxjdWxhdGVkIGRpZmZlcmVudGx5IGFzIHdlbGwsIHNpbmNlIG1vdmluZyA0CiAgICAgICAgICogcGl4ZWxzIHRvIHRoZSByaWdodCBhY3R1YWxseSBtb3ZlcyBhbiBlbnRpcmUgNHg0IGJsb2NrIHRvIHJpZ2h0LCBpZQogICAgICAgICAqIDE2IGJ5dGVzICg4IGluIGNhc2Ugb2YgRFhUMSkuICovCiAgICAgICAgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDEpCiAgICAgICAgewogICAgICAgICAgICBwTG9ja2VkUmVjdC0+cEJpdHMgPSBUaGlzLT5yZXNvdXJjZS5hbGxvY2F0ZWRNZW1vcnkgKyAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCAvIDQpICsgKHBSZWN0LT5sZWZ0ICogMik7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYgKFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDIgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUMyB8fAogICAgICAgICAgICAgICAgICAgIFRoaXMtPnJlc291cmNlLmZvcm1hdCA9PSBXSU5FRDNERk1UX0RYVDQgfHwgVGhpcy0+cmVzb3VyY2UuZm9ybWF0ID09IFdJTkVEM0RGTVRfRFhUNSkKICAgICAgICB7CiAgICAgICAgICAgIHBMb2NrZWRSZWN0LT5wQml0cyA9IFRoaXMtPnJlc291cmNlLmFsbG9jYXRlZE1lbW9yeSArIChwTG9ja2VkUmVjdC0+UGl0Y2ggKiBwUmVjdC0+dG9wIC8gNCkgKyAocFJlY3QtPmxlZnQgKiA0KTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcExvY2tlZFJlY3QtPnBCaXRzID0gVGhpcy0+cmVzb3VyY2UuYWxsb2NhdGVkTWVtb3J5ICsKICAgICAgICAgICAgICAgICAgICAocExvY2tlZFJlY3QtPlBpdGNoICogcFJlY3QtPnRvcCkgKwogICAgICAgICAgICAgICAgICAgIChwUmVjdC0+bGVmdCAqIFRoaXMtPmJ5dGVzUGVyUGl4ZWwpOwogICAgICAgIH0KICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmxlZnQgICA9IHBSZWN0LT5sZWZ0OwogICAgICAgIFRoaXMtPmxvY2tlZFJlY3QudG9wICAgID0gcFJlY3QtPnRvcDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LnJpZ2h0ICA9IHBSZWN0LT5yaWdodDsKICAgICAgICBUaGlzLT5sb2NrZWRSZWN0LmJvdHRvbSA9IHBSZWN0LT5ib3R0b207CiAgICB9CgogICAgLyogTm8gZGlydGlmeWluZyBpcyBuZWVkZWQgZm9yIHRoaXMgc3VyZmFjZSBpbXBsZW1lbnRhdGlvbiAqLwogICAgVFJBQ0UoInJldHVybmluZyBtZW1vcnlAJXAsIHBpdGNoKCVkKVxuIiwgcExvY2tlZFJlY3QtPnBCaXRzLCBwTG9ja2VkUmVjdC0+UGl0Y2gpOwoKICAgIHJldHVybiBXSU5FRDNEX09LOwp9Cgp2b2lkIFdJTkFQSSBJV2luZUQzREJhc2VTdXJmYWNlSW1wbF9CaW5kVGV4dHVyZShJV2luZUQzRFN1cmZhY2UgKmlmYWNlKSB7CiAgICBFUlIoIlNob3VsZCBub3QgYmUgY2FsbGVkIG9uIGJhc2UgdGV4dHVyZVxuIik7CiAgICByZXR1cm47Cn0K