LyoKICogU0hMV0FQSSBvcmRpbmFsIGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjdXMgTWVpc3NuZXIKICogICAgICAgICAgIDE5OTggSvxyZ2VuIFNjaG1pZWQKICogICAgICAgICAgIDIwMDEtMjAwMyBKb24gR3JpZmZpdGhzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNkZWZpbmUgQ09NX05PX1dJTkRPV1NfSAojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAiZG9jb2JqLmgiCiNpbmNsdWRlICJleGRpc3AuaCIKI2luY2x1ZGUgInNobGd1aWQuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAic2hsb2JqLmgiCiNpbmNsdWRlICJvbGVjdGwuaCIKI2luY2x1ZGUgInNoZWxsYXBpLmgiCiNpbmNsdWRlICJjb21tZGxnLmgiCiNpbmNsdWRlICJ3aW5lL3VuaWNvZGUuaCIKI2luY2x1ZGUgInNlcnZwcm92LmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgInNobHdhcGkuaCIKI2luY2x1ZGUgIndpbm50LmgiCgoKV0lORV9ERUZBVUxUX0RFQlVHX0NIQU5ORUwoc2hlbGwpOwoKLyogR2V0IGEgZnVuY3Rpb24gcG9pbnRlciBmcm9tIGEgRExMIGhhbmRsZSAqLwojZGVmaW5lIEdFVF9GVU5DKGZ1bmMsIG1vZHVsZSwgbmFtZSwgZmFpbCkgXAogIGRvIHsgXAogICAgaWYgKCFmdW5jKSB7IFwKICAgICAgaWYgKCFTSExXQVBJX2gjI21vZHVsZSAmJiAhKFNITFdBUElfaCMjbW9kdWxlID0gTG9hZExpYnJhcnlBKCNtb2R1bGUgIi5kbGwiKSkpIHJldHVybiBmYWlsOyBcCiAgICAgIGZ1bmMgPSAoZm4jI2Z1bmMpR2V0UHJvY0FkZHJlc3MoU0hMV0FQSV9oIyNtb2R1bGUsIG5hbWUpOyBcCiAgICAgIGlmICghZnVuYykgcmV0dXJuIGZhaWw7IFwKICAgIH0gXAogIH0gd2hpbGUgKDApCgovKiBETEwgaGFuZGxlcyBmb3IgbGF0ZSBib3VuZCBjYWxscyAqLwpleHRlcm4gSElOU1RBTkNFIHNobHdhcGlfaEluc3RhbmNlOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2hzaGVsbDMyOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2h3aW5tbTsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9oY29tZGxnMzI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaGNvbWN0bDMyOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2htcHI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaHVybG1vbjsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9odmVyc2lvbjsKCmV4dGVybiBEV09SRCBTSExXQVBJX1RocmVhZFJlZl9pbmRleDsKCi8qIGZvbGxvd2luZyBpcyBHVUlEIGZvciBJT2JqZWN0V2l0aFNpdGU6OlNldFNpdGUgIC0tIHNlZSBfMTc0ICAgICAgICAgICAqLwpzdGF0aWMgRFdPUkQgaWQxWzRdID0gezB4ZmM0ODAxYTMsIDB4MTFjZjJiYTksIDB4YWEwMDI5YTIsIDB4NTI3MzNkMDB9OwovKiBmb2xsb3dpbmcgaXMgR1VJRCBmb3IgSVBlcnNpc3RNb25pa2VyOjpHZXRDbGFzc0lEICAtLSBzZWUgXzE3NCAgICAgICAgKi8Kc3RhdGljIERXT1JEIGlkMls0XSA9IHsweDc5ZWFjOWVlLCAweDExY2ViYWY5LCAweGFhMDA4MjhjLCAweDBiYTk0YjAwfTsKCi8qIEZ1bmN0aW9uIHBvaW50ZXJzIGZvciBHRVRfRlVOQyBtYWNybzsgdGhlc2UgbmVlZCB0byBiZSBnbG9iYWwgYmVjYXVzZSBvZiBnY2MgYnVnICovCnR5cGVkZWYgTFBJVEVNSURMSVNUIChXSU5BUEkgKmZucFNIQnJvd3NlRm9yRm9sZGVyVykoTFBCUk9XU0VJTkZPVyk7CnN0YXRpYyAgZm5wU0hCcm93c2VGb3JGb2xkZXJXIHBTSEJyb3dzZUZvckZvbGRlclc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBQbGF5U291bmRXKShMUENXU1RSLCBITU9EVUxFLCBEV09SRCk7CnN0YXRpYyAgZm5wUGxheVNvdW5kVyBwUGxheVNvdW5kVzsKdHlwZWRlZiBEV09SRCAgIChXSU5BUEkgKmZucFNIR2V0RmlsZUluZm9XKShMUENXU1RSLERXT1JELFNIRklMRUlORk9XKixVSU5ULFVJTlQpOwpzdGF0aWMgIGZucFNIR2V0RmlsZUluZm9XIHBTSEdldEZpbGVJbmZvVzsKdHlwZWRlZiBVSU5UICAgIChXSU5BUEkgKmZucERyYWdRdWVyeUZpbGVXKShIRFJPUCwgVUlOVCwgTFBXU1RSLCBVSU5UKTsKc3RhdGljICBmbnBEcmFnUXVlcnlGaWxlVyBwRHJhZ1F1ZXJ5RmlsZVc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBTSEdldFBhdGhGcm9tSURMaXN0VykoTFBDSVRFTUlETElTVCwgTFBXU1RSKTsKc3RhdGljICBmbnBTSEdldFBhdGhGcm9tSURMaXN0VyBwU0hHZXRQYXRoRnJvbUlETGlzdFc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBTaGVsbEV4ZWN1dGVFeFcpKExQU0hFTExFWEVDVVRFSU5GT1cpOwpzdGF0aWMgIGZucFNoZWxsRXhlY3V0ZUV4VyBwU2hlbGxFeGVjdXRlRXhXOwp0eXBlZGVmIEhJQ09OICAgKFdJTkFQSSAqZm5wU0hGaWxlT3BlcmF0aW9uVykoTFBTSEZJTEVPUFNUUlVDVFcpOwpzdGF0aWMgIGZucFNIRmlsZU9wZXJhdGlvblcgcFNIRmlsZU9wZXJhdGlvblc7CnR5cGVkZWYgVUlOVCAgICAoV0lOQVBJICpmbnBFeHRyYWN0SWNvbkV4VykoTFBDV1NUUiwgSU5ULEhJQ09OICosSElDT04gKiwgVUlOVCk7CnN0YXRpYyAgZm5wRXh0cmFjdEljb25FeFcgcEV4dHJhY3RJY29uRXhXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wU0hHZXROZXdMaW5rSW5mb1cpKExQQ1dTVFIsIExQQ1dTVFIsIExQQ1dTVFIsIEJPT0wqLCBVSU5UKTsKc3RhdGljICBmbnBTSEdldE5ld0xpbmtJbmZvVyBwU0hHZXROZXdMaW5rSW5mb1c7CnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpmbnBTSERlZkV4dHJhY3RJY29uVykoTFBDV1NUUiwgaW50LCBVSU5ULCBISUNPTiosIEhJQ09OKiwgVUlOVCk7CnN0YXRpYyAgZm5wU0hEZWZFeHRyYWN0SWNvblcgcFNIRGVmRXh0cmFjdEljb25XOwp0eXBlZGVmIEhJQ09OICAgKFdJTkFQSSAqZm5wRXh0cmFjdEljb25XKShISU5TVEFOQ0UsIExQQ1dTVFIsIFVJTlQpOwpzdGF0aWMgIGZucEV4dHJhY3RJY29uVyBwRXh0cmFjdEljb25XOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wR2V0U2F2ZUZpbGVOYW1lVykoTFBPUEVORklMRU5BTUVXKTsKc3RhdGljICBmbnBHZXRTYXZlRmlsZU5hbWVXIHBHZXRTYXZlRmlsZU5hbWVXOwp0eXBlZGVmIERXT1JEICAgKFdJTkFQSSAqZm5wV05ldFJlc3RvcmVDb25uZWN0aW9uVykoSFdORCwgTFBXU1RSKTsKc3RhdGljICBmbnBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XIHBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XOwp0eXBlZGVmIERXT1JEICAgKFdJTkFQSSAqZm5wV05ldEdldExhc3RFcnJvclcpKExQRFdPUkQsIExQV1NUUiwgRFdPUkQsIExQV1NUUiwgRFdPUkQpOwpzdGF0aWMgIGZucFdOZXRHZXRMYXN0RXJyb3JXIHBXTmV0R2V0TGFzdEVycm9yVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFBhZ2VTZXR1cERsZ1cpKExQUEFHRVNFVFVQRExHVyk7CnN0YXRpYyAgZm5wUGFnZVNldHVwRGxnVyBwUGFnZVNldHVwRGxnVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFByaW50RGxnVykoTFBQUklOVERMR1cpOwpzdGF0aWMgIGZucFByaW50RGxnVyBwUHJpbnREbGdXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wR2V0T3BlbkZpbGVOYW1lVykoTFBPUEVORklMRU5BTUVXKTsKc3RhdGljICBmbnBHZXRPcGVuRmlsZU5hbWVXIHBHZXRPcGVuRmlsZU5hbWVXOwp0eXBlZGVmIERXT1JEICAgKFdJTkFQSSAqZm5wR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVcpKExQQ1dTVFIsTFBEV09SRCk7CnN0YXRpYyAgZm5wR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVcgcEdldEZpbGVWZXJzaW9uSW5mb1NpemVXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wR2V0RmlsZVZlcnNpb25JbmZvVykoTFBDV1NUUixEV09SRCxEV09SRCxMUFZPSUQpOwpzdGF0aWMgIGZucEdldEZpbGVWZXJzaW9uSW5mb1cgcEdldEZpbGVWZXJzaW9uSW5mb1c7CnR5cGVkZWYgV09SRCAgICAoV0lOQVBJICpmbnBWZXJRdWVyeVZhbHVlVykoTFBWT0lELExQQ1dTVFIsTFBWT0lEKixVSU5UKik7CnN0YXRpYyAgZm5wVmVyUXVlcnlWYWx1ZVcgcFZlclF1ZXJ5VmFsdWVXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wQ09NQ1RMMzJfNDE3KShIREMsSU5ULElOVCxVSU5ULGNvbnN0IFJFQ1QqLExQQ1dTVFIsVUlOVCxjb25zdCBJTlQqKTsKc3RhdGljICBmbnBDT01DVEwzMl80MTcgcENPTUNUTDMyXzQxNzsKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKmZucERsbEdldFZlcnNpb24pKERMTFZFUlNJT05JTkZPKik7CnN0YXRpYyAgZm5wRGxsR2V0VmVyc2lvbiBwRGxsR2V0VmVyc2lvbjsKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKmZucENyZWF0ZUZvcm1hdEVudW1lcmF0b3IpKFVJTlQsRk9STUFURVRDKixJRW51bUZPUk1BVEVUQyoqKTsKc3RhdGljIGZucENyZWF0ZUZvcm1hdEVudW1lcmF0b3IgcENyZWF0ZUZvcm1hdEVudW1lcmF0b3I7CnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpmbnBSZWdpc3RlckZvcm1hdEVudW1lcmF0b3IpKExQQkMsSUVudW1GT1JNQVRFVEMqLERXT1JEKTsKc3RhdGljIGZucFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvciBwUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yOwoKSFJFU1VMVCBXSU5BUEkgSVVua25vd25fUXVlcnlTZXJ2aWNlKElVbmtub3duKixSRUZHVUlELFJFRklJRCxMUFZPSUQqKTsKSFJFU1VMVCBXSU5BUEkgU0hJbnZva2VDb21tYW5kKEhXTkQsSVNoZWxsRm9sZGVyKixMUENJVEVNSURMSVNULEJPT0wpOwpIUkVTVUxUIFdJTkFQSSBDTFNJREZyb21TdHJpbmdXcmFwKExQQ1dTVFIsQ0xTSUQqKTsKQk9PTCAgICBXSU5BUEkgU0hBYm91dEluZm9XKExQV1NUUixEV09SRCk7CgovKgogTk9URVM6IE1vc3QgZnVuY3Rpb25zIGV4cG9ydGVkIGJ5IG9yZGluYWwgc2VlbSB0byBiZSBzdXBlcmZsb3VzLgogVGhlIHJlYXNvbiBmb3IgdGhlc2UgZnVuY3Rpb25zIHRvIGJlIHRoZXJlIGlzIHRvIHByb3ZpZGUgYSB3cmFwcGVyCiBmb3IgdW5pY29kZSBmdW5jdGlvbnMgdG8gcHJvdmlkZSB0aGVzZSBmdW5jdGlvbnMgb24gc3lzdGVtcyB3aXRob3V0CiB1bmljb2RlIGZ1bmN0aW9ucyBlZy4gd2luOTUvd2luOTguIFNpbmNlIHdlIGhhdmUgc3VjaCBmdW5jdGlvbnMgd2UganVzdAogY2FsbCB0aGVzZS4gSWYgcnVubmluZyBXaW5lIHdpdGggbmF0aXZlIERMTCdzLCBzb21lIGxhdGUgYm91bmQgY2FsbHMgbWF5CiBmYWlsLiBIb3dldmVyLCBpdCBpcyBiZXR0ZXIgdG8gaW1wbGVtZW50IHRoZSBmdW5jdGlvbnMgaW4gdGhlIGZvcndhcmQgRExMCiBhbmQgcmVjb21tZW5kIHRoZSBidWlsdGluIHJhdGhlciB0aGFuIHJlaW1wbGVtZW50aW5nIHRoZSBjYWxscyBoZXJlIQoqLwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUKICoKICogSW50ZXJuYWwgaW1wbGVtZXRhdGlvbiBvZiBTSExXQVBJXzExLgogKi8Kc3RhdGljCkhBTkRMRSBXSU5BUEkgU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3RHN0UHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1NyY1Byb2NJZCwgRFdPUkQgZHdBY2Nlc3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3T3B0aW9ucykKewogIEhBTkRMRSBoRHN0LCBoU3JjOwogIERXT1JEIGR3TXlQcm9jSWQgPSBHZXRDdXJyZW50UHJvY2Vzc0lkKCk7CiAgSEFORExFIGhSZXQgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQsJTA4bHgsJTA4bHgpXG4iLCBoU2hhcmVkLCBkd0RzdFByb2NJZCwgZHdTcmNQcm9jSWQsCiAgICAgICAgZHdBY2Nlc3MsIGR3T3B0aW9ucyk7CgogIC8qIEdldCBkZXN0IHByb2Nlc3MgaGFuZGxlICovCiAgaWYgKGR3RHN0UHJvY0lkID09IGR3TXlQcm9jSWQpCiAgICBoRHN0ID0gR2V0Q3VycmVudFByb2Nlc3MoKTsKICBlbHNlCiAgICBoRHN0ID0gT3BlblByb2Nlc3MoUFJPQ0VTU19EVVBfSEFORExFLCAwLCBkd0RzdFByb2NJZCk7CgogIGlmIChoRHN0KQogIHsKICAgIC8qIEdldCBzcmMgcHJvY2VzcyBoYW5kbGUgKi8KICAgIGlmIChkd1NyY1Byb2NJZCA9PSBkd015UHJvY0lkKQogICAgICBoU3JjID0gR2V0Q3VycmVudFByb2Nlc3MoKTsKICAgIGVsc2UKICAgICAgaFNyYyA9IE9wZW5Qcm9jZXNzKFBST0NFU1NfRFVQX0hBTkRMRSwgMCwgZHdTcmNQcm9jSWQpOwoKICAgIGlmIChoU3JjKQogICAgewogICAgICAvKiBNYWtlIGhhbmRsZSBhdmFpbGFibGUgdG8gZGVzdCBwcm9jZXNzICovCiAgICAgIGlmICghRHVwbGljYXRlSGFuZGxlKGhEc3QsIGhTaGFyZWQsIGhTcmMsICZoUmV0LAogICAgICAgICAgICAgICAgICAgICAgICAgICBkd0FjY2VzcywgMCwgZHdPcHRpb25zIHwgRFVQTElDQVRFX1NBTUVfQUNDRVNTKSkKICAgICAgICBoUmV0ID0gTlVMTDsKCiAgICAgIGlmIChkd1NyY1Byb2NJZCAhPSBkd015UHJvY0lkKQogICAgICAgIENsb3NlSGFuZGxlKGhTcmMpOwogICAgfQoKICAgIGlmIChkd0RzdFByb2NJZCAhPSBkd015UHJvY0lkKQogICAgICBDbG9zZUhhbmRsZShoRHN0KTsKICB9CgogIFRSQUNFKCJSZXR1cm5pbmcgaGFuZGxlICVwXG4iLCBoUmV0KTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgW1NITFdBUEkuN10KICoKICogQ3JlYXRlIGEgYmxvY2sgb2Ygc2hhcmFibGUgbWVtb3J5IGFuZCBpbml0aWFsaXNlIGl0IHdpdGggZGF0YS4KICoKICogUEFSQU1TCiAqIGxwdkRhdGEgIFtJXSBQb2ludGVyIHRvIGRhdGEgdG8gd3JpdGUKICogZHdTaXplICAgW0ldIFNpemUgb2YgZGF0YQogKiBkd1Byb2NJZCBbSV0gSUQgb2YgcHJvY2VzcyBvd25pbmcgZGF0YQogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IEEgc2hhcmVkIG1lbW9yeSBoYW5kbGUKICogRmFpbHVyZTogTlVMTAogKgogKiBOT1RFUwogKiBPcmRpbmFscyA3LTExIHByb3ZpZGUgYSBzZXQgb2YgY2FsbHMgdG8gY3JlYXRlIHNoYXJlZCBtZW1vcnkgYmV0d2VlbiBhCiAqIGdyb3VwIG9mIHByb2Nlc3Nlcy4gVGhlIHNoYXJlZCBtZW1vcnkgaXMgdHJlYXRlZCBvcGFxdWVseSBpbiB0aGF0IGl0cyBzaXplCiAqIGlzIG5vdCBleHBvc2VkIHRvIGNsaWVudHMgd2hvIG1hcCBpdC4gVGhpcyBpcyBhY2NvbXBsaXNoZWQgYnkgc3RvcmluZwogKiB0aGUgc2l6ZSBvZiB0aGUgbWFwIGFzIHRoZSBmaXJzdCBEV09SRCBvZiBtYXBwZWQgZGF0YSwgYW5kIHRoZW4gb2Zmc2V0dGluZwogKiB0aGUgdmlldyBwb2ludGVyIHJldHVybmVkIGJ5IHRoaXMgc2l6ZS4KICoKICovCkhBTkRMRSBXSU5BUEkgU0hBbGxvY1NoYXJlZChMUENWT0lEIGxwdkRhdGEsIERXT1JEIGR3U2l6ZSwgRFdPUkQgZHdQcm9jSWQpCnsKICBIQU5ETEUgaE1hcDsKICBMUFZPSUQgcE1hcHBlZDsKICBIQU5ETEUgaFJldCA9IE5VTEw7CgogIFRSQUNFKCIoJXAsJWxkLCVsZClcbiIsIGxwdkRhdGEsIGR3U2l6ZSwgZHdQcm9jSWQpOwoKICAvKiBDcmVhdGUgZmlsZSBtYXBwaW5nIG9mIHRoZSBjb3JyZWN0IGxlbmd0aCAqLwogIGhNYXAgPSBDcmVhdGVGaWxlTWFwcGluZ0EoSU5WQUxJRF9IQU5ETEVfVkFMVUUsIE5VTEwsIEZJTEVfTUFQX1JFQUQsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd1NpemUgKyBzaXplb2YoZHdTaXplKSwgTlVMTCk7CiAgaWYgKCFoTWFwKQogICAgcmV0dXJuIGhSZXQ7CgogIC8qIEdldCBhIHZpZXcgaW4gb3VyIHByb2Nlc3MgYWRkcmVzcyBzcGFjZSAqLwogIHBNYXBwZWQgPSBNYXBWaWV3T2ZGaWxlKGhNYXAsIEZJTEVfTUFQX1JFQUQgfCBGSUxFX01BUF9XUklURSwgMCwgMCwgMCk7CgogIGlmIChwTWFwcGVkKQogIHsKICAgIC8qIFdyaXRlIHNpemUgb2YgZGF0YSwgZm9sbG93ZWQgYnkgdGhlIGRhdGEsIHRvIHRoZSB2aWV3ICovCiAgICAqKChEV09SRCopcE1hcHBlZCkgPSBkd1NpemU7CiAgICBpZiAobHB2RGF0YSkKICAgICAgbWVtY3B5KChjaGFyICopIHBNYXBwZWQgKyBzaXplb2YoZHdTaXplKSwgbHB2RGF0YSwgZHdTaXplKTsKCiAgICAvKiBSZWxlYXNlIHZpZXcuIEFsbCBmdXJ0aGVyIHZpZXdzIG1hcHBlZCB3aWxsIGJlIG9wYXF1ZSAqLwogICAgVW5tYXBWaWV3T2ZGaWxlKHBNYXBwZWQpOwogICAgaFJldCA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhNYXAsIGR3UHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwgRklMRV9NQVBfQUxMX0FDQ0VTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEVVBMSUNBVEVfU0FNRV9BQ0NFU1MpOwogIH0KCiAgQ2xvc2VIYW5kbGUoaE1hcCk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuOF0KICoKICogR2V0IGEgcG9pbnRlciB0byBhIGJsb2NrIG9mIHNoYXJlZCBtZW1vcnkgZnJvbSBhIHNoYXJlZCBtZW1vcnkgaGFuZGxlLgogKgogKiBQQVJBTVMKICogaFNoYXJlZCAgW0ldIFNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIGR3UHJvY0lkIFtJXSBJRCBvZiBwcm9jZXNzIG93bmluZyBoU2hhcmVkCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogQSBwb2ludGVyIHRvIHRoZSBzaGFyZWQgbWVtb3J5CiAqIEZhaWx1cmU6IE5VTEwKICoKICovClBWT0lEIFdJTkFQSSBTSExvY2tTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhEdXA7CiAgTFBWT0lEIHBNYXBwZWQ7CgogIFRSQUNFKCIoJXAgJWxkKVxuIiwgaFNoYXJlZCwgZHdQcm9jSWQpOwoKICAvKiBHZXQgaGFuZGxlIHRvIHNoYXJlZCBtZW1vcnkgZm9yIGN1cnJlbnQgcHJvY2VzcyAqLwogIGhEdXAgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoU2hhcmVkLCBkd1Byb2NJZCwgR2V0Q3VycmVudFByb2Nlc3NJZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBGSUxFX01BUF9BTExfQUNDRVNTLCAwKTsKICAvKiBHZXQgVmlldyAqLwogIHBNYXBwZWQgPSBNYXBWaWV3T2ZGaWxlKGhEdXAsIEZJTEVfTUFQX1JFQUQgfCBGSUxFX01BUF9XUklURSwgMCwgMCwgMCk7CiAgQ2xvc2VIYW5kbGUoaER1cCk7CgogIGlmIChwTWFwcGVkKQogICAgcmV0dXJuIChjaGFyICopIHBNYXBwZWQgKyBzaXplb2YoRFdPUkQpOyAvKiBIaWRlIHNpemUgKi8KICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCBbU0hMV0FQSS45XQogKgogKiBSZWxlYXNlIGEgcG9pbnRlciB0byBhIGJsb2NrIG9mIHNoYXJlZCBtZW1vcnkuCiAqCiAqIFBBUkFNUwogKiBscFZpZXcgW0ldIFNoYXJlZCBtZW1vcnkgcG9pbnRlcgogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IFRSVUUKICogRmFpbHVyZTogRkFMU0UKICoKICovCkJPT0wgV0lOQVBJIFNIVW5sb2NrU2hhcmVkKExQVk9JRCBscFZpZXcpCnsKICBUUkFDRSgiKCVwKVxuIiwgbHBWaWV3KTsKICByZXR1cm4gVW5tYXBWaWV3T2ZGaWxlKChjaGFyICopIGxwVmlldyAtIHNpemVvZihEV09SRCkpOyAvKiBJbmNsdWRlIHNpemUgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCBbU0hMV0FQSS4xMF0KICoKICogRGVzdHJveSBhIGJsb2NrIG9mIHNoYXJhYmxlIG1lbW9yeS4KICoKICogUEFSQU1TCiAqIGhTaGFyZWQgIFtJXSBTaGFyZWQgbWVtb3J5IGhhbmRsZQogKiBkd1Byb2NJZCBbSV0gSUQgb2YgcHJvY2VzcyBvd25pbmcgaFNoYXJlZAogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IFRSVUUKICogRmFpbHVyZTogRkFMU0UKICoKICovCkJPT0wgV0lOQVBJIFNIRnJlZVNoYXJlZChIQU5ETEUgaFNoYXJlZCwgRFdPUkQgZHdQcm9jSWQpCnsKICBIQU5ETEUgaENsb3NlOwoKICBUUkFDRSgiKCVwICVsZClcbiIsIGhTaGFyZWQsIGR3UHJvY0lkKTsKCiAgLyogR2V0IGEgY29weSBvZiB0aGUgaGFuZGxlIGZvciBvdXIgcHJvY2VzcywgY2xvc2luZyB0aGUgc291cmNlIGhhbmRsZSAqLwogIGhDbG9zZSA9IFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKGhTaGFyZWQsIGR3UHJvY0lkLCBHZXRDdXJyZW50UHJvY2Vzc0lkKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9NQVBfQUxMX0FDQ0VTUyxEVVBMSUNBVEVfQ0xPU0VfU09VUkNFKTsKICAvKiBDbG9zZSBsb2NhbCBjb3B5ICovCiAgcmV0dXJuIENsb3NlSGFuZGxlKGhDbG9zZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICBbU0hMV0FQSS4xMV0KICoKICogQ29weSBhIHNoYXJhYmxlIG1lbW9yeSBoYW5kbGUgZnJvbSBvbmUgcHJvY2VzcyB0byBhbm90aGVyLgogKgogKiBQQVJBTVMKICogaFNoYXJlZCAgICAgW0ldIFNoYXJlZCBtZW1vcnkgaGFuZGxlIHRvIGR1cGxpY2F0ZQogKiBkd0RzdFByb2NJZCBbSV0gSUQgb2YgdGhlIHByb2Nlc3Mgd2FudGluZyB0aGUgZHVwbGljYXRlZCBoYW5kbGUKICogZHdTcmNQcm9jSWQgW0ldIElEIG9mIHRoZSBwcm9jZXNzIG93bmluZyBoU2hhcmVkCiAqIGR3QWNjZXNzICAgIFtJXSBEZXNpcmVkIER1cGxpY2F0ZUhhbmRsZSgpIGFjY2VzcwogKiBkd09wdGlvbnMgICBbSV0gRGVzaXJlZCBEdXBsaWNhdGVIYW5kbGUoKSBvcHRpb25zCiAqCiAqIFJFVFVSTlMKICogU3VjY2VzczogQSBoYW5kbGUgc3VpdGFibGUgZm9yIHVzZSBieSB0aGUgZHdEc3RQcm9jSWQgcHJvY2Vzcy4KICogRmFpbHVyZTogQSBOVUxMIGhhbmRsZS4KICoKICovCkhBTkRMRSBXSU5BUEkgU0hNYXBIYW5kbGUoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3RHN0UHJvY0lkLCBEV09SRCBkd1NyY1Byb2NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd0FjY2VzcywgRFdPUkQgZHdPcHRpb25zKQp7CiAgSEFORExFIGhSZXQ7CgogIGhSZXQgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoU2hhcmVkLCBkd0RzdFByb2NJZCwgZHdTcmNQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTNdCiAqCiAqIENyZWF0ZSBhbmQgcmVnaXN0ZXIgYSBjbGlwYm9hcmQgZW51bWVyYXRvciBmb3IgYSB3ZWIgYnJvd3Nlci4KICoKICogUEFSQU1TCiAqICBscEJDICAgICAgW0ldIEJpbmRpbmcgY29udGV4dAogKiAgbHBVbmtub3duIFtJXSBBbiBvYmplY3QgZXhwb3NpbmcgdGhlIElXZWJCcm93c2VyQXBwIGludGVyZmFjZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgVGhlIGVudW1lcmF0b3IgaXMgc3RvcmVkIGFzIGEgcHJvcGVydHkgb2YgdGhlIHdlYiBicm93c2VyLiBJZiBpdCBkb2VzIG5vdAogKiAgeWV0IGV4aXN0LCBpdCBpcyBjcmVhdGVkIGFuZCBzZXQgYmVmb3JlIGJlaW5nIHJlZ2lzdGVyZWQuCiAqLwpIUkVTVUxUIFdJTkFQSSBSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzKExQQkMgbHBCQywgSVVua25vd24gKmxwVW5rbm93bikKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelByb3BlcnR5W10gPSB7ICd7JywnRCcsJzAnLCdGJywnQycsJ0EnLCc0JywnMicsJzAnLAogICAgICAnLScsJ0QnLCczJywnRicsJzUnLCctJywnMScsJzEnLCdDJywnRicsICctJywnQicsJzInLCcxJywnMScsJy0nLCcwJywKICAgICAgJzAnLCdBJywnQScsJzAnLCcwJywnNCcsJ0EnLCdFJywnOCcsJzMnLCc3JywnfScsJ1wwJyB9OwogIElFbnVtRk9STUFURVRDKiBwSUVudW1Gb3JtYXRFdGMgPSBOVUxMOwogIFZBUklBTlRBUkcgdmFyOwogIEhSRVNVTFQgaFJldDsKICBJV2ViQnJvd3NlckFwcCogcEJyb3dzZXIgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCAlcClcbiIsIGxwQkMsIGxwVW5rbm93bik7CgogIC8qIEdldCBBbiBJV2ViQnJvd3NlckFwcCBpbnRlcmZhY2UgZnJvbSAgbHBVbmtub3duICovCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5U2VydmljZShscFVua25vd24sICZJSURfSVdlYkJyb3dzZXJBcHAsICZJSURfSVdlYkJyb3dzZXJBcHAsIChQVk9JRCkmcEJyb3dzZXIpOwogIGlmIChGQUlMRUQoaFJldCkgfHwgIXBCcm93c2VyKQogICAgcmV0dXJuIEVfTk9JTlRFUkZBQ0U7CgogIFZfVlQoJnZhcikgPSBWVF9FTVBUWTsKCiAgLyogVGhlIHByb3BlcnR5IHdlIGdldCBpcyB0aGUgYnJvd3NlcnMgY2xpcGJvYXJkIGVudW1lcmF0b3IgKi8KICBoUmV0ID0gSVdlYkJyb3dzZXJBcHBfR2V0UHJvcGVydHkocEJyb3dzZXIsIChCU1RSKXN6UHJvcGVydHksICZ2YXIpOwogIGlmIChGQUlMRUQoaFJldCkpCiAgICByZXR1cm4gaFJldDsKCiAgaWYgKFZfVlQoJnZhcikgPT0gVlRfRU1QVFkpCiAgewogICAgLyogSXRlcmF0ZSB0aHJvdWdoIGFjY2VwdGVkIGRvY3VtZW50cyBhbmQgUmVnaXN0ZXJDbGlwQm9hcmRGb3JtYXRBKCkgdGhlbSAqLwogICAgY2hhciBzektleUJ1ZmZbMTI4XSwgc3pWYWx1ZUJ1ZmZbMTI4XTsKICAgIERXT1JEIGR3S2V5U2l6ZSwgZHdWYWx1ZVNpemUsIGR3UmV0ID0gMCwgZHdDb3VudCA9IDAsIGR3TnVtVmFsdWVzLCBkd1R5cGU7CiAgICBGT1JNQVRFVEMqIGZvcm1hdExpc3QsICpmb3JtYXQ7CiAgICBIS0VZIGhEb2NzOwoKICAgIFRSQUNFKCJSZWdpc3RlcmluZyBmb3JtYXRzIGFuZCBjcmVhdGluZyBJRW51bUZPUk1BVEVUQyBpbnN0YW5jZVxuIik7CgogICAgaWYgKCFSZWdPcGVuS2V5QShIS0VZX0xPQ0FMX01BQ0hJTkUsICJTb2Z0d2FyZVxcTWljcm9zb2Z0XFxXaW5kb3dzXFxDdXJyZW50IgogICAgICAgICAgICAgICAgICAgICAiVmVyc2lvblxcSW50ZXJuZXQgU2V0dGluZ3NcXEFjY2VwdGVkIERvY3VtZW50cyIsICZoRG9jcykpCiAgICAgIHJldHVybiBFX0ZBSUw7CgogICAgLyogR2V0IGNvdW50IG9mIHZhbHVlcyBpbiBrZXkgKi8KICAgIHdoaWxlICghZHdSZXQpCiAgICB7CiAgICAgIGR3S2V5U2l6ZSA9IHNpemVvZihzektleUJ1ZmYpOwogICAgICBkd1JldCA9IFJlZ0VudW1WYWx1ZUEoaERvY3MsZHdDb3VudCxzektleUJ1ZmYsJmR3S2V5U2l6ZSwwLCZkd1R5cGUsMCwwKTsKICAgICAgZHdDb3VudCsrOwogICAgfQoKICAgIGR3TnVtVmFsdWVzID0gZHdDb3VudDsKCiAgICAvKiBOb3RlOiBkd0NvdW50ID0gbnVtYmVyIG9mIGl0ZW1zICsgMTsgVGhlIGV4dHJhIGl0ZW0gaXMgdGhlIGVuZCBub2RlICovCiAgICBmb3JtYXQgPSBmb3JtYXRMaXN0ID0gSGVhcEFsbG9jKEdldFByb2Nlc3NIZWFwKCksIDAsIGR3Q291bnQgKiBzaXplb2YoRk9STUFURVRDKSk7CiAgICBpZiAoIWZvcm1hdExpc3QpCiAgICAgIHJldHVybiBFX09VVE9GTUVNT1JZOwoKICAgIGlmIChkd051bVZhbHVlcyA+IDEpCiAgICB7CiAgICAgIGR3UmV0ID0gMDsKICAgICAgZHdDb3VudCA9IDA7CgogICAgICBkd051bVZhbHVlcy0tOwoKICAgICAgLyogUmVnaXN0ZXIgY2xpcGJvYXJkIGZvcm1hdHMgZm9yIHRoZSB2YWx1ZXMgYW5kIHBvcHVsYXRlIGZvcm1hdCBsaXN0ICovCiAgICAgIHdoaWxlKCFkd1JldCAmJiBkd0NvdW50IDwgZHdOdW1WYWx1ZXMpCiAgICAgIHsKICAgICAgICBkd0tleVNpemUgPSBzaXplb2Yoc3pLZXlCdWZmKTsKICAgICAgICBkd1ZhbHVlU2l6ZSA9IHNpemVvZihzelZhbHVlQnVmZik7CiAgICAgICAgZHdSZXQgPSBSZWdFbnVtVmFsdWVBKGhEb2NzLCBkd0NvdW50LCBzektleUJ1ZmYsICZkd0tleVNpemUsIDAsICZkd1R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQQllURSlzelZhbHVlQnVmZiwgJmR3VmFsdWVTaXplKTsKICAgICAgICBpZiAoIWR3UmV0KQogICAgICAgICAgcmV0dXJuIEVfRkFJTDsKCiAgICAgICAgZm9ybWF0LT5jZkZvcm1hdCA9IFJlZ2lzdGVyQ2xpcGJvYXJkRm9ybWF0QShzelZhbHVlQnVmZik7CiAgICAgICAgZm9ybWF0LT5wdGQgPSBOVUxMOwogICAgICAgIGZvcm1hdC0+ZHdBc3BlY3QgPSAxOwogICAgICAgIGZvcm1hdC0+bGluZGV4ID0gNDsKICAgICAgICBmb3JtYXQtPnR5bWVkID0gLTE7CgogICAgICAgIGZvcm1hdCsrOwogICAgICAgIGR3Q291bnQrKzsKICAgICAgfQogICAgfQoKICAgIC8qIFRlcm1pbmF0ZSB0aGUgKG1heWJlIGVtcHR5KSBsaXN0LCBsYXN0IGVudHJ5IGhhcyBhIGNmRm9ybWF0IG9mIDAgKi8KICAgIGZvcm1hdC0+Y2ZGb3JtYXQgPSAwOwogICAgZm9ybWF0LT5wdGQgPSBOVUxMOwogICAgZm9ybWF0LT5kd0FzcGVjdCA9IDE7CiAgICBmb3JtYXQtPmxpbmRleCA9IDQ7CiAgICBmb3JtYXQtPnR5bWVkID0gLTE7CgogICAgLyogQ3JlYXRlIGEgY2xpcGJvYXJkIGVudW1lcmF0b3IgKi8KICAgIEdFVF9GVU5DKHBDcmVhdGVGb3JtYXRFbnVtZXJhdG9yLCB1cmxtb24sICJDcmVhdGVGb3JtYXRFbnVtZXJhdG9yIiwgRV9GQUlMKTsKICAgIGhSZXQgPSBwQ3JlYXRlRm9ybWF0RW51bWVyYXRvcihkd051bVZhbHVlcywgZm9ybWF0TGlzdCwgJnBJRW51bUZvcm1hdEV0Yyk7CgogICAgaWYgKEZBSUxFRChoUmV0KSB8fCAhcElFbnVtRm9ybWF0RXRjKQogICAgICByZXR1cm4gaFJldDsKCiAgICAvKiBTZXQgb3VyIGVudW1lcmF0b3IgYXMgdGhlIGJyb3dzZXJzIHByb3BlcnR5ICovCiAgICBWX1ZUKCZ2YXIpID0gVlRfVU5LTk9XTjsKICAgIFZfVU5LTk9XTigmdmFyKSA9IChJVW5rbm93biopcElFbnVtRm9ybWF0RXRjOwoKICAgIGhSZXQgPSBJV2ViQnJvd3NlckFwcF9QdXRQcm9wZXJ0eShwQnJvd3NlciwgKEJTVFIpc3pQcm9wZXJ0eSwgdmFyKTsKICAgIGlmIChGQUlMRUQoaFJldCkpCiAgICB7CiAgICAgICBJRW51bUZPUk1BVEVUQ19SZWxlYXNlKHBJRW51bUZvcm1hdEV0Yyk7CiAgICAgICBnb3RvIFJlZ2lzdGVyRGVmYXVsdEFjY2VwdEhlYWRlcnNfRXhpdDsKICAgIH0KICB9CgogIGlmIChWX1ZUKCZ2YXIpID09IFZUX1VOS05PV04pCiAgewogICAgLyogT3VyIHZhcmlhbnQgaXMgaG9sZGluZyB0aGUgY2xpcGJvYXJkIGVudW1lcmF0b3IgKi8KICAgIElVbmtub3duKiBwSVVua25vd24gPSBWX1VOS05PV04oJnZhcik7CiAgICBJRW51bUZPUk1BVEVUQyogcENsb25lID0gTlVMTDsKCiAgICBUUkFDRSgiUmV0cmlldmVkIElFbnVtRk9STUFURVRDIHByb3BlcnR5XG4iKTsKCiAgICAvKiBHZXQgYW4gSUVudW1Gb3JtYXRFdGMgaW50ZXJmYWNlIGZyb20gdGhlIHZhcmlhbnRzIHZhbHVlICovCiAgICBwSUVudW1Gb3JtYXRFdGMgPSBOVUxMOwogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBJVW5rbm93biwgJklJRF9JRW51bUZPUk1BVEVUQywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUFZPSUQpJnBJRW51bUZvcm1hdEV0Yyk7CiAgICBpZiAoIWhSZXQgJiYgcElFbnVtRm9ybWF0RXRjKQogICAgewogICAgICAvKiBDbG9uZSBhbmQgcmVnaXN0ZXIgdGhlIGVudW1lcmF0b3IgKi8KICAgICAgaFJldCA9IElFbnVtRk9STUFURVRDX0Nsb25lKHBJRW51bUZvcm1hdEV0YywgJnBDbG9uZSk7CiAgICAgIGlmICghaFJldCAmJiBwQ2xvbmUpCiAgICAgIHsKICAgICAgICBHRVRfRlVOQyhwUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yLCB1cmxtb24sICJSZWdpc3RlckZvcm1hdEVudW1lcmF0b3IiLCBFX0ZBSUwpOwogICAgICAgIHBSZWdpc3RlckZvcm1hdEVudW1lcmF0b3IobHBCQywgcENsb25lLCAwKTsKCiAgICAgICAgSUVudW1GT1JNQVRFVENfUmVsZWFzZShwQ2xvbmUpOwogICAgICB9CgogICAgICAvKiBSZWxlYXNlIHRoZSBJRW51bUZvcm1hdEV0YyBpbnRlcmZhY2UgKi8KICAgICAgSUVudW1GT1JNQVRFVENfUmVsZWFzZShwSVVua25vd24pOwogICAgfQogICAgSVVua25vd25fUmVsZWFzZShWX1VOS05PV04oJnZhcikpOwogIH0KClJlZ2lzdGVyRGVmYXVsdEFjY2VwdEhlYWRlcnNfRXhpdDoKICBJV2ViQnJvd3NlckFwcF9SZWxlYXNlKHBCcm93c2VyKTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1XQogKgogKiBHZXQgRXhwbG9yZXJzICJBY2NlcHRMYW5ndWFnZSIgc2V0dGluZy4KICoKICogUEFSQU1TCiAqICBsYW5nYnVmIFtPXSBEZXN0aW5hdGlvbiBmb3IgbGFuZ3VhZ2Ugc3RyaW5nCiAqICBidWZsZW4gIFtJXSBMZW5ndGggb2YgbGFuZ2J1ZgogKiAgICAgICAgICBbMF0gU3VjY2VzczogdXNlZCBsZW5ndGggb2YgbGFuZ2J1ZgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiAgIGxhbmdidWYgaXMgc2V0IHRvIHRoZSBsYW5ndWFnZSBzdHJpbmcgZm91bmQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIElmIGFueSBhcmd1bWVudHMgYXJlIGludmFsaWQsIGVycm9yIG9jY3VycmVkLCBvciBFeHBsb3JlcgogKiAgICAgICAgICAgZG9lcyBub3QgY29udGFpbiB0aGUgc2V0dGluZy4KICogICAgICAgICAgIEVfSU5WQUxJREFSRywgSWYgdGhlIGJ1ZmZlciBpcyBub3QgYmlnIGVub3VnaAogKi8KSFJFU1VMVCBXSU5BUEkgR2V0QWNjZXB0TGFuZ3VhZ2VzVyggTFBXU1RSIGxhbmdidWYsIExQRFdPUkQgYnVmbGVuKQp7CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgc3prZXlXW10gPSB7CgknUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsCgknTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLAoJJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2UnLCd0JywnICcsJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXFwnLAoJJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2EnLCd0JywnaScsJ28nLCduJywnYScsJ2wnLDB9OwogICAgc3RhdGljIGNvbnN0IFdDSEFSIHZhbHVlV1tdID0gewoJJ0EnLCdjJywnYycsJ2UnLCdwJywndCcsJ0wnLCdhJywnbicsJ2cnLCd1JywnYScsJ2cnLCdlJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiBlbnVzV1tdID0geydlJywnbicsJy0nLCd1JywncycsMH07CiAgICBEV09SRCBteXN0cmxlbiwgbXl0eXBlOwogICAgSEtFWSBteWtleTsKICAgIEhSRVNVTFQgcmV0dmFsOwogICAgTENJRCBteWxjaWQ7CiAgICBXQ0hBUiAqbXlzdHI7CgogICAgaWYoIWxhbmdidWYgfHwgIWJ1ZmxlbiB8fCAhKmJ1ZmxlbikKCXJldHVybiBFX0ZBSUw7CgogICAgbXlzdHJsZW4gPSAoKmJ1ZmxlbiA+IDIwKSA/ICpidWZsZW4gOiAyMCA7CiAgICBteXN0ciA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpICogbXlzdHJsZW4pOwogICAgUmVnT3BlbktleVcoSEtFWV9DVVJSRU5UX1VTRVIsIHN6a2V5VywgJm15a2V5KTsKICAgIGlmKFJlZ1F1ZXJ5VmFsdWVFeFcobXlrZXksIHZhbHVlVywgMCwgJm15dHlwZSwgKFBCWVRFKW15c3RyLCAmbXlzdHJsZW4pKSB7CiAgICAgICAgLyogRGlkIG5vdCBmaW5kIHZhbHVlICovCiAgICAgICAgbXlsY2lkID0gR2V0VXNlckRlZmF1bHRMQ0lEKCk7CiAgICAgICAgLyogc29tZWhvdyB0aGUgbXlsY2lkIHRyYW5zbGF0ZXMgaW50byAiZW4tdXMiCiAgICAgICAgICogIHRoaXMgaXMgc2ltaWxhciB0byAiTE9DQUxFX1NBQkJSRVZMQU5HTkFNRSIKICAgICAgICAgKiAgd2hpY2ggY291bGQgYmUgZ290dGVuIHZpYSBHZXRMb2NhbGVJbmZvLgogICAgICAgICAqICBUaGUgb25seSBwcm9ibGVtIGlzIExPQ0FMRV9TQUJCUkVWTEFOR1VBR0UiIGlzCiAgICAgICAgICogIGEgMyBjaGFyIHN0cmluZyAoZmlyc3QgMiBhcmUgY291bnRyeSBjb2RlIGFuZCB0aGlyZCBpcwogICAgICAgICAqICBsZXR0ZXIgZm9yICJzdWJsYW5ndWFnZSIsIHdoaWNoIGRvZXMgbm90IGNvbWUgY2xvc2UgdG8KICAgICAgICAgKiAgImVuLXVzIgogICAgICAgICAqLwogICAgICAgIGxzdHJjcHlXKG15c3RyLCBlbnVzVyk7CiAgICAgICAgbXlzdHJsZW4gPSBsc3RybGVuVyhteXN0cik7CiAgICB9IGVsc2UgewogICAgICAgIC8qIGhhbmRsZSByZXR1cm5lZCBzdHJpbmcgKi8KICAgICAgICBGSVhNRSgibWlzc2luZyBjb2RlXG4iKTsKICAgIH0KICAgIG1lbWNweSggbGFuZ2J1ZiwgbXlzdHIsIG1pbigqYnVmbGVuLHN0cmxlblcobXlzdHIpKzEpKnNpemVvZihXQ0hBUikgKTsKCiAgICBpZigqYnVmbGVuID4gbHN0cmxlblcobXlzdHIpKSB7CgkqYnVmbGVuID0gbHN0cmxlblcobXlzdHIpOwoJcmV0dmFsID0gU19PSzsKICAgIH0gZWxzZSB7CgkqYnVmbGVuID0gMDsKCXJldHZhbCA9IEVfSU5WQUxJREFSRzsKCVNldExhc3RFcnJvcihFUlJPUl9JTlNVRkZJQ0lFTlRfQlVGRkVSKTsKICAgIH0KICAgIFJlZ0Nsb3NlS2V5KG15a2V5KTsKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIG15c3RyKTsKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNF0KICoKICogQXNjaWkgdmVyc2lvbiBvZiBHZXRBY2NlcHRMYW5ndWFnZXNXLgogKi8KSFJFU1VMVCBXSU5BUEkgR2V0QWNjZXB0TGFuZ3VhZ2VzQSggTFBTVFIgbGFuZ2J1ZiwgTFBEV09SRCBidWZsZW4pCnsKICAgIFdDSEFSICpsYW5nYnVmVzsKICAgIERXT1JEIGJ1ZmxlblcsIGNvbnZsZW47CiAgICBIUkVTVUxUIHJldHZhbDsKCiAgICBpZighbGFuZ2J1ZiB8fCAhYnVmbGVuIHx8ICEqYnVmbGVuKSByZXR1cm4gRV9GQUlMOwoKICAgIGJ1ZmxlblcgPSAqYnVmbGVuOwogICAgbGFuZ2J1ZlcgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSAqIGJ1ZmxlblcpOwogICAgcmV0dmFsID0gR2V0QWNjZXB0TGFuZ3VhZ2VzVyhsYW5nYnVmVywgJmJ1ZmxlblcpOwoKICAgIC8qIEZJWE1FOiB0aGlzIGlzIHdyb25nLCB0aGUgc3RyaW5nIG1heSBub3QgYmUgbnVsbC10ZXJtaW5hdGVkICovCiAgICBjb252bGVuID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGxhbmdidWZXLCAtMSwgbGFuZ2J1ZiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpidWZsZW4sIE5VTEwsIE5VTEwpOwogICAgKmJ1ZmxlbiA9IGJ1ZmxlblcgPyBjb252bGVuIDogMDsKCiAgICBpZihsYW5nYnVmVykgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbGFuZ2J1ZlcpOwogICAgcmV0dXJuIHJldHZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzXQogKgogKiBDb252ZXJ0IGEgR1VJRCB0byBhIHN0cmluZy4KICoKICogUEFSQU1TCiAqICBndWlkIFtJXSBHVUlEIHRvIGNvbnZlcnQKICogIHN0ciAgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNtYXggW0ldIExlbmd0aCBvZiBvdXRwdXQgYnVmZmVyCiAqCiAqIFJFVFVSTlMKICogIFRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyBjcmVhdGVkLgogKi8KSU5UIFdJTkFQSSBTSFN0cmluZ0Zyb21HVUlEQShSRUZHVUlEIGd1aWQsIExQU1RSIGxwc3pEZXN0LCBJTlQgY2NoTWF4KQp7CiAgY2hhciB4Z3VpZFs0MF07CiAgSU5UIGlMZW47CgogIFRSQUNFKCIoJXMsJXAsJWQpXG4iLCBkZWJ1Z3N0cl9ndWlkKGd1aWQpLCBscHN6RGVzdCwgY2NoTWF4KTsKCiAgc3ByaW50Zih4Z3VpZCwgInslMDhsWC0lMDRYLSUwNFgtJTAyWCUwMlgtJTAyWCUwMlglMDJYJTAyWCUwMlglMDJYfSIsCiAgICAgICAgICBndWlkLT5EYXRhMSwgZ3VpZC0+RGF0YTIsIGd1aWQtPkRhdGEzLAogICAgICAgICAgZ3VpZC0+RGF0YTRbMF0sIGd1aWQtPkRhdGE0WzFdLCBndWlkLT5EYXRhNFsyXSwgZ3VpZC0+RGF0YTRbM10sCiAgICAgICAgICBndWlkLT5EYXRhNFs0XSwgZ3VpZC0+RGF0YTRbNV0sIGd1aWQtPkRhdGE0WzZdLCBndWlkLT5EYXRhNFs3XSk7CgogIGlMZW4gPSBzdHJsZW4oeGd1aWQpICsgMTsKCiAgaWYgKGlMZW4gPiBjY2hNYXgpCiAgICByZXR1cm4gMDsKICBtZW1jcHkobHBzekRlc3QsIHhndWlkLCBpTGVuKTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI0XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU0hTdHJpbmdGcm9tR1VJREEuCiAqLwpJTlQgV0lOQVBJIFNIU3RyaW5nRnJvbUdVSURXKFJFRkdVSUQgZ3VpZCwgTFBXU1RSIGxwc3pEZXN0LCBJTlQgY2NoTWF4KQp7CiAgY2hhciB4Z3VpZFs0MF07CiAgSU5UIGlMZW4gPSBTSFN0cmluZ0Zyb21HVUlEQShndWlkLCB4Z3VpZCwgY2NoTWF4KTsKCiAgaWYgKGlMZW4pCiAgICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgeGd1aWQsIC0xLCBscHN6RGVzdCwgY2NoTWF4KTsKICByZXR1cm4gaUxlbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI1XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhbHBoYWJldGljLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGFscGhhYmV0aWMsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJBbHBoYVdyYXBXKFdDSEFSIHdjKQp7CiAgICByZXR1cm4gKGdldF9jaGFyX3R5cGVXKHdjKSAmIEMxX0FMUEhBKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjZdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIHVwcGVyLWNhc2UuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgdXBwZXItY2FzZSwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhclVwcGVyV3JhcFcoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfVVBQRVIpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yN10KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgbG93ZXItY2FzZS4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBsb3dlci1jYXNlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyTG93ZXJXcmFwVyhXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9MT1dFUikgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhbHBoYWJldGljIG9yIGEgZGlnaXQuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYWxwaGFiZXRpYyBvciBhIGRpZ2l0LAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyQWxwaGFOdW1lcmljV3JhcFcoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgKEMxX0FMUEhBfEMxX0RJR0lUKSkgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIHNwYWNlLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgc3BhY2UsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJTcGFjZVcoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfU1BBQ0UpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMF0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBibGFuay4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGJsYW5rLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyQmxhbmtXKFdDSEFSIHdjKQp7CiAgICByZXR1cm4gKGdldF9jaGFyX3R5cGVXKHdjKSAmIEMxX0JMQU5LKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzFdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIHB1bmN0dWF0aW9uLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIHB1bmN0dWF0aW9uLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyUHVuY3RXKFdDSEFSIHdjKQp7CiAgICByZXR1cm4gKGdldF9jaGFyX3R5cGVXKHdjKSAmIEMxX1BVTkNUKSAhPSAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzJdCiAqCiAqIERldGVybWluZSBpZiBhIFVuaWNvZGUgY2hhcmFjdGVyIGlzIGEgY29udHJvbCBjaGFyYWN0ZXIuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBjb250cm9sIGNoYXJhY3RlciwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhckNudHJsVyhXQ0hBUiB3YykKewogICAgcmV0dXJuIChnZXRfY2hhcl90eXBlVyh3YykgJiBDMV9DTlRSTCkgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGRpZ2l0LgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgZGlnaXQsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJEaWdpdFcoV0NIQVIgd2MpCnsKICAgIHJldHVybiAoZ2V0X2NoYXJfdHlwZVcod2MpICYgQzFfRElHSVQpICE9IDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNF0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBoZXggZGlnaXQuCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgYSBoZXggZGlnaXQsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJYRGlnaXRXKFdDSEFSIHdjKQp7CiAgICByZXR1cm4gKGdldF9jaGFyX3R5cGVXKHdjKSAmIEMxX1hESUdJVCkgIT0gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1XQogKgogKi8KQk9PTCBXSU5BUEkgR2V0U3RyaW5nVHlwZTNFeFcoTFBXU1RSIGxwc3pTdHIsIERXT1JEIGR3TGVuLCBMUFZPSUQgcDMpCnsKICAgIEZJWE1FKCIoJXMsMHglMDhseCwlcCk6IHN0dWJcbiIsIGRlYnVnc3RyX3cobHBzelN0ciksIGR3TGVuLCBwMyk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM2XQogKgogKiBJbnNlcnQgYSBiaXRtYXAgbWVudSBpdGVtIGF0IHRoZSBib3R0b20gb2YgYSBtZW51LgogKgogKiBQQVJBTVMKICogIGhNZW51IFtJXSBNZW51IHRvIGluc2VydCBpbnRvCiAqICBmbGFncyBbSV0gRmxhZ3MgZm9yIGluc2VydGlvbgogKiAgaWQgICAgW0ldIE1lbnUgSUQgb2YgdGhlIGl0ZW0KICogIHN0ciAgIFtJXSBNZW51IHRleHQgZm9yIHRoZSBpdGVtCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUsICB0aGUgaXRlbSBpcyBpbnNlcnRlZCBpbnRvIHRoZSBtZW51CiAqICBGYWlsdXJlOiBGQUxTRSwgaWYgYW55IHBhcmFtZXRlciBpcyBpbnZhbGlkCiAqLwpCT09MIFdJTkFQSSBBcHBlbmRNZW51V3JhcFcoSE1FTlUgaE1lbnUsIFVJTlQgZmxhZ3MsIFVJTlQgaWQsIExQQ1dTVFIgc3RyKQp7CiAgICBUUkFDRSgiKCVwLDB4JTA4eCwweCUwOHgsJXMpXG4iLGhNZW51LCBmbGFncywgaWQsIGRlYnVnc3RyX3coc3RyKSk7CiAgICByZXR1cm4gSW5zZXJ0TWVudVcoaE1lbnUsIC0xLCBmbGFncyB8IE1GX0JJVE1BUCwgaWQsIHN0cik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS43NF0KICoKICogR2V0IHRoZSB0ZXh0IGZyb20gYSBnaXZlbiBkaWFsb2cgaXRlbS4KICoKICogUEFSQU1TCiAqICBoV25kICAgICBbSV0gSGFuZGxlIG9mIGRpYWxvZwogKiAgbkl0ZW0gICAgW0ldIEluZGV4IG9mIGl0ZW0KICogIGxwc0Rlc3QgIFtPXSBCdWZmZXIgZm9yIHJlY2VpdmluZyB3aW5kb3cgdGV4dAogKiAgbkRlc3RMZW4gW0ldIExlbmd0aCBvZiBidWZmZXIuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBsZW5ndGggb2YgdGhlIHJldHVybmVkIHRleHQuCiAqICBGYWlsdXJlOiAwLgogKi8KSU5UIFdJTkFQSSBHZXREbGdJdGVtVGV4dFdyYXBXKEhXTkQgaFduZCwgSU5UIG5JdGVtLCBMUFdTVFIgbHBzRGVzdCxJTlQgbkRlc3RMZW4pCnsKICBIV05EIGhJdGVtID0gR2V0RGxnSXRlbShoV25kLCBuSXRlbSk7CgogIGlmIChoSXRlbSkKICAgIHJldHVybiBHZXRXaW5kb3dUZXh0VyhoSXRlbSwgbHBzRGVzdCwgbkRlc3RMZW4pOwogIGlmIChuRGVzdExlbikKICAgICpscHNEZXN0ID0gKFdDSEFSKSdcMCc7CiAgcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgIFtTSExXQVBJLjEzOF0KICoKICogU2V0IHRoZSB0ZXh0IG9mIGEgZ2l2ZW4gZGlhbG9nIGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgW0ldIEhhbmRsZSBvZiBkaWFsb2cKICogIGlJdGVtICAgIFtJXSBJbmRleCBvZiBpdGVtCiAqICBscHN6VGV4dCBbT10gVGV4dCB0byBzZXQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gIFRoZSB0ZXh0IG9mIHRoZSBkaWFsb2cgaXMgc2V0IHRvIGxwc3pUZXh0LgogKiAgRmFpbHVyZTogRkFMU0UsIE90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIFNldERsZ0l0ZW1UZXh0V3JhcFcoSFdORCBoV25kLCBJTlQgaUl0ZW0sIExQQ1dTVFIgbHBzelRleHQpCnsKICAgIEhXTkQgaFduZEl0ZW0gPSBHZXREbGdJdGVtKGhXbmQsIGlJdGVtKTsKICAgIGlmIChoV25kSXRlbSkKICAgICAgICByZXR1cm4gU2V0V2luZG93VGV4dFcoaFduZEl0ZW0sIGxwc3pUZXh0KTsKICAgIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1MV0KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncyB1cCB0byBhIGdpdmVuIGxlbmd0aC4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqICBsZW4gICAgIFtJXSBNYXhpbXVtIGxlbmd0aAogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wTkNBKExQQ1NUUiBscHN6U3JjLCBMUENTVFIgbHBzekNtcCwgSU5UIGxlbikKewogICAgcmV0dXJuIHN0cm5jbXAobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1Ml0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFN0ckNtcE5DQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBOQ1coTFBDV1NUUiBscHN6U3JjLCBMUENXU1RSIGxwc3pDbXAsIElOVCBsZW4pCnsKICAgIHJldHVybiBzdHJuY21wVyhscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTUzXQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzIHVwIHRvIGEgZ2l2ZW4gbGVuZ3RoLCBpZ25vcmluZyBjYXNlLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICogIGxlbiAgICAgW0ldIE1heGltdW0gbGVuZ3RoCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBOSUNBKExQQ1NUUiBscHN6U3JjLCBMUENTVFIgbHBzekNtcCwgRFdPUkQgbGVuKQp7CiAgICByZXR1cm4gc3RybmNhc2VjbXAobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1NF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFN0ckNtcE5JQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wTklDVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCwgRFdPUkQgbGVuKQp7CiAgICByZXR1cm4gc3RybmNtcGlXKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTVdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY21wKGxwc3pTcmMsIGxwc3pDbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU2XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wQ1coTFBDV1NUUiBscHN6U3JjLCBMUENXU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBzdHJjbXBXKGxwc3pTcmMsIGxwc3pDbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU3XQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzLCBpZ25vcmluZyBjYXNlLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcElDQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBzdHJjYXNlY21wKGxwc3pTcmMsIGxwc3pDbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU4XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgU3RyQ21wSUNBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcElDVyhMUENXU1RSIGxwc3pTcmMsIExQQ1dTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNtcGlXKGxwc3pTcmMsIGxwc3pDbXApOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTYwXQogKgogKiBHZXQgYW4gaWRlbnRpZmljYXRpb24gc3RyaW5nIGZvciB0aGUgT1MgYW5kIGV4cGxvcmVyLgogKgogKiBQQVJBTVMKICogIGxwc3pEZXN0ICBbT10gRGVzdGluYXRpb24gZm9yIElkIHN0cmluZwogKiAgZHdEZXN0TGVuIFtJXSBMZW5ndGggb2YgbHBzekRlc3QKICoKICogUkVUVVJOUwogKiAgVFJVRSwgIElmIHRoZSBzdHJpbmcgd2FzIGNyZWF0ZWQgc3VjY2Vzc2Z1bGx5CiAqICBGQUxTRSwgT3RoZXJ3aXNlCiAqLwpCT09MIFdJTkFQSSBTSEFib3V0SW5mb0EoTFBTVFIgbHBzekRlc3QsIERXT1JEIGR3RGVzdExlbikKewogIFdDSEFSIGJ1ZmZbMjA4NF07CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgbHBzekRlc3QsIGR3RGVzdExlbik7CgogIGlmIChscHN6RGVzdCAmJiBTSEFib3V0SW5mb1coYnVmZiwgZHdEZXN0TGVuKSkKICB7CiAgICBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgYnVmZiwgLTEsIGxwc3pEZXN0LCBkd0Rlc3RMZW4sIE5VTEwsIE5VTEwpOwogICAgcmV0dXJuIFRSVUU7CiAgfQogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2MV0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNIQWJvdXRJbmZvQS4KICovCkJPT0wgV0lOQVBJIFNIQWJvdXRJbmZvVyhMUFdTVFIgbHBzekRlc3QsIERXT1JEIGR3RGVzdExlbikKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzeklFS2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2UnLCd0JywKICAgICcgJywnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pXaW5OdEtleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnICcsCiAgICAnTicsJ1QnLCdcXCcsJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6V2luS2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ1cnLCdpJywnbicsJ2QnLCdvJywndycsJ3MnLCdcXCcsCiAgICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pSZWdLZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnSScsJ24nLCd0JywnZScsJ3InLCduJywnZScsJ3QnLAogICAgJyAnLCdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1xcJywKICAgICdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdyJywnYScsJ3QnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pWZXJzaW9uW10gPSB7ICdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q3VzdG9taXplZFtdID0geyAnQycsJ3UnLCdzJywndCcsJ28nLCdtJywnaScsJ3onLCdlJywnZCcsCiAgICAnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzek93bmVyW10gPSB7ICdSJywnZScsJ2cnLCdpJywncycsJ3QnLCdlJywncicsJ2UnLCdkJywKICAgICdPJywndycsJ24nLCdlJywncicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzek9yZ1tdID0geyAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywnZScsJ3InLCdlJywnZCcsCiAgICAnTycsJ3InLCdnJywnYScsJ24nLCdpJywneicsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6UHJvZHVjdFtdID0geyAnUCcsJ3InLCdvJywnZCcsJ3UnLCdjJywndCcsJ0knLCdkJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6VXBkYXRlW10gPSB7ICdJJywnRScsJ0EnLCdLJywKICAgICdVJywncCcsJ2QnLCdhJywndCcsJ2UnLCdVJywncicsJ2wnLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pIZWxwW10gPSB7ICdJJywnRScsJ0EnLCdLJywKICAgICdIJywnZScsJ2wnLCdwJywnUycsJ3QnLCdyJywnaScsJ24nLCdnJywnXDAnIH07CiAgV0NIQVIgYnVmZlsyMDg0XTsKICBIS0VZIGhSZWc7CiAgRFdPUkQgZHdUeXBlLCBkd0xlbjsKCiAgVFJBQ0UoIiglcCwlbGQpXG4iLCBscHN6RGVzdCwgZHdEZXN0TGVuKTsKCiAgaWYgKCFscHN6RGVzdCkKICAgIHJldHVybiBGQUxTRTsKCiAgKmxwc3pEZXN0ID0gJ1wwJzsKCiAgLyogVHJ5IHRoZSBOVCBrZXkgZmlyc3QsIGZvbGxvd2VkIGJ5IDk1Lzk4IGtleSAqLwogIGlmIChSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5OdEtleSwgMCwgS0VZX1JFQUQsICZoUmVnKSAmJgogICAgICBSZWdPcGVuS2V5RXhXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pXaW5LZXksIDAsIEtFWV9SRUFELCAmaFJlZykpCiAgICByZXR1cm4gRkFMU0U7CgogIC8qIE9TIFZlcnNpb24gKi8KICBidWZmWzBdID0gJ1wwJzsKICBkd0xlbiA9IDMwOwogIGlmICghU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeklFS2V5LCBzelZlcnNpb24sICZkd1R5cGUsIGJ1ZmYsICZkd0xlbikpCiAgewogICAgRFdPUkQgZHdTdHJMZW4gPSBzdHJsZW5XKGJ1ZmYpOwogICAgZHdMZW4gPSAzMCAtIGR3U3RyTGVuOwogICAgU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeklFS2V5LAogICAgICAgICAgICAgICAgc3pDdXN0b21pemVkLCAmZHdUeXBlLCBidWZmK2R3U3RyTGVuLCAmZHdMZW4pOwogIH0KICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflJlZ2lzdGVyZWQgT3duZXIgKi8KICBidWZmWzBdID0gJ34nOwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhoUmVnLCBzek93bmVyLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflJlZ2lzdGVyZWQgT3JnYW5pemF0aW9uICovCiAgZHdMZW4gPSAyNTY7CiAgaWYgKFNIR2V0VmFsdWVXKGhSZWcsIHN6T3JnLCAwLCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogRklYTUU6IE5vdCBzdXJlIHdoZXJlIHRoaXMgbnVtYmVyIGNvbWVzIGZyb20gICovCiAgYnVmZlswXSA9ICd+JzsKICBidWZmWzFdID0gJzAnOwogIGJ1ZmZbMl0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+UHJvZHVjdCBJZCAqLwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6UmVnS2V5LCBzelByb2R1Y3QsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+SUUgVXBkYXRlIFVybCAqLwogIGR3TGVuID0gMjA0ODsKICBpZihTSEdldFZhbHVlVyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luS2V5LCBzelVwZGF0ZSwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5JRSBIZWxwIFN0cmluZyAqLwogIGR3TGVuID0gMjU2OwogIGlmKFNIR2V0VmFsdWVXKGhSZWcsIHN6SGVscCwgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIFJlZ0Nsb3NlS2V5KGhSZWcpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTYzXQogKgogKiBDYWxsIElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29tbWFuZFRhcmdldCBpbnRlcmZhY2UKICogIHBndWlkQ21kR3JvdXAgW0ldIEdVSUQgZm9yIHRoZSBjb21tYW5kIGdyb3VwCiAqICBjQ21kcyAgICAgICAgIFtJXQogKiAgcHJnQ21kcyAgICAgICBbT10gQ29tbWFuZHMKICogIHBDbWRUZXh0ICAgICAgW09dIENvbW1hbmQgdGV4dAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9GQUlMLCBpZiBscFVua25vd24gaXMgTlVMTC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBkb2VzIG5vdCBzdXBwb3J0IElPbGVDb21tYW5kVGFyZ2V0LgogKiAgICAgICAgICAgT3RoZXJ3aXNlLCBhbiBlcnJvciBjb2RlIGZyb20gSU9sZUNvbW1hbmRUYXJnZXRfUXVlcnlTdGF0dXMoKS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U3RhdHVzKElVbmtub3duKiBscFVua25vd24sIFJFRkdVSUQgcGd1aWRDbWRHcm91cCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgVUxPTkcgY0NtZHMsIE9MRUNNRCAqcHJnQ21kcywgT0xFQ01EVEVYVCogcENtZFRleHQpCnsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXAsJWxkLCVwLCVwKVxuIixscFVua25vd24sIHBndWlkQ21kR3JvdXAsIGNDbWRzLCBwcmdDbWRzLCBwQ21kVGV4dCk7CgogIGlmIChscFVua25vd24pCiAgewogICAgSU9sZUNvbW1hbmRUYXJnZXQqIGxwT2xlOwoKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZUNvbW1hbmRUYXJnZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBPbGUpOwoKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBPbGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2xlQ29tbWFuZFRhcmdldF9RdWVyeVN0YXR1cyhscE9sZSwgcGd1aWRDbWRHcm91cCwgY0NtZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmdDbWRzLCBwQ21kVGV4dCk7CiAgICAgIElPbGVDb21tYW5kVGFyZ2V0X1JlbGVhc2UobHBPbGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACQlbU0hMV0FQSS4xNjRdCiAqCiAqIENhbGwgSU9sZUNvbW1hbmRUYXJnZXRfRXhlYygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gICAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbW1hbmRUYXJnZXQgaW50ZXJmYWNlCiAqICBwZ3VpZENtZEdyb3VwIFtJXSBHVUlEIGZvciB0aGUgY29tbWFuZCBncm91cAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9GQUlMLCBpZiBscFVua25vd24gaXMgTlVMTC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBkb2VzIG5vdCBzdXBwb3J0IElPbGVDb21tYW5kVGFyZ2V0LgogKiAgICAgICAgICAgT3RoZXJ3aXNlLCBhbiBlcnJvciBjb2RlIGZyb20gSU9sZUNvbW1hbmRUYXJnZXRfRXhlYygpLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fRXhlYyhJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIG5DbWRJRCwgRFdPUkQgbkNtZGV4ZWNvcHQsIFZBUklBTlQqIHB2YUluLAogICAgICAgICAgICAgICAgICAgICAgICAgICBWQVJJQU5UKiBwdmFPdXQpCnsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXAsJWxkLCVsZCwlcCwlcClcbiIsbHBVbmtub3duLCBwZ3VpZENtZEdyb3VwLCBuQ21kSUQsCiAgICAgICAgbkNtZGV4ZWNvcHQsIHB2YUluLCBwdmFPdXQpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIElPbGVDb21tYW5kVGFyZ2V0KiBscE9sZTsKCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb21tYW5kVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwT2xlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBPbGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2xlQ29tbWFuZFRhcmdldF9FeGVjKGxwT2xlLCBwZ3VpZENtZEdyb3VwLCBuQ21kSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5DbWRleGVjb3B0LCBwdmFJbiwgcHZhT3V0KTsKICAgICAgSU9sZUNvbW1hbmRUYXJnZXRfUmVsZWFzZShscE9sZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTY1XQogKgogKiBSZXRyaWV2ZSwgbW9kaWZ5LCBhbmQgcmUtc2V0IGEgdmFsdWUgZnJvbSBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kICAgW0ldIFdpbmRvdyB0byBnZXQgdmFsdWUgZnJvbQogKiAgb2Zmc2V0IFtJXSBPZmZzZXQgb2YgdmFsdWUKICogIHdNYXNrICBbSV0gTWFzayBmb3IgdWlGbGFncwogKiAgd0ZsYWdzIFtJXSBCaXRzIHRvIHNldCBpbiB3aW5kb3cgdmFsdWUKICoKICogUkVUVVJOUwogKiAgVGhlIG5ldyB2YWx1ZSBhcyBpdCB3YXMgc2V0LCBvciAwIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZC4KICoKICogTk9URVMKICogIEFueSBiaXRzIHNldCBpbiB1aU1hc2sgYXJlIGNsZWFyZWQgZnJvbSB0aGUgdmFsdWUsIHRoZW4gYW55IGJpdHMgc2V0IGluCiAqICB1aUZsYWdzIGFyZSBzZXQgaW4gdGhlIHZhbHVlLgogKi8KTE9ORyBXSU5BUEkgU0hTZXRXaW5kb3dCaXRzKEhXTkQgaHduZCwgSU5UIG9mZnNldCwgVUlOVCB3TWFzaywgVUlOVCB3RmxhZ3MpCnsKICBMT05HIHJldCA9IEdldFdpbmRvd0xvbmdBKGh3bmQsIG9mZnNldCk7CiAgTE9ORyBuZXdGbGFncyA9ICh3RmxhZ3MgJiB3TWFzaykgfCAocmV0ICYgfndGbGFncyk7CgogIGlmIChuZXdGbGFncyAhPSByZXQpCiAgICByZXQgPSBTZXRXaW5kb3dMb25nQShod25kLCBvZmZzZXQsIG5ld0ZsYWdzKTsKICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTY3XQogKgogKiBDaGFuZ2UgYSB3aW5kb3cncyBwYXJlbnQuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgICBbSV0gV2luZG93IHRvIGNoYW5nZSBwYXJlbnQgb2YKICogIGhXbmRQYXJlbnQgW0ldIE5ldyBwYXJlbnQgd2luZG93CiAqCiAqIFJFVFVSTlMKICogIFRoZSBvbGQgcGFyZW50IG9mIGhXbmQuCiAqCiAqIE5PVEVTCiAqICBJZiBoV25kUGFyZW50IGlzIE5VTEwgKGRlc2t0b3ApLCB0aGUgd2luZG93IHN0eWxlIGlzIGNoYW5nZWQgdG8gV1NfUE9QVVAuCiAqICBJZiBoV25kUGFyZW50IGlzIE5PVCBOVUxMIHRoZW4gd2Ugc2V0IHRoZSBXU19DSElMRCBzdHlsZS4KICovCkhXTkQgV0lOQVBJIFNIU2V0UGFyZW50SHduZChIV05EIGhXbmQsIEhXTkQgaFduZFBhcmVudCkKewogIFRSQUNFKCIlcCwgJXBcbiIsIGhXbmQsIGhXbmRQYXJlbnQpOwoKICBpZihHZXRQYXJlbnQoaFduZCkgPT0gaFduZFBhcmVudCkKICAgIHJldHVybiAwOwoKICBpZihoV25kUGFyZW50KQogICAgU0hTZXRXaW5kb3dCaXRzKGhXbmQsIEdXTF9TVFlMRSwgV1NfQ0hJTEQsIFdTX0NISUxEKTsKICBlbHNlCiAgICBTSFNldFdpbmRvd0JpdHMoaFduZCwgR1dMX1NUWUxFLCBXU19QT1BVUCwgV1NfUE9QVVApOwoKICByZXR1cm4gU2V0UGFyZW50KGhXbmQsIGhXbmRQYXJlbnQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMTY4XQogKgogKiBMb2NhdGUgYW5kIGFkdmlzZSBhIGNvbm5lY3Rpb24gcG9pbnQgaW4gYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtTaW5rICAgW0ldIFNpbmsgZm9yIHRoZSBjb25uZWN0aW9uIHBvaW50IGFkdmlzZSBjYWxsCiAqICByaWlkICAgICAgICBbSV0gUkVGSUlEIG9mIGNvbm5lY3Rpb24gcG9pbnQgdG8gYWR2aXNlCiAqICBiQWR2aXNlT25seSBbSV0gVFJVRSA9IEFkdmlzZSBvbmx5LCBGQUxTRSA9IFVuYWR2aXNlIGZpcnN0CiAqICBscFVua25vd24gICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgaW50ZXJmYWNlCiAqICBscENvb2tpZSAgICBbT10gUG9pbnRlciB0byBjb25uZWN0aW9uIHBvaW50IGNvb2tpZQogKiAgbHBwQ1AgICAgICAgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgSUNvbm5lY3Rpb25Qb2ludCBmb3VuZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBJZiBscHBDUCBpcyBub24tTlVMTCwgaXQgaXMgZmlsbGVkIHdpdGggdGhlIElDb25uZWN0aW9uUG9pbnQKICogICAgICAgICAgIHRoYXQgd2FzIGFkdmlzZWQuIFRoZSBjYWxsZXIgaXMgcmVzcG9uc2FibGUgZm9yIHJlbGVhc2luZyBpdC4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgYW55IGFyZ3VtZW50cyBhcmUgaW52YWxpZC4KICogICAgICAgICAgIEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBpc24ndCBhbiBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyLAogKiAgICAgICAgICAgT3IgYW4gSFJFU1VMVCBlcnJvciBjb2RlIGlmIGFueSBjYWxsIGZhaWxzLgogKi8KSFJFU1VMVCBXSU5BUEkgQ29ubmVjdFRvQ29ubmVjdGlvblBvaW50KElVbmtub3duKiBscFVua1NpbmssIFJFRklJRCByaWlkLCBCT09MIGJBZHZpc2VPbmx5LAogICAgICAgICAgICAgICAgICAgICAgICAgICBJVW5rbm93biogbHBVbmtub3duLCBMUERXT1JEIGxwQ29va2llLAogICAgICAgICAgICAgICAgICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50ICoqbHBwQ1ApCnsKICBIUkVTVUxUIGhSZXQ7CiAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciogbHBDb250YWluZXI7CiAgSUNvbm5lY3Rpb25Qb2ludCAqbHBDUDsKCiAgaWYoIWxwVW5rbm93biB8fCAoYkFkdmlzZU9ubHkgJiYgIWxwVW5rU2luaykpCiAgICByZXR1cm4gRV9GQUlMOwoKICBpZihscHBDUCkKICAgICpscHBDUCA9IE5VTEw7CgogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBDb250YWluZXIpOwogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfRmluZENvbm5lY3Rpb25Qb2ludChscENvbnRhaW5lciwgcmlpZCwgJmxwQ1ApOwoKICAgIGlmIChTVUNDRUVERUQoaFJldCkpCiAgICB7CiAgICAgIGlmKCFiQWR2aXNlT25seSkKICAgICAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9VbmFkdmlzZShscENQLCAqbHBDb29raWUpOwogICAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9BZHZpc2UobHBDUCwgbHBVbmtTaW5rLCBscENvb2tpZSk7CgogICAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgICAgICpscENvb2tpZSA9IDA7CgogICAgICBpZiAobHBwQ1AgJiYgU1VDQ0VFREVEKGhSZXQpKQogICAgICAgICpscHBDUCA9IGxwQ1A7IC8qIENhbGxlciBrZWVwcyB0aGUgaW50ZXJmYWNlICovCiAgICAgIGVsc2UKICAgICAgICBJQ29ubmVjdGlvblBvaW50X1JlbGVhc2UobHBDUCk7IC8qIFJlbGVhc2UgaXQgKi8KICAgIH0KCiAgICBJVW5rbm93bl9SZWxlYXNlKGxwQ29udGFpbmVyKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCUAJW1NITFdBUEkuMTY5XQogKgogKiBSZWxlYXNlIGFuIGludGVyZmFjZS4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byByZWxlYXNlCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpEV09SRCBXSU5BUEkgSVVua25vd25fQXRvbWljUmVsZWFzZShJVW5rbm93biAqKiBscFVua25vd24pCnsKICAgIElVbmtub3duICp0ZW1wOwoKICAgIFRSQUNFKCIoJXApXG4iLGxwVW5rbm93bik7CgogICAgaWYoIWxwVW5rbm93biB8fCAhKigoTFBEV09SRClscFVua25vd24pKSByZXR1cm4gMDsKICAgIHRlbXAgPSAqbHBVbmtub3duOwogICAgKmxwVW5rbm93biA9IE5VTEw7CgogICAgVFJBQ0UoImRvaW5nIFJlbGVhc2VcbiIpOwogICAgCiAgICByZXR1cm4gSVVua25vd25fUmVsZWFzZSh0ZW1wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3MF0KICoKICogU2tpcCAnLy8nIGlmIHByZXNlbnQgaW4gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU3RyaW5nIHRvIGNoZWNrIGZvciAnLy8nCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBuZXh0IGNoYXJhY3RlciBhZnRlciB0aGUgJy8vJyBvciB0aGUgc3RyaW5nIGlmIG5vdCBwcmVzZW50CiAqICBGYWlsdXJlOiBOVUxMLCBpZiBscHN6U3RyIGlzIE5VTEwuCiAqLwpMUENTVFIgV0lOQVBJIFBhdGhTa2lwTGVhZGluZ1NsYXNoZXNBKExQQ1NUUiBscHN6U3JjKQp7CiAgaWYgKGxwc3pTcmMgJiYgbHBzelNyY1swXSA9PSAnLycgJiYgbHBzelNyY1sxXSA9PSAnLycpCiAgICBscHN6U3JjICs9IDI7CiAgcmV0dXJuIGxwc3pTcmM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAkJW1NITFdBUEkuMTcxXQogKgogKiBDaGVjayBpZiB0d28gaW50ZXJmYWNlcyBjb21lIGZyb20gdGhlIHNhbWUgb2JqZWN0LgogKgogKiBQQVJBTVMKICogICBscEludDEgW0ldIEludGVyZmFjZSB0byBjaGVjayBhZ2FpbnN0IGxwSW50Mi4KICogICBscEludDIgW0ldIEludGVyZmFjZSB0byBjaGVjayBhZ2FpbnN0IGxwSW50MS4KICoKICogUkVUVVJOUwogKiAgIFRSVUUsIElmIHRoZSBpbnRlcmZhY2VzIGNvbWUgZnJvbSB0aGUgc2FtZSBvYmplY3QuCiAqICAgRkFMU0UgT3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hJc1NhbWVPYmplY3QoSVVua25vd24qIGxwSW50MSwgSVVua25vd24qIGxwSW50MikKewogIExQVk9JRCBscFVua25vd24xLCBscFVua25vd24yOwoKICBUUkFDRSgiJXAgJXBcbiIsIGxwSW50MSwgbHBJbnQyKTsKCiAgaWYgKCFscEludDEgfHwgIWxwSW50MikKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKGxwSW50MSA9PSBscEludDIpCiAgICByZXR1cm4gVFJVRTsKCiAgaWYgKCFTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBJbnQxLCAmSUlEX0lVbmtub3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEICopJmxwVW5rbm93bjEpKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKCFTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBJbnQyLCAmSUlEX0lVbmtub3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEICopJmxwVW5rbm93bjIpKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKGxwVW5rbm93bjEgPT0gbHBVbmtub3duMikKICAgIHJldHVybiBUUlVFOwogIAogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3Ml0KICoKICogR2V0IHRoZSB3aW5kb3cgaGFuZGxlIG9mIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBnZXQgdGhlIHdpbmRvdyBoYW5kbGUgb2YKICogIGxwaFduZCAgICBbT10gRGVzdGluYXRpb24gZm9yIHdpbmRvdyBoYW5kbGUKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBoV25kIGNvbnRhaW5zIHRoZSBvYmplY3RzIHdpbmRvdyBoYW5kbGUuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCBvbmUgb2YgdGhlIGZvbGxvd2luZyBpbnRlcmZhY2VzOgogKiAgSU9sZVdpbmRvdygpLCBJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUoKSwgb3IgSVNoZWxsVmlldygpLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fR2V0V2luZG93KElVbmtub3duICpscFVua25vd24sIEhXTkQgKmxwaFduZCkKewogIC8qIEZJWE1FOiBXaW5lIGhhcyBubyBoZWFkZXIgZm9yIHRoaXMgb2JqZWN0ICovCiAgc3RhdGljIGNvbnN0IEdVSUQgSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSA9IHsgMHg3OWVhYzllZCwKICAgIDB4YmFmOSwgMHgxMWNlLCB7IDB4OGMsIDB4ODIsIDB4MDAsIDB4YWEsIDB4MDAsIDB4NGIsIDB4YTksIDB4MGIgfX07CiAgSVVua25vd24gKmxwT2xlOwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwVW5rbm93biwgbHBoV25kKTsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gaFJldDsKCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlV2luZG93LCAodm9pZCoqKSZscE9sZSk7CgogIGlmIChGQUlMRUQoaFJldCkpCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwmSUlEX0lTaGVsbFZpZXcsICh2b2lkKiopJmxwT2xlKTsKCiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgewogICAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CiAgICB9CiAgfQoKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIC8qIExhenluZXNzIGhlcmUgLSBTaW5jZSBHZXRXaW5kb3coKSBpcyB0aGUgZmlyc3QgbWV0aG9kIGZvciB0aGUgYWJvdmUgMwogICAgICogaW50ZXJmYWNlcywgd2UgdXNlIHRoZSBzYW1lIGNhbGwgZm9yIHRoZW0gYWxsLgogICAgICovCiAgICBoUmV0ID0gSU9sZVdpbmRvd19HZXRXaW5kb3coKElPbGVXaW5kb3cqKWxwT2xlLCBscGhXbmQpOwogICAgSVVua25vd25fUmVsZWFzZShscE9sZSk7CiAgICBpZiAobHBoV25kKQogICAgICBUUkFDRSgiUmV0dXJuaW5nIEhXTkQ9JXBcbiIsICpscGhXbmQpOwogIH0KCiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzNdCiAqCiAqIENhbGwgYSBtZXRob2Qgb24gYXMgYXMgeWV0IHVuaWRlbnRpZmllZCBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgcFVuayBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIHVuaWRlbnRpZmllZCBpbnRlcmZhY2UsCiAqICBhcmcgIFtJXSBBcmd1bWVudCBmb3IgdGhlIGNhbGwgb24gdGhlIG9iamVjdC4KICoKICogUkVUVVJOUwogKiAgU19PSy4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1NldE93bmVyKElVbmtub3duICpwVW5rLCBVTE9ORyBhcmcpCnsKICBzdGF0aWMgY29uc3QgR1VJRCBndWlkXzE3MyA9IHsKICAgIDB4NTgzNmZiMDAsIDB4ODE4NywgMHgxMWNmLCB7IDB4YTEsMHgyYiwweDAwLDB4YWEsMHgwMCwweDRhLDB4ZTgsMHgzNyB9CiAgfTsKICBJTWFsbG9jICpwVW5rMjsKCiAgVFJBQ0UoIiglcCwlbGQpXG4iLCBwVW5rLCBhcmcpOwoKICAvKiBOb3RlOiBhcmcgbWF5IG5vdCBiZSBhIFVMT05HIGFuZCBwVW5rMiBpcyBmb3Igc3VyZSBub3QgYW4gSU1hbGxvYyAtCiAgICogICAgICAgV2UgdXNlIHRoaXMgaW50ZXJmYWNlIGFzIGl0cyB2dGFibGUgZW50cnkgaXMgY29tcGF0aWJsZSB3aXRoIHRoZQogICAqICAgICAgIG9iamVjdCBpbiBxdWVzdGlvbi4KICAgKiBGSVhNRTogRmluZCBvdXQgd2hhdCB0aGlzIG9iamVjdCBpcyBhbmQgd2hlcmUgaXQgc2hvdWxkIGJlIGRlZmluZWQuCiAgICovCiAgaWYgKHBVbmsgJiYKICAgICAgU1VDQ0VFREVEKElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKHBVbmssICZndWlkXzE3MywgKHZvaWQqKikmcFVuazIpKSkKICB7CiAgICBJTWFsbG9jX0FsbG9jKHBVbmsyLCBhcmcpOyAvKiBGYWtlZCBjYWxsISEgKi8KICAgIElNYWxsb2NfUmVsZWFzZShwVW5rMik7CiAgfQogIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTc0XQogKgogKiBDYWxsIGVpdGhlciBJT2JqZWN0V2l0aFNpdGVfU2V0U2l0ZSgpIG9yIElQZXJzaXN0TW9uaWtlcl9HZXRDbGFzc0lEKCkgb24KICogYW4gaW50ZXJmYWNlLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9GQUlMLCBpZiBwMSBpcyBOVUxMLgogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSBJZiBwMSBkb2VzIG5vdCBzdXBwb3J0IHRoZSBJUGVyc2lzdCBpbnRlcmZhY2UsCiAqICAgICAgICAgICBPciBhbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqLwpEV09SRCBXSU5BUEkgSVVua25vd25fU2V0U2l0ZSgKICAgICAgICBJVW5rbm93biAqcDEsICAgICAvKiBbaW5dICAgT0xFIG9iamVjdCAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICBMUFZPSUQgKnAyKSAgICAgICAvKiBbb3V0XSAgcHRyIGZvciBjYWxsIHJlc3VsdHMgKi8KewogICAgRFdPUkQgcmV0LCBhYTsKCiAgICBpZiAoIXAxKSByZXR1cm4gRV9GQUlMOwoKICAgIC8qIHNlZSBpZiBTZXRTaXRlIGludGVyZmFjZSBleGlzdHMgZm9yIElPYmplY3RXaXRoU2l0ZSBvYmplY3QgKi8KICAgIHJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKChJVW5rbm93biAqKXAxLCAoUkVGSUlEKWlkMSwgKExQVk9JRCAqKSZwMSk7CiAgICBUUkFDRSgiZmlyc3QgSVVfUUkgcmV0PSUwOGx4LCBwMT0lcFxuIiwgcmV0LCBwMSk7CiAgICBpZiAocmV0KSB7CgoJLyogc2VlIGlmIEdldENsYXNzSWQgaW50ZXJmYWNlIGV4aXN0cyBmb3IgSVBlcnNpc3RNb25pa2VyIG9iamVjdCAqLwoJcmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UoKElVbmtub3duICopcDEsIChSRUZJSUQpaWQyLCAoTFBWT0lEICopJmFhKTsKCVRSQUNFKCJzZWNvbmQgSVVfUUkgcmV0PSUwOGx4LCBhYT0lMDhseFxuIiwgcmV0LCBhYSk7CglpZiAocmV0KSByZXR1cm4gcmV0OwoKCS8qIGZha2UgYSBHZXRDbGFzc0lkIGNhbGwgKi8KCXJldCA9IElPbGVXaW5kb3dfR2V0V2luZG93KChJT2xlV2luZG93ICopYWEsIChIV05EKilwMik7CglUUkFDRSgic2Vjb25kIElVX1FJIGRvaW5nIDB4MGMgcmV0PSUwOGx4LCAqcDI9JTA4bHhcbiIsIHJldCwKCSAgICAgICooTFBEV09SRClwMik7CglJVW5rbm93bl9SZWxlYXNlKChJVW5rbm93biAqKWFhKTsKICAgIH0KICAgIGVsc2UgewoJLyogZmFrZSBhIFNldFNpdGUgY2FsbCAqLwoJcmV0ID0gSU9sZVdpbmRvd19HZXRXaW5kb3coKElPbGVXaW5kb3cgKilwMSwgKEhXTkQqKXAyKTsKCVRSQUNFKCJmaXJzdCBJVV9RSSBkb2luZyAweDBjIHJldD0lMDhseCwgKnAyPSUwOGx4XG4iLCByZXQsCgkgICAgICAqKExQRFdPUkQpcDIpOwoJSVVua25vd25fUmVsZWFzZSgoSVVua25vd24gKilwMSk7CiAgICB9CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTc1XQogKgogKiBDYWxsIElQZXJzaXN0X0dldENsYXNzSUQoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSVBlcnNpc3QgaW50ZXJmYWNlCiAqICBscENsYXNzSWQgW09dIERlc3RpbmF0aW9uIGZvciBDbGFzcyBJZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBscENsYXNzSWQgY29udGFpbnMgdGhlIENsYXNzIElkIHJlcXVlc3RlZC4KICogIEZhaWx1cmU6IEVfRkFJTCwgSWYgbHBVbmtub3duIGlzIE5VTEwsCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFIElmIGxwVW5rbm93biBkb2VzIG5vdCBzdXBwb3J0IElQZXJzaXN0LAogKiAgICAgICAgICAgT3IgYW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fR2V0Q2xhc3NJRChJVW5rbm93biAqbHBVbmtub3duLCBDTFNJRCogbHBDbGFzc0lkKQp7CiAgSVBlcnNpc3QqIGxwUGVyc2lzdDsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGRlYnVnc3RyX2d1aWQobHBDbGFzc0lkKSk7CgogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwmSUlEX0lQZXJzaXN0LCh2b2lkKiopJmxwUGVyc2lzdCk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogICAgewogICAgICBJUGVyc2lzdF9HZXRDbGFzc0lEKGxwUGVyc2lzdCwgbHBDbGFzc0lkKTsKICAgICAgSVBlcnNpc3RfUmVsZWFzZShscFBlcnNpc3QpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3Nl0KICoKICogUmV0cmlldmUgYSBTZXJ2aWNlIEludGVyZmFjZSBmcm9tIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBnZXQgYW4gSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UgZnJvbQogKiAgc2lkICAgICAgIFtJXSBTZXJ2aWNlIElEIGZvciBJU2VydmljZVByb3ZpZGVyX1F1ZXJ5U2VydmljZSgpIGNhbGwKICogIHJpaWQgICAgICBbSV0gRnVuY3Rpb24gcmVxdWVzdGVkIGZvciBRdWVyeVNlcnZpY2UgY2FsbAogKiAgbHBwT3V0ICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIHNlcnZpY2UgaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBwT3V0IGNvbnRhaW5zIGFuIG9iamVjdCBwcm92aWRpbmcgdGhlIHJlcXVlc3RlZCBzZXJ2aWNlCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUKICoKICogTk9URVMKICogIGxwVW5rbm93biBpcyBleHBlY3RlZCB0byBzdXBwb3J0IHRoZSBJU2VydmljZVByb3ZpZGVyIGludGVyZmFjZS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1F1ZXJ5U2VydmljZShJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHNpZCwgUkVGSUlEIHJpaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIExQVk9JRCAqbHBwT3V0KQp7CiAgSVNlcnZpY2VQcm92aWRlciogcFNlcnZpY2UgPSBOVUxMOwogIEhSRVNVTFQgaFJldDsKCiAgaWYgKCFscHBPdXQpCiAgICByZXR1cm4gRV9GQUlMOwoKICAqbHBwT3V0ID0gTlVMTDsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gRV9GQUlMOwoKICAvKiBHZXQgYW4gSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UgZnJvbSB0aGUgb2JqZWN0ICovCiAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JU2VydmljZVByb3ZpZGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEKikmcFNlcnZpY2UpOwoKICBpZiAoIWhSZXQgJiYgcFNlcnZpY2UpCiAgewogICAgVFJBQ0UoIlF1ZXJ5SW50ZXJmYWNlIHJldHVybmVkIChJU2VydmljZVByb3ZpZGVyKiklcFxuIiwgcFNlcnZpY2UpOwoKICAgIC8qIEdldCBhIFNlcnZpY2UgaW50ZXJmYWNlIGZyb20gdGhlIG9iamVjdCAqLwogICAgaFJldCA9IElTZXJ2aWNlUHJvdmlkZXJfUXVlcnlTZXJ2aWNlKHBTZXJ2aWNlLCBzaWQsIHJpaWQsIGxwcE91dCk7CgogICAgVFJBQ0UoIihJU2VydmljZVByb3ZpZGVyKiklcCByZXR1cm5lZCAoSVVua25vd24qKSVwXG4iLCBwU2VydmljZSwgKmxwcE91dCk7CgogICAgLyogUmVsZWFzZSB0aGUgSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UgKi8KICAgIElVbmtub3duX1JlbGVhc2UocFNlcnZpY2UpOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3N10KICoKICogTG9hZHMgYSBwb3B1cCBtZW51LgogKgogKiBQQVJBTVMKICogIGhJbnN0ICBbSV0gSW5zdGFuY2UgaGFuZGxlCiAqICBzek5hbWUgW0ldIE1lbnUgbmFtZQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLgogKiAgRmFpbHVyZTogRkFMU0UuCiAqLwpCT09MIFdJTkFQSSBTSExvYWRNZW51UG9wdXAoSElOU1RBTkNFIGhJbnN0LCBMUENXU1RSIHN6TmFtZSkKewogIEhNRU5VIGhNZW51LCBoU3ViTWVudTsKCiAgaWYgKChoTWVudSA9IExvYWRNZW51VyhoSW5zdCwgc3pOYW1lKSkpCiAgewogICAgaWYgKChoU3ViTWVudSA9IEdldFN1Yk1lbnUoaE1lbnUsIDApKSkKICAgICAgUmVtb3ZlTWVudShoTWVudSwgMCwgTUZfQllQT1NJVElPTik7CgogICAgRGVzdHJveU1lbnUoaE1lbnUpOwogICAgcmV0dXJuIFRSVUU7CiAgfQogIHJldHVybiBGQUxTRTsKfQoKdHlwZWRlZiBzdHJ1Y3QgX2VudW1XbmREYXRhCnsKICBVSU5UICAgdWlNc2dJZDsKICBXUEFSQU0gd1BhcmFtOwogIExQQVJBTSBsUGFyYW07CiAgTFJFU1VMVCAoV0lOQVBJICpwZm5Qb3N0KShIV05ELFVJTlQsV1BBUkFNLExQQVJBTSk7Cn0gZW51bVduZERhdGE7CgovKiBDYWxsYmFjayBmb3IgU0hMV0FQSV8xNzggKi8Kc3RhdGljIEJPT0wgQ0FMTEJBQ0sgU0hMV0FQSV9FbnVtQ2hpbGRQcm9jKEhXTkQgaFduZCwgTFBBUkFNIGxQYXJhbSkKewogIGVudW1XbmREYXRhICpkYXRhID0gKGVudW1XbmREYXRhICopbFBhcmFtOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgaFduZCwgZGF0YSk7CiAgZGF0YS0+cGZuUG9zdChoV25kLCBkYXRhLT51aU1zZ0lkLCBkYXRhLT53UGFyYW0sIGRhdGEtPmxQYXJhbSk7CiAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjE3OF0KICoKICogU2VuZCBvciBwb3N0IGEgbWVzc2FnZSB0byBldmVyeSBjaGlsZCBvZiBhIHdpbmRvdy4KICoKICogUEFSQU1TCiAqICBoV25kICAgIFtJXSBXaW5kb3cgd2hvc2UgY2hpbGRyZW4gd2lsbCBnZXQgdGhlIG1lc3NhZ2VzCiAqICB1aU1zZ0lkIFtJXSBNZXNzYWdlIElkCiAqICB3UGFyYW0gIFtJXSBXUEFSQU0gb2YgbWVzc2FnZQogKiAgbFBhcmFtICBbSV0gTFBBUkFNIG9mIG1lc3NhZ2UKICogIGJTZW5kICAgW0ldIFRSVUUgPSBVc2UgU2VuZE1lc3NhZ2VBKCksIEZBTFNFID0gVXNlIFBvc3RNZXNzYWdlQSgpCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqCiAqIE5PVEVTCiAqICBUaGUgYXBwcm9wcmlhdGUgQVNDSUkgb3IgVW5pY29kZSBmdW5jdGlvbiBpcyBjYWxsZWQgZm9yIHRoZSB3aW5kb3cuCiAqLwp2b2lkIFdJTkFQSSBTSFByb3BhZ2F0ZU1lc3NhZ2UoSFdORCBoV25kLCBVSU5UIHVpTXNnSWQsIFdQQVJBTSB3UGFyYW0sIExQQVJBTSBsUGFyYW0sIEJPT0wgYlNlbmQpCnsKICBlbnVtV25kRGF0YSBkYXRhOwoKICBUUkFDRSgiKCVwLCV1LCVkLCVsZCwlZClcbiIsIGhXbmQsIHVpTXNnSWQsIHdQYXJhbSwgbFBhcmFtLCBiU2VuZCk7CgogIGlmKGhXbmQpCiAgewogICAgZGF0YS51aU1zZ0lkID0gdWlNc2dJZDsKICAgIGRhdGEud1BhcmFtICA9IHdQYXJhbTsKICAgIGRhdGEubFBhcmFtICA9IGxQYXJhbTsKCiAgICBpZiAoYlNlbmQpCiAgICAgIGRhdGEucGZuUG9zdCA9IElzV2luZG93VW5pY29kZShoV25kKSA/ICh2b2lkKilTZW5kTWVzc2FnZVcgOiAodm9pZCopU2VuZE1lc3NhZ2VBOwogICAgZWxzZQogICAgICBkYXRhLnBmblBvc3QgPSBJc1dpbmRvd1VuaWNvZGUoaFduZCkgPyAodm9pZCopUG9zdE1lc3NhZ2VXIDogKHZvaWQqKVBvc3RNZXNzYWdlQTsKCiAgICBFbnVtQ2hpbGRXaW5kb3dzKGhXbmQsIFNITFdBUElfRW51bUNoaWxkUHJvYywgKExQQVJBTSkmZGF0YSk7CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTgwXQogKgogKiBSZW1vdmUgYWxsIHN1Yi1tZW51cyBmcm9tIGEgbWVudS4KICoKICogUEFSQU1TCiAqICBoTWVudSBbSV0gTWVudSB0byByZW1vdmUgc3ViLW1lbnVzIGZyb20KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogMC4gIEFsbCBzdWItbWVudXMgdW5kZXIgaE1lbnUgYXJlIHJlbW92ZWQKICogIEZhaWx1cmU6IC0xLCBpZiBhbnkgcGFyYW1ldGVyIGlzIGludmFsaWQKICovCkRXT1JEIFdJTkFQSSBTSFJlbW92ZUFsbFN1Yk1lbnVzKEhNRU5VIGhNZW51KQp7CiAgaW50IGlJdGVtQ291bnQgPSBHZXRNZW51SXRlbUNvdW50KGhNZW51KSAtIDE7CiAgd2hpbGUgKGlJdGVtQ291bnQgPj0gMCkKICB7CiAgICBITUVOVSBoU3ViTWVudSA9IEdldFN1Yk1lbnUoaE1lbnUsIGlJdGVtQ291bnQpOwogICAgaWYgKGhTdWJNZW51KQogICAgICBSZW1vdmVNZW51KGhNZW51LCBpSXRlbUNvdW50LCBNRl9CWVBPU0lUSU9OKTsKICAgIGlJdGVtQ291bnQtLTsKICB9CiAgcmV0dXJuIGlJdGVtQ291bnQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODFdCiAqCiAqIEVuYWJsZSBvciBkaXNhYmxlIGEgbWVudSBpdGVtLgogKgogKiBQQVJBTVMKICogIGhNZW51ICAgW0ldIE1lbnUgaG9sZGluZyBtZW51IGl0ZW0KICogIHVJRCAgICAgW0ldIElEIG9mIG1lbnUgaXRlbSB0byBlbmFibGUvZGlzYWJsZQogKiAgYkVuYWJsZSBbSV0gV2hldGhlciB0byBlbmFibGUgKFRSVUUpIG9yIGRpc2FibGUgKEZBTFNFKSB0aGUgaXRlbS4KICoKICogUkVUVVJOUwogKiAgVGhlIHJldHVybiBjb2RlIGZyb20gRW5hYmxlTWVudUl0ZW0uCiAqLwpVSU5UIFdJTkFQSSBTSEVuYWJsZU1lbnVJdGVtKEhNRU5VIGhNZW51LCBVSU5UIHdJdGVtSUQsIEJPT0wgYkVuYWJsZSkKewogIHJldHVybiBFbmFibGVNZW51SXRlbShoTWVudSwgd0l0ZW1JRCwgYkVuYWJsZSA/IE1GX0VOQUJMRUQgOiBNRl9HUkFZRUQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBACVtTSExXQVBJLjE4Ml0KICoKICogQ2hlY2sgb3IgdW5jaGVjayBhIG1lbnUgaXRlbS4KICoKICogUEFSQU1TCiAqICBoTWVudSAgW0ldIE1lbnUgaG9sZGluZyBtZW51IGl0ZW0KICogIHVJRCAgICBbSV0gSUQgb2YgbWVudSBpdGVtIHRvIGNoZWNrL3VuY2hlY2sKICogIGJDaGVjayBbSV0gV2hldGhlciB0byBjaGVjayAoVFJVRSkgb3IgdW5jaGVjayAoRkFMU0UpIHRoZSBpdGVtLgogKgogKiBSRVRVUk5TCiAqICBUaGUgcmV0dXJuIGNvZGUgZnJvbSBDaGVja01lbnVJdGVtLgogKi8KRFdPUkQgV0lOQVBJIFNIQ2hlY2tNZW51SXRlbShITUVOVSBoTWVudSwgVUlOVCB1SUQsIEJPT0wgYkNoZWNrKQp7CiAgcmV0dXJuIENoZWNrTWVudUl0ZW0oaE1lbnUsIHVJRCwgYkNoZWNrID8gTUZfQ0hFQ0tFRCA6IE1GX1VOQ0hFQ0tFRCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODNdCiAqCiAqIFJlZ2lzdGVyIGEgd2luZG93IGNsYXNzIGlmIGl0IGlzbid0IGFscmVhZHkuCiAqCiAqIFBBUkFNUwogKiAgbHBXbmRDbGFzcyBbSV0gV2luZG93IGNsYXNzIHRvIHJlZ2lzdGVyCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXN1bHQgb2YgdGhlIFJlZ2lzdGVyQ2xhc3NBIGNhbGwuCiAqLwpEV09SRCBXSU5BUEkgU0hSZWdpc3RlckNsYXNzQShXTkRDTEFTU0EgKnduZGNsYXNzKQp7CiAgV05EQ0xBU1NBIHdjYTsKICBpZiAoR2V0Q2xhc3NJbmZvQSh3bmRjbGFzcy0+aEluc3RhbmNlLCB3bmRjbGFzcy0+bHBzekNsYXNzTmFtZSwgJndjYSkpCiAgICByZXR1cm4gVFJVRTsKICByZXR1cm4gKERXT1JEKVJlZ2lzdGVyQ2xhc3NBKHduZGNsYXNzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4Nl0KICovCkJPT0wgV0lOQVBJIFNIU2ltdWxhdGVEcm9wKElEcm9wVGFyZ2V0ICpwRHJvcCwgSURhdGFPYmplY3QgKnBEYXRhT2JqLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBncmZLZXlTdGF0ZSwgUFBPSU5UTCBscFB0LCBEV09SRCogcGR3RWZmZWN0KQp7CiAgRFdPUkQgZHdFZmZlY3QgPSBEUk9QRUZGRUNUX0xJTksgfCBEUk9QRUZGRUNUX01PVkUgfCBEUk9QRUZGRUNUX0NPUFk7CiAgUE9JTlRMIHB0ID0geyAwLCAwIH07CgogIGlmICghbHBQdCkKICAgIGxwUHQgPSAmcHQ7CgogIGlmICghcGR3RWZmZWN0KQogICAgcGR3RWZmZWN0ID0gJmR3RWZmZWN0OwoKICBJRHJvcFRhcmdldF9EcmFnRW50ZXIocERyb3AsIHBEYXRhT2JqLCBncmZLZXlTdGF0ZSwgKmxwUHQsIHBkd0VmZmVjdCk7CgogIGlmICgqcGR3RWZmZWN0KQogICAgcmV0dXJuIElEcm9wVGFyZ2V0X0Ryb3AocERyb3AsIHBEYXRhT2JqLCBncmZLZXlTdGF0ZSwgKmxwUHQsIHBkd0VmZmVjdCk7CgogIElEcm9wVGFyZ2V0X0RyYWdMZWF2ZShwRHJvcCk7CiAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODddCiAqCiAqIENhbGwgSVBlcnNpc3RQcm9wZXJ0eUJhZ19Mb2FkKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElQZXJzaXN0UHJvcGVydHlCYWcgaW50ZXJmYWNlCiAqICBscFByb3BCYWcgW09dIERlc3RpbmF0aW9uIGZvciBsb2FkZWQgSVByb3BlcnR5QmFnCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfRkFJTCBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkRXT1JEIFdJTkFQSSBTSExvYWRGcm9tUHJvcGVydHlCYWcoSVVua25vd24gKmxwVW5rbm93biwgSVByb3BlcnR5QmFnKiBscFByb3BCYWcpCnsKICBJUGVyc2lzdFByb3BlcnR5QmFnKiBscFBQQmFnOwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwVW5rbm93biwgbHBQcm9wQmFnKTsKCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lQZXJzaXN0UHJvcGVydHlCYWcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBQUEJhZyk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwUFBCYWcpCiAgICB7CiAgICAgIGhSZXQgPSBJUGVyc2lzdFByb3BlcnR5QmFnX0xvYWQobHBQUEJhZywgbHBQcm9wQmFnLCBOVUxMKTsKICAgICAgSVBlcnNpc3RQcm9wZXJ0eUJhZ19SZWxlYXNlKGxwUFBCYWcpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgW1NITFdBUEkuMTg5XQogKgogKiBDYWxsIElPbGVDb250cm9sU2l0ZV9HZXRFeHRlbmRlZENvbnRyb2woKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbnRyb2xTaXRlIGludGVyZmFjZQogKiAgbHBwRGlzcCAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgcmVzdWx0aW5nIElEaXNwYXRjaC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9GQUlMIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KRFdPUkQgV0lOQVBJIElVbmtub3duX09uRm9jdXNPQ1MoSVVua25vd24gKmxwVW5rbm93biwgSURpc3BhdGNoKiogbHBwRGlzcCkKewogIElPbGVDb250cm9sU2l0ZSogbHBDU2l0ZTsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwcERpc3ApOwogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29udHJvbFNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBDU2l0ZSk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwQ1NpdGUpCiAgICB7CiAgICAgIGhSZXQgPSBJT2xlQ29udHJvbFNpdGVfR2V0RXh0ZW5kZWRDb250cm9sKGxwQ1NpdGUsIGxwcERpc3ApOwogICAgICBJT2xlQ29udHJvbFNpdGVfUmVsZWFzZShscENTaXRlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgW1NITFdBUEkuMTkyXQogKgogKiBHZXQgYSBzdWItbWVudSBmcm9tIGEgbWVudSBpdGVtLgogKgogKiBQQVJBTVMKICogIGhNZW51IFtJXSBNZW51IHRvIGdldCBzdWItbWVudSBmcm9tCiAqICB1SUQgICBbSV0gSUQgb2YgbWVudSBpdGVtIGNvbnRhaW5pbmcgc3ViLW1lbnUKICoKICogUkVUVVJOUwogKiAgVGhlIHN1Yi1tZW51IG9mIHRoZSBpdGVtLCBvciBhIE5VTEwgaGFuZGxlIGlmIGFueSBwYXJhbWV0ZXJzIGFyZSBpbnZhbGlkLgogKi8KSE1FTlUgV0lOQVBJIFNIR2V0TWVudUZyb21JRChITUVOVSBoTWVudSwgVUlOVCB1SUQpCnsKICBNRU5VSVRFTUlORk9BIG1pOwoKICBUUkFDRSgiKCVwLCV1bGQpXG4iLCBoTWVudSwgdUlEKTsKCiAgbWkuY2JTaXplID0gc2l6ZW9mKE1FTlVJVEVNSU5GT0EpOwogIG1pLmZNYXNrID0gTUlJTV9TVUJNRU5VOwoKICBpZiAoIUdldE1lbnVJdGVtSW5mb0EoaE1lbnUsIHVJRCwgMCwgJm1pKSkKICAgIHJldHVybiAoSE1FTlUpTlVMTDsKCiAgcmV0dXJuIG1pLmhTdWJNZW51Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTkzXQogKgogKiBHZXQgdGhlIGNvbG9yIGRlcHRoIG9mIHRoZSBwcmltYXJ5IGRpc3BsYXkuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGNvbG9yIGRlcHRoIG9mIHRoZSBwcmltYXJ5IGRpc3BsYXkuCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRDdXJDb2xvclJlcygpCnsKICAgIEhEQyBoZGM7CiAgICBEV09SRCByZXQ7CgogICAgVFJBQ0UoIigpXG4iKTsKCiAgICBoZGMgPSBHZXREQygwKTsKICAgIHJldCA9IEdldERldmljZUNhcHMoaGRjLCBCSVRTUElYRUwpICogR2V0RGV2aWNlQ2FwcyhoZGMsIFBMQU5FUyk7CiAgICBSZWxlYXNlREMoMCwgaGRjKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOTRdCiAqCiAqIFdhaXQgZm9yIGEgbWVzc2FnZSB0byBhcnJpdmUsIHdpdGggYSB0aW1lb3V0LgogKgogKiBQQVJBTVMKICogIGhhbmQgICAgICBbSV0gSGFuZGxlIHRvIHF1ZXJ5CiAqICBkd1RpbWVvdXQgW0ldIFRpbWVvdXQgaW4gdGlja3Mgb3IgSU5GSU5JVEUgdG8gbmV2ZXIgdGltZW91dAogKgogKiBSRVRVUk5TCiAqICBTVEFUVVNfVElNRU9VVCBpZiBubyBtZXNzYWdlIGlzIHJlY2VpdmVkIGJlZm9yZSBkd1RpbWVvdXQgdGlja3MgcGFzc2VzLgogKiAgT3RoZXJ3aXNlIHJldHVybnMgdGhlIHZhbHVlIGZyb20gTXNnV2FpdEZvck11bHRpcGxlT2JqZWN0c0V4IHdoZW4gYQogKiAgbWVzc2FnZSBpcyBhdmFpbGFibGUuCiAqLwpEV09SRCBXSU5BUEkgU0hXYWl0Rm9yU2VuZE1lc3NhZ2VUaHJlYWQoSEFORExFIGhhbmQsIERXT1JEIGR3VGltZW91dCkKewogIERXT1JEIGR3RW5kVGlja3MgPSBHZXRUaWNrQ291bnQoKSArIGR3VGltZW91dDsKICBEV09SRCBkd1JldDsKCiAgd2hpbGUgKChkd1JldCA9IE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHNFeCgxLCAmaGFuZCwgZHdUaW1lb3V0LCBRU19TRU5ETUVTU0FHRSwgMCkpID09IDEpCiAgewogICAgTVNHIG1zZzsKCiAgICBQZWVrTWVzc2FnZVcoJm1zZywgTlVMTCwgMCwgMCwgUE1fTk9SRU1PVkUpOwoKICAgIGlmIChkd1RpbWVvdXQgIT0gSU5GSU5JVEUpCiAgICB7CiAgICAgICAgaWYgKChpbnQpKGR3VGltZW91dCA9IGR3RW5kVGlja3MgLSBHZXRUaWNrQ291bnQoKSkgPD0gMCkKICAgICAgICAgICAgcmV0dXJuIFdBSVRfVElNRU9VVDsKICAgIH0KICB9CgogIHJldHVybiBkd1JldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE5N10KICoKICogQmxhbmsgb3V0IGEgcmVnaW9uIG9mIHRleHQgYnkgZHJhd2luZyB0aGUgYmFja2dyb3VuZCBvbmx5LgogKgogKiBQQVJBTVMKICogIGhEQyAgIFtJXSBEZXZpY2UgY29udGV4dCB0byBkcmF3IGluCiAqICBwUmVjdCBbSV0gQXJlYSB0byBkcmF3IGluCiAqICBjUmVmICBbSV0gQ29sb3IgdG8gZHJhdyBpbgogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KRFdPUkQgV0lOQVBJIFNIRmlsbFJlY3RDbHIoSERDIGhEQywgTFBDUkVDVCBwUmVjdCwgQ09MT1JSRUYgY1JlZikKewogICAgQ09MT1JSRUYgY09sZENvbG9yID0gU2V0QmtDb2xvcihoREMsIGNSZWYpOwogICAgRXh0VGV4dE91dEEoaERDLCAwLCAwLCBFVE9fT1BBUVVFLCBwUmVjdCwgMCwgMCwgMCk7CiAgICBTZXRCa0NvbG9yKGhEQywgY09sZENvbG9yKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTk4XQogKgogKiBSZXR1cm4gdGhlIHZhbHVlIGFzb2NpYXRlZCB3aXRoIGEga2V5IGluIGEgbWFwLgogKgogKiBQQVJBTVMKICogIGxwS2V5cyAgIFtJXSBBIGxpc3Qgb2Yga2V5cyBvZiBsZW5ndGggaUxlbgogKiAgbHBWYWx1ZXMgW0ldIEEgbGlzdCBvZiB2YWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGxwS2V5cywgb2YgbGVuZ3RoIGlMZW4KICogIGlMZW4gICAgIFtJXSBMZW5ndGggb2YgYm90aCBscEtleXMgYW5kIGxwVmFsdWVzCiAqICBpS2V5ICAgICBbSV0gVGhlIGtleSB2YWx1ZSB0byBsb29rIHVwIGluIGxwS2V5cwogKgogKiBSRVRVUk5TCiAqICBUaGUgdmFsdWUgaW4gbHBWYWx1ZXMgYXNzb2NpYXRlZCB3aXRoIGlLZXksIG9yIC0xIGlmIGlLZXkgaXMgbm90CiAqICBmb3VuZCBpbiBscEtleXMuCiAqCiAqIE5PVEVTCiAqICAtIElmIHR3byBlbGVtZW50cyBpbiB0aGUgbWFwIHNoYXJlIHRoZSBzYW1lIGtleSwgdGhpcyBmdW5jdGlvbiByZXR1cm5zCiAqICAgIHRoZSB2YWx1ZSBjbG9zZXN0IHRvIHRoZSBzdGFydCBvZiB0aGUgbWFwCiAqICAtIFRoZSBuYXRpdmUgdmVyc2lvbiBvZiB0aGlzIGZ1bmN0aW9uIGNyYXNoZXMgaWYgbHBLZXlzIG9yIGxwVmFsdWVzIGlzIE5VTEwuCiAqLwppbnQgV0lOQVBJIFNIU2VhcmNoTWFwSW50KGNvbnN0IGludCAqbHBLZXlzLCBjb25zdCBpbnQgKmxwVmFsdWVzLCBpbnQgaUxlbiwgaW50IGlLZXkpCnsKICBpZiAobHBLZXlzICYmIGxwVmFsdWVzKQogIHsKICAgIGludCBpID0gMDsKCiAgICB3aGlsZSAoaSA8IGlMZW4pCiAgICB7CiAgICAgIGlmIChscEtleXNbaV0gPT0gaUtleSkKICAgICAgICByZXR1cm4gbHBWYWx1ZXNbaV07IC8qIEZvdW5kICovCiAgICAgIGkrKzsKICAgIH0KICB9CiAgcmV0dXJuIC0xOyAvKiBOb3QgZm91bmQgKi8KfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xOTldCiAqCiAqIENvcHkgYW4gaW50ZXJmYWNlIHBvaW50ZXIKICoKICogUEFSQU1TCiAqICAgbHBwRGVzdCAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29weQogKiAgIGxwVW5rbm93biBbSV0gU291cmNlIGZvciBjb3B5CiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwpWT0lEIFdJTkFQSSBJVW5rbm93bl9TZXQoSVVua25vd24gKipscHBEZXN0LCBJVW5rbm93biAqbHBVbmtub3duKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwcERlc3QsIGxwVW5rbm93bik7CgogIGlmIChscHBEZXN0KQogICAgSVVua25vd25fQXRvbWljUmVsZWFzZShscHBEZXN0KTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICAvKiBDb3B5ICovCiAgICBJVW5rbm93bl9BZGRSZWYobHBVbmtub3duKTsKICAgICpscHBEZXN0ID0gbHBVbmtub3duOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwMV0KICoKICovCkhSRVNVTFQgV0lOQVBJIE1heUV4ZWNGb3J3YXJkKElVbmtub3duKiBscFVua25vd24sIElOVCBpVW5rLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIG5DbWRJRCwgRFdPUkQgbkNtZGV4ZWNvcHQsIFZBUklBTlQqIHB2YUluLAogICAgICAgICAgICAgICAgICAgICAgICAgICBWQVJJQU5UKiBwdmFPdXQpCnsKICBGSVhNRSgiKCVwLCVkLCVwLCVsZCwlbGQsJXAsJXApIC0gc3R1YiFcbiIsIGxwVW5rbm93biwgaVVuaywgcGd1aWRDbWRHcm91cCwKICAgICAgICBuQ21kSUQsIG5DbWRleGVjb3B0LCBwdmFJbiwgcHZhT3V0KTsKICByZXR1cm4gRFJBR0RST1BfRV9OT1RSRUdJU1RFUkVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjAyXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgSXNRU0ZvcndhcmQoUkVGR1VJRCBwZ3VpZENtZEdyb3VwLFVMT05HIGNDbWRzLCBPTEVDTUQgKnByZ0NtZHMpCnsKICBGSVhNRSgiKCVwLCVsZCwlcCkgLSBzdHViIVxuIiwgcGd1aWRDbWRHcm91cCwgY0NtZHMsIHByZ0NtZHMpOwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAJW1NITFdBUEkuMjA0XQogKgogKiBEZXRlcm1pbmUgaWYgYSB3aW5kb3cgaXMgbm90IGEgY2hpbGQgb2YgYW5vdGhlciB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiBoUGFyZW50IFtJXSBTdXNwZWN0ZWQgcGFyZW50IHdpbmRvdwogKiBoQ2hpbGQgIFtJXSBTdXNwZWN0ZWQgY2hpbGQgd2luZG93CiAqCiAqIFJFVFVSTlMKICogVFJVRTogIElmIGhDaGlsZCBpcyBhIGNoaWxkIHdpbmRvdyBvZiBoUGFyZW50CiAqIEZBTFNFOiBJZiBoQ2hpbGQgaXMgbm90IGEgY2hpbGQgd2luZG93IG9mIGhQYXJlbnQsIG9yIHRoZXkgYXJlIGVxdWFsCiAqLwpCT09MIFdJTkFQSSBTSElzQ2hpbGRPclNlbGYoSFdORCBoUGFyZW50LCBIV05EIGhDaGlsZCkKewogIFRSQUNFKCIoJXAsJXApXG4iLCBoUGFyZW50LCBoQ2hpbGQpOwoKICBpZiAoIWhQYXJlbnQgfHwgIWhDaGlsZCkKICAgIHJldHVybiBUUlVFOwogIGVsc2UgaWYoaFBhcmVudCA9PSBoQ2hpbGQpCiAgICByZXR1cm4gRkFMU0U7CiAgcmV0dXJuICFJc0NoaWxkKGhQYXJlbnQsIGhDaGlsZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDhdCiAqCiAqIFNvbWUgc29ydCBvZiBtZW1vcnkgbWFuYWdlbWVudCBwcm9jZXNzLgogKi8KRFdPUkQgV0lOQVBJIEZEU0FfSW5pdGlhbGl6ZSgKCURXT1JEICAgIGEsCglEV09SRCAgICBiLAoJTFBWT0lEICAgYywKCUxQVk9JRCAgIGQsCglEV09SRCAgICBlKQp7CiAgICBGSVhNRSgiKDB4JTA4bHggMHglMDhseCAlcCAlcCAweCUwOGx4KSBzdHViXG4iLAoJICBhLCBiLCBjLCBkLCBlKTsKICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjA5XQogKgogKiBTb21lIHNvcnQgb2YgbWVtb3J5IG1hbmFnZW1lbnQgcHJvY2Vzcy4KICovCkRXT1JEIFdJTkFQSSBGRFNBX0Rlc3Ryb3koCglMUFZPSUQgICBhKQp7CiAgICBGSVhNRSgiKCVwKSBzdHViXG4iLAoJICBhKTsKICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjEwXQogKgogKiBTb21lIHNvcnQgb2YgbWVtb3J5IG1hbmFnZW1lbnQgcHJvY2Vzcy4KICovCkRXT1JEIFdJTkFQSSBGRFNBX0luc2VydEl0ZW0oCglMUFZPSUQgICBhLAoJRFdPUkQgICAgYiwKCUxQVk9JRCAgIGMpCnsKICAgIEZJWE1FKCIoJXAgMHglMDhseCAlcCkgc3R1YlxuIiwKCSAgYSwgYiwgYyk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxMV0KICovCkRXT1JEIFdJTkFQSSBGRFNBX0RlbGV0ZUl0ZW0oCglMUFZPSUQgICBhLAoJRFdPUkQgICAgYikKewogICAgRklYTUUoIiglcCAweCUwOGx4KSBzdHViXG4iLAoJICBhLCBiKTsKICAgIHJldHVybiAxOwp9Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBSRUZJSUQgICByZWZpZDsKICAgIERXT1JEICAgIGluZHg7Cn0gSUZBQ0VfSU5ERVhfVEJMOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxOV0KICoKICogQ2FsbCBJVW5rbm93bl9RdWVyeUludGVyZmFjZSgpIG9uIGEgdGFibGUgb2Ygb2JqZWN0cy4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfUE9JTlRFUiBvciBFX05PSU5URVJGQUNFLgogKi8KSFJFU1VMVCBXSU5BUEkgUUlTZWFyY2goCglMUFZPSUQgdywgICAgICAgICAgIC8qIFtpbl0gICBUYWJsZSBvZiBpbnRlcmZhY2VzICovCglJRkFDRV9JTkRFWF9UQkwgKngsIC8qIFtpbl0gICBBcnJheSBvZiBSRUZJSURzIGFuZCBpbmRleGVzIGludG8gdGhlIHRhYmxlICovCglSRUZJSUQgcmlpZCwgICAgICAgIC8qIFtpbl0gICBSRUZJSUQgdG8gZ2V0IGludGVyZmFjZSBmb3IgKi8KCUxQVk9JRCAqcHB2KSAgICAgICAgICAvKiBbb3V0XSAgRGVzdGluYXRpb24gZm9yIGludGVyZmFjZSBwb2ludGVyICovCnsKCUhSRVNVTFQgcmV0OwoJSVVua25vd24gKmFfdnRibDsKCUlGQUNFX0lOREVYX1RCTCAqeG1vdmU7CgoJVFJBQ0UoIiglcCAlcCAlcyAlcClcbiIsIHcseCxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdik7CglpZiAocHB2KSB7CgkgICAgeG1vdmUgPSB4OwoJICAgIHdoaWxlICh4bW92ZS0+cmVmaWQpIHsKCQlUUkFDRSgidHJ5aW5nIChpbmR4ICVsZCkgJXNcbiIsIHhtb3ZlLT5pbmR4LCBkZWJ1Z3N0cl9ndWlkKHhtb3ZlLT5yZWZpZCkpOwoJCWlmIChJc0VxdWFsSUlEKHJpaWQsIHhtb3ZlLT5yZWZpZCkpIHsKCQkgICAgYV92dGJsID0gKElVbmtub3duKikoeG1vdmUtPmluZHggKyAoTFBCWVRFKXcpOwoJCSAgICBUUkFDRSgibWF0Y2hlZCwgcmV0dXJuaW5nICglcClcbiIsIGFfdnRibCk7CgkJICAgICpwcHYgPSAoTFBWT0lEKWFfdnRibDsKCQkgICAgSVVua25vd25fQWRkUmVmKGFfdnRibCk7CgkJICAgIHJldHVybiBTX09LOwoJCX0KCQl4bW92ZSsrOwoJICAgIH0KCgkgICAgaWYgKElzRXF1YWxJSUQocmlpZCwgJklJRF9JVW5rbm93bikpIHsKCQlhX3Z0YmwgPSAoSVVua25vd24qKSh4LT5pbmR4ICsgKExQQllURSl3KTsKCQlUUkFDRSgicmV0dXJuaW5nIGZpcnN0IGZvciBJVW5rbm93biAoJXApXG4iLCBhX3Z0YmwpOwoJCSpwcHYgPSAoTFBWT0lEKWFfdnRibDsKCQlJVW5rbm93bl9BZGRSZWYoYV92dGJsKTsKCQlyZXR1cm4gU19PSzsKCSAgICB9CgkgICAgKnBwdiA9IDA7CgkgICAgcmV0ID0gRV9OT0lOVEVSRkFDRTsKCX0gZWxzZQoJICAgIHJldCA9IEVfUE9JTlRFUjsKCglUUkFDRSgiLS0gMHglMDhseFxuIiwgcmV0KTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMjFdCiAqCiAqIFJlbW92ZSB0aGUgIlByb3BEbGdGb250IiBwcm9wZXJ0eSBmcm9tIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgW0ldIFdpbmRvdyB0byByZW1vdmUgdGhlIHByb3BlcnR5IGZyb20KICoKICogUkVUVVJOUwogKiAgQSBoYW5kbGUgdG8gdGhlIHJlbW92ZWQgcHJvcGVydHksIG9yIE5VTEwgaWYgaXQgZGlkIG5vdCBleGlzdC4KICovCkhBTkRMRSBXSU5BUEkgU0hSZW1vdmVEZWZhdWx0RGlhbG9nRm9udChIV05EIGhXbmQpCnsKICBIQU5ETEUgaFByb3A7CgogIFRSQUNFKCIoJXApXG4iLCBoV25kKTsKCiAgaFByb3AgPSBHZXRQcm9wQShoV25kLCAiUHJvcERsZ0ZvbnQiKTsKCiAgaWYoaFByb3ApCiAgewogICAgRGVsZXRlT2JqZWN0KGhQcm9wKTsKICAgIGhQcm9wID0gUmVtb3ZlUHJvcEEoaFduZCwgIlByb3BEbGdGb250Iik7CiAgfQogIHJldHVybiBoUHJvcDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzNl0KICoKICogTG9hZCB0aGUgaW4tcHJvY2VzcyBzZXJ2ZXIgb2YgYSBnaXZlbiBHVUlELgogKgogKiBQQVJBTVMKICogIHJlZmlpZCBbSV0gR1VJRCBvZiB0aGUgc2VydmVyIHRvIGxvYWQuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgc2VydmVyIGRsbC4KICogIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqLwpITU9EVUxFIFdJTkFQSSBTSFBpbkRsbE9mQ0xTSUQoUkVGSUlEIHJlZmlpZCkKewogICAgSEtFWSBuZXdrZXk7CiAgICBEV09SRCB0eXBlLCBjb3VudDsKICAgIENIQVIgdmFsdWVbTUFYX1BBVEhdLCBzdHJpbmdbTUFYX1BBVEhdOwoKICAgIHN0cmNweShzdHJpbmcsICJDTFNJRFxcIik7CiAgICBTSFN0cmluZ0Zyb21HVUlEQShyZWZpaWQsIHN0cmluZyArIDYsIHNpemVvZihzdHJpbmcpL3NpemVvZihjaGFyKSAtIDYpOwogICAgc3RyY2F0KHN0cmluZywgIlxcSW5Qcm9jU2VydmVyMzIiKTsKCiAgICBjb3VudCA9IE1BWF9QQVRIOwogICAgUmVnT3BlbktleUV4QShIS0VZX0NMQVNTRVNfUk9PVCwgc3RyaW5nLCAwLCAxLCAmbmV3a2V5KTsKICAgIFJlZ1F1ZXJ5VmFsdWVFeEEobmV3a2V5LCAwLCAwLCAmdHlwZSwgKFBCWVRFKXZhbHVlLCAmY291bnQpOwogICAgUmVnQ2xvc2VLZXkobmV3a2V5KTsKICAgIHJldHVybiBMb2FkTGlicmFyeUV4QSh2YWx1ZSwgMCwgMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzddCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSExXQVBJXzE4My4KICovCkRXT1JEIFdJTkFQSSBTSFJlZ2lzdGVyQ2xhc3NXKFdORENMQVNTVyAqIGxwV25kQ2xhc3MpCnsKCVdORENMQVNTVyBXbmRDbGFzczsKCglUUkFDRSgiKCVwICVzKVxuIixscFduZENsYXNzLT5oSW5zdGFuY2UsIGRlYnVnc3RyX3cobHBXbmRDbGFzcy0+bHBzekNsYXNzTmFtZSkpOwoKCWlmIChHZXRDbGFzc0luZm9XKGxwV25kQ2xhc3MtPmhJbnN0YW5jZSwgbHBXbmRDbGFzcy0+bHBzekNsYXNzTmFtZSwgJlduZENsYXNzKSkKCQlyZXR1cm4gVFJVRTsKCXJldHVybiBSZWdpc3RlckNsYXNzVyhscFduZENsYXNzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzOF0KICoKICogVW5yZWdpc3RlciBhIGxpc3Qgb2YgY2xhc3Nlcy4KICoKICogUEFSQU1TCiAqICBoSW5zdCAgICAgIFtJXSBBcHBsaWNhdGlvbiBpbnN0YW5jZSB0aGF0IHJlZ2lzdGVyZWQgdGhlIGNsYXNzZXMKICogIGxwcENsYXNzZXMgW0ldIExpc3Qgb2YgY2xhc3MgbmFtZXMKICogIGlDb3VudCAgICAgW0ldIE51bWJlciBvZiBuYW1lcyBpbiBscHBDbGFzc2VzCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwp2b2lkIFdJTkFQSSBTSFVucmVnaXN0ZXJDbGFzc2VzQShISU5TVEFOQ0UgaEluc3QsIExQQ1NUUiAqbHBwQ2xhc3NlcywgSU5UIGlDb3VudCkKewogIFdORENMQVNTQSBXbmRDbGFzczsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIGhJbnN0LCBscHBDbGFzc2VzLCBpQ291bnQpOwoKICB3aGlsZSAoaUNvdW50ID4gMCkKICB7CiAgICBpZiAoR2V0Q2xhc3NJbmZvQShoSW5zdCwgKmxwcENsYXNzZXMsICZXbmRDbGFzcykpCiAgICAgIFVucmVnaXN0ZXJDbGFzc0EoKmxwcENsYXNzZXMsIGhJbnN0KTsKICAgIGxwcENsYXNzZXMrKzsKICAgIGlDb3VudC0tOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzOV0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNIVW5yZWdpc3RlckNsYXNzZXNBLgogKi8Kdm9pZCBXSU5BUEkgU0hVbnJlZ2lzdGVyQ2xhc3Nlc1coSElOU1RBTkNFIGhJbnN0LCBMUENXU1RSICpscHBDbGFzc2VzLCBJTlQgaUNvdW50KQp7CiAgV05EQ0xBU1NXIFduZENsYXNzOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaEluc3QsIGxwcENsYXNzZXMsIGlDb3VudCk7CgogIHdoaWxlIChpQ291bnQgPiAwKQogIHsKICAgIGlmIChHZXRDbGFzc0luZm9XKGhJbnN0LCAqbHBwQ2xhc3NlcywgJlduZENsYXNzKSkKICAgICAgVW5yZWdpc3RlckNsYXNzVygqbHBwQ2xhc3NlcywgaEluc3QpOwogICAgbHBwQ2xhc3NlcysrOwogICAgaUNvdW50LS07CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjQwXQogKgogKiBDYWxsIFRoZSBjb3JyZWN0IChBc2NpaS9Vbmljb2RlKSBkZWZhdWx0IHdpbmRvdyBwcm9jZWR1cmUgZm9yIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgIFtJXSBXaW5kb3cgdG8gY2FsbCB0aGUgZGVmYXVsdCBwcm9jZWR1cmUgZm9yCiAqICB1TWVzc2FnZSBbSV0gTWVzc2FnZSBJRAogKiAgd1BhcmFtICAgW0ldIFdQQVJBTSBvZiBtZXNzYWdlCiAqICBsUGFyYW0gICBbSV0gTFBBUkFNIG9mIG1lc3NhZ2UKICoKICogUkVUVVJOUwogKiAgVGhlIHJlc3VsdCBvZiBjYWxsaW5nIERlZldpbmRvd1Byb2NBKCkgb3IgRGVmV2luZG93UHJvY1coKS4KICovCkxSRVNVTFQgQ0FMTEJBQ0sgU0hEZWZXaW5kb3dQcm9jKEhXTkQgaFduZCwgVUlOVCB1TWVzc2FnZSwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewoJaWYgKElzV2luZG93VW5pY29kZShoV25kKSkKCQlyZXR1cm4gRGVmV2luZG93UHJvY1coaFduZCwgdU1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtKTsKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TWVzc2FnZSwgd1BhcmFtLCBsUGFyYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjU3XQogKgogKiBDcmVhdGUgYSB3b3JrZXIgd2luZG93IHVzaW5nIENyZWF0ZVdpbmRvd0V4QSgpLgogKgogKiBQQVJBTVMKICogIHduZFByb2MgICAgW0ldIFdpbmRvdyBwcm9jZWR1cmUKICogIGhXbmRQYXJlbnQgW0ldIFBhcmVudCB3aW5kb3cKICogIGR3RXhTdHlsZSAgW0ldIEV4dHJhIHN0eWxlIGZsYWdzCiAqICBkd1N0eWxlICAgIFtJXSBTdHlsZSBmbGFncwogKiAgaE1lbnUgICAgICBbSV0gV2luZG93IG1lbnUKICogIHogICAgICAgICAgW0ldIFVua25vd24KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVGhlIHdpbmRvdyBoYW5kbGUgb2YgdGhlIG5ld2x5IGNyZWF0ZWQgd2luZG93LgogKiAgRmFpbHVyZTogMC4KICovCkhXTkQgV0lOQVBJIFNIQ3JlYXRlV29ya2VyV2luZG93QShMT05HIHduZFByb2MsIEhXTkQgaFduZFBhcmVudCwgRFdPUkQgZHdFeFN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1N0eWxlLCBITUVOVSBoTWVudSwgTE9ORyB6KQp7CiAgc3RhdGljIGNvbnN0IGNoYXIqIHN6Q2xhc3MgPSAiV29ya2VyQSI7CiAgV05EQ0xBU1NBIHdjOwogIEhXTkQgaFduZDsKCiAgVFJBQ0UoIigweCUwOGx4LCVwLDB4JTA4bHgsMHglMDhseCwlcCwweCUwOGx4KVxuIiwKICAgICAgICAgd25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIENyZWF0ZSBXaW5kb3cgY2xhc3MgKi8KICB3Yy5zdHlsZSAgICAgICAgID0gMDsKICB3Yy5scGZuV25kUHJvYyAgID0gRGVmV2luZG93UHJvY0E7CiAgd2MuY2JDbHNFeHRyYSAgICA9IDA7CiAgd2MuY2JXbmRFeHRyYSAgICA9IDQ7CiAgd2MuaEluc3RhbmNlICAgICA9IHNobHdhcGlfaEluc3RhbmNlOwogIHdjLmhJY29uICAgICAgICAgPSAoSElDT04pMDsKICB3Yy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvckEoKEhJTlNUQU5DRSkwLCAoTFBTVFIpSURDX0FSUk9XKTsKICB3Yy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSClDT0xPUl9CVE5TSEFET1c7CiAgd2MubHBzek1lbnVOYW1lICA9IE5VTEw7CiAgd2MubHBzekNsYXNzTmFtZSA9IHN6Q2xhc3M7CgogIFNIUmVnaXN0ZXJDbGFzc0EoJndjKTsgLyogUmVnaXN0ZXIgY2xhc3MgKi8KCiAgLyogRklYTUU6IFNldCBleHRyYSBiaXRzIGluIGR3RXhTdHlsZSAqLwoKICBoV25kID0gQ3JlYXRlV2luZG93RXhBKGR3RXhTdHlsZSwgc3pDbGFzcywgMCwgZHdTdHlsZSwgMCwgMCwgMCwgMCwKICAgICAgICAgICAgICAgICAgICAgICAgIGhXbmRQYXJlbnQsIGhNZW51LCBzaGx3YXBpX2hJbnN0YW5jZSwgMCk7CiAgaWYgKGhXbmQpCiAgewogICAgU2V0V2luZG93TG9uZ0EoaFduZCwgRFdMX01TR1JFU1VMVCwgeik7CgogICAgaWYgKHduZFByb2MpCiAgICAgIFNldFdpbmRvd0xvbmdBKGhXbmQsIEdXTF9XTkRQUk9DLCB3bmRQcm9jKTsKICB9CiAgcmV0dXJuIGhXbmQ7Cn0KCnR5cGVkZWYgc3RydWN0IHRhZ1BPTElDWURBVEEKewogIERXT1JEIHBvbGljeTsgICAgICAgIC8qIGZsYWdzIHZhbHVlIHBhc3NlZCB0byBTSFJlc3RyaWN0ZWQgKi8KICBMUENXU1RSIGFwcHN0cjsgICAgICAvKiBhcHBsaWNhdGlvbiBzdHIgc3VjaCBhcyAiRXhwbG9yZXIiICovCiAgTFBDV1NUUiBrZXlzdHI7ICAgICAgLyogbmFtZSBvZiB0aGUgYWN0dWFsIHJlZ2lzdHJ5IGtleSAvIHBvbGljeSAqLwp9IFBPTElDWURBVEEsICpMUFBPTElDWURBVEE7CgojZGVmaW5lIFNIRUxMX05PX1BPTElDWSAweGZmZmZmZmZmCgovKiBkZWZhdWx0IHNoZWxsIHBvbGljeSByZWdpc3RyeSBrZXkgKi8Kc3RhdGljIGNvbnN0IFdDSEFSIHN0clJlZ2lzdHJ5UG9saWN5V1tdID0geydTJywnbycsJ2YnLCd0JywndycsJ2EnLCdyJywnZScsJ1xcJywnTScsJ2knLCdjJywncicsJ28nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ1xcJywnUCcsJ28nLCdsJywnaScsJ2MnLCdpJywnZScsJ3MnLDB9OwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICAgICAgICAgICAgICAgICAgICAgICAgW1NITFdBUEkuMjcxXQogKgogKiBSZXRyaWV2ZSBhIHBvbGljeSB2YWx1ZSBmcm9tIHRoZSByZWdpc3RyeS4KICoKICogUEFSQU1TCiAqICBscFN1YktleSAgIFtJXSAgIHJlZ2lzdHJ5IGtleSBuYW1lCiAqICBscFN1Yk5hbWUgIFtJXSAgIHN1Ym5hbWUgb2YgcmVnaXN0cnkga2V5CiAqICBscFZhbHVlICAgIFtJXSAgIHZhbHVlIG5hbWUgb2YgcmVnaXN0cnkgdmFsdWUKICoKICogUkVUVVJOUwogKiAgdGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUgcmVnaXN0cnkga2V5IG9yIDAgaWYgbm90IGZvdW5kCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRSZXN0cmljdGlvbihMUENXU1RSIGxwU3ViS2V5LCBMUENXU1RSIGxwU3ViTmFtZSwgTFBDV1NUUiBscFZhbHVlKQp7CglEV09SRCByZXR2YWwsIGRhdHNpemUgPSBzaXplb2YocmV0dmFsKTsKCUhLRVkgaEtleTsKCglpZiAoIWxwU3ViS2V5KQoJICBscFN1YktleSA9IHN0clJlZ2lzdHJ5UG9saWN5VzsKCglyZXR2YWwgPSBSZWdPcGVuS2V5VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIGxwU3ViS2V5LCAmaEtleSk7CiAgICBpZiAocmV0dmFsICE9IEVSUk9SX1NVQ0NFU1MpCgkgIHJldHZhbCA9IFJlZ09wZW5LZXlXKEhLRVlfQ1VSUkVOVF9VU0VSLCBscFN1YktleSwgJmhLZXkpOwoJaWYgKHJldHZhbCAhPSBFUlJPUl9TVUNDRVNTKQoJICByZXR1cm4gMDsKCglTSEdldFZhbHVlVyhoS2V5LCBscFN1Yk5hbWUsIGxwVmFsdWUsIE5VTEwsIChMUEJZVEUpJnJldHZhbCwgJmRhdHNpemUpOwoJUmVnQ2xvc2VLZXkoaEtleSk7CglyZXR1cm4gcmV0dmFsOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgICAgICAgICAgICAgICAgICAgICAgIFtTSExXQVBJLjI2Nl0KICoKICogSGVscGVyIGZ1bmN0aW9uIHRvIHJldHJpZXZlIHRoZSBwb3NzaWJseSBjYWNoZWQgdmFsdWUgZm9yIGEgc3BlY2lmaWMgcG9saWN5CiAqCiAqIFBBUkFNUwogKiAgcG9saWN5ICAgICBbSV0gICBUaGUgcG9saWN5IHRvIGxvb2sgZm9yCiAqICBpbml0aWFsICAgIFtJXSAgIE1haW4gcmVnaXN0cnkga2V5IHRvIG9wZW4sIGlmIE5VTEwgdXNlIGRlZmF1bHQKICogIHBvbFRhYmxlICAgW0ldICAgVGFibGUgb2Yga25vd24gcG9saWNpZXMsIDAgdGVybWluYXRlZAogKiAgcG9sQXJyICAgICBbSV0gICBDYWNoZSBhcnJheSBvZiBwb2xpY3kgdmFsdWVzCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXRyaWV2ZWQgcG9saWN5IHZhbHVlIG9yIDAgaWYgbm90IHN1Y2Nlc3NmdWwKICoKICogTk9URVMKICogIFRoaXMgZnVuY3Rpb24gaXMgdXNlZCBieSB0aGUgbmF0aXZlIFNIUmVzdHJpY3RlZCBmdW5jdGlvbiB0byBzZWFyY2ggZm9yIHRoZQogKiAgcG9saWN5IGFuZCBjYWNoZSBpdCBvbmNlIHJldHJpZXZlZC4gVGhlIGN1cnJlbnQgV2luZSBpbXBsZW1lbnRhdGlvbiB1c2VzIGEKICogIGRpZmZlcmVudCBQT0xJQ1lEQVRBIHN0cnVjdHVyZSBhbmQgaW1wbGVtZW50cyBhIHNpbWlsYXIgYWxnb3JpdGhtZSBhZGFwdGVkIHRvCiAqICB0aGF0IHN0cnVjdHVyZS4KICovCkRXT1JEIFdJTkFQSSBTSFJlc3RyaWN0aW9uTG9va3VwKAoJRFdPUkQgcG9saWN5LAoJTFBDV1NUUiBpbml0aWFsLAoJTFBQT0xJQ1lEQVRBIHBvbFRhYmxlLAoJTFBEV09SRCBwb2xBcnIpCnsKCVRSQUNFKCIoMHglMDhseCAlcyAlcCAlcClcbiIsIHBvbGljeSwgZGVidWdzdHJfdyhpbml0aWFsKSwgcG9sVGFibGUsIHBvbEFycik7CgoJaWYgKCFwb2xUYWJsZSB8fCAhcG9sQXJyKQoJICByZXR1cm4gMDsKCglmb3IgKDtwb2xUYWJsZS0+cG9saWN5OyBwb2xUYWJsZSsrLCBwb2xBcnIrKykKCXsKCSAgaWYgKHBvbGljeSA9PSBwb2xUYWJsZS0+cG9saWN5KQoJICB7CgkgICAgLyogd2UgaGF2ZSBhIGtub3duIHBvbGljeSAqLwoKCSAgICAvKiBjaGVjayBpZiB0aGlzIHBvbGljeSBoYXMgYmVlbiBjYWNoZWQgKi8KCQlpZiAoKnBvbEFyciA9PSBTSEVMTF9OT19QT0xJQ1kpCgkgICAgICAqcG9sQXJyID0gU0hHZXRSZXN0cmljdGlvbihpbml0aWFsLCBwb2xUYWJsZS0+YXBwc3RyLCBwb2xUYWJsZS0+a2V5c3RyKTsKCSAgICByZXR1cm4gKnBvbEFycjsKCSAgfQoJfQoJLyogd2UgZG9uJ3Qga25vdyB0aGlzIHBvbGljeSwgcmV0dXJuIDAgKi8KCVRSQUNFKCJ1bmtub3duIHBvbGljeTogKCUwOGx4KVxuIiwgcG9saWN5KTsKCXJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjY3XQogKgogKiBHZXQgYW4gaW50ZXJmYWNlIGZyb20gYW4gb2JqZWN0LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBwcHYgY29udGFpbnMgdGhlIHJlcXVlc3RlZCBpbnRlcmZhY2UuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUuCiAqCiAqIE5PVEVTCiAqICAgVGhpcyBRdWVyeUludGVyZmFjZSBhc2tzIHRoZSBpbm5lciBvYmplY3QgZm9yIGEgaW50ZXJmYWNlLiBJbiBjYXNlCiAqICAgb2YgYWdncmVnYXRpb24gdGhpcyByZXF1ZXN0IHdvdWxkIGJlIGZvcndhcmRlZCBieSB0aGUgaW5uZXIgdG8gdGhlCiAqICAgb3V0ZXIgb2JqZWN0LiBUaGlzIGZ1bmN0aW9uIGFza3MgdGhlIGlubmVyIG9iamVjdCBkaXJlY3RseSBmb3IgdGhlCiAqICAgaW50ZXJmYWNlIGNpcmN1bXZlbnRpbmcgdGhlIGZvcndhcmRpbmcgdG8gdGhlIG91dGVyIG9iamVjdC4KICovCkhSRVNVTFQgV0lOQVBJIFNIV2Vha1F1ZXJ5SW50ZXJmYWNlKAoJSVVua25vd24gKiBwVW5rLCAgIC8qIFtpbl0gT3V0ZXIgb2JqZWN0ICovCglJVW5rbm93biAqIHBJbm5lciwgLyogW2luXSBJbm5lciBvYmplY3QgKi8KCUlJRCAqIHJpaWQsIC8qIFtpbl0gSW50ZXJmYWNlIEdVSUQgdG8gcXVlcnkgZm9yICovCglMUFZPSUQqIHBwdikgLyogW291dF0gRGVzdGluYXRpb24gZm9yIHF1ZXJpZWQgaW50ZXJmYWNlICovCnsKCUhSRVNVTFQgaHJldCA9IEVfTk9JTlRFUkZBQ0U7CglUUkFDRSgiKHBVbms9JXAgcElubmVyPSVwXG5cdElJRDogICVzICVwKVxuIixwVW5rLHBJbm5lcixkZWJ1Z3N0cl9ndWlkKHJpaWQpLCBwcHYpOwoKCSpwcHYgPSBOVUxMOwoJaWYocFVuayAmJiBwSW5uZXIpIHsKCSAgICBocmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UocElubmVyLCByaWlkLCAoTFBWT0lEKilwcHYpOwoJICAgIGlmIChTVUNDRUVERUQoaHJldCkpIElVbmtub3duX1JlbGVhc2UocFVuayk7Cgl9CglUUkFDRSgiLS0gMHglMDhseFxuIiwgaHJldCk7CglyZXR1cm4gaHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI2OF0KICoKICogTW92ZSBhIHJlZmVyZW5jZSBmcm9tIG9uZSBpbnRlcmZhY2UgdG8gYW5vdGhlci4KICoKICogUEFSQU1TCiAqICAgbHBEZXN0ICAgICBbT10gRGVzdGluYXRpb24gdG8gcmVjZWl2ZSB0aGUgcmVmZXJlbmNlCiAqICAgbHBwVW5rbm93biBbT10gU291cmNlIHRvIGdpdmUgdXAgdGhlIHJlZmVyZW5jZSB0byBscERlc3QKICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovClZPSUQgV0lOQVBJIFNIV2Vha1JlbGVhc2VJbnRlcmZhY2UoSVVua25vd24gKmxwRGVzdCwgSVVua25vd24gKipscHBVbmtub3duKQp7CiAgVFJBQ0UoIiglcCwlcClcbiIsIGxwRGVzdCwgbHBwVW5rbm93bik7CgogIGlmICgqbHBwVW5rbm93bikKICB7CiAgICAvKiBDb3B5IFJlZmVyZW5jZSovCiAgICBJVW5rbm93bl9BZGRSZWYobHBEZXN0KTsKICAgIElVbmtub3duX0F0b21pY1JlbGVhc2UobHBwVW5rbm93bik7IC8qIFJlbGVhc2UgZXhpc3RpbmcgaW50ZXJmYWNlICovCiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjY5XQogKgogKiBDb252ZXJ0IGFuIEFTQ0lJIHN0cmluZyBvZiBhIENMU0lEIGludG8gYSBDTFNJRC4KICoKICogUEFSQU1TCiAqICBpZHN0ciBbSV0gU3RyaW5nIHJlcHJlc2VudGluZyBhIENMU0lEIGluIHJlZ2lzdHJ5IGZvcm1hdAogKiAgaWQgICAgW09dIERlc3RpbmF0aW9uIGZvciB0aGUgY29udmVydGVkIENMU0lECiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuIGlkIGNvbnRhaW5zIHRoZSBjb252ZXJ0ZWQgQ0xTSUQuCiAqICBGYWlsdXJlOiBGQUxTRS4KICovCkJPT0wgV0lOQVBJIEdVSURGcm9tU3RyaW5nQShMUENTVFIgaWRzdHIsIENMU0lEICppZCkKewogIFdDSEFSIHdDbHNpZFs0MF07CiAgTXVsdGlCeXRlVG9XaWRlQ2hhcihDUF9BQ1AsIDAsIGlkc3RyLCAtMSwgd0Nsc2lkLCBzaXplb2Yod0Nsc2lkKS9zaXplb2YoV0NIQVIpKTsKICByZXR1cm4gU1VDQ0VFREVEKENMU0lERnJvbVN0cmluZ1dyYXAod0Nsc2lkLCBpZCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjcwXQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgR1VJREZyb21TdHJpbmdBLgogKi8KQk9PTCBXSU5BUEkgR1VJREZyb21TdHJpbmdXKExQQ1dTVFIgaWRzdHIsIENMU0lEICppZCkKewogIHJldHVybiBTVUNDRUVERUQoQ0xTSURGcm9tU3RyaW5nV3JhcChpZHN0ciwgaWQpKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3Nl0KICoKICogRGV0ZXJtaW5lIGlmIHRoZSBicm93c2VyIGlzIGludGVncmF0ZWQgaW50byB0aGUgc2hlbGwsIGFuZCBzZXQgYSByZWdpc3RyeQogKiBrZXkgYWNjb3JkaW5nbHkuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgMSwgSWYgdGhlIGJyb3dzZXIgaXMgbm90IGludGVncmF0ZWQuCiAqICAyLCBJZiB0aGUgYnJvd3NlciBpcyBpbnRlZ3JhdGVkLgogKgogKiBOT1RFUwogKiAgVGhlIGtleSAiSEtMTVxTb2Z0d2FyZVxNaWNyb3NvZnRcSW50ZXJuZXQgRXhwbG9yZXJcSW50ZWdyYXRlZEJyb3dzZXIiIGlzCiAqICBlaXRoZXIgc2V0IHRvIFRSVUUsIG9yIHJlbW92ZWQgZGVwZW5kaW5nIG9uIHdoZXRoZXIgdGhlIGJyb3dzZXIgaXMgZGVlbWVkCiAqICB0byBiZSBpbnRlZ3JhdGVkLgogKi8KRFdPUkQgV0lOQVBJIFdoaWNoUGxhdGZvcm0oKQp7CiAgc3RhdGljIExQQ1NUUiBzekludGVncmF0ZWRCcm93c2VyID0gIkludGVncmF0ZWRCcm93c2VyIjsKICBzdGF0aWMgRFdPUkQgZHdTdGF0ZSA9IDA7CiAgSEtFWSBoS2V5OwogIERXT1JEIGR3UmV0LCBkd0RhdGEsIGR3U2l6ZTsKCiAgaWYgKGR3U3RhdGUpCiAgICByZXR1cm4gZHdTdGF0ZTsKCiAgLyogSWYgc2hlbGwzMiBleHBvcnRzIERsbEdldFZlcnNpb24oKSwgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZCAqLwogIEdFVF9GVU5DKHBEbGxHZXRWZXJzaW9uLCBzaGVsbDMyLCAiRGxsR2V0VmVyc2lvbiIsIDEpOwogIGR3U3RhdGUgPSBwRGxsR2V0VmVyc2lvbiA/IDIgOiAxOwoKICAvKiBTZXQgb3IgZGVsZXRlIHRoZSBrZXkgYWNjb3JkaW5nbHkgKi8KICBkd1JldCA9IFJlZ09wZW5LZXlFeEEoSEtFWV9MT0NBTF9NQUNISU5FLAogICAgICAgICAgICAgICAgICAgICAgICAiU29mdHdhcmVcXE1pY3Jvc29mdFxcSW50ZXJuZXQgRXhwbG9yZXIiLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0FMTF9BQ0NFU1MsICZoS2V5KTsKICBpZiAoIWR3UmV0KQogIHsKICAgIGR3UmV0ID0gUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCBzekludGVncmF0ZWRCcm93c2VyLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpJmR3RGF0YSwgJmR3U2l6ZSk7CgogICAgaWYgKCFkd1JldCAmJiBkd1N0YXRlID09IDEpCiAgICB7CiAgICAgIC8qIFZhbHVlIGV4aXN0cyBidXQgYnJvd3NlciBpcyBub3QgaW50ZWdyYXRlZCAqLwogICAgICBSZWdEZWxldGVWYWx1ZUEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3Nlcik7CiAgICB9CiAgICBlbHNlIGlmIChkd1JldCAmJiBkd1N0YXRlID09IDIpCiAgICB7CiAgICAgIC8qIEJyb3dzZXIgaXMgaW50ZWdyYXRlZCBidXQgdmFsdWUgZG9lcyBub3QgZXhpc3QgKi8KICAgICAgZHdEYXRhID0gVFJVRTsKICAgICAgUmVnU2V0VmFsdWVFeEEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3NlciwgMCwgUkVHX0RXT1JELAogICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSZkd0RhdGEsIHNpemVvZihkd0RhdGEpKTsKICAgIH0KICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwogIH0KICByZXR1cm4gZHdTdGF0ZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNIQ3JlYXRlV29ya2VyV2luZG93QS4KICovCkhXTkQgV0lOQVBJIFNIQ3JlYXRlV29ya2VyV2luZG93VyhMT05HIHduZFByb2MsIEhXTkQgaFduZFBhcmVudCwgRFdPUkQgZHdFeFN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1N0eWxlLCBITUVOVSBoTWVudSwgTE9ORyB6KQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2xhc3NbXSA9IHsgJ1cnLCAnbycsICdyJywgJ2snLCAnZScsICdyJywgJ1cnLCAnXDAnIH07CiAgV05EQ0xBU1NXIHdjOwogIEhXTkQgaFduZDsKCiAgVFJBQ0UoIigweCUwOGx4LCVwLDB4JTA4bHgsMHglMDhseCwlcCwweCUwOGx4KVxuIiwKICAgICAgICAgd25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIElmIG91ciBPUyBpcyBuYXRpdmVseSBBU0NJSSwgdXNlIHRoZSBBU0NJSSB2ZXJzaW9uICovCiAgaWYgKCEoR2V0VmVyc2lvbigpICYgMHg4MDAwMDAwMCkpICAvKiBOVCAqLwogICAgcmV0dXJuIFNIQ3JlYXRlV29ya2VyV2luZG93QSh3bmRQcm9jLCBoV25kUGFyZW50LCBkd0V4U3R5bGUsIGR3U3R5bGUsIGhNZW51LCB6KTsKCiAgLyogQ3JlYXRlIFdpbmRvdyBjbGFzcyAqLwogIHdjLnN0eWxlICAgICAgICAgPSAwOwogIHdjLmxwZm5XbmRQcm9jICAgPSBEZWZXaW5kb3dQcm9jVzsKICB3Yy5jYkNsc0V4dHJhICAgID0gMDsKICB3Yy5jYlduZEV4dHJhICAgID0gNDsKICB3Yy5oSW5zdGFuY2UgICAgID0gc2hsd2FwaV9oSW5zdGFuY2U7CiAgd2MuaEljb24gICAgICAgICA9IChISUNPTikwOwogIHdjLmhDdXJzb3IgICAgICAgPSBMb2FkQ3Vyc29yQSgoSElOU1RBTkNFKTAsIChMUFNUUilJRENfQVJST1cpOwogIHdjLmhickJhY2tncm91bmQgPSAoSEJSVVNIKUNPTE9SX0JUTlNIQURPVzsKICB3Yy5scHN6TWVudU5hbWUgID0gTlVMTDsKICB3Yy5scHN6Q2xhc3NOYW1lID0gc3pDbGFzczsKCiAgU0hSZWdpc3RlckNsYXNzVygmd2MpOyAvKiBSZWdpc3RlciBjbGFzcyAqLwoKICAvKiBGSVhNRTogU2V0IGV4dHJhIGJpdHMgaW4gZHdFeFN0eWxlICovCgogIGhXbmQgPSBDcmVhdGVXaW5kb3dFeFcoZHdFeFN0eWxlLCBzekNsYXNzLCAwLCBkd1N0eWxlLCAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgaFduZFBhcmVudCwgaE1lbnUsIHNobHdhcGlfaEluc3RhbmNlLCAwKTsKICBpZiAoaFduZCkKICB7CiAgICBTZXRXaW5kb3dMb25nQShoV25kLCBEV0xfTVNHUkVTVUxULCB6KTsKCiAgICBpZiAod25kUHJvYykKICAgICAgU2V0V2luZG93TG9uZ0EoaFduZCwgR1dMX1dORFBST0MsIHduZFByb2MpOwogIH0KICByZXR1cm4gaFduZDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3OV0KICoKICogR2V0IGFuZCBzaG93IGEgY29udGV4dCBtZW51IGZyb20gYSBzaGVsbCBmb2xkZXIuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgICAgICAgW0ldIFdpbmRvdyBkaXNwbGF5aW5nIHRoZSBzaGVsbCBmb2xkZXIKICogIGxwRm9sZGVyICAgICAgIFtJXSBJU2hlbGxGb2xkZXIgaW50ZXJmYWNlCiAqICBscEFwaWRsICAgICAgICBbSV0gSWQgZm9yIHRoZSBwYXJ0aWN1bGFyIGZvbGRlciBkZXNpcmVkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUgaW5kaWNhdGluZyB0aGUgZXJyb3IuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEludm9rZURlZmF1bHRDb21tYW5kKEhXTkQgaFduZCwgSVNoZWxsRm9sZGVyKiBscEZvbGRlciwgTFBDSVRFTUlETElTVCBscEFwaWRsKQp7CiAgcmV0dXJuIFNISW52b2tlQ29tbWFuZChoV25kLCBscEZvbGRlciwgbHBBcGlkbCwgRkFMU0UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjgxXQogKgogKiBfU0hQYWNrRGlzcFBhcmFtc1YKICovCkhSRVNVTFQgV0lOQVBJIFNIUGFja0Rpc3BQYXJhbXNWKExQVk9JRCB3LCBMUFZPSUQgeCwgTFBWT0lEIHksIExQVk9JRCB6KQp7CglGSVhNRSgiJXAgJXAgJXAgJXBcbiIsdyx4LHkseik7CglyZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMjgyXQogKgogKiBUaGlzIGZ1bmN0aW9uIHNlZW1zIHRvIGJlIGEgZm9yd2FyZCB0byBTSFBhY2tEaXNwUGFyYW1zViAod2hhdGV2ZXIgVEhBVAogKiBmdW5jdGlvbiBkb2VzLi4uKS4KICovCkhSRVNVTFQgV0lOQVBJIFNIUGFja0Rpc3BQYXJhbXMoTFBWT0lEIHcsIExQVk9JRCB4LCBMUFZPSUQgeSwgTFBWT0lEIHopCnsKICBGSVhNRSgiJXAgJXAgJXAgJXBcbiIsIHcsIHgsIHksIHopOwogIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODRdCiAqCiAqIF9JQ29ubmVjdGlvblBvaW50X1NpbXBsZUludm9rZQogKi8KRFdPUkQgV0lOQVBJIElDb25uZWN0aW9uUG9pbnRfU2ltcGxlSW52b2tlKAoJTFBWT0lEIHgsCglMUFZPSUQgeSwKCUxQVk9JRCB6KQp7CiAgICAgICAgRklYTUUoIiglcCAlcCAlcCkgc3R1YlxuIix4LHkseik7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4NV0KICoKICogTm90aWZ5IGFuIElDb25uZWN0aW9uUG9pbnQgb2JqZWN0IG9mIGNoYW5nZXMuCiAqCiAqIFBBUkFNUwogKiAgbHBDUCAgIFtJXSBPYmplY3QgdG8gbm90aWZ5CiAqICBkaXNwSUQgW0ldCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBFX05PSU5URVJGQUNFLCBpZiBscENQIGlzIE5VTEwgb3IgZG9lcyBub3Qgc3VwcG9ydCB0aGUKICogICAgICAgICAgIElDb25uZWN0aW9uUG9pbnQgaW50ZXJmYWNlLgogKi8KSFJFU1VMVCBXSU5BUEkgSUNvbm5lY3Rpb25Qb2ludF9PbkNoYW5nZWQoSUNvbm5lY3Rpb25Qb2ludCogbHBDUCwgRElTUElEIGRpc3BJRCkKewogIElFbnVtQ29ubmVjdGlvbnMgKmxwRW51bTsKICBIUkVTVUxUIGhSZXQgPSBFX05PSU5URVJGQUNFOwoKICBUUkFDRSgiKCVwLDB4JThsWClcbiIsIGxwQ1AsIGRpc3BJRCk7CgogIC8qIEdldCBhbiBlbnVtZXJhdG9yIGZvciB0aGUgY29ubmVjdGlvbnMgKi8KICBpZiAobHBDUCkKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50X0VudW1Db25uZWN0aW9ucyhscENQLCAmbHBFbnVtKTsKCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBJUHJvcGVydHlOb3RpZnlTaW5rICpscFNpbms7CiAgICBDT05ORUNUREFUQSBjb25uRGF0YTsKICAgIFVMT05HIHVsRmV0Y2hlZDsKCiAgICAvKiBDYWxsIE9uQ2hhbmdlZCgpIGZvciBldmVyeSBub3RpZnkgc2luayBpbiB0aGUgY29ubmVjdGlvbiBwb2ludCAqLwogICAgd2hpbGUgKElFbnVtQ29ubmVjdGlvbnNfTmV4dChscEVudW0sIDEsICZjb25uRGF0YSwgJnVsRmV0Y2hlZCkgPT0gU19PSykKICAgIHsKICAgICAgaWYgKFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShjb25uRGF0YS5wVW5rLCAmSUlEX0lQcm9wZXJ0eU5vdGlmeVNpbmssICh2b2lkKiopJmxwU2luaykpICYmCiAgICAgICAgICBscFNpbmspCiAgICAgIHsKICAgICAgICBJUHJvcGVydHlOb3RpZnlTaW5rX09uQ2hhbmdlZChscFNpbmssIGRpc3BJRCk7CiAgICAgICAgSVByb3BlcnR5Tm90aWZ5U2lua19SZWxlYXNlKGxwU2luayk7CiAgICAgIH0KICAgICAgSVVua25vd25fUmVsZWFzZShjb25uRGF0YS5wVW5rKTsKICAgIH0KCiAgICBJRW51bUNvbm5lY3Rpb25zX1JlbGVhc2UobHBFbnVtKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODddCiAqCiAqIE5vdGlmeSBhbiBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIG9iamVjdCBvZiBjaGFuZ2VzLgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHRvIG5vdGlmeQogKiAgZGlzcElEICAgIFtJXQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRSwgaWYgbHBVbmtub3duIGlzIE5VTEwgb3IgZG9lcyBub3Qgc3VwcG9ydCB0aGUKICogICAgICAgICAgIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgaW50ZXJmYWNlLgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fQ1BDb250YWluZXJPbkNoYW5nZWQoSVVua25vd24gKmxwVW5rbm93biwgRElTUElEIGRpc3BJRCkKewogIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIqIGxwQ1BDID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX05PSU5URVJGQUNFOwoKICBUUkFDRSgiKCVwLDB4JThsWClcbiIsIGxwVW5rbm93biwgZGlzcElEKTsKCiAgaWYgKGxwVW5rbm93bikKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwgKHZvaWQqKikmbHBDUEMpOwoKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIElDb25uZWN0aW9uUG9pbnQqIGxwQ1A7CgogICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRDb250YWluZXJfRmluZENvbm5lY3Rpb25Qb2ludChscENQQywgJklJRF9JUHJvcGVydHlOb3RpZnlTaW5rLCAmbHBDUCk7CiAgICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX1JlbGVhc2UobHBDUEMpOwoKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50X09uQ2hhbmdlZChscENQLCBkaXNwSUQpOwogICAgSUNvbm5lY3Rpb25Qb2ludF9SZWxlYXNlKGxwQ1ApOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4OV0KICoKICogU2VlIFBsYXlTb3VuZFcuCiAqLwpCT09MIFdJTkFQSSBQbGF5U291bmRXcmFwVyhMUENXU1RSIHBzelNvdW5kLCBITU9EVUxFIGhtb2QsIERXT1JEIGZkd1NvdW5kKQp7CiAgR0VUX0ZVTkMocFBsYXlTb3VuZFcsIHdpbm1tLCAiUGxheVNvdW5kVyIsIEZBTFNFKTsKICByZXR1cm4gcFBsYXlTb3VuZFcocHN6U291bmQsIGhtb2QsIGZkd1NvdW5kKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5NF0KICovCkJPT0wgV0lOQVBJIFNIR2V0SW5pU3RyaW5nVyhMUFNUUiBzdHIxLCBMUFNUUiBzdHIyLCBMUFNUUiBwU3RyLCBEV09SRCBzb21lX2xlbiwgIExQQ1NUUiBscFN0cjIpCnsKICAgIC8qCiAgICAgKiBzdHIxOgkJIkkiCSJJIglwdXNobCBlc3ArMHgyMAogICAgICogc3RyMjoJCSJVIgkiSSIJcHVzaGwgMHg3N2M5MzgxMAogICAgICogKGlzICJJIiBhbmQgIlUiICJpbnRlZ2VyIiBhbmQgInVuc2lnbmVkIiA/PykKICAgICAqCiAgICAgKiBwU3RyOgkJIiIJIiIJcHVzaGwgZWF4CiAgICAgKiBzb21lX2xlbjoJMHg4MjQJMHgxMDQJcHVzaGwgMHg4MjQKICAgICAqIGxwU3RyMjoJCSIlbCIJIiVsIglwdXNobCBlc3ArMHhjCiAgICAgKgogICAgICogc2hsd2FwaS4gU3RyQ3B5TlcobHBTdHIyLCBpcnJlbGV2YW50X3ZhciwgMHgxMDQpOwogICAgICogTG9jYWxBbGxvYygweDAwLCBzb21lX2xlbikgLT4gaXJyZWxldmFudF92YXIKICAgICAqIExvY2FsQWxsb2MoMHg0MCwgaXJyZWxldmFudF9sZW4pIC0+IHBTdHIKICAgICAqIHNobHdhcGkuMjk0KHN0cjEsIHN0cjIsIHBTdHIsIHNvbWVfbGVuLCBscFN0cjIpOwogICAgICogc2hsd2FwaS5QYXRoUmVtb3ZlQmxhbmtzVyhwU3RyKTsKICAgICAqLwogICAgRklYTUUoIignJXMnLCAnJXMnLCAnJXMnLCAlMDhseCwgJyVzJyk6IHN0dWIhXG4iLCBzdHIxLCBzdHIyLCBwU3RyLCBzb21lX2xlbiwgbHBTdHIyKTsKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjk1XQogKgogKiBDYWxsZWQgYnkgSUNRMjAwMGIgaW5zdGFsbCB2aWEgU0hET0NWVzoKICogc3RyMTogIkludGVybmV0U2hvcnRjdXQiCiAqIHg6IHNvbWUgdW5rbm93biBwb2ludGVyCiAqIHN0cjI6ICJodHRwOi8vZnJlZS5hb2wuY29tL3RyeWFvbGZyZWUvaW5kZXguYWRwPzEzOTI2OSIKICogc3RyMzogIkM6XFxXSU5ET1dTXFxEZXNrdG9wLm5ldzJcXEZyZWUgQU9MICYgVW5saW1pdGVkIEludGVybmV0LnVybCIKICoKICogSW4gc2hvcnQ6IHRoaXMgb25lIG1heWJlIGNyZWF0ZXMgYSBkZXNrdG9wIGxpbmsgOi0pCiAqLwpCT09MIFdJTkFQSSBTSFNldEluaVN0cmluZ1coTFBXU1RSIHN0cjEsIExQVk9JRCB4LCBMUFdTVFIgc3RyMiwgTFBXU1RSIHN0cjMpCnsKICAgIEZJWE1FKCIoJyVzJywgJXAsICclcycsICclcycpLCBzdHViLlxuIiwgZGVidWdzdHJfdyhzdHIxKSwgeCwgZGVidWdzdHJfdyhzdHIyKSwgZGVidWdzdHJfdyhzdHIzKSk7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5OV0KICoKICogU2VlIENPTUNUTDMyXzQxNy4KICovCkJPT0wgV0lOQVBJIEV4dFRleHRPdXRXcmFwVyhIREMgaGRjLCBJTlQgeCwgSU5UIHksIFVJTlQgZmxhZ3MsIGNvbnN0IFJFQ1QgKmxwcmVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgIExQQ1dTVFIgc3RyLCBVSU5UIGNvdW50LCBjb25zdCBJTlQgKmxwRHgpCnsKICAgIEdFVF9GVU5DKHBDT01DVEwzMl80MTcsIGNvbWN0bDMyLCAoTFBDU1RSKTQxNywgRkFMU0UpOwogICAgcmV0dXJuIHBDT01DVEwzMl80MTcoaGRjLCB4LCB5LCBmbGFncywgbHByZWN0LCBzdHIsIGNvdW50LCBscER4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxM10KICoKICogU2VlIFNIR2V0RmlsZUluZm9XLgogKi8KRFdPUkQgV0lOQVBJIFNIR2V0RmlsZUluZm9XcmFwVyhMUENXU1RSIHBhdGgsIERXT1JEIGR3RmlsZUF0dHJpYnV0ZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICBTSEZJTEVJTkZPVyAqcHNmaSwgVUlOVCBzaXplb2Zwc2ZpLCBVSU5UIGZsYWdzKQp7CiAgR0VUX0ZVTkMocFNIR2V0RmlsZUluZm9XLCBzaGVsbDMyLCAiU0hHZXRGaWxlSW5mb1ciLCAwKTsKICByZXR1cm4gcFNIR2V0RmlsZUluZm9XKHBhdGgsIGR3RmlsZUF0dHJpYnV0ZXMsIHBzZmksIHNpemVvZnBzZmksIGZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMxOF0KICoKICogU2VlIERyYWdRdWVyeUZpbGVXLgogKi8KVUlOVCBXSU5BUEkgRHJhZ1F1ZXJ5RmlsZVdyYXBXKEhEUk9QIGhEcm9wLCBVSU5UIGxGaWxlLCBMUFdTVFIgbHBzekZpbGUsIFVJTlQgbExlbmd0aCkKewogIEdFVF9GVU5DKHBEcmFnUXVlcnlGaWxlVywgc2hlbGwzMiwgIkRyYWdRdWVyeUZpbGVXIiwgMCk7CiAgcmV0dXJuIHBEcmFnUXVlcnlGaWxlVyhoRHJvcCwgbEZpbGUsIGxwc3pGaWxlLCBsTGVuZ3RoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzM10KICoKICogU2VlIFNIQnJvd3NlRm9yRm9sZGVyVy4KICovCkxQSVRFTUlETElTVCBXSU5BUEkgU0hCcm93c2VGb3JGb2xkZXJXcmFwVyhMUEJST1dTRUlORk9XIGxwQmkpCnsKICBHRVRfRlVOQyhwU0hCcm93c2VGb3JGb2xkZXJXLCBzaGVsbDMyLCAiU0hCcm93c2VGb3JGb2xkZXJXIiwgTlVMTCk7CiAgcmV0dXJuIHBTSEJyb3dzZUZvckZvbGRlclcobHBCaSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzRdCiAqCiAqIFNlZSBTSEdldFBhdGhGcm9tSURMaXN0Vy4KICovCkJPT0wgV0lOQVBJIFNIR2V0UGF0aEZyb21JRExpc3RXcmFwVyhMUENJVEVNSURMSVNUIHBpZGwsTFBXU1RSIHBzelBhdGgpCnsKICBHRVRfRlVOQyhwU0hHZXRQYXRoRnJvbUlETGlzdFcsIHNoZWxsMzIsICJTSEdldFBhdGhGcm9tSURMaXN0VyIsIDApOwogIHJldHVybiBwU0hHZXRQYXRoRnJvbUlETGlzdFcocGlkbCwgcHN6UGF0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzVdCiAqCiAqIFNlZSBTaGVsbEV4ZWN1dGVFeFcuCiAqLwpCT09MIFdJTkFQSSBTaGVsbEV4ZWN1dGVFeFdyYXBXKExQU0hFTExFWEVDVVRFSU5GT1cgbHBFeGVjSW5mbykKewogIEdFVF9GVU5DKHBTaGVsbEV4ZWN1dGVFeFcsIHNoZWxsMzIsICJTaGVsbEV4ZWN1dGVFeFciLCBGQUxTRSk7CiAgcmV0dXJuIHBTaGVsbEV4ZWN1dGVFeFcobHBFeGVjSW5mbyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzZdCiAqCiAqIFNlZSBTSEZpbGVPcGVyYXRpb25XLgogKi8KSElDT04gV0lOQVBJIFNIRmlsZU9wZXJhdGlvbldyYXBXKExQU0hGSUxFT1BTVFJVQ1RXIGxwRmlsZU9wKQp7CiAgR0VUX0ZVTkMocFNIRmlsZU9wZXJhdGlvblcsIHNoZWxsMzIsICJTSEZpbGVPcGVyYXRpb25XIiwgMCk7CiAgcmV0dXJuIHBTSEZpbGVPcGVyYXRpb25XKGxwRmlsZU9wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzN10KICoKICogU2VlIEV4dHJhY3RJY29uRXhXLgogKi8KVUlOVCBXSU5BUEkgRXh0cmFjdEljb25FeFdyYXBXKExQQ1dTVFIgbHBzekZpbGUsIElOVCBuSWNvbkluZGV4LCBISUNPTiAqcGhpY29uTGFyZ2UsCiAgICAgICAgICAgICAgICAgICAgICAgICBISUNPTiAqcGhpY29uU21hbGwsIFVJTlQgbkljb25zKQp7CiAgR0VUX0ZVTkMocEV4dHJhY3RJY29uRXhXLCBzaGVsbDMyLCAiRXh0cmFjdEljb25FeFciLCAwKTsKICByZXR1cm4gcEV4dHJhY3RJY29uRXhXKGxwc3pGaWxlLCBuSWNvbkluZGV4LCBwaGljb25MYXJnZSwgcGhpY29uU21hbGwsIG5JY29ucyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNDJdCiAqCiAqLwpMT05HIFdJTkFQSSBTSEludGVybG9ja2VkQ29tcGFyZUV4Y2hhbmdlKCBQTE9ORyBkZXN0LCBMT05HIHhjaGcsIExPTkcgY29tcGFyZSkKewogICAgICAgIHJldHVybiBJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZShkZXN0LCB4Y2hnLCBjb21wYXJlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1MF0KICoKICogU2VlIEdldEZpbGVWZXJzaW9uSW5mb1NpemVXLgogKi8KRFdPUkQgV0lOQVBJIEdldEZpbGVWZXJzaW9uSW5mb1NpemVXcmFwVygKCUxQV1NUUiB4LAoJTFBWT0lEIHkpCnsKICAgICAgICBEV09SRCByZXQ7CgoJR0VUX0ZVTkMocEdldEZpbGVWZXJzaW9uSW5mb1NpemVXLCB2ZXJzaW9uLCAiR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVciLCAwKTsKCXJldCA9IHBHZXRGaWxlVmVyc2lvbkluZm9TaXplVyh4LCB5KTsKCXJldHVybiAweDIwOCArIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1MV0KICoKICogU2VlIEdldEZpbGVWZXJzaW9uSW5mb1cuCiAqLwpCT09MICBXSU5BUEkgR2V0RmlsZVZlcnNpb25JbmZvV3JhcFcoCglMUFdTVFIgdywgICAvKiBbaW5dIHBhdGggdG8gZGxsICovCglEV09SRCAgeCwgICAvKiBbaW5dIHBhcm0gMiB0byBHZXRGaWxlVmVyc2lvbkluZm9BICovCglEV09SRCAgeSwgICAvKiBbaW5dIHJldHVybiB2YWx1ZSBmcm9tIFNITFdBUElfMzUwKCkgLSBhc3N1bWUgbGVuZ3RoICovCglMUFZPSUQgeikgICAvKiBbaW4vb3V0XSBidWZmZXIgKCsweDIwOCBzZW50IHRvIEdldEZpbGVWZXJzaW9uSW5mb0EoKSkgKi8KewogICAgR0VUX0ZVTkMocEdldEZpbGVWZXJzaW9uSW5mb1csIHZlcnNpb24sICJHZXRGaWxlVmVyc2lvbkluZm9XIiwgMCk7CiAgICByZXR1cm4gcEdldEZpbGVWZXJzaW9uSW5mb1codywgeCwgeS0weDIwOCwgKGNoYXIqKXorMHgyMDgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzUyXQogKgogKiBTZWUgVmVyUXVlcnlWYWx1ZVcuCiAqLwpXT1JEIFdJTkFQSSBWZXJRdWVyeVZhbHVlV3JhcFcoCglMUFZPSUQgdywgICAvKiBbaW5dIEJ1ZmZlciBmcm9tIFNITFdBUElfMzUxKCkgKi8KCUxQV1NUUiB4LCAgIC8qIFtpbl0gICBWYWx1ZSB0byByZXRyaWV2ZSAtIGNvbnZlcnRlZCBhbmQgcGFzc2VkIHRvIFZlclF1ZXJ5VmFsdWVBKCkgYXMgIzIgKi8KCUxQVk9JRCB5LCAgIC8qIFtvdXRdICBWZXIgYnVmZmVyIC0gcGFzc2VkIHRvIFZlclF1ZXJ5VmFsdWVBIGFzICMzICovCglVSU5UKiAgeikgICAvKiBbaW5dICAgVmVyIGxlbmd0aCAtIHBhc3NlZCB0byBWZXJRdWVyeVZhbHVlQSBhcyAjNCAqLwp7CiAgICBHRVRfRlVOQyhwVmVyUXVlcnlWYWx1ZVcsIHZlcnNpb24sICJWZXJRdWVyeVZhbHVlVyIsIDApOwogICAgcmV0dXJuIHBWZXJRdWVyeVZhbHVlVygoY2hhciopdysweDIwOCwgeCwgeSwgeik7Cn0KCiNkZWZpbmUgSXNJZmFjZSh0eXBlKSBTVUNDRUVERUQoKGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfIyN0eXBlLCAodm9pZCoqKSZscE9iaikpKQojZGVmaW5lIElTaGVsbEJyb3dzZXJfRW5hYmxlTW9kZWxlc3MgSVNoZWxsQnJvd3Nlcl9FbmFibGVNb2RlbGVzc1NCCiNkZWZpbmUgRW5hYmxlTW9kZWxlc3ModHlwZSkgdHlwZSMjX0VuYWJsZU1vZGVsZXNzKCh0eXBlKilscE9iaiwgYk1vZGVsZXNzKQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1NV0KICoKICogQ2hhbmdlIHRoZSBtb2RhbGl0eSBvZiBhIHNoZWxsIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBtYWtlIG1vZGVsZXNzCiAqICBiTW9kZWxlc3MgW0ldIFRSVUU9TWFrZSBtb2RlbGVzcywgRkFMU0U9TWFrZSBtb2RhbAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLiBUaGUgbW9kYWxpdHkgbHBVbmtub3duIGlzIGNoYW5nZWQuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUgaW5kaWNhdGluZyB0aGUgZXJyb3IuCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gbXVzdCBzdXBwb3J0IHRoZSBJT2xlSW5QbGFjZUZyYW1lIGludGVyZmFjZSwgdGhlCiAqICBJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUgaW50ZXJmYWNlLCB0aGUgSVNoZWxsQnJvd3NlciBpbnRlcmZhY2UKICogIG9yIHRoZSBJRG9jSG9zdFVJSGFuZGxlciBpbnRlcmZhY2UsIG9yIHRoaXMgY2FsbCBmYWlscy4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0VuYWJsZU1vZGVsZXNzKElVbmtub3duICpscFVua25vd24sIEJPT0wgYk1vZGVsZXNzKQp7CiAgSVVua25vd24gKmxwT2JqOwogIEhSRVNVTFQgaFJldDsKCiAgVFJBQ0UoIiglcCwlZClcbiIsIGxwVW5rbm93biwgYk1vZGVsZXNzKTsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gRV9GQUlMOwoKICBpZiAoSXNJZmFjZShJT2xlSW5QbGFjZUZyYW1lKSkKICAgIEVuYWJsZU1vZGVsZXNzKElPbGVJblBsYWNlRnJhbWUpOwogIGVsc2UgaWYgKElzSWZhY2UoSVNoZWxsQnJvd3NlcikpCiAgICBFbmFibGVNb2RlbGVzcyhJU2hlbGxCcm93c2VyKTsKI2lmIDAKICAvKiBGSVhNRTogV2luZSBoYXMgbm8gaGVhZGVycyBmb3IgdGhlc2Ugb2JqZWN0cyB5ZXQgKi8KICBlbHNlIGlmIChJc0lmYWNlKElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSkpCiAgICBFbmFibGVNb2RlbGVzcyhJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUpOwogIGVsc2UgaWYgKElzSWZhY2UoSURvY0hvc3RVSUhhbmRsZXIpKQogICAgRW5hYmxlTW9kZWxlc3MoSURvY0hvc3RVSUhhbmRsZXIpOwojZW5kaWYKICBlbHNlCiAgICByZXR1cm4gaFJldDsKCiAgSVVua25vd25fUmVsZWFzZShscE9iaik7CiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTddCiAqCiAqIFNlZSBTSEdldE5ld0xpbmtJbmZvVy4KICovCkJPT0wgV0lOQVBJIFNIR2V0TmV3TGlua0luZm9XcmFwVyhMUENXU1RSIHBzekxpbmtUbywgTFBDV1NUUiBwc3pEaXIsIExQV1NUUiBwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBCT09MICpwZk11c3RDb3B5LCBVSU5UIHVGbGFncykKewogIEdFVF9GVU5DKHBTSEdldE5ld0xpbmtJbmZvVywgc2hlbGwzMiwgIlNIR2V0TmV3TGlua0luZm9XIiwgRkFMU0UpOwogIHJldHVybiBwU0hHZXROZXdMaW5rSW5mb1cocHN6TGlua1RvLCBwc3pEaXIsIHBzek5hbWUsIHBmTXVzdENvcHksIHVGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNThdCiAqCiAqIFNlZSBTSERlZkV4dHJhY3RJY29uVy4KICovClVJTlQgV0lOQVBJIFNIRGVmRXh0cmFjdEljb25XcmFwVyhMUENXU1RSIHBzekljb25GaWxlLCBpbnQgaUluZGV4LCBVSU5UIHVGbGFncywgSElDT04qIHBoaWNvbkxhcmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgSElDT04qIHBoaWNvblNtYWxsLCBVSU5UIG5JY29uU2l6ZSkKewogIEdFVF9GVU5DKHBTSERlZkV4dHJhY3RJY29uVywgc2hlbGwzMiwgIlNIRGVmRXh0cmFjdEljb25XIiwgMCk7CiAgcmV0dXJuIHBTSERlZkV4dHJhY3RJY29uVyhwc3pJY29uRmlsZSwgaUluZGV4LCB1RmxhZ3MsIHBoaWNvbkxhcmdlLCBwaGljb25TbWFsbCwgbkljb25TaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM2M10KICoKICogR2V0IGFuZCBzaG93IGEgY29udGV4dCBtZW51IGZyb20gYSBzaGVsbCBmb2xkZXIuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgICAgICAgW0ldIFdpbmRvdyBkaXNwbGF5aW5nIHRoZSBzaGVsbCBmb2xkZXIKICogIGxwRm9sZGVyICAgICAgIFtJXSBJU2hlbGxGb2xkZXIgaW50ZXJmYWNlCiAqICBscEFwaWRsICAgICAgICBbSV0gSWQgZm9yIHRoZSBwYXJ0aWN1bGFyIGZvbGRlciBkZXNpcmVkCiAqICBiSW52b2tlRGVmYXVsdCBbSV0gV2hldGhlciB0byBpbnZva2UgdGhlIGRlZmF1bHQgbWVudSBpdGVtCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIElmIGJJbnZva2VEZWZhdWx0IGlzIFRSVUUsIHRoZSBkZWZhdWx0IG1lbnUgYWN0aW9uIHdhcwogKiAgICAgICAgICAgZXhlY3V0ZWQuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUgaW5kaWNhdGluZyB0aGUgZXJyb3IuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEludm9rZUNvbW1hbmQoSFdORCBoV25kLCBJU2hlbGxGb2xkZXIqIGxwRm9sZGVyLCBMUENJVEVNSURMSVNUIGxwQXBpZGwsIEJPT0wgYkludm9rZURlZmF1bHQpCnsKICBJQ29udGV4dE1lbnUgKmlDb250ZXh0OwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlZClcbiIsIGhXbmQsIGxwRm9sZGVyLCBscEFwaWRsLCBiSW52b2tlRGVmYXVsdCk7CgogIGlmICghbHBGb2xkZXIpCiAgICByZXR1cm4gaFJldDsKCiAgLyogR2V0IHRoZSBjb250ZXh0IG1lbnUgZnJvbSB0aGUgc2hlbGwgZm9sZGVyICovCiAgaFJldCA9IElTaGVsbEZvbGRlcl9HZXRVSU9iamVjdE9mKGxwRm9sZGVyLCBoV25kLCAxLCAmbHBBcGlkbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJklJRF9JQ29udGV4dE1lbnUsIDAsICh2b2lkKiopJmlDb250ZXh0KTsKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIEhNRU5VIGhNZW51OwogICAgaWYgKChoTWVudSA9IENyZWF0ZVBvcHVwTWVudSgpKSkKICAgIHsKICAgICAgSFJFU1VMVCBoUXVlcnk7CiAgICAgIERXT1JEIGR3RGVmYXVsdElkID0gMDsKCiAgICAgIC8qIEFkZCB0aGUgY29udGV4dCBtZW51IGVudHJpZXMgdG8gdGhlIHBvcHVwICovCiAgICAgIGhRdWVyeSA9IElDb250ZXh0TWVudV9RdWVyeUNvbnRleHRNZW51KGlDb250ZXh0LCBoTWVudSwgMCwgMSwgMHg3RkZGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiSW52b2tlRGVmYXVsdCA/IENNRl9OT1JNQUwgOiBDTUZfREVGQVVMVE9OTFkpOwoKICAgICAgaWYgKFNVQ0NFRURFRChoUXVlcnkpKQogICAgICB7CiAgICAgICAgaWYgKGJJbnZva2VEZWZhdWx0ICYmCiAgICAgICAgICAgIChkd0RlZmF1bHRJZCA9IEdldE1lbnVEZWZhdWx0SXRlbShoTWVudSwgMCwgMCkpICE9IDB4RkZGRkZGRkYpCiAgICAgICAgewogICAgICAgICAgQ01JTlZPS0VDT01NQU5ESU5GTyBjbUljaTsKICAgICAgICAgIC8qIEludm9rZSB0aGUgZGVmYXVsdCBpdGVtICovCiAgICAgICAgICBtZW1zZXQoJmNtSWNpLDAsc2l6ZW9mKGNtSWNpKSk7CiAgICAgICAgICBjbUljaS5jYlNpemUgPSBzaXplb2YoY21JY2kpOwogICAgICAgICAgY21JY2kuZk1hc2sgPSBDTUlDX01BU0tfQVNZTkNPSzsKICAgICAgICAgIGNtSWNpLmh3bmQgPSBoV25kOwogICAgICAgICAgY21JY2kubHBWZXJiID0gTUFLRUlOVFJFU09VUkNFQShkd0RlZmF1bHRJZCk7CiAgICAgICAgICBjbUljaS5uU2hvdyA9IFNXX1NDUk9MTENISUxEUkVOOwoKICAgICAgICAgIGhSZXQgPSBJQ29udGV4dE1lbnVfSW52b2tlQ29tbWFuZChpQ29udGV4dCwgJmNtSWNpKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgRGVzdHJveU1lbnUoaE1lbnUpOwogICAgfQogICAgSUNvbnRleHRNZW51X1JlbGVhc2UoaUNvbnRleHQpOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3MF0KICoKICogU2VlIEV4dHJhY3RJY29uVy4KICovCkhJQ09OIFdJTkFQSSBFeHRyYWN0SWNvbldyYXBXKEhJTlNUQU5DRSBoSW5zdGFuY2UsIExQQ1dTVFIgbHBzekV4ZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBuSWNvbkluZGV4KQp7CiAgR0VUX0ZVTkMocEV4dHJhY3RJY29uVywgc2hlbGwzMiwgIkV4dHJhY3RJY29uVyIsIE5VTEwpOwogIHJldHVybiBwRXh0cmFjdEljb25XKGhJbnN0YW5jZSwgbHBzekV4ZUZpbGVOYW1lLCBuSWNvbkluZGV4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3Nl0KICovCkxBTkdJRCBXSU5BUEkgTUxHZXRVSUxhbmd1YWdlKCkKewogICAgRklYTUUoIigpIHN0dWJcbiIpOwogICAgLyogRklYTUU6IFRoaXMgc2hvdWxkIGJlIGEgZm9yd2FyZCBpbiB0aGUgLnNwZWMgZmlsZSB0byB0aGUgd2luMmsgZnVuY3Rpb24KICAgICAqIGtlcm5lbDMyLkdldFVzZXJEZWZhdWx0VUlMYW5ndWFnZSwgaG93ZXZlciB0aGF0IGZ1bmN0aW9uIGlzbid0IHRoZXJlIHlldC4KICAgICAqLwogICAgcmV0dXJuIEdldFVzZXJEZWZhdWx0TGFuZ0lEKCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNzddCiAqCiAqIExvYWQgYSBsaWJyYXJ5IGZyb20gdGhlIGRpcmVjdG9yeSBvZiBhIHBhcnRpY3VsYXIgcHJvY2Vzcy4KICoKICogUEFSQU1TCiAqICBuZXdfbW9kICAgW0ldIExpYnJhcnkgbmFtZQogKiAgaW5zdF9od25kIFtJXSBNb2R1bGUgd2hvc2UgZGlyZWN0b3J5IGlzIHRvIGJlIHVzZWQKICogIGR3RmxhZ3MgICBbSV0gRmxhZ3MgY29udHJvbGxpbmcgdGhlIGxvYWQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogQSBoYW5kbGUgdG8gdGhlIGxvYWRlZCBtb2R1bGUKICogIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqLwpITU9EVUxFIFdJTkFQSSBNTExvYWRMaWJyYXJ5QShMUENTVFIgbmV3X21vZCwgSE1PRFVMRSBpbnN0X2h3bmQsIERXT1JEIGR3RmxhZ3MpCnsKICAvKiBGSVhNRTogTmF0aXZlIGFwcGVhcnMgdG8gZG8gRFBBX0NyZWF0ZSBhbmQgYSBEUEFfSW5zZXJ0UHRyIGZvcgogICAqICAgICAgICBlYWNoIGNhbGwgaGVyZS4KICAgKiBGSVhNRTogTmF0aXZlIHNob3dzIGNhbGxzIHRvOgogICAqICBTSFJlZ0dldFVTVmFsdWUgZm9yICJTb2Z0d2FyZVxNaWNyb3NvZnRcSW50ZXJuZXQgRXhwbG9yZXJcSW50ZXJuYXRpb25hbCIKICAgKiAgICAgICAgICAgICAgICAgICAgICBDaGVja1ZlcnNpb24KICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyIgogICAqICBSZWdRdWVyeVZhbHVlRXhBIGZvciAiTFBLSW5zdGFsbGVkIgogICAqICBSZWdDbG9zZUtleQogICAqICBSZWdPcGVuS2V5RXhBIGZvciAiSEtDVVxTb2Z0d2FyZVxNaWNyb3NvZnRcSW50ZXJuZXQgRXhwbG9yZXJcSW50ZXJuYXRpb25hbCIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIlJlc291cmNlTG9jYWxlIgogICAqICBSZWdDbG9zZUtleQogICAqICBSZWdPcGVuS2V5RXhBIGZvciAiSEtMTVxTb2Z0d2FyZVxNaWNyb3NvZnRcQWN0aXZlIFNldHVwXEluc3RhbGxlZCBDb21wb25lbnRzXHtndWlkfSIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIkxvY2FsZSIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgYW5kIHRoZW4gdGVzdHMgdGhlIExvY2FsZSAoImVuIiBmb3IgbWUpLgogICAqICAgICBjb2RlIGJlbG93CiAgICogIGFmdGVyIHRoZSBjb2RlIHRoZW4gYSBEUEFfQ3JlYXRlIChmaXJzdCB0aW1lKSBhbmQgRFBBX0luc2VydFB0ciBhcmUgZG9uZS4KICAgKi8KICAgIENIQVIgbW9kX3BhdGhbMipNQVhfUEFUSF07CiAgICBMUFNUUiBwdHI7CiAgICBEV09SRCBsZW47CgogICAgRklYTUUoIiglcywlcCwweCUwOGx4KSBzZW1pLXN0dWIhXG4iLCBkZWJ1Z3N0cl9hKG5ld19tb2QpLCBpbnN0X2h3bmQsIGR3RmxhZ3MpOwogICAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVBKGluc3RfaHduZCwgbW9kX3BhdGgsIHNpemVvZihtb2RfcGF0aCkpOwogICAgaWYgKCFsZW4gfHwgbGVuID49IHNpemVvZihtb2RfcGF0aCkpIHJldHVybiBOVUxMOwoKICAgIHB0ciA9IHN0cnJjaHIobW9kX3BhdGgsICdcXCcpOwogICAgaWYgKHB0cikgewoJc3RyY3B5KHB0cisxLCBuZXdfbW9kKTsKCVRSQUNFKCJsb2FkaW5nICVzXG4iLCBkZWJ1Z3N0cl9hKG1vZF9wYXRoKSk7CglyZXR1cm4gTG9hZExpYnJhcnlBKG1vZF9wYXRoKTsKICAgIH0KICAgIHJldHVybiBOVUxMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzc4XQogKgogKiBVbmljb2RlIHZlcnNpb24gb2YgTUxMb2FkTGlicmFyeUEuCiAqLwpITU9EVUxFIFdJTkFQSSBNTExvYWRMaWJyYXJ5VyhMUENXU1RSIG5ld19tb2QsIEhNT0RVTEUgaW5zdF9od25kLCBEV09SRCBkd0ZsYWdzKQp7CiAgICBXQ0hBUiBtb2RfcGF0aFsyKk1BWF9QQVRIXTsKICAgIExQV1NUUiBwdHI7CiAgICBEV09SRCBsZW47CgogICAgRklYTUUoIiglcywlcCwweCUwOGx4KSBzZW1pLXN0dWIhXG4iLCBkZWJ1Z3N0cl93KG5ld19tb2QpLCBpbnN0X2h3bmQsIGR3RmxhZ3MpOwogICAgbGVuID0gR2V0TW9kdWxlRmlsZU5hbWVXKGluc3RfaHduZCwgbW9kX3BhdGgsIHNpemVvZihtb2RfcGF0aCkgLyBzaXplb2YoV0NIQVIpKTsKICAgIGlmICghbGVuIHx8IGxlbiA+PSBzaXplb2YobW9kX3BhdGgpIC8gc2l6ZW9mKFdDSEFSKSkgcmV0dXJuIE5VTEw7CgogICAgcHRyID0gc3RycmNoclcobW9kX3BhdGgsICdcXCcpOwogICAgaWYgKHB0cikgewoJc3RyY3B5VyhwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfdyhtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5Vyhtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQ29sb3JBZGp1c3RMdW1hICAgICAgW1NITFdBUEkuQF0KICoKICogQWRqdXN0IHRoZSBsdW1pbm9zaXR5IG9mIGEgY29sb3IKICoKICogUEFSQU1TCiAqICBjUkdCICAgICAgICAgW0ldIFJHQiB2YWx1ZSB0byBjb252ZXJ0CiAqICBkd0x1bWEgICAgICAgW0ldIEx1bWEgYWRqdXN0bWVudAogKiAgYlVua25vd24gICAgIFtJXSBVbmtub3duCiAqCiAqIFJFVFVSTlMKICogIFRoZSBhZGp1c3RlZCBSR0IgY29sb3IuCiAqLwpDT0xPUlJFRiBXSU5BUEkgQ29sb3JBZGp1c3RMdW1hKENPTE9SUkVGIGNSR0IsIGludCBkd0x1bWEsIEJPT0wgYlVua25vd24pCnsKICBUUkFDRSgiKDB4JThseCwlZCwlZClcbiIsIGNSR0IsIGR3THVtYSwgYlVua25vd24pOwoKICBpZiAoZHdMdW1hKQogIHsKICAgIFdPUkQgd0gsIHdMLCB3UzsKCiAgICBDb2xvclJHQlRvSExTKGNSR0IsICZ3SCwgJndMLCAmd1MpOwoKICAgIEZJWE1FKCJJZ25vcmluZyBsdW1hIGFkanVzdG1lbnRcbiIpOwoKICAgIC8qIEZJWE1FOiBUaGUgYWpkdXN0bWVudCBpcyBub3QgbGluZWFyICovCgogICAgY1JHQiA9IENvbG9ySExTVG9SR0Iod0gsIHdMLCB3Uyk7CiAgfQogIHJldHVybiBjUkdCOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzg5XQogKgogKiBTZWUgR2V0U2F2ZUZpbGVOYW1lVy4KICovCkJPT0wgV0lOQVBJIEdldFNhdmVGaWxlTmFtZVdyYXBXKExQT1BFTkZJTEVOQU1FVyBvZm4pCnsKICBHRVRfRlVOQyhwR2V0U2F2ZUZpbGVOYW1lVywgY29tZGxnMzIsICJHZXRTYXZlRmlsZU5hbWVXIiwgRkFMU0UpOwogIHJldHVybiBwR2V0U2F2ZUZpbGVOYW1lVyhvZm4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzkwXQogKgogKiBTZWUgV05ldFJlc3RvcmVDb25uZWN0aW9uVy4KICovCkRXT1JEIFdJTkFQSSBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XcmFwVyhIV05EIGh3bmRPd25lciwgTFBXU1RSIGxwc3pEZXZpY2UpCnsKICBHRVRfRlVOQyhwV05ldFJlc3RvcmVDb25uZWN0aW9uVywgbXByLCAiV05ldFJlc3RvcmVDb25uZWN0aW9uVyIsIDApOwogIHJldHVybiBwV05ldFJlc3RvcmVDb25uZWN0aW9uVyhod25kT3duZXIsIGxwc3pEZXZpY2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzkxXQogKgogKiBTZWUgV05ldEdldExhc3RFcnJvclcuCiAqLwpEV09SRCBXSU5BUEkgV05ldEdldExhc3RFcnJvcldyYXBXKExQRFdPUkQgbHBFcnJvciwgTFBXU1RSIGxwRXJyb3JCdWYsIERXT1JEIG5FcnJvckJ1ZlNpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUFdTVFIgbHBOYW1lQnVmLCBEV09SRCBuTmFtZUJ1ZlNpemUpCnsKICBHRVRfRlVOQyhwV05ldEdldExhc3RFcnJvclcsIG1wciwgIldOZXRHZXRMYXN0RXJyb3JXIiwgMCk7CiAgcmV0dXJuIHBXTmV0R2V0TGFzdEVycm9yVyhscEVycm9yLCBscEVycm9yQnVmLCBuRXJyb3JCdWZTaXplLCBscE5hbWVCdWYsIG5OYW1lQnVmU2l6ZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDFdCiAqCiAqIFNlZSBQYWdlU2V0dXBEbGdXLgogKi8KQk9PTCBXSU5BUEkgUGFnZVNldHVwRGxnV3JhcFcoTFBQQUdFU0VUVVBETEdXIHBhZ2VkbGcpCnsKICBHRVRfRlVOQyhwUGFnZVNldHVwRGxnVywgY29tZGxnMzIsICJQYWdlU2V0dXBEbGdXIiwgRkFMU0UpOwogIHJldHVybiBwUGFnZVNldHVwRGxnVyhwYWdlZGxnKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQwMl0KICoKICogU2VlIFByaW50RGxnVy4KICovCkJPT0wgV0lOQVBJIFByaW50RGxnV3JhcFcoTFBQUklOVERMR1cgcHJpbnRkbGcpCnsKICBHRVRfRlVOQyhwUHJpbnREbGdXLCBjb21kbGczMiwgIlByaW50RGxnVyIsIEZBTFNFKTsKICByZXR1cm4gcFByaW50RGxnVyhwcmludGRsZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDNdCiAqCiAqIFNlZSBHZXRPcGVuRmlsZU5hbWVXLgogKi8KQk9PTCBXSU5BUEkgR2V0T3BlbkZpbGVOYW1lV3JhcFcoTFBPUEVORklMRU5BTUVXIG9mbikKewogIEdFVF9GVU5DKHBHZXRPcGVuRmlsZU5hbWVXLCBjb21kbGczMiwgIkdldE9wZW5GaWxlTmFtZVciLCBGQUxTRSk7CiAgcmV0dXJuIHBHZXRPcGVuRmlsZU5hbWVXKG9mbik7Cn0KCi8qIElOVEVSTkFMOiBNYXAgZnJvbSBITFMgY29sb3Igc3BhY2UgdG8gUkdCICovCnN0YXRpYyBXT1JEIFdJTkFQSSBDb252ZXJ0SHVlKGludCB3SHVlLCBXT1JEIHdNaWQxLCBXT1JEIHdNaWQyKQp7CiAgd0h1ZSA9IHdIdWUgPiAyNDAgPyB3SHVlIC0gMjQwIDogd0h1ZSA8IDAgPyB3SHVlICsgMjQwIDogd0h1ZTsKCiAgaWYgKHdIdWUgPiAxNjApCiAgICByZXR1cm4gd01pZDE7CiAgZWxzZSBpZiAod0h1ZSA+IDEyMCkKICAgIHdIdWUgPSAxNjAgLSB3SHVlOwogIGVsc2UgaWYgKHdIdWUgPiA0MCkKICAgIHJldHVybiB3TWlkMjsKCiAgcmV0dXJuICgod0h1ZSAqICh3TWlkMiAtIHdNaWQxKSArIDIwKSAvIDQwKSArIHdNaWQxOwp9CgovKiBDb252ZXJ0IHRvIFJHQiBhbmQgc2NhbGUgaW50byBSR0IgcmFuZ2UgKDAuLjI1NSkgKi8KI2RlZmluZSBHRVRfUkdCKGgpIChDb252ZXJ0SHVlKGgsIHdNaWQxLCB3TWlkMikgKiAyNTUgKyAxMjApIC8gMjQwCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENvbG9ySExTVG9SR0IJW1NITFdBUEkuQF0KICoKICogQ29udmVydCBmcm9tIGhscyBjb2xvciBzcGFjZSBpbnRvIGFuIHJnYiBDT0xPUlJFRi4KICoKICogUEFSQU1TCiAqICB3SHVlICAgICAgICBbSV0gSHVlIGFtb3VudAogKiAgd0x1bWlub3NpdHkgW0ldIEx1bWlub3NpdHkgYW1vdW50CiAqICB3U2F0dXJhdGlvbiBbSV0gU2F0dXJhdGlvbiBhbW91bnQKICoKICogUkVUVVJOUwogKiAgQSBDT0xPUlJFRiByZXByZXNlbnRpbmcgdGhlIGNvbnZlcnRlZCBjb2xvci4KICoKICogTk9URVMKICogIElucHV0IGhscyB2YWx1ZXMgYXJlIGNvbnN0cmFpbmVkIHRvIHRoZSByYW5nZSAoMC4uMjQwKS4KICovCkNPTE9SUkVGIFdJTkFQSSBDb2xvckhMU1RvUkdCKFdPUkQgd0h1ZSwgV09SRCB3THVtaW5vc2l0eSwgV09SRCB3U2F0dXJhdGlvbikKewogIFdPUkQgd1JlZDsKCiAgaWYgKHdTYXR1cmF0aW9uKQogIHsKICAgIFdPUkQgd0dyZWVuLCB3Qmx1ZSwgd01pZDEsIHdNaWQyOwoKICAgIGlmICh3THVtaW5vc2l0eSA+IDEyMCkKICAgICAgd01pZDIgPSB3U2F0dXJhdGlvbiArIHdMdW1pbm9zaXR5IC0gKHdTYXR1cmF0aW9uICogd0x1bWlub3NpdHkgKyAxMjApIC8gMjQwOwogICAgZWxzZQogICAgICB3TWlkMiA9ICgod1NhdHVyYXRpb24gKyAyNDApICogd0x1bWlub3NpdHkgKyAxMjApIC8gMjQwOwoKICAgIHdNaWQxID0gd0x1bWlub3NpdHkgKiAyIC0gd01pZDI7CgogICAgd1JlZCAgID0gR0VUX1JHQih3SHVlICsgODApOwogICAgd0dyZWVuID0gR0VUX1JHQih3SHVlKTsKICAgIHdCbHVlICA9IEdFVF9SR0Iod0h1ZSAtIDgwKTsKCiAgICByZXR1cm4gUkdCKHdSZWQsIHdHcmVlbiwgd0JsdWUpOwogIH0KCiAgd1JlZCA9IHdMdW1pbm9zaXR5ICogMjU1IC8gMjQwOwogIHJldHVybiBSR0Iod1JlZCwgd1JlZCwgd1JlZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTNdCiAqCiAqIEdldCB0aGUgY3VycmVudCBkb2NraW5nIHN0YXR1cyBvZiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGR3RmxhZ3MgW0ldIERPQ0tJTkZPXyBmbGFncyBmcm9tICJ3aW5iYXNlLmgiLCB1bnVzZWQKICoKICogUkVUVVJOUwogKiAgT25lIG9mIERPQ0tJTkZPX1VORE9DS0VELCBET0NLSU5GT19VTkRPQ0tFRCwgb3IgMCBpZiB0aGUgc3lzdGVtIGlzIG5vdAogKiAgYSBub3RlYm9vay4KICovCkRXT1JEIFdJTkFQSSBTSEdldE1hY2hpbmVJbmZvKERXT1JEIGR3RmxhZ3MpCnsKICBIV19QUk9GSUxFX0lORk9BIGh3SW5mbzsKCiAgVFJBQ0UoIigweCUwOGx4KVxuIiwgZHdGbGFncyk7CgogIEdldEN1cnJlbnRId1Byb2ZpbGVBKCZod0luZm8pOwogIHN3aXRjaCAoaHdJbmZvLmR3RG9ja0luZm8gJiAoRE9DS0lORk9fRE9DS0VEfERPQ0tJTkZPX1VORE9DS0VEKSkKICB7CiAgY2FzZSBET0NLSU5GT19ET0NLRUQ6CiAgY2FzZSBET0NLSU5GT19VTkRPQ0tFRDoKICAgIHJldHVybiBod0luZm8uZHdEb2NrSW5mbyAmIChET0NLSU5GT19ET0NLRUR8RE9DS0lORk9fVU5ET0NLRUQpOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gMDsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MThdCiAqCiAqIEZ1bmN0aW9uIHNlZW1zIHRvIGRvIEZyZWVMaWJyYXJ5IHBsdXMgb3RoZXIgdGhpbmdzLgogKgogKiBGSVhNRSBuYXRpdmUgc2hvd3MgdGhlIGZvbGxvd2luZyBjYWxsczoKICogICBSdGxFbnRlckNyaXRpY2FsU2VjdGlvbgogKiAgIExvY2FsRnJlZQogKiAgIEdldFByb2NBZGRyZXNzKENvbWN0bDMyPz8sIDE1MEwpCiAqICAgRFBBX0RlbGV0ZVB0cgogKiAgIFJ0bExlYXZlQ3JpdGljYWxTZWN0aW9uCiAqICBmb2xsb3dlZCBieSB0aGUgRnJlZUxpYnJhcnkuCiAqICBUaGUgYWJvdmUgY29kZSBtYXkgYmUgcmVsYXRlZCB0byAuMzc3IGFib3ZlLgogKi8KQk9PTCBXSU5BUEkgTUxGcmVlTGlicmFyeShITU9EVUxFIGhNb2R1bGUpCnsKCUZJWE1FKCIoJXApIHNlbWktc3R1YlxuIiwgaE1vZHVsZSk7CglyZXR1cm4gRnJlZUxpYnJhcnkoaE1vZHVsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTldCiAqLwpCT09MIFdJTkFQSSBTSEZsdXNoU0ZDYWNoZVdyYXAodm9pZCkgewogIEZJWE1FKCI6IHN0dWJcbiIpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICBbU0hMV0FQSS40MjldCiAqIEZJWE1FIEkgaGF2ZSBubyBpZGVhIHdoYXQgdGhpcyBmdW5jdGlvbiBkb2VzIG9yIHdoYXQgaXRzIGFyZ3VtZW50cyBhcmUuCiAqLwpCT09MIFdJTkFQSSBNTElzTUxISW5zdGFuY2UoSElOU1RBTkNFIGhJbnN0KQp7CiAgICAgICBGSVhNRSgiKCVwKSBzdHViXG4iLCBoSW5zdCk7CiAgICAgICByZXR1cm4gRkFMU0U7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDMwXQogKi8KRFdPUkQgV0lOQVBJIE1MU2V0TUxISW5zdGFuY2UoSElOU1RBTkNFIGhJbnN0LCBIQU5ETEUgaEhlYXApCnsKCUZJWE1FKCIoJXAsJXApIHN0dWJcbiIsIGhJbnN0LCBoSGVhcCk7CglyZXR1cm4gRV9GQUlMOyAgIC8qIFRoaXMgaXMgd2hhdCBpcyB1c2VkIGlmIHNobHdhcGkgbm90IGxvYWRlZCAqLwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDMxXQogKi8KRFdPUkQgV0lOQVBJIE1MQ2xlYXJNTEhJbnN0YW5jZShEV09SRCB4KQp7CglGSVhNRSgiKDB4JTA4bHgpc3R1YlxuIiwgeCk7CglyZXR1cm4gMHhhYmJhMTI0NzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzNl0KICoKICogQ29udmVydCBhbiBVbmljb2RlIHN0cmluZyBDTFNJRCBpbnRvIGEgQ0xTSUQuCiAqCiAqIFBBUkFNUwogKiAgaWRzdHIgICAgICBbSV0gICBzdHJpbmcgY29udGFpbmluZyBhIENMU0lEIGluIHRleHQgZm9ybQogKiAgaWQgICAgICAgICBbT10gICBDTFNJRCBleHRyYWN0ZWQgZnJvbSB0aGUgc3RyaW5nCiAqCiAqIFJFVFVSTlMKICogIFNfT0sgb24gc3VjY2VzcyBvciBFX0lOVkFMSURBUkcgb24gZmFpbHVyZQogKgogKiBOT1RFUwogKiAgVGhpcyBpcyByZWFsbHkgQ0xTSURGcm9tU3RyaW5nKCkgd2hpY2ggaXMgZXhwb3J0ZWQgYnkgb2xlMzIuZGxsLAogKiAgaG93ZXZlciB0aGUgbmF0aXZlIHNobHdhcGkuZGxsIGRvZXMgKm5vdCogaW1wb3J0IG9sZTMyLiBOb3IgZG9lcwogKiAgb2xlMzIuZGxsIGltcG9ydCB0aGlzIG9yZGluYWwgZnJvbSBzaGx3YXBpLiBUaGVyZWZvcmUgd2UgbXVzdCBjb25jbHVkZQogKiAgdGhhdCBNUyBkdXBsaWNhdGVkIHRoZSBjb2RlIGZvciBDTFNJREZyb21TdHJpbmcoKSwgYW5kIHllcyB0aGV5IGRpZCwgb25seQogKiAgaXQgcmV0dXJucyBhbiBFX0lOVkFMSURBUkcgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKiAgVGhpcyBpcyBhIGR1cGxpY2F0ZSAod2l0aCBjaGFuZ2VzIGZvciBVbmljb2RlKSBvZiBDTFNJREZyb21TdHJpbmcxNigpCiAqICBpbiAiZGxscy9vbGUzMi9jb21wb2JqLmMiLgogKi8KSFJFU1VMVCBXSU5BUEkgQ0xTSURGcm9tU3RyaW5nV3JhcChMUENXU1RSIGlkc3RyLCBDTFNJRCAqaWQpCnsKCUxQQ1dTVFIgcyA9IGlkc3RyOwoJQllURSAqcDsKCUlOVCBpOwoJV0NIQVIgdGFibGVbMjU2XTsKCglpZiAoIXMpIHsKCSAgbWVtc2V0KGlkLCAwLCBzaXplb2YoQ0xTSUQpKTsKCSAgcmV0dXJuIFNfT0s7Cgl9CgllbHNlIHsgIC8qIHZhbGlkYXRlIHRoZSBDTFNJRCBzdHJpbmcgKi8KCgkgIGlmIChzdHJsZW5XKHMpICE9IDM4KQoJICAgIHJldHVybiBFX0lOVkFMSURBUkc7CgoJICBpZiAoKHNbMF0hPUwneycpIHx8IChzWzldIT1MJy0nKSB8fCAoc1sxNF0hPUwnLScpIHx8IChzWzE5XSE9TCctJykgfHwgKHNbMjRdIT1MJy0nKSB8fCAoc1szN10hPUwnfScpKQoJICAgIHJldHVybiBFX0lOVkFMSURBUkc7CgoJICBmb3IgKGk9MTsgaTwzNzsgaSsrKQoJICB7CgkgICAgaWYgKChpID09IDkpfHwoaSA9PSAxNCl8fChpID09IDE5KXx8KGkgPT0gMjQpKQoJICAgICAgY29udGludWU7CgkgICAgaWYgKCEoKChzW2ldID49IEwnMCcpICYmIChzW2ldIDw9IEwnOScpKSAgfHwKCSAgICAgICAgKChzW2ldID49IEwnYScpICYmIChzW2ldIDw9IEwnZicpKSAgfHwKCSAgICAgICAgKChzW2ldID49IEwnQScpICYmIChzW2ldIDw9IEwnRicpKSkKCSAgICAgICApCgkgICAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoJICB9Cgl9CgogICAgVFJBQ0UoIiVzIC0+ICVwXG4iLCBkZWJ1Z3N0cl93KHMpLCBpZCk7CgogIC8qIHF1aWNrIGxvb2t1cCB0YWJsZSAqLwogICAgbWVtc2V0KHRhYmxlLCAwLCAyNTYqc2l6ZW9mKFdDSEFSKSk7CgogICAgZm9yIChpID0gMDsgaSA8IDEwOyBpKyspIHsKCXRhYmxlWycwJyArIGldID0gaTsKICAgIH0KICAgIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKCXRhYmxlWydBJyArIGldID0gaSsxMDsKCXRhYmxlWydhJyArIGldID0gaSsxMDsKICAgIH0KCiAgICAvKiBpbiBmb3JtIHtYWFhYWFhYWC1YWFhYLVhYWFgtWFhYWC1YWFhYWFhYWFhYWFh9ICovCgogICAgcCA9IChCWVRFICopIGlkOwoKICAgIHMrKzsJLyogc2tpcCBsZWFkaW5nIGJyYWNlICAqLwogICAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgewoJcFszIC0gaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwoJcyArPSAyOwogICAgfQogICAgcCArPSA0OwogICAgcysrOwkvKiBza2lwIC0gKi8KCiAgICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CglwWzEtaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwoJcyArPSAyOwogICAgfQogICAgcCArPSAyOwogICAgcysrOwkvKiBza2lwIC0gKi8KCiAgICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CglwWzEtaV0gPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwoJcyArPSAyOwogICAgfQogICAgcCArPSAyOwogICAgcysrOwkvKiBza2lwIC0gKi8KCiAgICAvKiB0aGVzZSBhcmUganVzdCBzZXF1ZW50aWFsIGJ5dGVzICovCiAgICBmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKSB7CgkqcCsrID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDY7IGkrKykgewoJKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CglzICs9IDI7CiAgICB9CgogICAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MzddCiAqCiAqIERldGVybWluZSBpZiB0aGUgT1Mgc3VwcG9ydHMgYSBnaXZlbiBmZWF0dXJlLgogKgogKiBQQVJBTVMKICogIGR3RmVhdHVyZSBbSV0gRmVhdHVyZSByZXF1ZXN0ZWQgKHVuZG9jdW1lbnRlZCkKICoKICogUkVUVVJOUwogKiAgVFJVRSAgSWYgdGhlIGZlYXR1cmUgaXMgYXZhaWxhYmxlLgogKiAgRkFMU0UgSWYgdGhlIGZlYXR1cmUgaXMgbm90IGF2YWlsYWJsZS4KICovCkJPT0wgV0lOQVBJIElzT1MoRFdPUkQgZmVhdHVyZSkKewogICAgT1NWRVJTSU9OSU5GT0Egb3N2aTsKICAgIERXT1JEIHBsYXRmb3JtLCBtYWpvcnYsIG1pbm9ydjsKCiAgICBvc3ZpLmR3T1NWZXJzaW9uSW5mb1NpemUgPSBzaXplb2YoT1NWRVJTSU9OSU5GT0EpOwogICAgaWYoIUdldFZlcnNpb25FeEEoJm9zdmkpKSAgewogICAgICAgIEVSUigiR2V0VmVyc2lvbkV4IGZhaWxlZCIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiAgICBtYWpvcnYgPSBvc3ZpLmR3TWFqb3JWZXJzaW9uOwogICAgbWlub3J2ID0gb3N2aS5kd01pbm9yVmVyc2lvbjsKICAgIHBsYXRmb3JtID0gb3N2aS5kd1BsYXRmb3JtSWQ7CgojZGVmaW5lIElTT1NfUkVUVVJOKHgpIFwKICAgIFRSQUNFKCIoMHglbHgpIHJldD0lZFxuIixmZWF0dXJlLCh4KSk7IFwKICAgIHJldHVybiAoeCk7CgogICAgc3dpdGNoKGZlYXR1cmUpICB7CiAgICBjYXNlIE9TX1dJTjMyU09SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJzCiAgICAgICAgICAgICAgICAgfHwgcGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MpCiAgICBjYXNlIE9TX05UOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfV0lOOTVPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MpCiAgICBjYXNlIE9TX05UNE9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDQpCiAgICBjYXNlIE9TX1dJTjIwMDBPUkdSRUFURVJfQUxUOgogICAgY2FzZSBPU19XSU4yMDAwT1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfV0lOOThPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MgJiYgbWlub3J2ID49IDEwKQogICAgY2FzZSBPU19XSU45OF9HT0xEOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA9PSAxMCkKICAgIGNhc2UgT1NfV0lOMjAwMFBSTzoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX1dJTjIwMDBTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX1dJTjIwMDBBRFZTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX1dJTjIwMDBEQVRBQ0VOVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwVEVSTUlOQUw6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIChtaW5vcnYgPT0gMCB8fCBtaW5vcnYgPT0gMSkpCiAgICBjYXNlIE9TX0VNQkVEREVEOgogICAgICAgIEZJWE1FKCIoT1NfRU1CRURERUQpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19URVJNSU5BTENMSUVOVDoKICAgICAgICBGSVhNRSgiKE9TX1RFUk1JTkFMQ0xJRU5UKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfVEVSTUlOQUxSRU1PVEVBRE1JTjoKICAgICAgICBGSVhNRSgiKE9TX1RFUk1JTkFMUkVNT1RFQURNSU4pIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19XSU45NV9HT0xEOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA9PSAwKQogICAgY2FzZSBPU19NRU9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPj0gOTApCiAgICBjYXNlIE9TX1hQT1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSAmJiBtaW5vcnYgPj0gMSkKICAgIGNhc2UgT1NfSE9NRToKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUgJiYgbWlub3J2ID49IDEpCiAgICBjYXNlIE9TX1BST0ZFU1NJT05BTDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpIAogICAgY2FzZSBPU19EQVRBQ0VOVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfQURWU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfVEVSTUlOQUxTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19QRVJTT05BTFRFUk1JTkFMU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtaW5vcnYgPj0gMSAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfRkFTVFVTRVJTV0lUQ0hJTkc6CiAgICAgICAgRklYTUUoIihPU19GQVNUVVNFUlNXSVRDSElORykgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGNhc2UgT1NfV0VMQ09NRUxPR09OVUk6CiAgICAgICAgRklYTUUoIihPU19XRUxDT01FTE9HT05VSSkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX0RPTUFJTk1FTUJFUjoKICAgICAgICBGSVhNRSgiKE9TX0RPTUFJTk1FTUJFUikgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGNhc2UgT1NfQU5ZU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfV09XNjQzMjoKICAgICAgICBGSVhNRSgiKE9TX1dPVzY0MzIpIFNob3VsZCB3ZSBjaGVjayB0aGlzP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19XRUJTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19TTUFMTEJVU0lORVNTU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfVEFCTEVUUEM6CiAgICAgICAgRklYTUUoIihPU19UQUJMRVBDKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfU0VSVkVSQURNSU5VSToKICAgICAgICBGSVhNRSgiKE9TX1NFUlZFUkFETUlOVUkpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19NRURJQUNFTlRFUjoKICAgICAgICBGSVhNRSgiKE9TX01FRElBQ0VOVEVSKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfQVBQTElBTkNFOgogICAgICAgIEZJWE1FKCIoT1NfQVBQTElBTkNFKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiN1bmRlZiBJU09TX1JFVFVSTgoKICAgIFdBUk4oIigweCVseCkgdW5rbm93biBwYXJhbWV0ZXJcbiIsZmVhdHVyZSk7CgogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENvbG9yUkdCVG9ITFMJW1NITFdBUEkuQF0KICoKICogQ29udmVydCBhbiByZ2IgQ09MT1JSRUYgaW50byB0aGUgaGxzIGNvbG9yIHNwYWNlLgogKgogKiBQQVJBTVMKICogIGNSR0IgICAgICAgICBbSV0gU291cmNlIHJnYiB2YWx1ZQogKiAgcHdIdWUgICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIGh1ZQogKiAgcHdMdW1pbmFuY2UgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIGx1bWluYW5jZQogKiAgcHdTYXR1cmF0aW9uIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29udmVydGVkIHNhdHVyYXRpb24KICoKICogUkVUVVJOUwogKiAgTm90aGluZy4gcHdIdWUsIHB3THVtaW5hbmNlIGFuZCBwd1NhdHVyYXRpb24gYXJlIHNldCB0byB0aGUgY29udmVydGVkCiAqICB2YWx1ZXMuCiAqCiAqIE5PVEVTCiAqICBPdXRwdXQgSExTIHZhbHVlcyBhcmUgY29uc3RyYWluZWQgdG8gdGhlIHJhbmdlICgwLi4yNDApLgogKiAgRm9yIEFjaHJvbWF0aWMgY29udmVyc2lvbnMsIEh1ZSBpcyBzZXQgdG8gMTYwLgogKi8KVk9JRCBXSU5BUEkgQ29sb3JSR0JUb0hMUyhDT0xPUlJFRiBjUkdCLCBMUFdPUkQgcHdIdWUsCgkJCSAgTFBXT1JEIHB3THVtaW5hbmNlLCBMUFdPUkQgcHdTYXR1cmF0aW9uKQp7CiAgaW50IHdSLCB3Rywgd0IsIHdNYXgsIHdNaW4sIHdIdWUsIHdMdW1pbm9zaXR5LCB3U2F0dXJhdGlvbjsKCiAgVFJBQ0UoIiglMDhseCwlcCwlcCwlcClcbiIsIGNSR0IsIHB3SHVlLCBwd0x1bWluYW5jZSwgcHdTYXR1cmF0aW9uKTsKCiAgd1IgPSBHZXRSVmFsdWUoY1JHQik7CiAgd0cgPSBHZXRHVmFsdWUoY1JHQik7CiAgd0IgPSBHZXRCVmFsdWUoY1JHQik7CgogIHdNYXggPSBtYXgod1IsIG1heCh3Rywgd0IpKTsKICB3TWluID0gbWluKHdSLCBtaW4od0csIHdCKSk7CgogIC8qIEx1bWlub3NpdHkgKi8KICB3THVtaW5vc2l0eSA9ICgod01heCArIHdNaW4pICogMjQwICsgMjU1KSAvIDUxMDsKCiAgaWYgKHdNYXggPT0gd01pbikKICB7CiAgICAvKiBBY2hyb21hdGljIGNhc2UgKi8KICAgIHdTYXR1cmF0aW9uID0gMDsKICAgIC8qIEh1ZSBpcyBub3cgdW5yZXByZXNlbnRhYmxlLCBidXQgdGhpcyBpcyB3aGF0IG5hdGl2ZSByZXR1cm5zLi4uICovCiAgICB3SHVlID0gMTYwOwogIH0KICBlbHNlCiAgewogICAgLyogQ2hyb21hdGljIGNhc2UgKi8KICAgIGludCB3RGVsdGEgPSB3TWF4IC0gd01pbiwgd1JOb3JtLCB3R05vcm0sIHdCTm9ybTsKCiAgICAvKiBTYXR1cmF0aW9uICovCiAgICBpZiAod0x1bWlub3NpdHkgPD0gMTIwKQogICAgICB3U2F0dXJhdGlvbiA9ICgod01heCArIHdNaW4pLzIgKyB3RGVsdGEgKiAyNDApIC8gKHdNYXggKyB3TWluKTsKICAgIGVsc2UKICAgICAgd1NhdHVyYXRpb24gPSAoKDUxMCAtIHdNYXggLSB3TWluKS8yICsgd0RlbHRhICogMjQwKSAvICg1MTAgLSB3TWF4IC0gd01pbik7CgogICAgLyogSHVlICovCiAgICB3Uk5vcm0gPSAod0RlbHRhLzIgKyB3TWF4ICogNDAgLSB3UiAqIDQwKSAvIHdEZWx0YTsKICAgIHdHTm9ybSA9ICh3RGVsdGEvMiArIHdNYXggKiA0MCAtIHdHICogNDApIC8gd0RlbHRhOwogICAgd0JOb3JtID0gKHdEZWx0YS8yICsgd01heCAqIDQwIC0gd0IgKiA0MCkgLyB3RGVsdGE7CgogICAgaWYgKHdSID09IHdNYXgpCiAgICAgIHdIdWUgPSB3Qk5vcm0gLSB3R05vcm07CiAgICBlbHNlIGlmICh3RyA9PSB3TWF4KQogICAgICB3SHVlID0gODAgKyB3Uk5vcm0gLSB3Qk5vcm07CiAgICBlbHNlCiAgICAgIHdIdWUgPSAxNjAgKyB3R05vcm0gLSB3Uk5vcm07CiAgICBpZiAod0h1ZSA8IDApCiAgICAgIHdIdWUgKz0gMjQwOwogICAgZWxzZSBpZiAod0h1ZSA+IDI0MCkKICAgICAgd0h1ZSAtPSAyNDA7CiAgfQogIGlmIChwd0h1ZSkKICAgICpwd0h1ZSA9IHdIdWU7CiAgaWYgKHB3THVtaW5hbmNlKQogICAgKnB3THVtaW5hbmNlID0gd0x1bWlub3NpdHk7CiAgaWYgKHB3U2F0dXJhdGlvbikKICAgICpwd1NhdHVyYXRpb24gPSB3U2F0dXJhdGlvbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSENyZWF0ZVNoZWxsUGFsZXR0ZQlbU0hMV0FQSS5AXQogKi8KSFBBTEVUVEUgV0lOQVBJIFNIQ3JlYXRlU2hlbGxQYWxldHRlKEhEQyBoZGMpCnsKCUZJWE1FKCJzdHViXG4iKTsKCXJldHVybiBDcmVhdGVIYWxmdG9uZVBhbGV0dGUoaGRjKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJU0hHZXRJbnZlcnNlQ01BUCAoU0hMV0FQSS5AKQogKgogKiBHZXQgYW4gaW52ZXJzZSBjb2xvciBtYXAgdGFibGUuCiAqCiAqIFBBUkFNUwogKiAgbHBDbWFwICBbT10gRGVzdGluYXRpb24gZm9yIGNvbG9yIG1hcAogKiAgZHdTaXplICBbSV0gU2l6ZSBvZiBtZW1vcnkgcG9pbnRlZCB0byBieSBscENtYXAKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfUE9JTlRFUiwgICAgSWYgbHBDbWFwIGlzIGludmFsaWQuCiAqICAgICAgICAgICBFX0lOVkFMSURBUkcsIElmIGR3RmxhZ3MgaXMgaW52YWxpZAogKiAgICAgICAgICAgRV9PVVRPRk1FTU9SWSwgSWYgdGhlcmUgaXMgbm8gbWVtb3J5IGF2YWlsYWJsZQogKgogKiBOT1RFUwogKiAgZHdTaXplIG1heSBvbmx5IGJlIENNQVBfUFRSX1NJWkUgKDQpIG9yIENNQVBfU0laRSAoODE5MikuCiAqICBJZiBkd1NpemUgPSBDTUFQX1BUUl9TSVpFLCAqbHBDbWFwIGlzIHNldCB0byB0aGUgYWRkcmVzcyBvZiB0aGlzIERMTCdzCiAqICBpbnRlcm5hbCBDTWFwLgogKiAgSWYgZHdTaXplID0gQ01BUF9TSVpFLCBscENtYXAgaXMgZmlsbGVkIHdpdGggYSBjb3B5IG9mIHRoZSBkYXRhIGZyb20KICogIHRoaXMgRExMJ3MgaW50ZXJuYWwgQ01hcC4KICovCkhSRVNVTFQgV0lOQVBJIFNIR2V0SW52ZXJzZUNNQVAoTFBEV09SRCBkZXN0LCBEV09SRCBkd1NpemUpCnsKICAgIGlmIChkd1NpemUgPT0gNCkgewoJRklYTUUoIiAtIHJldHVybmluZyBib2d1cyBhZGRyZXNzIGZvciBTSEdldEludmVyc2VDTUFQXG4iKTsKCSpkZXN0ID0gKERXT1JEKTB4YWJiYTEyNDk7CglyZXR1cm4gMDsKICAgIH0KICAgIEZJWE1FKCIoJXAsICUjbHgpIHN0dWJcbiIsIGRlc3QsIGR3U2l6ZSk7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBTSElzTG93TWVtb3J5TWFjaGluZQlbU0hMV0FQSS5AXQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIGN1cnJlbnQgY29tcHV0ZXIgaGFzIGxvdyBtZW1vcnkuCiAqCiAqIFBBUkFNUwogKiAgeCBbSV0gRklYTUUKICoKICogUkVUVVJOUwogKiAgVFJVRSBpZiB0aGUgdXNlcnMgbWFjaGluZSBoYXMgMTYgTWVnYWJ5dGVzIG9mIG1lbW9yeSBvciBsZXNzLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hJc0xvd01lbW9yeU1hY2hpbmUgKERXT1JEIHgpCnsKICBGSVhNRSgiKDB4JTA4bHgpIHN0dWJcbiIsIHgpOwogIHJldHVybiBGQUxTRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBHZXRNZW51UG9zRnJvbUlECVtTSExXQVBJLkBdCiAqCiAqIFJldHVybiB0aGUgcG9zaXRpb24gb2YgYSBtZW51IGl0ZW0gZnJvbSBpdHMgSWQuCiAqCiAqIFBBUkFNUwogKiAgIGhNZW51IFtJXSBNZW51IGNvbnRhaW5pbmcgdGhlIGl0ZW0KICogICB3SUQgICBbSV0gSWQgb2YgdGhlIG1lbnUgaXRlbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgaW5kZXggb2YgdGhlIG1lbnUgaXRlbSBpbiBoTWVudS4KICogIEZhaWx1cmU6IC0xLCBJZiB0aGUgaXRlbSBpcyBub3QgZm91bmQuCiAqLwpJTlQgV0lOQVBJIEdldE1lbnVQb3NGcm9tSUQoSE1FTlUgaE1lbnUsIFVJTlQgd0lEKQp7CiBNRU5VSVRFTUlORk9BIG1pOwogSU5UIG5Db3VudCA9IEdldE1lbnVJdGVtQ291bnQoaE1lbnUpLCBuSXRlciA9IDA7Cgogd2hpbGUgKG5JdGVyIDwgbkNvdW50KQogewogICBtaS53SUQgPSAwOwogICBpZiAoIUdldE1lbnVJdGVtSW5mb0EoaE1lbnUsIG5JdGVyLCBUUlVFLCAmbWkpICYmIG1pLndJRCA9PSB3SUQpCiAgICAgcmV0dXJuIG5JdGVyOwogICBuSXRlcisrOwogfQogcmV0dXJuIC0xOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTc5XQogKgogKiBTYW1lIGFzIFNITFdBUEkuR2V0TWVudVBvc0Zyb21JRAogKi8KRFdPUkQgV0lOQVBJIFNITWVudUluZGV4RnJvbUlEKEhNRU5VIGhNZW51LCBVSU5UIHVJRCkKewogICAgcmV0dXJuIEdldE1lbnVQb3NGcm9tSUQoaE1lbnUsIHVJRCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDQ4XQogKi8KVk9JRCBXSU5BUEkgRml4U2xhc2hlc0FuZENvbG9uVyhMUFdTVFIgbHB3c3RyKQp7CiAgICB3aGlsZSAoKmxwd3N0cikKICAgIHsKICAgICAgICBpZiAoKmxwd3N0ciA9PSAnLycpCiAgICAgICAgICAgICpscHdzdHIgPSAnXFwnOwogICAgICAgIGxwd3N0cisrOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQ2MV0KICovCkRXT1JEIFdJTkFQSSBTSEdldEFwcENvbXBhdEZsYWdzKCkKewogIEZJWE1FKCJzdHViXG4iKTsKICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS41NDldCiAqLwpIUkVTVUxUIFdJTkFQSSBTSENvQ3JlYXRlSW5zdGFuY2VBQyhSRUZDTFNJRCByY2xzaWQsIExQVU5LTk9XTiBwVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3Q2xzQ29udGV4dCwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYpCnsKICAgIHJldHVybiBDb0NyZWF0ZUluc3RhbmNlKHJjbHNpZCwgcFVua091dGVyLCBkd0Nsc0NvbnRleHQsIGlpZCwgcHB2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hTa2lwSnVuY3Rpb24JW1NITFdBUEkuQF0KICoKICogRGV0ZXJtaW5lIGlmIGEgYmluZCBjb250ZXh0IGNhbiBiZSBib3VuZCB0byBhbiBvYmplY3QKICoKICogUEFSQU1TCiAqICBwYmMgICAgW0ldIEJpbmQgY29udGV4dCB0byBjaGVjawogKiAgcGNsc2lkIFtJXSBDTFNJRCBvZiBvYmplY3QgdG8gYmUgYm91bmQgdG8KICoKICogUkVUVVJOUwogKiAgVFJVRTogSWYgaXQgaXMgc2FmZSB0byBiaW5kCiAqICBGQUxTRTogSWYgcGJjIGlzIGludmFsaWQgb3IgYmluZGluZyB3b3VsZCBub3QgYmUgc2FmZQogKgogKi8KQk9PTCBXSU5BUEkgU0hTa2lwSnVuY3Rpb24oSUJpbmRDdHggKnBiYywgY29uc3QgQ0xTSUQgKnBjbHNpZCkKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelNraXBCaW5kaW5nW10gPSB7ICdTJywnaycsJ2knLCdwJywnICcsCiAgICAnQicsJ2knLCduJywnZCcsJ2knLCduJywnZycsJyAnLCdDJywnTCcsJ1MnLCdJJywnRCcsJ1wwJyB9OwogIEJPT0wgYlJldCA9IEZBTFNFOwoKICBpZiAocGJjKQogIHsKICAgIElVbmtub3duKiBscFVuazsKCiAgICBpZiAoU1VDQ0VFREVEKElCaW5kQ3R4X0dldE9iamVjdFBhcmFtKHBiYywgKExQT0xFU1RSKXN6U2tpcEJpbmRpbmcsICZscFVuaykpKQogICAgewogICAgICBDTFNJRCBjbHNpZDsKCiAgICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fR2V0Q2xhc3NJRChscFVuaywgJmNsc2lkKSkgJiYKICAgICAgICAgIElzRXF1YWxHVUlEKHBjbHNpZCwgJmNsc2lkKSkKICAgICAgICBiUmV0ID0gVFJVRTsKCiAgICAgIElVbmtub3duX1JlbGVhc2UobHBVbmspOwogICAgfQogIH0KICByZXR1cm4gYlJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFNoZWxsS2V5IChTSExXQVBJLkApCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRTaGVsbEtleShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjKQp7CiAgICBGSVhNRSgiKCVseCwgJWx4LCAlbHgpOiBzdHViXG4iLCBhLCBiLCBjKTsKICAgIHJldHVybiAweDUwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIUXVldWVVc2VyV29ya0l0ZW0gKFNITFdBUEkuQCkKICovCkhSRVNVTFQgV0lOQVBJIFNIUXVldWVVc2VyV29ya0l0ZW0oRFdPUkQgYSwgRFdPUkQgYiwgRFdPUkQgYywgRFdPUkQgZCwgRFdPUkQgZSwgRFdPUkQgZiwgRFdPUkQgZykKewogICAgRklYTUUoIiglbHgsICVseCwgJWx4LCAlbHgsICVseCwgJWx4LCAlbHgpOiBzdHViXG4iLCBhLCBiLCBjLCBkLCBlLCBmLCBnKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSVVua25vd25fT25Gb2N1c0NoYW5nZUlTIChTSExXQVBJLkApCiAqLwpEV09SRCBXSU5BUEkgSVVua25vd25fT25Gb2N1c0NoYW5nZUlTKElVbmtub3duICogcFVuaywgSVVua25vd24gKiBwRm9jdXNPYmplY3QsIEJPT0wgYkNoYW5nZSkKewogICAgRklYTUUoIiglcCwgJXAsICVzKVxuIiwgcFVuaywgcEZvY3VzT2JqZWN0LCBiQ2hhbmdlID8gIlRSVUUiIDogIkZBTFNFIik7CgovKgogICAgSUlucHV0T2JqZWN0U2l0ZSAqIHBJT1MgPSBOVUxMOwogICAgaWYgKFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShwVW5rLCAmSUlEX0lJbnB1dE9iamVjdFNpdGUsICh2b2lkICoqKSZwSU9TKSkKICAgICAgICBJSW5wdXRPYmplY3RTaXRlX09uRm9jdXNDaGFuZ2VJUyhwSU9TLCBwRm9jdXNPYmplY3QsIGJDaGFuZ2UpOwoqLwoKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIR2V0VmFsdWVXIChTSExXQVBJLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBTS0dldFZhbHVlVyhEV09SRCBhLCBMUFdTVFIgYiwgTFBXU1RSIGMsIERXT1JEIGQsIERXT1JEIGUsIERXT1JEIGYpCnsKICAgIEZJWE1FKCIoJWx4LCAlcywgJXMsICVseCwgJWx4LCAlbHgpOiBzdHViXG4iLCBhLCBkZWJ1Z3N0cl93KGIpLCBkZWJ1Z3N0cl93KGMpLCBkLCBlLCBmKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCnR5cGVkZWYgSFJFU1VMVCAoV0lOQVBJICpEbGxHZXRWZXJzaW9uX2Z1bmMpKERMTFZFUlNJT05JTkZPICopOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBHZXRVSVZlcnNpb24gKFNITFdBUEkuNDUyKQogKi8KRFdPUkQgV0lOQVBJIEdldFVJVmVyc2lvbih2b2lkKQp7CiAgICBzdGF0aWMgRFdPUkQgdmVyc2lvbjsKCiAgICBpZiAoIXZlcnNpb24pCiAgICB7CiAgICAgICAgRGxsR2V0VmVyc2lvbl9mdW5jIHBEbGxHZXRWZXJzaW9uOwogICAgICAgIEhNT0RVTEUgZGxsID0gTG9hZExpYnJhcnlBKCJzaGVsbDMyLmRsbCIpOwogICAgICAgIGlmICghZGxsKSByZXR1cm4gMDsKCiAgICAgICAgcERsbEdldFZlcnNpb24gPSAoRGxsR2V0VmVyc2lvbl9mdW5jKUdldFByb2NBZGRyZXNzKGRsbCwgIkRsbEdldFZlcnNpb24iKTsKICAgICAgICBpZiAocERsbEdldFZlcnNpb24pCiAgICAgICAgewogICAgICAgICAgICBETExWRVJTSU9OSU5GTyBkdmk7CiAgICAgICAgICAgIGR2aS5jYlNpemUgPSBzaXplb2YoRExMVkVSU0lPTklORk8pOwogICAgICAgICAgICBpZiAocERsbEdldFZlcnNpb24oJmR2aSkgPT0gU19PSykgdmVyc2lvbiA9IGR2aS5kd01ham9yVmVyc2lvbjsKICAgICAgICB9CiAgICAgICAgRnJlZUxpYnJhcnkoIGRsbCApOwogICAgICAgIGlmICghdmVyc2lvbikgdmVyc2lvbiA9IDM7ICAvKiBvbGQgc2hlbGwgZGxscyBkb24ndCBoYXZlIERsbEdldFZlcnNpb24gKi8KICAgIH0KICAgIHJldHVybiB2ZXJzaW9uOwp9Cg==