LyoKICogU0hMV0FQSSBvcmRpbmFsIGZ1bmN0aW9ucwogKgogKiBDb3B5cmlnaHQgMTk5NyBNYXJjdXMgTWVpc3NuZXIKICogICAgICAgICAgIDE5OTggSvxyZ2VuIFNjaG1pZWQKICogICAgICAgICAgIDIwMDEtMjAwMyBKb24gR3JpZmZpdGhzCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNkZWZpbmUgQ09NX05PX1dJTkRPV1NfSAojaW5jbHVkZSAiY29uZmlnLmgiCiNpbmNsdWRlICJ3aW5lL3BvcnQuaCIKCiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KCiNkZWZpbmUgQ09CSk1BQ1JPUwojZGVmaW5lIE5PTkFNRUxFU1NVTklPTgojZGVmaW5lIE5PTkFNRUxFU1NTVFJVQ1QKCiNpbmNsdWRlICJ3aW5kZWYuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbnVzZXIuaCIKI2luY2x1ZGUgIndpbm5scy5oIgojaW5jbHVkZSAib2JqYmFzZS5oIgojaW5jbHVkZSAiZG9jb2JqLmgiCiNpbmNsdWRlICJleGRpc3AuaCIKI2luY2x1ZGUgInNobGd1aWQuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAic2hsb2JqLmgiCiNpbmNsdWRlICJzaGVsbGFwaS5oIgojaW5jbHVkZSAiY29tbWRsZy5oIgojaW5jbHVkZSAid2luZS91bmljb2RlLmgiCiNpbmNsdWRlICJ3aW5yZWcuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKI2luY2x1ZGUgInNobHdhcGkuaCIKCgpXSU5FX0RFRkFVTFRfREVCVUdfQ0hBTk5FTChzaGVsbCk7CgovKiBHZXQgYSBmdW5jdGlvbiBwb2ludGVyIGZyb20gYSBETEwgaGFuZGxlICovCiNkZWZpbmUgR0VUX0ZVTkMoZnVuYywgbW9kdWxlLCBuYW1lLCBmYWlsKSBcCiAgZG8geyBcCiAgICBpZiAoIWZ1bmMpIHsgXAogICAgICBpZiAoIVNITFdBUElfaCMjbW9kdWxlICYmICEoU0hMV0FQSV9oIyNtb2R1bGUgPSBMb2FkTGlicmFyeUEoI21vZHVsZSAiLmRsbCIpKSkgcmV0dXJuIGZhaWw7IFwKICAgICAgZnVuYyA9IChmbiMjZnVuYylHZXRQcm9jQWRkcmVzcyhTSExXQVBJX2gjI21vZHVsZSwgbmFtZSk7IFwKICAgICAgaWYgKCFmdW5jKSByZXR1cm4gZmFpbDsgXAogICAgfSBcCiAgfSB3aGlsZSAoMCkKCi8qIERMTCBoYW5kbGVzIGZvciBsYXRlIGJvdW5kIGNhbGxzICovCmV4dGVybiBISU5TVEFOQ0Ugc2hsd2FwaV9oSW5zdGFuY2U7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaHNoZWxsMzI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaHdpbm1tOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2hjb21kbGczMjsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9oY29tY3RsMzI7CmV4dGVybiBITU9EVUxFIFNITFdBUElfaG1wcjsKZXh0ZXJuIEhNT0RVTEUgU0hMV0FQSV9odXJsbW9uOwpleHRlcm4gSE1PRFVMRSBTSExXQVBJX2h2ZXJzaW9uOwoKZXh0ZXJuIERXT1JEIFNITFdBUElfVGhyZWFkUmVmX2luZGV4OwoKLyogRnVuY3Rpb24gcG9pbnRlcnMgZm9yIEdFVF9GVU5DIG1hY3JvOyB0aGVzZSBuZWVkIHRvIGJlIGdsb2JhbCBiZWNhdXNlIG9mIGdjYyBidWcgKi8KdHlwZWRlZiBMUElURU1JRExJU1QgKFdJTkFQSSAqZm5wU0hCcm93c2VGb3JGb2xkZXJXKShMUEJST1dTRUlORk9XKTsKc3RhdGljICBmbnBTSEJyb3dzZUZvckZvbGRlclcgcFNIQnJvd3NlRm9yRm9sZGVyVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFBsYXlTb3VuZFcpKExQQ1dTVFIsIEhNT0RVTEUsIERXT1JEKTsKc3RhdGljICBmbnBQbGF5U291bmRXIHBQbGF5U291bmRXOwp0eXBlZGVmIERXT1JEICAgKFdJTkFQSSAqZm5wU0hHZXRGaWxlSW5mb1cpKExQQ1dTVFIsRFdPUkQsU0hGSUxFSU5GT1cqLFVJTlQsVUlOVCk7CnN0YXRpYyAgZm5wU0hHZXRGaWxlSW5mb1cgcFNIR2V0RmlsZUluZm9XOwp0eXBlZGVmIFVJTlQgICAgKFdJTkFQSSAqZm5wRHJhZ1F1ZXJ5RmlsZVcpKEhEUk9QLCBVSU5ULCBMUFdTVFIsIFVJTlQpOwpzdGF0aWMgIGZucERyYWdRdWVyeUZpbGVXIHBEcmFnUXVlcnlGaWxlVzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFNIR2V0UGF0aEZyb21JRExpc3RXKShMUENJVEVNSURMSVNULCBMUFdTVFIpOwpzdGF0aWMgIGZucFNIR2V0UGF0aEZyb21JRExpc3RXIHBTSEdldFBhdGhGcm9tSURMaXN0VzsKdHlwZWRlZiBCT09MICAgIChXSU5BUEkgKmZucFNoZWxsRXhlY3V0ZUV4VykoTFBTSEVMTEVYRUNVVEVJTkZPVyk7CnN0YXRpYyAgZm5wU2hlbGxFeGVjdXRlRXhXIHBTaGVsbEV4ZWN1dGVFeFc7CnR5cGVkZWYgSElDT04gICAoV0lOQVBJICpmbnBTSEZpbGVPcGVyYXRpb25XKShMUFNIRklMRU9QU1RSVUNUVyk7CnN0YXRpYyAgZm5wU0hGaWxlT3BlcmF0aW9uVyBwU0hGaWxlT3BlcmF0aW9uVzsKdHlwZWRlZiBVSU5UICAgIChXSU5BUEkgKmZucEV4dHJhY3RJY29uRXhXKShMUENXU1RSLCBJTlQsSElDT04gKixISUNPTiAqLCBVSU5UKTsKc3RhdGljICBmbnBFeHRyYWN0SWNvbkV4VyBwRXh0cmFjdEljb25FeFc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBTSEdldE5ld0xpbmtJbmZvVykoTFBDV1NUUiwgTFBDV1NUUiwgTFBDV1NUUiwgQk9PTCosIFVJTlQpOwpzdGF0aWMgIGZucFNIR2V0TmV3TGlua0luZm9XIHBTSEdldE5ld0xpbmtJbmZvVzsKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKmZucFNIRGVmRXh0cmFjdEljb25XKShMUENXU1RSLCBpbnQsIFVJTlQsIEhJQ09OKiwgSElDT04qLCBVSU5UKTsKc3RhdGljICBmbnBTSERlZkV4dHJhY3RJY29uVyBwU0hEZWZFeHRyYWN0SWNvblc7CnR5cGVkZWYgSElDT04gICAoV0lOQVBJICpmbnBFeHRyYWN0SWNvblcpKEhJTlNUQU5DRSwgTFBDV1NUUiwgVUlOVCk7CnN0YXRpYyAgZm5wRXh0cmFjdEljb25XIHBFeHRyYWN0SWNvblc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRTYXZlRmlsZU5hbWVXKShMUE9QRU5GSUxFTkFNRVcpOwpzdGF0aWMgIGZucEdldFNhdmVGaWxlTmFtZVcgcEdldFNhdmVGaWxlTmFtZVc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBXTmV0UmVzdG9yZUNvbm5lY3Rpb25XKShIV05ELCBMUFdTVFIpOwpzdGF0aWMgIGZucFdOZXRSZXN0b3JlQ29ubmVjdGlvblcgcFdOZXRSZXN0b3JlQ29ubmVjdGlvblc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBXTmV0R2V0TGFzdEVycm9yVykoTFBEV09SRCwgTFBXU1RSLCBEV09SRCwgTFBXU1RSLCBEV09SRCk7CnN0YXRpYyAgZm5wV05ldEdldExhc3RFcnJvclcgcFdOZXRHZXRMYXN0RXJyb3JXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wUGFnZVNldHVwRGxnVykoTFBQQUdFU0VUVVBETEdXKTsKc3RhdGljICBmbnBQYWdlU2V0dXBEbGdXIHBQYWdlU2V0dXBEbGdXOwp0eXBlZGVmIEJPT0wgICAgKFdJTkFQSSAqZm5wUHJpbnREbGdXKShMUFBSSU5URExHVyk7CnN0YXRpYyAgZm5wUHJpbnREbGdXIHBQcmludERsZ1c7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRPcGVuRmlsZU5hbWVXKShMUE9QRU5GSUxFTkFNRVcpOwpzdGF0aWMgIGZucEdldE9wZW5GaWxlTmFtZVcgcEdldE9wZW5GaWxlTmFtZVc7CnR5cGVkZWYgRFdPUkQgICAoV0lOQVBJICpmbnBHZXRGaWxlVmVyc2lvbkluZm9TaXplVykoTFBDV1NUUixMUERXT1JEKTsKc3RhdGljICBmbnBHZXRGaWxlVmVyc2lvbkluZm9TaXplVyBwR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBHZXRGaWxlVmVyc2lvbkluZm9XKShMUENXU1RSLERXT1JELERXT1JELExQVk9JRCk7CnN0YXRpYyAgZm5wR2V0RmlsZVZlcnNpb25JbmZvVyBwR2V0RmlsZVZlcnNpb25JbmZvVzsKdHlwZWRlZiBXT1JEICAgIChXSU5BUEkgKmZucFZlclF1ZXJ5VmFsdWVXKShMUFZPSUQsTFBDV1NUUixMUFZPSUQqLFVJTlQqKTsKc3RhdGljICBmbnBWZXJRdWVyeVZhbHVlVyBwVmVyUXVlcnlWYWx1ZVc7CnR5cGVkZWYgQk9PTCAgICAoV0lOQVBJICpmbnBDT01DVEwzMl80MTcpKEhEQyxJTlQsSU5ULFVJTlQsY29uc3QgUkVDVCosTFBDV1NUUixVSU5ULGNvbnN0IElOVCopOwpzdGF0aWMgIGZucENPTUNUTDMyXzQxNyBwQ09NQ1RMMzJfNDE3Owp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wRGxsR2V0VmVyc2lvbikoRExMVkVSU0lPTklORk8qKTsKc3RhdGljICBmbnBEbGxHZXRWZXJzaW9uIHBEbGxHZXRWZXJzaW9uOwp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqZm5wQ3JlYXRlRm9ybWF0RW51bWVyYXRvcikoVUlOVCxGT1JNQVRFVEMqLElFbnVtRk9STUFURVRDKiopOwpzdGF0aWMgZm5wQ3JlYXRlRm9ybWF0RW51bWVyYXRvciBwQ3JlYXRlRm9ybWF0RW51bWVyYXRvcjsKdHlwZWRlZiBIUkVTVUxUIChXSU5BUEkgKmZucFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvcikoTFBCQyxJRW51bUZPUk1BVEVUQyosRFdPUkQpOwpzdGF0aWMgZm5wUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yIHBSZWdpc3RlckZvcm1hdEVudW1lcmF0b3I7CgpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2UoSVVua25vd24qLFJFRkdVSUQsUkVGSUlELExQVk9JRCopOwpIUkVTVUxUIFdJTkFQSSBTSEludm9rZUNvbW1hbmQoSFdORCxJU2hlbGxGb2xkZXIqLExQQ0lURU1JRExJU1QsQk9PTCk7CkhSRVNVTFQgV0lOQVBJIENMU0lERnJvbVN0cmluZ1dyYXAoTFBDV1NUUixDTFNJRCopOwpCT09MICAgIFdJTkFQSSBTSEFib3V0SW5mb1coTFBXU1RSLERXT1JEKTsKCi8qCiBOT1RFUzogTW9zdCBmdW5jdGlvbnMgZXhwb3J0ZWQgYnkgb3JkaW5hbCBzZWVtIHRvIGJlIHN1cGVyZmxvdXMuCiBUaGUgcmVhc29uIGZvciB0aGVzZSBmdW5jdGlvbnMgdG8gYmUgdGhlcmUgaXMgdG8gcHJvdmlkZSBhIHdyYXBwZXIKIGZvciB1bmljb2RlIGZ1bmN0aW9ucyB0byBwcm92aWRlIHRoZXNlIGZ1bmN0aW9ucyBvbiBzeXN0ZW1zIHdpdGhvdXQKIHVuaWNvZGUgZnVuY3Rpb25zIGVnLiB3aW45NS93aW45OC4gU2luY2Ugd2UgaGF2ZSBzdWNoIGZ1bmN0aW9ucyB3ZSBqdXN0CiBjYWxsIHRoZXNlLiBJZiBydW5uaW5nIFdpbmUgd2l0aCBuYXRpdmUgRExMcywgc29tZSBsYXRlIGJvdW5kIGNhbGxzIG1heQogZmFpbC4gSG93ZXZlciwgaXQgaXMgYmV0dGVyIHRvIGltcGxlbWVudCB0aGUgZnVuY3Rpb25zIGluIHRoZSBmb3J3YXJkIERMTAogYW5kIHJlY29tbWVuZCB0aGUgYnVpbHRpbiByYXRoZXIgdGhhbiByZWltcGxlbWVudGluZyB0aGUgY2FsbHMgaGVyZSEKKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIFNITFdBUElfRHVwU2hhcmVkSGFuZGxlCiAqCiAqIEludGVybmFsIGltcGxlbWV0YXRpb24gb2YgU0hMV0FQSV8xMS4KICovCnN0YXRpYwpIQU5ETEUgV0lOQVBJIFNITFdBUElfRHVwU2hhcmVkSGFuZGxlKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd0RzdFByb2NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTcmNQcm9jSWQsIERXT1JEIGR3QWNjZXNzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd09wdGlvbnMpCnsKICBIQU5ETEUgaERzdCwgaFNyYzsKICBEV09SRCBkd015UHJvY0lkID0gR2V0Q3VycmVudFByb2Nlc3NJZCgpOwogIEhBTkRMRSBoUmV0ID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwlbGQsJWxkLCUwOGx4LCUwOGx4KVxuIiwgaFNoYXJlZCwgZHdEc3RQcm9jSWQsIGR3U3JjUHJvY0lkLAogICAgICAgIGR3QWNjZXNzLCBkd09wdGlvbnMpOwoKICAvKiBHZXQgZGVzdCBwcm9jZXNzIGhhbmRsZSAqLwogIGlmIChkd0RzdFByb2NJZCA9PSBkd015UHJvY0lkKQogICAgaERzdCA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgZWxzZQogICAgaERzdCA9IE9wZW5Qcm9jZXNzKFBST0NFU1NfRFVQX0hBTkRMRSwgMCwgZHdEc3RQcm9jSWQpOwoKICBpZiAoaERzdCkKICB7CiAgICAvKiBHZXQgc3JjIHByb2Nlc3MgaGFuZGxlICovCiAgICBpZiAoZHdTcmNQcm9jSWQgPT0gZHdNeVByb2NJZCkKICAgICAgaFNyYyA9IEdldEN1cnJlbnRQcm9jZXNzKCk7CiAgICBlbHNlCiAgICAgIGhTcmMgPSBPcGVuUHJvY2VzcyhQUk9DRVNTX0RVUF9IQU5ETEUsIDAsIGR3U3JjUHJvY0lkKTsKCiAgICBpZiAoaFNyYykKICAgIHsKICAgICAgLyogTWFrZSBoYW5kbGUgYXZhaWxhYmxlIHRvIGRlc3QgcHJvY2VzcyAqLwogICAgICBpZiAoIUR1cGxpY2F0ZUhhbmRsZShoRHN0LCBoU2hhcmVkLCBoU3JjLCAmaFJldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdBY2Nlc3MsIDAsIGR3T3B0aW9ucyB8IERVUExJQ0FURV9TQU1FX0FDQ0VTUykpCiAgICAgICAgaFJldCA9IE5VTEw7CgogICAgICBpZiAoZHdTcmNQcm9jSWQgIT0gZHdNeVByb2NJZCkKICAgICAgICBDbG9zZUhhbmRsZShoU3JjKTsKICAgIH0KCiAgICBpZiAoZHdEc3RQcm9jSWQgIT0gZHdNeVByb2NJZCkKICAgICAgQ2xvc2VIYW5kbGUoaERzdCk7CiAgfQoKICBUUkFDRSgiUmV0dXJuaW5nIGhhbmRsZSAlcFxuIiwgaFJldCk7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjddCiAqCiAqIENyZWF0ZSBhIGJsb2NrIG9mIHNoYXJhYmxlIG1lbW9yeSBhbmQgaW5pdGlhbGlzZSBpdCB3aXRoIGRhdGEuCiAqCiAqIFBBUkFNUwogKiBscHZEYXRhICBbSV0gUG9pbnRlciB0byBkYXRhIHRvIHdyaXRlCiAqIGR3U2l6ZSAgIFtJXSBTaXplIG9mIGRhdGEKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGRhdGEKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBBIHNoYXJlZCBtZW1vcnkgaGFuZGxlCiAqIEZhaWx1cmU6IE5VTEwKICoKICogTk9URVMKICogT3JkaW5hbHMgNy0xMSBwcm92aWRlIGEgc2V0IG9mIGNhbGxzIHRvIGNyZWF0ZSBzaGFyZWQgbWVtb3J5IGJldHdlZW4gYQogKiBncm91cCBvZiBwcm9jZXNzZXMuIFRoZSBzaGFyZWQgbWVtb3J5IGlzIHRyZWF0ZWQgb3BhcXVlbHkgaW4gdGhhdCBpdHMgc2l6ZQogKiBpcyBub3QgZXhwb3NlZCB0byBjbGllbnRzIHdobyBtYXAgaXQuIFRoaXMgaXMgYWNjb21wbGlzaGVkIGJ5IHN0b3JpbmcKICogdGhlIHNpemUgb2YgdGhlIG1hcCBhcyB0aGUgZmlyc3QgRFdPUkQgb2YgbWFwcGVkIGRhdGEsIGFuZCB0aGVuIG9mZnNldHRpbmcKICogdGhlIHZpZXcgcG9pbnRlciByZXR1cm5lZCBieSB0aGlzIHNpemUuCiAqCiAqLwpIQU5ETEUgV0lOQVBJIFNIQWxsb2NTaGFyZWQoTFBDVk9JRCBscHZEYXRhLCBEV09SRCBkd1NpemUsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhNYXA7CiAgTFBWT0lEIHBNYXBwZWQ7CiAgSEFORExFIGhSZXQgPSBOVUxMOwoKICBUUkFDRSgiKCVwLCVsZCwlbGQpXG4iLCBscHZEYXRhLCBkd1NpemUsIGR3UHJvY0lkKTsKCiAgLyogQ3JlYXRlIGZpbGUgbWFwcGluZyBvZiB0aGUgY29ycmVjdCBsZW5ndGggKi8KICBoTWFwID0gQ3JlYXRlRmlsZU1hcHBpbmdBKElOVkFMSURfSEFORExFX1ZBTFVFLCBOVUxMLCBGSUxFX01BUF9SRUFELCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZHdTaXplICsgc2l6ZW9mKGR3U2l6ZSksIE5VTEwpOwogIGlmICghaE1hcCkKICAgIHJldHVybiBoUmV0OwoKICAvKiBHZXQgYSB2aWV3IGluIG91ciBwcm9jZXNzIGFkZHJlc3Mgc3BhY2UgKi8KICBwTWFwcGVkID0gTWFwVmlld09mRmlsZShoTWFwLCBGSUxFX01BUF9SRUFEIHwgRklMRV9NQVBfV1JJVEUsIDAsIDAsIDApOwoKICBpZiAocE1hcHBlZCkKICB7CiAgICAvKiBXcml0ZSBzaXplIG9mIGRhdGEsIGZvbGxvd2VkIGJ5IHRoZSBkYXRhLCB0byB0aGUgdmlldyAqLwogICAgKigoRFdPUkQqKXBNYXBwZWQpID0gZHdTaXplOwogICAgaWYgKGxwdkRhdGEpCiAgICAgIG1lbWNweSgoY2hhciAqKSBwTWFwcGVkICsgc2l6ZW9mKGR3U2l6ZSksIGxwdkRhdGEsIGR3U2l6ZSk7CgogICAgLyogUmVsZWFzZSB2aWV3LiBBbGwgZnVydGhlciB2aWV3cyBtYXBwZWQgd2lsbCBiZSBvcGFxdWUgKi8KICAgIFVubWFwVmlld09mRmlsZShwTWFwcGVkKTsKICAgIGhSZXQgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoTWFwLCBkd1Byb2NJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBHZXRDdXJyZW50UHJvY2Vzc0lkKCksIEZJTEVfTUFQX0FMTF9BQ0NFU1MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFVQTElDQVRFX1NBTUVfQUNDRVNTKTsKICB9CgogIENsb3NlSGFuZGxlKGhNYXApOwogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAIFtTSExXQVBJLjhdCiAqCiAqIEdldCBhIHBvaW50ZXIgdG8gYSBibG9jayBvZiBzaGFyZWQgbWVtb3J5IGZyb20gYSBzaGFyZWQgbWVtb3J5IGhhbmRsZS4KICoKICogUEFSQU1TCiAqIGhTaGFyZWQgIFtJXSBTaGFyZWQgbWVtb3J5IGhhbmRsZQogKiBkd1Byb2NJZCBbSV0gSUQgb2YgcHJvY2VzcyBvd25pbmcgaFNoYXJlZAogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IEEgcG9pbnRlciB0byB0aGUgc2hhcmVkIG1lbW9yeQogKiBGYWlsdXJlOiBOVUxMCiAqCiAqLwpQVk9JRCBXSU5BUEkgU0hMb2NrU2hhcmVkKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd1Byb2NJZCkKewogIEhBTkRMRSBoRHVwOwogIExQVk9JRCBwTWFwcGVkOwoKICBUUkFDRSgiKCVwICVsZClcbiIsIGhTaGFyZWQsIGR3UHJvY0lkKTsKCiAgLyogR2V0IGhhbmRsZSB0byBzaGFyZWQgbWVtb3J5IGZvciBjdXJyZW50IHByb2Nlc3MgKi8KICBoRHVwID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdQcm9jSWQsIEdldEN1cnJlbnRQcm9jZXNzSWQoKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRklMRV9NQVBfQUxMX0FDQ0VTUywgMCk7CiAgLyogR2V0IFZpZXcgKi8KICBwTWFwcGVkID0gTWFwVmlld09mRmlsZShoRHVwLCBGSUxFX01BUF9SRUFEIHwgRklMRV9NQVBfV1JJVEUsIDAsIDAsIDApOwogIENsb3NlSGFuZGxlKGhEdXApOwoKICBpZiAocE1hcHBlZCkKICAgIHJldHVybiAoY2hhciAqKSBwTWFwcGVkICsgc2l6ZW9mKERXT1JEKTsgLyogSGlkZSBzaXplICovCiAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuOV0KICoKICogUmVsZWFzZSBhIHBvaW50ZXIgdG8gYSBibG9jayBvZiBzaGFyZWQgbWVtb3J5LgogKgogKiBQQVJBTVMKICogbHBWaWV3IFtJXSBTaGFyZWQgbWVtb3J5IHBvaW50ZXIKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqLwpCT09MIFdJTkFQSSBTSFVubG9ja1NoYXJlZChMUFZPSUQgbHBWaWV3KQp7CiAgVFJBQ0UoIiglcClcbiIsIGxwVmlldyk7CiAgcmV0dXJuIFVubWFwVmlld09mRmlsZSgoY2hhciAqKSBscFZpZXcgLSBzaXplb2YoRFdPUkQpKTsgLyogSW5jbHVkZSBzaXplICovCn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgW1NITFdBUEkuMTBdCiAqCiAqIERlc3Ryb3kgYSBibG9jayBvZiBzaGFyYWJsZSBtZW1vcnkuCiAqCiAqIFBBUkFNUwogKiBoU2hhcmVkICBbSV0gU2hhcmVkIG1lbW9yeSBoYW5kbGUKICogZHdQcm9jSWQgW0ldIElEIG9mIHByb2Nlc3Mgb3duaW5nIGhTaGFyZWQKICoKICogUkVUVVJOUwogKiBTdWNjZXNzOiBUUlVFCiAqIEZhaWx1cmU6IEZBTFNFCiAqCiAqLwpCT09MIFdJTkFQSSBTSEZyZWVTaGFyZWQoSEFORExFIGhTaGFyZWQsIERXT1JEIGR3UHJvY0lkKQp7CiAgSEFORExFIGhDbG9zZTsKCiAgVFJBQ0UoIiglcCAlbGQpXG4iLCBoU2hhcmVkLCBkd1Byb2NJZCk7CgogIC8qIEdldCBhIGNvcHkgb2YgdGhlIGhhbmRsZSBmb3Igb3VyIHByb2Nlc3MsIGNsb3NpbmcgdGhlIHNvdXJjZSBoYW5kbGUgKi8KICBoQ2xvc2UgPSBTSExXQVBJX0R1cFNoYXJlZEhhbmRsZShoU2hhcmVkLCBkd1Byb2NJZCwgR2V0Q3VycmVudFByb2Nlc3NJZCgpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEVfTUFQX0FMTF9BQ0NFU1MsRFVQTElDQVRFX0NMT1NFX1NPVVJDRSk7CiAgLyogQ2xvc2UgbG9jYWwgY29weSAqLwogIHJldHVybiBDbG9zZUhhbmRsZShoQ2xvc2UpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgW1NITFdBUEkuMTFdCiAqCiAqIENvcHkgYSBzaGFyYWJsZSBtZW1vcnkgaGFuZGxlIGZyb20gb25lIHByb2Nlc3MgdG8gYW5vdGhlci4KICoKICogUEFSQU1TCiAqIGhTaGFyZWQgICAgIFtJXSBTaGFyZWQgbWVtb3J5IGhhbmRsZSB0byBkdXBsaWNhdGUKICogZHdEc3RQcm9jSWQgW0ldIElEIG9mIHRoZSBwcm9jZXNzIHdhbnRpbmcgdGhlIGR1cGxpY2F0ZWQgaGFuZGxlCiAqIGR3U3JjUHJvY0lkIFtJXSBJRCBvZiB0aGUgcHJvY2VzcyBvd25pbmcgaFNoYXJlZAogKiBkd0FjY2VzcyAgICBbSV0gRGVzaXJlZCBEdXBsaWNhdGVIYW5kbGUoKSBhY2Nlc3MKICogZHdPcHRpb25zICAgW0ldIERlc2lyZWQgRHVwbGljYXRlSGFuZGxlKCkgb3B0aW9ucwogKgogKiBSRVRVUk5TCiAqIFN1Y2Nlc3M6IEEgaGFuZGxlIHN1aXRhYmxlIGZvciB1c2UgYnkgdGhlIGR3RHN0UHJvY0lkIHByb2Nlc3MuCiAqIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqCiAqLwpIQU5ETEUgV0lOQVBJIFNITWFwSGFuZGxlKEhBTkRMRSBoU2hhcmVkLCBEV09SRCBkd0RzdFByb2NJZCwgRFdPUkQgZHdTcmNQcm9jSWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdBY2Nlc3MsIERXT1JEIGR3T3B0aW9ucykKewogIEhBTkRMRSBoUmV0OwoKICBoUmV0ID0gU0hMV0FQSV9EdXBTaGFyZWRIYW5kbGUoaFNoYXJlZCwgZHdEc3RQcm9jSWQsIGR3U3JjUHJvY0lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkd0FjY2VzcywgZHdPcHRpb25zKTsKICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjEzXQogKgogKiBDcmVhdGUgYW5kIHJlZ2lzdGVyIGEgY2xpcGJvYXJkIGVudW1lcmF0b3IgZm9yIGEgd2ViIGJyb3dzZXIuCiAqCiAqIFBBUkFNUwogKiAgbHBCQyAgICAgIFtJXSBCaW5kaW5nIGNvbnRleHQKICogIGxwVW5rbm93biBbSV0gQW4gb2JqZWN0IGV4cG9zaW5nIHRoZSBJV2ViQnJvd3NlckFwcCBpbnRlcmZhY2UKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICoKICogTk9URVMKICogIFRoZSBlbnVtZXJhdG9yIGlzIHN0b3JlZCBhcyBhIHByb3BlcnR5IG9mIHRoZSB3ZWIgYnJvd3Nlci4gSWYgaXQgZG9lcyBub3QKICogIHlldCBleGlzdCwgaXQgaXMgY3JlYXRlZCBhbmQgc2V0IGJlZm9yZSBiZWluZyByZWdpc3RlcmVkLgogKi8KSFJFU1VMVCBXSU5BUEkgUmVnaXN0ZXJEZWZhdWx0QWNjZXB0SGVhZGVycyhMUEJDIGxwQkMsIElVbmtub3duICpscFVua25vd24pCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pQcm9wZXJ0eVtdID0geyAneycsJ0QnLCcwJywnRicsJ0MnLCdBJywnNCcsJzInLCcwJywKICAgICAgJy0nLCdEJywnMycsJ0YnLCc1JywnLScsJzEnLCcxJywnQycsJ0YnLCAnLScsJ0InLCcyJywnMScsJzEnLCctJywnMCcsCiAgICAgICcwJywnQScsJ0EnLCcwJywnMCcsJzQnLCdBJywnRScsJzgnLCczJywnNycsJ30nLCdcMCcgfTsKICBJRW51bUZPUk1BVEVUQyogcElFbnVtRm9ybWF0RXRjID0gTlVMTDsKICBWQVJJQU5UQVJHIHZhcjsKICBIUkVTVUxUIGhSZXQ7CiAgSVdlYkJyb3dzZXJBcHAqIHBCcm93c2VyID0gTlVMTDsKCiAgVFJBQ0UoIiglcCwgJXApXG4iLCBscEJDLCBscFVua25vd24pOwoKICAvKiBHZXQgQW4gSVdlYkJyb3dzZXJBcHAgaW50ZXJmYWNlIGZyb20gIGxwVW5rbm93biAqLwogIGhSZXQgPSBJVW5rbm93bl9RdWVyeVNlcnZpY2UobHBVbmtub3duLCAmSUlEX0lXZWJCcm93c2VyQXBwLCAmSUlEX0lXZWJCcm93c2VyQXBwLCAoUFZPSUQpJnBCcm93c2VyKTsKICBpZiAoRkFJTEVEKGhSZXQpIHx8ICFwQnJvd3NlcikKICAgIHJldHVybiBFX05PSU5URVJGQUNFOwoKICBWX1ZUKCZ2YXIpID0gVlRfRU1QVFk7CgogIC8qIFRoZSBwcm9wZXJ0eSB3ZSBnZXQgaXMgdGhlIGJyb3dzZXJzIGNsaXBib2FyZCBlbnVtZXJhdG9yICovCiAgaFJldCA9IElXZWJCcm93c2VyQXBwX0dldFByb3BlcnR5KHBCcm93c2VyLCAoQlNUUilzelByb3BlcnR5LCAmdmFyKTsKICBpZiAoRkFJTEVEKGhSZXQpKQogICAgcmV0dXJuIGhSZXQ7CgogIGlmIChWX1ZUKCZ2YXIpID09IFZUX0VNUFRZKQogIHsKICAgIC8qIEl0ZXJhdGUgdGhyb3VnaCBhY2NlcHRlZCBkb2N1bWVudHMgYW5kIFJlZ2lzdGVyQ2xpcEJvYXJkRm9ybWF0QSgpIHRoZW0gKi8KICAgIGNoYXIgc3pLZXlCdWZmWzEyOF0sIHN6VmFsdWVCdWZmWzEyOF07CiAgICBEV09SRCBkd0tleVNpemUsIGR3VmFsdWVTaXplLCBkd1JldCA9IDAsIGR3Q291bnQgPSAwLCBkd051bVZhbHVlcywgZHdUeXBlOwogICAgRk9STUFURVRDKiBmb3JtYXRMaXN0LCAqZm9ybWF0OwogICAgSEtFWSBoRG9jczsKCiAgICBUUkFDRSgiUmVnaXN0ZXJpbmcgZm9ybWF0cyBhbmQgY3JlYXRpbmcgSUVudW1GT1JNQVRFVEMgaW5zdGFuY2VcbiIpOwoKICAgIGlmICghUmVnT3BlbktleUEoSEtFWV9MT0NBTF9NQUNISU5FLCAiU29mdHdhcmVcXE1pY3Jvc29mdFxcV2luZG93c1xcQ3VycmVudCIKICAgICAgICAgICAgICAgICAgICAgIlZlcnNpb25cXEludGVybmV0IFNldHRpbmdzXFxBY2NlcHRlZCBEb2N1bWVudHMiLCAmaERvY3MpKQogICAgICByZXR1cm4gRV9GQUlMOwoKICAgIC8qIEdldCBjb3VudCBvZiB2YWx1ZXMgaW4ga2V5ICovCiAgICB3aGlsZSAoIWR3UmV0KQogICAgewogICAgICBkd0tleVNpemUgPSBzaXplb2Yoc3pLZXlCdWZmKTsKICAgICAgZHdSZXQgPSBSZWdFbnVtVmFsdWVBKGhEb2NzLGR3Q291bnQsc3pLZXlCdWZmLCZkd0tleVNpemUsMCwmZHdUeXBlLDAsMCk7CiAgICAgIGR3Q291bnQrKzsKICAgIH0KCiAgICBkd051bVZhbHVlcyA9IGR3Q291bnQ7CgogICAgLyogTm90ZTogZHdDb3VudCA9IG51bWJlciBvZiBpdGVtcyArIDE7IFRoZSBleHRyYSBpdGVtIGlzIHRoZSBlbmQgbm9kZSAqLwogICAgZm9ybWF0ID0gZm9ybWF0TGlzdCA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBkd0NvdW50ICogc2l6ZW9mKEZPUk1BVEVUQykpOwogICAgaWYgKCFmb3JtYXRMaXN0KQogICAgICByZXR1cm4gRV9PVVRPRk1FTU9SWTsKCiAgICBpZiAoZHdOdW1WYWx1ZXMgPiAxKQogICAgewogICAgICBkd1JldCA9IDA7CiAgICAgIGR3Q291bnQgPSAwOwoKICAgICAgZHdOdW1WYWx1ZXMtLTsKCiAgICAgIC8qIFJlZ2lzdGVyIGNsaXBib2FyZCBmb3JtYXRzIGZvciB0aGUgdmFsdWVzIGFuZCBwb3B1bGF0ZSBmb3JtYXQgbGlzdCAqLwogICAgICB3aGlsZSghZHdSZXQgJiYgZHdDb3VudCA8IGR3TnVtVmFsdWVzKQogICAgICB7CiAgICAgICAgZHdLZXlTaXplID0gc2l6ZW9mKHN6S2V5QnVmZik7CiAgICAgICAgZHdWYWx1ZVNpemUgPSBzaXplb2Yoc3pWYWx1ZUJ1ZmYpOwogICAgICAgIGR3UmV0ID0gUmVnRW51bVZhbHVlQShoRG9jcywgZHdDb3VudCwgc3pLZXlCdWZmLCAmZHdLZXlTaXplLCAwLCAmZHdUeXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUEJZVEUpc3pWYWx1ZUJ1ZmYsICZkd1ZhbHVlU2l6ZSk7CiAgICAgICAgaWYgKCFkd1JldCkKICAgICAgICAgIHJldHVybiBFX0ZBSUw7CgogICAgICAgIGZvcm1hdC0+Y2ZGb3JtYXQgPSBSZWdpc3RlckNsaXBib2FyZEZvcm1hdEEoc3pWYWx1ZUJ1ZmYpOwogICAgICAgIGZvcm1hdC0+cHRkID0gTlVMTDsKICAgICAgICBmb3JtYXQtPmR3QXNwZWN0ID0gMTsKICAgICAgICBmb3JtYXQtPmxpbmRleCA9IDQ7CiAgICAgICAgZm9ybWF0LT50eW1lZCA9IC0xOwoKICAgICAgICBmb3JtYXQrKzsKICAgICAgICBkd0NvdW50Kys7CiAgICAgIH0KICAgIH0KCiAgICAvKiBUZXJtaW5hdGUgdGhlIChtYXliZSBlbXB0eSkgbGlzdCwgbGFzdCBlbnRyeSBoYXMgYSBjZkZvcm1hdCBvZiAwICovCiAgICBmb3JtYXQtPmNmRm9ybWF0ID0gMDsKICAgIGZvcm1hdC0+cHRkID0gTlVMTDsKICAgIGZvcm1hdC0+ZHdBc3BlY3QgPSAxOwogICAgZm9ybWF0LT5saW5kZXggPSA0OwogICAgZm9ybWF0LT50eW1lZCA9IC0xOwoKICAgIC8qIENyZWF0ZSBhIGNsaXBib2FyZCBlbnVtZXJhdG9yICovCiAgICBHRVRfRlVOQyhwQ3JlYXRlRm9ybWF0RW51bWVyYXRvciwgdXJsbW9uLCAiQ3JlYXRlRm9ybWF0RW51bWVyYXRvciIsIEVfRkFJTCk7CiAgICBoUmV0ID0gcENyZWF0ZUZvcm1hdEVudW1lcmF0b3IoZHdOdW1WYWx1ZXMsIGZvcm1hdExpc3QsICZwSUVudW1Gb3JtYXRFdGMpOwoKICAgIGlmIChGQUlMRUQoaFJldCkgfHwgIXBJRW51bUZvcm1hdEV0YykKICAgICAgcmV0dXJuIGhSZXQ7CgogICAgLyogU2V0IG91ciBlbnVtZXJhdG9yIGFzIHRoZSBicm93c2VycyBwcm9wZXJ0eSAqLwogICAgVl9WVCgmdmFyKSA9IFZUX1VOS05PV047CiAgICBWX1VOS05PV04oJnZhcikgPSAoSVVua25vd24qKXBJRW51bUZvcm1hdEV0YzsKCiAgICBoUmV0ID0gSVdlYkJyb3dzZXJBcHBfUHV0UHJvcGVydHkocEJyb3dzZXIsIChCU1RSKXN6UHJvcGVydHksIHZhcik7CiAgICBpZiAoRkFJTEVEKGhSZXQpKQogICAgewogICAgICAgSUVudW1GT1JNQVRFVENfUmVsZWFzZShwSUVudW1Gb3JtYXRFdGMpOwogICAgICAgZ290byBSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzX0V4aXQ7CiAgICB9CiAgfQoKICBpZiAoVl9WVCgmdmFyKSA9PSBWVF9VTktOT1dOKQogIHsKICAgIC8qIE91ciB2YXJpYW50IGlzIGhvbGRpbmcgdGhlIGNsaXBib2FyZCBlbnVtZXJhdG9yICovCiAgICBJVW5rbm93biogcElVbmtub3duID0gVl9VTktOT1dOKCZ2YXIpOwogICAgSUVudW1GT1JNQVRFVEMqIHBDbG9uZSA9IE5VTEw7CgogICAgVFJBQ0UoIlJldHJpZXZlZCBJRW51bUZPUk1BVEVUQyBwcm9wZXJ0eVxuIik7CgogICAgLyogR2V0IGFuIElFbnVtRm9ybWF0RXRjIGludGVyZmFjZSBmcm9tIHRoZSB2YXJpYW50cyB2YWx1ZSAqLwogICAgcElFbnVtRm9ybWF0RXRjID0gTlVMTDsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwSVVua25vd24sICZJSURfSUVudW1GT1JNQVRFVEMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFBWT0lEKSZwSUVudW1Gb3JtYXRFdGMpOwogICAgaWYgKCFoUmV0ICYmIHBJRW51bUZvcm1hdEV0YykKICAgIHsKICAgICAgLyogQ2xvbmUgYW5kIHJlZ2lzdGVyIHRoZSBlbnVtZXJhdG9yICovCiAgICAgIGhSZXQgPSBJRW51bUZPUk1BVEVUQ19DbG9uZShwSUVudW1Gb3JtYXRFdGMsICZwQ2xvbmUpOwogICAgICBpZiAoIWhSZXQgJiYgcENsb25lKQogICAgICB7CiAgICAgICAgR0VUX0ZVTkMocFJlZ2lzdGVyRm9ybWF0RW51bWVyYXRvciwgdXJsbW9uLCAiUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yIiwgRV9GQUlMKTsKICAgICAgICBwUmVnaXN0ZXJGb3JtYXRFbnVtZXJhdG9yKGxwQkMsIHBDbG9uZSwgMCk7CgogICAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocENsb25lKTsKICAgICAgfQoKICAgICAgLyogUmVsZWFzZSB0aGUgSUVudW1Gb3JtYXRFdGMgaW50ZXJmYWNlICovCiAgICAgIElFbnVtRk9STUFURVRDX1JlbGVhc2UocElVbmtub3duKTsKICAgIH0KICAgIElVbmtub3duX1JlbGVhc2UoVl9VTktOT1dOKCZ2YXIpKTsKICB9CgpSZWdpc3RlckRlZmF1bHRBY2NlcHRIZWFkZXJzX0V4aXQ6CiAgSVdlYkJyb3dzZXJBcHBfUmVsZWFzZShwQnJvd3Nlcik7CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNV0KICoKICogR2V0IEV4cGxvcmVycyAiQWNjZXB0TGFuZ3VhZ2UiIHNldHRpbmcuCiAqCiAqIFBBUkFNUwogKiAgbGFuZ2J1ZiBbT10gRGVzdGluYXRpb24gZm9yIGxhbmd1YWdlIHN0cmluZwogKiAgYnVmbGVuICBbSV0gTGVuZ3RoIG9mIGxhbmdidWYKICogICAgICAgICAgWzBdIFN1Y2Nlc3M6IHVzZWQgbGVuZ3RoIG9mIGxhbmdidWYKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gICBsYW5nYnVmIGlzIHNldCB0byB0aGUgbGFuZ3VhZ2Ugc3RyaW5nIGZvdW5kLgogKiAgRmFpbHVyZTogRV9GQUlMLCBJZiBhbnkgYXJndW1lbnRzIGFyZSBpbnZhbGlkLCBlcnJvciBvY2N1cnJlZCwgb3IgRXhwbG9yZXIKICogICAgICAgICAgIGRvZXMgbm90IGNvbnRhaW4gdGhlIHNldHRpbmcuCiAqICAgICAgICAgICBFX0lOVkFMSURBUkcsIElmIHRoZSBidWZmZXIgaXMgbm90IGJpZyBlbm91Z2gKICovCkhSRVNVTFQgV0lOQVBJIEdldEFjY2VwdExhbmd1YWdlc1coIExQV1NUUiBsYW5nYnVmLCBMUERXT1JEIGJ1ZmxlbikKewogICAgc3RhdGljIGNvbnN0IFdDSEFSIHN6a2V5V1tdID0gewoJJ1MnLCdvJywnZicsJ3QnLCd3JywnYScsJ3InLCdlJywnXFwnLAoJJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywKCSdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsJyAnLCdFJywneCcsJ3AnLCdsJywnbycsJ3InLCdlJywncicsJ1xcJywKCSdJJywnbicsJ3QnLCdlJywncicsJ24nLCdhJywndCcsJ2knLCdvJywnbicsJ2EnLCdsJywwfTsKICAgIHN0YXRpYyBjb25zdCBXQ0hBUiB2YWx1ZVdbXSA9IHsKCSdBJywnYycsJ2MnLCdlJywncCcsJ3QnLCdMJywnYScsJ24nLCdnJywndScsJ2EnLCdnJywnZScsMH07CiAgICBzdGF0aWMgY29uc3QgV0NIQVIgZW51c1dbXSA9IHsnZScsJ24nLCctJywndScsJ3MnLDB9OwogICAgRFdPUkQgbXlzdHJsZW4sIG15dHlwZTsKICAgIEhLRVkgbXlrZXk7CiAgICBIUkVTVUxUIHJldHZhbDsKICAgIExDSUQgbXlsY2lkOwogICAgV0NIQVIgKm15c3RyOwoKICAgIGlmKCFsYW5nYnVmIHx8ICFidWZsZW4gfHwgISpidWZsZW4pCglyZXR1cm4gRV9GQUlMOwoKICAgIG15c3RybGVuID0gKCpidWZsZW4gPiAyMCkgPyAqYnVmbGVuIDogMjAgOwogICAgbXlzdHIgPSBIZWFwQWxsb2MoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgc2l6ZW9mKFdDSEFSKSAqIG15c3RybGVuKTsKICAgIFJlZ09wZW5LZXlXKEhLRVlfQ1VSUkVOVF9VU0VSLCBzemtleVcsICZteWtleSk7CiAgICBpZihSZWdRdWVyeVZhbHVlRXhXKG15a2V5LCB2YWx1ZVcsIDAsICZteXR5cGUsIChQQllURSlteXN0ciwgJm15c3RybGVuKSkgewogICAgICAgIC8qIERpZCBub3QgZmluZCB2YWx1ZSAqLwogICAgICAgIG15bGNpZCA9IEdldFVzZXJEZWZhdWx0TENJRCgpOwogICAgICAgIC8qIHNvbWVob3cgdGhlIG15bGNpZCB0cmFuc2xhdGVzIGludG8gImVuLXVzIgogICAgICAgICAqICB0aGlzIGlzIHNpbWlsYXIgdG8gIkxPQ0FMRV9TQUJCUkVWTEFOR05BTUUiCiAgICAgICAgICogIHdoaWNoIGNvdWxkIGJlIGdvdHRlbiB2aWEgR2V0TG9jYWxlSW5mby4KICAgICAgICAgKiAgVGhlIG9ubHkgcHJvYmxlbSBpcyBMT0NBTEVfU0FCQlJFVkxBTkdVQUdFIiBpcwogICAgICAgICAqICBhIDMgY2hhciBzdHJpbmcgKGZpcnN0IDIgYXJlIGNvdW50cnkgY29kZSBhbmQgdGhpcmQgaXMKICAgICAgICAgKiAgbGV0dGVyIGZvciAic3VibGFuZ3VhZ2UiLCB3aGljaCBkb2VzIG5vdCBjb21lIGNsb3NlIHRvCiAgICAgICAgICogICJlbi11cyIKICAgICAgICAgKi8KICAgICAgICBsc3RyY3B5VyhteXN0ciwgZW51c1cpOwogICAgICAgIG15c3RybGVuID0gbHN0cmxlblcobXlzdHIpOwogICAgfSBlbHNlIHsKICAgICAgICAvKiBoYW5kbGUgcmV0dXJuZWQgc3RyaW5nICovCiAgICAgICAgRklYTUUoIm1pc3NpbmcgY29kZVxuIik7CiAgICB9CiAgICBtZW1jcHkoIGxhbmdidWYsIG15c3RyLCBtaW4oKmJ1ZmxlbixzdHJsZW5XKG15c3RyKSsxKSpzaXplb2YoV0NIQVIpICk7CgogICAgaWYoKmJ1ZmxlbiA+IHN0cmxlblcobXlzdHIpKSB7CgkqYnVmbGVuID0gc3RybGVuVyhteXN0cik7CglyZXR2YWwgPSBTX09LOwogICAgfSBlbHNlIHsKCSpidWZsZW4gPSAwOwoJcmV0dmFsID0gRV9JTlZBTElEQVJHOwoJU2V0TGFzdEVycm9yKEVSUk9SX0lOU1VGRklDSUVOVF9CVUZGRVIpOwogICAgfQogICAgUmVnQ2xvc2VLZXkobXlrZXkpOwogICAgSGVhcEZyZWUoR2V0UHJvY2Vzc0hlYXAoKSwgMCwgbXlzdHIpOwogICAgcmV0dXJuIHJldHZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE0XQogKgogKiBBc2NpaSB2ZXJzaW9uIG9mIEdldEFjY2VwdExhbmd1YWdlc1cuCiAqLwpIUkVTVUxUIFdJTkFQSSBHZXRBY2NlcHRMYW5ndWFnZXNBKCBMUFNUUiBsYW5nYnVmLCBMUERXT1JEIGJ1ZmxlbikKewogICAgV0NIQVIgKmxhbmdidWZXOwogICAgRFdPUkQgYnVmbGVuVywgY29udmxlbjsKICAgIEhSRVNVTFQgcmV0dmFsOwoKICAgIGlmKCFsYW5nYnVmIHx8ICFidWZsZW4gfHwgISpidWZsZW4pIHJldHVybiBFX0ZBSUw7CgogICAgYnVmbGVuVyA9ICpidWZsZW47CiAgICBsYW5nYnVmVyA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCAwLCBzaXplb2YoV0NIQVIpICogYnVmbGVuVyk7CiAgICByZXR2YWwgPSBHZXRBY2NlcHRMYW5ndWFnZXNXKGxhbmdidWZXLCAmYnVmbGVuVyk7CgogICAgLyogRklYTUU6IHRoaXMgaXMgd3JvbmcsIHRoZSBzdHJpbmcgbWF5IG5vdCBiZSBudWxsLXRlcm1pbmF0ZWQgKi8KICAgIGNvbnZsZW4gPSBXaWRlQ2hhclRvTXVsdGlCeXRlKENQX0FDUCwgMCwgbGFuZ2J1ZlcsIC0xLCBsYW5nYnVmLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKmJ1ZmxlbiwgTlVMTCwgTlVMTCk7CiAgICAqYnVmbGVuID0gYnVmbGVuVyA/IGNvbnZsZW4gOiAwOwoKICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGxhbmdidWZXKTsKICAgIHJldHVybiByZXR2YWw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yM10KICoKICogQ29udmVydCBhIEdVSUQgdG8gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgZ3VpZCAgICAgW0ldIEdVSUQgdG8gY29udmVydAogKiAgbHBzekRlc3QgW09dIERlc3RpbmF0aW9uIGZvciBzdHJpbmcKICogIGNjaE1heCAgIFtJXSBMZW5ndGggb2Ygb3V0cHV0IGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgY3JlYXRlZC4KICovCklOVCBXSU5BUEkgU0hTdHJpbmdGcm9tR1VJREEoUkVGR1VJRCBndWlkLCBMUFNUUiBscHN6RGVzdCwgSU5UIGNjaE1heCkKewogIGNoYXIgeGd1aWRbNDBdOwogIElOVCBpTGVuOwoKICBUUkFDRSgiKCVzLCVwLCVkKVxuIiwgZGVidWdzdHJfZ3VpZChndWlkKSwgbHBzekRlc3QsIGNjaE1heCk7CgogIHNwcmludGYoeGd1aWQsICJ7JTA4bFgtJTA0WC0lMDRYLSUwMlglMDJYLSUwMlglMDJYJTAyWCUwMlglMDJYJTAyWH0iLAogICAgICAgICAgZ3VpZC0+RGF0YTEsIGd1aWQtPkRhdGEyLCBndWlkLT5EYXRhMywKICAgICAgICAgIGd1aWQtPkRhdGE0WzBdLCBndWlkLT5EYXRhNFsxXSwgZ3VpZC0+RGF0YTRbMl0sIGd1aWQtPkRhdGE0WzNdLAogICAgICAgICAgZ3VpZC0+RGF0YTRbNF0sIGd1aWQtPkRhdGE0WzVdLCBndWlkLT5EYXRhNFs2XSwgZ3VpZC0+RGF0YTRbN10pOwoKICBpTGVuID0gc3RybGVuKHhndWlkKSArIDE7CgogIGlmIChpTGVuID4gY2NoTWF4KQogICAgcmV0dXJuIDA7CiAgbWVtY3B5KGxwc3pEZXN0LCB4Z3VpZCwgaUxlbik7CiAgcmV0dXJuIGlMZW47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNF0KICoKICogQ29udmVydCBhIEdVSUQgdG8gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgZ3VpZCBbSV0gR1VJRCB0byBjb252ZXJ0CiAqICBzdHIgIFtPXSBEZXN0aW5hdGlvbiBmb3Igc3RyaW5nCiAqICBjbWF4IFtJXSBMZW5ndGggb2Ygb3V0cHV0IGJ1ZmZlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgY3JlYXRlZC4KICovCklOVCBXSU5BUEkgU0hTdHJpbmdGcm9tR1VJRFcoUkVGR1VJRCBndWlkLCBMUFdTVFIgbHBzekRlc3QsIElOVCBjY2hNYXgpCnsKICBXQ0hBUiB4Z3VpZFs0MF07CiAgSU5UIGlMZW47CiAgc3RhdGljIGNvbnN0IFdDSEFSIHdzekZvcm1hdFtdID0geyd7JywnJScsJzAnLCc4JywnbCcsJ1gnLCctJywnJScsJzAnLCc0JywnWCcsJy0nLCclJywnMCcsJzQnLCdYJywnLScsCiAgICAgICclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJy0nLCclJywnMCcsJzInLCdYJywnJScsJzAnLCcyJywnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLAogICAgICAnWCcsJyUnLCcwJywnMicsJ1gnLCclJywnMCcsJzInLCdYJywnfScsMH07CgogIFRSQUNFKCIoJXMsJXAsJWQpXG4iLCBkZWJ1Z3N0cl9ndWlkKGd1aWQpLCBscHN6RGVzdCwgY2NoTWF4KTsKCiAgc3ByaW50ZlcoeGd1aWQsIHdzekZvcm1hdCwgZ3VpZC0+RGF0YTEsIGd1aWQtPkRhdGEyLCBndWlkLT5EYXRhMywKICAgICAgICAgIGd1aWQtPkRhdGE0WzBdLCBndWlkLT5EYXRhNFsxXSwgZ3VpZC0+RGF0YTRbMl0sIGd1aWQtPkRhdGE0WzNdLAogICAgICAgICAgZ3VpZC0+RGF0YTRbNF0sIGd1aWQtPkRhdGE0WzVdLCBndWlkLT5EYXRhNFs2XSwgZ3VpZC0+RGF0YTRbN10pOwoKICBpTGVuID0gc3RybGVuVyh4Z3VpZCkgKyAxOwoKICBpZiAoaUxlbiA+IGNjaE1heCkKICAgIHJldHVybiAwOwogIG1lbWNweShscHN6RGVzdCwgeGd1aWQsIGlMZW4qc2l6ZW9mKFdDSEFSKSk7CiAgcmV0dXJuIGlMZW47Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOV0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBzcGFjZS4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIHNwYWNlLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyU3BhY2VXKFdDSEFSIHdjKQp7CiAgICBXT1JEIENoYXJUeXBlOwoKICAgIHJldHVybiBHZXRTdHJpbmdUeXBlVyhDVF9DVFlQRTEsICZ3YywgMSwgJkNoYXJUeXBlKSAmJiAoQ2hhclR5cGUgJiBDMV9TUEFDRSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMF0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgYSBibGFuay4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGJsYW5rLAogKiAgRkFMU0Ugb3RoZXJ3aXNlLgogKgogKi8KQk9PTCBXSU5BUEkgSXNDaGFyQmxhbmtXKFdDSEFSIHdjKQp7CiAgICBXT1JEIENoYXJUeXBlOwoKICAgIHJldHVybiBHZXRTdHJpbmdUeXBlVyhDVF9DVFlQRTEsICZ3YywgMSwgJkNoYXJUeXBlKSAmJiAoQ2hhclR5cGUgJiBDMV9CTEFOSyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMV0KICoKICogRGV0ZXJtaW5lIGlmIGEgVW5pY29kZSBjaGFyYWN0ZXIgaXMgcHVuY3R1YXRpb24uCiAqCiAqIFBBUkFNUwogKiAgd2MgW0ldIENoYXJhY3RlciB0byBjaGVjay4KICoKICogUkVUVVJOUwogKiAgVFJVRSwgaWYgd2MgaXMgcHVuY3R1YXRpb24sCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJQdW5jdFcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX1BVTkNUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMyXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGNvbnRyb2wgY2hhcmFjdGVyLgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgY29udHJvbCBjaGFyYWN0ZXIsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJDbnRybFcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX0NOVFJMKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjMzXQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGRpZ2l0LgogKgogKiBQQVJBTVMKICogIHdjIFtJXSBDaGFyYWN0ZXIgdG8gY2hlY2suCiAqCiAqIFJFVFVSTlMKICogIFRSVUUsIGlmIHdjIGlzIGEgZGlnaXQsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBJc0NoYXJEaWdpdFcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX0RJR0lUKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM0XQogKgogKiBEZXRlcm1pbmUgaWYgYSBVbmljb2RlIGNoYXJhY3RlciBpcyBhIGhleCBkaWdpdC4KICoKICogUEFSQU1TCiAqICB3YyBbSV0gQ2hhcmFjdGVyIHRvIGNoZWNrLgogKgogKiBSRVRVUk5TCiAqICBUUlVFLCBpZiB3YyBpcyBhIGhleCBkaWdpdCwKICogIEZBTFNFIG90aGVyd2lzZS4KICovCkJPT0wgV0lOQVBJIElzQ2hhclhEaWdpdFcoV0NIQVIgd2MpCnsKICAgIFdPUkQgQ2hhclR5cGU7CgogICAgcmV0dXJuIEdldFN0cmluZ1R5cGVXKENUX0NUWVBFMSwgJndjLCAxLCAmQ2hhclR5cGUpICYmIChDaGFyVHlwZSAmIEMxX1hESUdJVCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNV0KICoKICovCkJPT0wgV0lOQVBJIEdldFN0cmluZ1R5cGUzRXhXKExQV1NUUiBscHN6U3RyLCBEV09SRCBkd0xlbiwgTFBWT0lEIHAzKQp7CiAgICBGSVhNRSgiKCVzLDB4JTA4bHgsJXApOiBzdHViXG4iLCBkZWJ1Z3N0cl93KGxwc3pTdHIpLCBkd0xlbiwgcDMpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNl0KICoKICogSW5zZXJ0IGEgYml0bWFwIG1lbnUgaXRlbSBhdCB0aGUgYm90dG9tIG9mIGEgbWVudS4KICoKICogUEFSQU1TCiAqICBoTWVudSBbSV0gTWVudSB0byBpbnNlcnQgaW50bwogKiAgZmxhZ3MgW0ldIEZsYWdzIGZvciBpbnNlcnRpb24KICogIGlkICAgIFtJXSBNZW51IElEIG9mIHRoZSBpdGVtCiAqICBzdHIgICBbSV0gTWVudSB0ZXh0IGZvciB0aGUgaXRlbQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUUlVFLCAgdGhlIGl0ZW0gaXMgaW5zZXJ0ZWQgaW50byB0aGUgbWVudQogKiAgRmFpbHVyZTogRkFMU0UsIGlmIGFueSBwYXJhbWV0ZXIgaXMgaW52YWxpZAogKi8KQk9PTCBXSU5BUEkgQXBwZW5kTWVudVdyYXBXKEhNRU5VIGhNZW51LCBVSU5UIGZsYWdzLCBVSU5UIGlkLCBMUENXU1RSIHN0cikKewogICAgVFJBQ0UoIiglcCwweCUwOHgsMHglMDh4LCVzKVxuIixoTWVudSwgZmxhZ3MsIGlkLCBkZWJ1Z3N0cl93KHN0cikpOwogICAgcmV0dXJuIEluc2VydE1lbnVXKGhNZW51LCAtMSwgZmxhZ3MgfCBNRl9CSVRNQVAsIGlkLCBzdHIpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNzRdCiAqCiAqIEdldCB0aGUgdGV4dCBmcm9tIGEgZ2l2ZW4gZGlhbG9nIGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgW0ldIEhhbmRsZSBvZiBkaWFsb2cKICogIG5JdGVtICAgIFtJXSBJbmRleCBvZiBpdGVtCiAqICBscHNEZXN0ICBbT10gQnVmZmVyIGZvciByZWNlaXZpbmcgd2luZG93IHRleHQKICogIG5EZXN0TGVuIFtJXSBMZW5ndGggb2YgYnVmZmVyLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBUaGUgbGVuZ3RoIG9mIHRoZSByZXR1cm5lZCB0ZXh0LgogKiAgRmFpbHVyZTogMC4KICovCklOVCBXSU5BUEkgR2V0RGxnSXRlbVRleHRXcmFwVyhIV05EIGhXbmQsIElOVCBuSXRlbSwgTFBXU1RSIGxwc0Rlc3QsSU5UIG5EZXN0TGVuKQp7CiAgSFdORCBoSXRlbSA9IEdldERsZ0l0ZW0oaFduZCwgbkl0ZW0pOwoKICBpZiAoaEl0ZW0pCiAgICByZXR1cm4gR2V0V2luZG93VGV4dFcoaEl0ZW0sIGxwc0Rlc3QsIG5EZXN0TGVuKTsKICBpZiAobkRlc3RMZW4pCiAgICAqbHBzRGVzdCA9IChXQ0hBUiknXDAnOwogIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICBbU0hMV0FQSS4xMzhdCiAqCiAqIFNldCB0aGUgdGV4dCBvZiBhIGdpdmVuIGRpYWxvZyBpdGVtLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgIFtJXSBIYW5kbGUgb2YgZGlhbG9nCiAqICBpSXRlbSAgICBbSV0gSW5kZXggb2YgaXRlbQogKiAgbHBzelRleHQgW09dIFRleHQgdG8gc2V0CiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRSVUUuICBUaGUgdGV4dCBvZiB0aGUgZGlhbG9nIGlzIHNldCB0byBscHN6VGV4dC4KICogIEZhaWx1cmU6IEZBTFNFLCBPdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTZXREbGdJdGVtVGV4dFdyYXBXKEhXTkQgaFduZCwgSU5UIGlJdGVtLCBMUENXU1RSIGxwc3pUZXh0KQp7CiAgICBIV05EIGhXbmRJdGVtID0gR2V0RGxnSXRlbShoV25kLCBpSXRlbSk7CiAgICBpZiAoaFduZEl0ZW0pCiAgICAgICAgcmV0dXJuIFNldFdpbmRvd1RleHRXKGhXbmRJdGVtLCBscHN6VGV4dCk7CiAgICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTFdCiAqCiAqIENvbXBhcmUgdHdvIEFzY2lpIHN0cmluZ3MgdXAgdG8gYSBnaXZlbiBsZW5ndGguCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU291cmNlIHN0cmluZwogKiAgbHBzekNtcCBbSV0gU3RyaW5nIHRvIGNvbXBhcmUgdG8gbHBzelNyYwogKiAgbGVuICAgICBbSV0gTWF4aW11bSBsZW5ndGgKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5DQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXAsIElOVCBsZW4pCnsKICAgIHJldHVybiBzdHJuY21wKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTJdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBOQ0EuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wTkNXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wLCBJTlQgbGVuKQp7CiAgICByZXR1cm4gc3RybmNtcFcobHBzelNyYywgbHBzekNtcCwgbGVuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1M10KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncyB1cCB0byBhIGdpdmVuIGxlbmd0aCwgaWdub3JpbmcgY2FzZS4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqICBsZW4gICAgIFtJXSBNYXhpbXVtIGxlbmd0aAogKgogKiBSRVRVUk5TCiAqICBBIG51bWJlciBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byAwIGRlcGVuZGluZyBvbiB3aGV0aGVyCiAqICBscHN6U3JjIGlzIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIGxwc3pDbXAuCiAqLwpEV09SRCBXSU5BUEkgU3RyQ21wTklDQShMUENTVFIgbHBzelNyYywgTFBDU1RSIGxwc3pDbXAsIERXT1JEIGxlbikKewogICAgcmV0dXJuIHN0cm5jYXNlY21wKGxwc3pTcmMsIGxwc3pDbXAsIGxlbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNTRdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTdHJDbXBOSUNBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcE5JQ1coTFBDV1NUUiBscHN6U3JjLCBMUENXU1RSIGxwc3pDbXAsIERXT1JEIGxlbikKewogICAgcmV0dXJuIHN0cm5jbXBpVyhscHN6U3JjLCBscHN6Q21wLCBsZW4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTU1XQogKgogKiBDb21wYXJlIHR3byBBc2NpaSBzdHJpbmdzLgogKgogKiBQQVJBTVMKICogIGxwc3pTcmMgW0ldIFNvdXJjZSBzdHJpbmcKICogIGxwc3pDbXAgW0ldIFN0cmluZyB0byBjb21wYXJlIHRvIGxwc3pTcmMKICoKICogUkVUVVJOUwogKiAgQSBudW1iZXIgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gMCBkZXBlbmRpbmcgb24gd2hldGhlcgogKiAgbHBzelNyYyBpcyBncmVhdGVyIHRoYW4sIGxlc3MgdGhhbiBvciBlcXVhbCB0byBscHN6Q21wLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcENBKExQQ1NUUiBscHN6U3JjLCBMUENTVFIgbHBzekNtcCkKewogICAgcmV0dXJuIHN0cmNtcChscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1Nl0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFN0ckNtcENBLgogKi8KRFdPUkQgV0lOQVBJIFN0ckNtcENXKExQQ1dTVFIgbHBzelNyYywgTFBDV1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY21wVyhscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1N10KICoKICogQ29tcGFyZSB0d28gQXNjaWkgc3RyaW5ncywgaWdub3JpbmcgY2FzZS4KICoKICogUEFSQU1TCiAqICBscHN6U3JjIFtJXSBTb3VyY2Ugc3RyaW5nCiAqICBscHN6Q21wIFtJXSBTdHJpbmcgdG8gY29tcGFyZSB0byBscHN6U3JjCiAqCiAqIFJFVFVSTlMKICogIEEgbnVtYmVyIGdyZWF0ZXIgdGhhbiwgbGVzcyB0aGFuIG9yIGVxdWFsIHRvIDAgZGVwZW5kaW5nIG9uIHdoZXRoZXIKICogIGxwc3pTcmMgaXMgZ3JlYXRlciB0aGFuLCBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbHBzekNtcC4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBJQ0EoTFBDU1RSIGxwc3pTcmMsIExQQ1NUUiBscHN6Q21wKQp7CiAgICByZXR1cm4gc3RyY2FzZWNtcChscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE1OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFN0ckNtcElDQS4KICovCkRXT1JEIFdJTkFQSSBTdHJDbXBJQ1coTFBDV1NUUiBscHN6U3JjLCBMUENXU1RSIGxwc3pDbXApCnsKICAgIHJldHVybiBzdHJjbXBpVyhscHN6U3JjLCBscHN6Q21wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2MF0KICoKICogR2V0IGFuIGlkZW50aWZpY2F0aW9uIHN0cmluZyBmb3IgdGhlIE9TIGFuZCBleHBsb3Jlci4KICoKICogUEFSQU1TCiAqICBscHN6RGVzdCAgW09dIERlc3RpbmF0aW9uIGZvciBJZCBzdHJpbmcKICogIGR3RGVzdExlbiBbSV0gTGVuZ3RoIG9mIGxwc3pEZXN0CiAqCiAqIFJFVFVSTlMKICogIFRSVUUsICBJZiB0aGUgc3RyaW5nIHdhcyBjcmVhdGVkIHN1Y2Nlc3NmdWxseQogKiAgRkFMU0UsIE90aGVyd2lzZQogKi8KQk9PTCBXSU5BUEkgU0hBYm91dEluZm9BKExQU1RSIGxwc3pEZXN0LCBEV09SRCBkd0Rlc3RMZW4pCnsKICBXQ0hBUiBidWZmWzIwODRdOwoKICBUUkFDRSgiKCVwLCVsZClcbiIsIGxwc3pEZXN0LCBkd0Rlc3RMZW4pOwoKICBpZiAobHBzekRlc3QgJiYgU0hBYm91dEluZm9XKGJ1ZmYsIGR3RGVzdExlbikpCiAgewogICAgV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIGJ1ZmYsIC0xLCBscHN6RGVzdCwgZHdEZXN0TGVuLCBOVUxMLCBOVUxMKTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNjFdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSEFib3V0SW5mb0EuCiAqLwpCT09MIFdJTkFQSSBTSEFib3V0SW5mb1coTFBXU1RSIGxwc3pEZXN0LCBEV09SRCBkd0Rlc3RMZW4pCnsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pJRUtleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdJJywnbicsJ3QnLCdlJywncicsJ24nLCdlJywndCcsCiAgICAnICcsJ0UnLCd4JywncCcsJ2wnLCdvJywncicsJ2UnLCdyJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6V2luTnRLZXlbXSA9IHsgJ1MnLCdPJywnRicsJ1QnLCdXJywnQScsJ1InLCdFJywnXFwnLAogICAgJ00nLCdpJywnYycsJ3InLCdvJywncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJyAnLAogICAgJ04nLCdUJywnXFwnLCdDJywndScsJ3InLCdyJywnZScsJ24nLCd0JywnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzeldpbktleVtdID0geyAnUycsJ08nLCdGJywnVCcsJ1cnLCdBJywnUicsJ0UnLCdcXCcsCiAgICAnTScsJ2knLCdjJywncicsJ28nLCdzJywnbycsJ2YnLCd0JywnXFwnLCdXJywnaScsJ24nLCdkJywnbycsJ3cnLCdzJywnXFwnLAogICAgJ0MnLCd1JywncicsJ3InLCdlJywnbicsJ3QnLCdWJywnZScsJ3InLCdzJywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6UmVnS2V5W10gPSB7ICdTJywnTycsJ0YnLCdUJywnVycsJ0EnLCdSJywnRScsJ1xcJywKICAgICdNJywnaScsJ2MnLCdyJywnbycsJ3MnLCdvJywnZicsJ3QnLCdcXCcsJ0knLCduJywndCcsJ2UnLCdyJywnbicsJ2UnLCd0JywKICAgICcgJywnRScsJ3gnLCdwJywnbCcsJ28nLCdyJywnZScsJ3InLCdcXCcsCiAgICAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywncicsJ2EnLCd0JywnaScsJ28nLCduJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6VmVyc2lvbltdID0geyAnVicsJ2UnLCdyJywncycsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzekN1c3RvbWl6ZWRbXSA9IHsgJ0MnLCd1JywncycsJ3QnLCdvJywnbScsJ2knLCd6JywnZScsJ2QnLAogICAgJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pPd25lcltdID0geyAnUicsJ2UnLCdnJywnaScsJ3MnLCd0JywnZScsJ3InLCdlJywnZCcsCiAgICAnTycsJ3cnLCduJywnZScsJ3InLCdcMCcgfTsKICBzdGF0aWMgY29uc3QgV0NIQVIgc3pPcmdbXSA9IHsgJ1InLCdlJywnZycsJ2knLCdzJywndCcsJ2UnLCdyJywnZScsJ2QnLAogICAgJ08nLCdyJywnZycsJ2EnLCduJywnaScsJ3onLCdhJywndCcsJ2knLCdvJywnbicsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelByb2R1Y3RbXSA9IHsgJ1AnLCdyJywnbycsJ2QnLCd1JywnYycsJ3QnLCdJJywnZCcsJ1wwJyB9OwogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelVwZGF0ZVtdID0geyAnSScsJ0UnLCdBJywnSycsCiAgICAnVScsJ3AnLCdkJywnYScsJ3QnLCdlJywnVScsJ3InLCdsJywnXDAnIH07CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6SGVscFtdID0geyAnSScsJ0UnLCdBJywnSycsCiAgICAnSCcsJ2UnLCdsJywncCcsJ1MnLCd0JywncicsJ2knLCduJywnZycsJ1wwJyB9OwogIFdDSEFSIGJ1ZmZbMjA4NF07CiAgSEtFWSBoUmVnOwogIERXT1JEIGR3VHlwZSwgZHdMZW47CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgbHBzekRlc3QsIGR3RGVzdExlbik7CgogIGlmICghbHBzekRlc3QpCiAgICByZXR1cm4gRkFMU0U7CgogICpscHN6RGVzdCA9ICdcMCc7CgogIC8qIFRyeSB0aGUgTlQga2V5IGZpcnN0LCBmb2xsb3dlZCBieSA5NS85OCBrZXkgKi8KICBpZiAoUmVnT3BlbktleUV4VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luTnRLZXksIDAsIEtFWV9SRUFELCAmaFJlZykgJiYKICAgICAgUmVnT3BlbktleUV4VyhIS0VZX0xPQ0FMX01BQ0hJTkUsIHN6V2luS2V5LCAwLCBLRVlfUkVBRCwgJmhSZWcpKQogICAgcmV0dXJuIEZBTFNFOwoKICAvKiBPUyBWZXJzaW9uICovCiAgYnVmZlswXSA9ICdcMCc7CiAgZHdMZW4gPSAzMDsKICBpZiAoIVNIR2V0VmFsdWVXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pJRUtleSwgc3pWZXJzaW9uLCAmZHdUeXBlLCBidWZmLCAmZHdMZW4pKQogIHsKICAgIERXT1JEIGR3U3RyTGVuID0gc3RybGVuVyhidWZmKTsKICAgIGR3TGVuID0gMzAgLSBkd1N0ckxlbjsKICAgIFNIR2V0VmFsdWVXKEhLRVlfTE9DQUxfTUFDSElORSwgc3pJRUtleSwKICAgICAgICAgICAgICAgIHN6Q3VzdG9taXplZCwgJmR3VHlwZSwgYnVmZitkd1N0ckxlbiwgJmR3TGVuKTsKICB9CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5SZWdpc3RlcmVkIE93bmVyICovCiAgYnVmZlswXSA9ICd+JzsKICBkd0xlbiA9IDI1NjsKICBpZiAoU0hHZXRWYWx1ZVcoaFJlZywgc3pPd25lciwgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIH5SZWdpc3RlcmVkIE9yZ2FuaXphdGlvbiAqLwogIGR3TGVuID0gMjU2OwogIGlmIChTSEdldFZhbHVlVyhoUmVnLCBzek9yZywgMCwgJmR3VHlwZSwgYnVmZisxLCAmZHdMZW4pKQogICAgYnVmZlsxXSA9ICdcMCc7CiAgU3RyQ2F0QnVmZlcobHBzekRlc3QsIGJ1ZmYsIGR3RGVzdExlbik7CgogIC8qIEZJWE1FOiBOb3Qgc3VyZSB3aGVyZSB0aGlzIG51bWJlciBjb21lcyBmcm9tICAqLwogIGJ1ZmZbMF0gPSAnfic7CiAgYnVmZlsxXSA9ICcwJzsKICBidWZmWzJdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogflByb2R1Y3QgSWQgKi8KICBkd0xlbiA9IDI1NjsKICBpZiAoU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzelJlZ0tleSwgc3pQcm9kdWN0LCAmZHdUeXBlLCBidWZmKzEsICZkd0xlbikpCiAgICBidWZmWzFdID0gJ1wwJzsKICBTdHJDYXRCdWZmVyhscHN6RGVzdCwgYnVmZiwgZHdEZXN0TGVuKTsKCiAgLyogfklFIFVwZGF0ZSBVcmwgKi8KICBkd0xlbiA9IDIwNDg7CiAgaWYoU0hHZXRWYWx1ZVcoSEtFWV9MT0NBTF9NQUNISU5FLCBzeldpbktleSwgc3pVcGRhdGUsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICAvKiB+SUUgSGVscCBTdHJpbmcgKi8KICBkd0xlbiA9IDI1NjsKICBpZihTSEdldFZhbHVlVyhoUmVnLCBzekhlbHAsIDAsICZkd1R5cGUsIGJ1ZmYrMSwgJmR3TGVuKSkKICAgIGJ1ZmZbMV0gPSAnXDAnOwogIFN0ckNhdEJ1ZmZXKGxwc3pEZXN0LCBidWZmLCBkd0Rlc3RMZW4pOwoKICBSZWdDbG9zZUtleShoUmVnKTsKICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2M10KICoKICogQ2FsbCBJT2xlQ29tbWFuZFRhcmdldF9RdWVyeVN0YXR1cygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gICAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbW1hbmRUYXJnZXQgaW50ZXJmYWNlCiAqICBwZ3VpZENtZEdyb3VwIFtJXSBHVUlEIGZvciB0aGUgY29tbWFuZCBncm91cAogKiAgY0NtZHMgICAgICAgICBbSV0KICogIHByZ0NtZHMgICAgICAgW09dIENvbW1hbmRzCiAqICBwQ21kVGV4dCAgICAgIFtPXSBDb21tYW5kIHRleHQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJT2xlQ29tbWFuZFRhcmdldC4KICogICAgICAgICAgIE90aGVyd2lzZSwgYW4gZXJyb3IgY29kZSBmcm9tIElPbGVDb21tYW5kVGFyZ2V0X1F1ZXJ5U3RhdHVzKCkuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVN0YXR1cyhJVW5rbm93biogbHBVbmtub3duLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFVMT05HIGNDbWRzLCBPTEVDTUQgKnByZ0NtZHMsIE9MRUNNRFRFWFQqIHBDbWRUZXh0KQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVsZCwlcCwlcClcbiIsbHBVbmtub3duLCBwZ3VpZENtZEdyb3VwLCBjQ21kcywgcHJnQ21kcywgcENtZFRleHQpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIElPbGVDb21tYW5kVGFyZ2V0KiBscE9sZTsKCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb21tYW5kVGFyZ2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwT2xlKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwT2xlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbW1hbmRUYXJnZXRfUXVlcnlTdGF0dXMobHBPbGUsIHBndWlkQ21kR3JvdXAsIGNDbWRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJnQ21kcywgcENtZFRleHQpOwogICAgICBJT2xlQ29tbWFuZFRhcmdldF9SZWxlYXNlKGxwT2xlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAkJW1NITFdBUEkuMTY0XQogKgogKiBDYWxsIElPbGVDb21tYW5kVGFyZ2V0X0V4ZWMoKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duICAgICBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElPbGVDb21tYW5kVGFyZ2V0IGludGVyZmFjZQogKiAgcGd1aWRDbWRHcm91cCBbSV0gR1VJRCBmb3IgdGhlIGNvbW1hbmQgZ3JvdXAKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfRkFJTCwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJT2xlQ29tbWFuZFRhcmdldC4KICogICAgICAgICAgIE90aGVyd2lzZSwgYW4gZXJyb3IgY29kZSBmcm9tIElPbGVDb21tYW5kVGFyZ2V0X0V4ZWMoKS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0V4ZWMoSVVua25vd24qIGxwVW5rbm93biwgUkVGR1VJRCBwZ3VpZENtZEdyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBuQ21kSUQsIERXT1JEIG5DbWRleGVjb3B0LCBWQVJJQU5UKiBwdmFJbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgVkFSSUFOVCogcHZhT3V0KQp7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwLCVsZCwlbGQsJXAsJXApXG4iLGxwVW5rbm93biwgcGd1aWRDbWRHcm91cCwgbkNtZElELAogICAgICAgIG5DbWRleGVjb3B0LCBwdmFJbiwgcHZhT3V0KTsKCiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBJT2xlQ29tbWFuZFRhcmdldCogbHBPbGU7CgogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2xlQ29tbWFuZFRhcmdldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscE9sZSk7CiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpICYmIGxwT2xlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbW1hbmRUYXJnZXRfRXhlYyhscE9sZSwgcGd1aWRDbWRHcm91cCwgbkNtZElELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuQ21kZXhlY29wdCwgcHZhSW4sIHB2YU91dCk7CiAgICAgIElPbGVDb21tYW5kVGFyZ2V0X1JlbGVhc2UobHBPbGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2NV0KICoKICogUmV0cmlldmUsIG1vZGlmeSwgYW5kIHJlLXNldCBhIHZhbHVlIGZyb20gYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgIFtJXSBXaW5kb3cgdG8gZ2V0IHZhbHVlIGZyb20KICogIG9mZnNldCBbSV0gT2Zmc2V0IG9mIHZhbHVlCiAqICB3TWFzayAgW0ldIE1hc2sgZm9yIHVpRmxhZ3MKICogIHdGbGFncyBbSV0gQml0cyB0byBzZXQgaW4gd2luZG93IHZhbHVlCiAqCiAqIFJFVFVSTlMKICogIFRoZSBuZXcgdmFsdWUgYXMgaXQgd2FzIHNldCwgb3IgMCBpZiBhbnkgcGFyYW1ldGVyIGlzIGludmFsaWQuCiAqCiAqIE5PVEVTCiAqICBBbnkgYml0cyBzZXQgaW4gdWlNYXNrIGFyZSBjbGVhcmVkIGZyb20gdGhlIHZhbHVlLCB0aGVuIGFueSBiaXRzIHNldCBpbgogKiAgdWlGbGFncyBhcmUgc2V0IGluIHRoZSB2YWx1ZS4KICovCkxPTkcgV0lOQVBJIFNIU2V0V2luZG93Qml0cyhIV05EIGh3bmQsIElOVCBvZmZzZXQsIFVJTlQgd01hc2ssIFVJTlQgd0ZsYWdzKQp7CiAgTE9ORyByZXQgPSBHZXRXaW5kb3dMb25nQShod25kLCBvZmZzZXQpOwogIExPTkcgbmV3RmxhZ3MgPSAod0ZsYWdzICYgd01hc2spIHwgKHJldCAmIH53RmxhZ3MpOwoKICBpZiAobmV3RmxhZ3MgIT0gcmV0KQogICAgcmV0ID0gU2V0V2luZG93TG9uZ0EoaHduZCwgb2Zmc2V0LCBuZXdGbGFncyk7CiAgcmV0dXJuIHJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE2N10KICoKICogQ2hhbmdlIGEgd2luZG93J3MgcGFyZW50LgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgW0ldIFdpbmRvdyB0byBjaGFuZ2UgcGFyZW50IG9mCiAqICBoV25kUGFyZW50IFtJXSBOZXcgcGFyZW50IHdpbmRvdwogKgogKiBSRVRVUk5TCiAqICBUaGUgb2xkIHBhcmVudCBvZiBoV25kLgogKgogKiBOT1RFUwogKiAgSWYgaFduZFBhcmVudCBpcyBOVUxMIChkZXNrdG9wKSwgdGhlIHdpbmRvdyBzdHlsZSBpcyBjaGFuZ2VkIHRvIFdTX1BPUFVQLgogKiAgSWYgaFduZFBhcmVudCBpcyBOT1QgTlVMTCB0aGVuIHdlIHNldCB0aGUgV1NfQ0hJTEQgc3R5bGUuCiAqLwpIV05EIFdJTkFQSSBTSFNldFBhcmVudEh3bmQoSFdORCBoV25kLCBIV05EIGhXbmRQYXJlbnQpCnsKICBUUkFDRSgiJXAsICVwXG4iLCBoV25kLCBoV25kUGFyZW50KTsKCiAgaWYoR2V0UGFyZW50KGhXbmQpID09IGhXbmRQYXJlbnQpCiAgICByZXR1cm4gMDsKCiAgaWYoaFduZFBhcmVudCkKICAgIFNIU2V0V2luZG93Qml0cyhoV25kLCBHV0xfU1RZTEUsIFdTX0NISUxELCBXU19DSElMRCk7CiAgZWxzZQogICAgU0hTZXRXaW5kb3dCaXRzKGhXbmQsIEdXTF9TVFlMRSwgV1NfUE9QVVAsIFdTX1BPUFVQKTsKCiAgcmV0dXJuIFNldFBhcmVudChoV25kLCBoV25kUGFyZW50KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjE2OF0KICoKICogTG9jYXRlIGFuZCBhZHZpc2UgYSBjb25uZWN0aW9uIHBvaW50IGluIGFuIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rU2luayAgIFtJXSBTaW5rIGZvciB0aGUgY29ubmVjdGlvbiBwb2ludCBhZHZpc2UgY2FsbAogKiAgcmlpZCAgICAgICAgW0ldIFJFRklJRCBvZiBjb25uZWN0aW9uIHBvaW50IHRvIGFkdmlzZQogKiAgYkFkdmlzZU9ubHkgW0ldIFRSVUUgPSBBZHZpc2Ugb25seSwgRkFMU0UgPSBVbmFkdmlzZSBmaXJzdAogKiAgbHBVbmtub3duICAgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIGludGVyZmFjZQogKiAgbHBDb29raWUgICAgW09dIFBvaW50ZXIgdG8gY29ubmVjdGlvbiBwb2ludCBjb29raWUKICogIGxwcENQICAgICAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgdGhlIElDb25uZWN0aW9uUG9pbnQgZm91bmQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gSWYgbHBwQ1AgaXMgbm9uLU5VTEwsIGl0IGlzIGZpbGxlZCB3aXRoIHRoZSBJQ29ubmVjdGlvblBvaW50CiAqICAgICAgICAgICB0aGF0IHdhcyBhZHZpc2VkLiBUaGUgY2FsbGVyIGlzIHJlc3BvbnNpYmxlIGZvciByZWxlYXNpbmcgaXQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIGlmIGFueSBhcmd1bWVudHMgYXJlIGludmFsaWQuCiAqICAgICAgICAgICBFX05PSU5URVJGQUNFLCBpZiBscFVua25vd24gaXNuJ3QgYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZSBpZiBhbnkgY2FsbCBmYWlscy4KICovCkhSRVNVTFQgV0lOQVBJIENvbm5lY3RUb0Nvbm5lY3Rpb25Qb2ludChJVW5rbm93biogbHBVbmtTaW5rLCBSRUZJSUQgcmlpZCwgQk9PTCBiQWR2aXNlT25seSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSVVua25vd24qIGxwVW5rbm93biwgTFBEV09SRCBscENvb2tpZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgSUNvbm5lY3Rpb25Qb2ludCAqKmxwcENQKQp7CiAgSFJFU1VMVCBoUmV0OwogIElDb25uZWN0aW9uUG9pbnRDb250YWluZXIqIGxwQ29udGFpbmVyOwogIElDb25uZWN0aW9uUG9pbnQgKmxwQ1A7CgogIGlmKCFscFVua25vd24gfHwgKGJBZHZpc2VPbmx5ICYmICFscFVua1NpbmspKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgaWYobHBwQ1ApCiAgICAqbHBwQ1AgPSBOVUxMOwoKICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lDb25uZWN0aW9uUG9pbnRDb250YWluZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwQ29udGFpbmVyKTsKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX0ZpbmRDb25uZWN0aW9uUG9pbnQobHBDb250YWluZXIsIHJpaWQsICZscENQKTsKCiAgICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogICAgewogICAgICBpZighYkFkdmlzZU9ubHkpCiAgICAgICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfVW5hZHZpc2UobHBDUCwgKmxwQ29va2llKTsKICAgICAgaFJldCA9IElDb25uZWN0aW9uUG9pbnRfQWR2aXNlKGxwQ1AsIGxwVW5rU2luaywgbHBDb29raWUpOwoKICAgICAgaWYgKEZBSUxFRChoUmV0KSkKICAgICAgICAqbHBDb29raWUgPSAwOwoKICAgICAgaWYgKGxwcENQICYmIFNVQ0NFRURFRChoUmV0KSkKICAgICAgICAqbHBwQ1AgPSBscENQOyAvKiBDYWxsZXIga2VlcHMgdGhlIGludGVyZmFjZSAqLwogICAgICBlbHNlCiAgICAgICAgSUNvbm5lY3Rpb25Qb2ludF9SZWxlYXNlKGxwQ1ApOyAvKiBSZWxlYXNlIGl0ICovCiAgICB9CgogICAgSVVua25vd25fUmVsZWFzZShscENvbnRhaW5lcik7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglACVtTSExXQVBJLjE2OV0KICoKICogUmVsZWFzZSBhbiBpbnRlcmZhY2UuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gcmVsZWFzZQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KRFdPUkQgV0lOQVBJIElVbmtub3duX0F0b21pY1JlbGVhc2UoSVVua25vd24gKiogbHBVbmtub3duKQp7CiAgICBJVW5rbm93biAqdGVtcDsKCiAgICBUUkFDRSgiKCVwKVxuIixscFVua25vd24pOwoKICAgIGlmKCFscFVua25vd24gfHwgISooKExQRFdPUkQpbHBVbmtub3duKSkgcmV0dXJuIDA7CiAgICB0ZW1wID0gKmxwVW5rbm93bjsKICAgICpscFVua25vd24gPSBOVUxMOwoKICAgIFRSQUNFKCJkb2luZyBSZWxlYXNlXG4iKTsKCiAgICByZXR1cm4gSVVua25vd25fUmVsZWFzZSh0ZW1wKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3MF0KICoKICogU2tpcCAnLy8nIGlmIHByZXNlbnQgaW4gYSBzdHJpbmcuCiAqCiAqIFBBUkFNUwogKiAgbHBzelNyYyBbSV0gU3RyaW5nIHRvIGNoZWNrIGZvciAnLy8nCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBuZXh0IGNoYXJhY3RlciBhZnRlciB0aGUgJy8vJyBvciB0aGUgc3RyaW5nIGlmIG5vdCBwcmVzZW50CiAqICBGYWlsdXJlOiBOVUxMLCBpZiBscHN6U3RyIGlzIE5VTEwuCiAqLwpMUENTVFIgV0lOQVBJIFBhdGhTa2lwTGVhZGluZ1NsYXNoZXNBKExQQ1NUUiBscHN6U3JjKQp7CiAgaWYgKGxwc3pTcmMgJiYgbHBzelNyY1swXSA9PSAnLycgJiYgbHBzelNyY1sxXSA9PSAnLycpCiAgICBscHN6U3JjICs9IDI7CiAgcmV0dXJuIGxwc3pTcmM7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAkJW1NITFdBUEkuMTcxXQogKgogKiBDaGVjayBpZiB0d28gaW50ZXJmYWNlcyBjb21lIGZyb20gdGhlIHNhbWUgb2JqZWN0LgogKgogKiBQQVJBTVMKICogICBscEludDEgW0ldIEludGVyZmFjZSB0byBjaGVjayBhZ2FpbnN0IGxwSW50Mi4KICogICBscEludDIgW0ldIEludGVyZmFjZSB0byBjaGVjayBhZ2FpbnN0IGxwSW50MS4KICoKICogUkVUVVJOUwogKiAgIFRSVUUsIElmIHRoZSBpbnRlcmZhY2VzIGNvbWUgZnJvbSB0aGUgc2FtZSBvYmplY3QuCiAqICAgRkFMU0UgT3RoZXJ3aXNlLgogKi8KQk9PTCBXSU5BUEkgU0hJc1NhbWVPYmplY3QoSVVua25vd24qIGxwSW50MSwgSVVua25vd24qIGxwSW50MikKewogIExQVk9JRCBscFVua25vd24xLCBscFVua25vd24yOwoKICBUUkFDRSgiJXAgJXBcbiIsIGxwSW50MSwgbHBJbnQyKTsKCiAgaWYgKCFscEludDEgfHwgIWxwSW50MikKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKGxwSW50MSA9PSBscEludDIpCiAgICByZXR1cm4gVFJVRTsKCiAgaWYgKCFTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBJbnQxLCAmSUlEX0lVbmtub3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEICopJmxwVW5rbm93bjEpKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKCFTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBJbnQyLCAmSUlEX0lVbmtub3duLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoTFBWT0lEICopJmxwVW5rbm93bjIpKSkKICAgIHJldHVybiBGQUxTRTsKCiAgaWYgKGxwVW5rbm93bjEgPT0gbHBVbmtub3duMikKICAgIHJldHVybiBUUlVFOwoKICByZXR1cm4gRkFMU0U7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzJdCiAqCiAqIEdldCB0aGUgd2luZG93IGhhbmRsZSBvZiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gZ2V0IHRoZSB3aW5kb3cgaGFuZGxlIG9mCiAqICBscGhXbmQgICAgW09dIERlc3RpbmF0aW9uIGZvciB3aW5kb3cgaGFuZGxlCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwaFduZCBjb250YWlucyB0aGUgb2JqZWN0cyB3aW5kb3cgaGFuZGxlLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgbHBVbmtub3duIGlzIGV4cGVjdGVkIHRvIHN1cHBvcnQgb25lIG9mIHRoZSBmb2xsb3dpbmcgaW50ZXJmYWNlczoKICogIElPbGVXaW5kb3coKSwgSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlKCksIG9yIElTaGVsbFZpZXcoKS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0dldFdpbmRvdyhJVW5rbm93biAqbHBVbmtub3duLCBIV05EICpscGhXbmQpCnsKICAvKiBGSVhNRTogV2luZSBoYXMgbm8gaGVhZGVyIGZvciB0aGlzIG9iamVjdCAqLwogIHN0YXRpYyBjb25zdCBHVUlEIElJRF9JSW50ZXJuZXRTZWN1cml0eU1nclNpdGUgPSB7IDB4NzllYWM5ZWQsCiAgICAweGJhZjksIDB4MTFjZSwgeyAweDhjLCAweDgyLCAweDAwLCAweGFhLCAweDAwLCAweDRiLCAweGE5LCAweDBiIH19OwogIElVbmtub3duICpscE9sZTsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwaFduZCk7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIGhSZXQ7CgogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZVdpbmRvdywgKHZvaWQqKikmbHBPbGUpOwoKICBpZiAoRkFJTEVEKGhSZXQpKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sJklJRF9JU2hlbGxWaWV3LCAodm9pZCoqKSZscE9sZSk7CgogICAgaWYgKEZBSUxFRChoUmV0KSkKICAgIHsKICAgICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JSW50ZXJuZXRTZWN1cml0eU1nclNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBPbGUpOwogICAgfQogIH0KCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICAvKiBMYXp5bmVzcyBoZXJlIC0gU2luY2UgR2V0V2luZG93KCkgaXMgdGhlIGZpcnN0IG1ldGhvZCBmb3IgdGhlIGFib3ZlIDMKICAgICAqIGludGVyZmFjZXMsIHdlIHVzZSB0aGUgc2FtZSBjYWxsIGZvciB0aGVtIGFsbC4KICAgICAqLwogICAgaFJldCA9IElPbGVXaW5kb3dfR2V0V2luZG93KChJT2xlV2luZG93KilscE9sZSwgbHBoV25kKTsKICAgIElVbmtub3duX1JlbGVhc2UobHBPbGUpOwogICAgaWYgKGxwaFduZCkKICAgICAgVFJBQ0UoIlJldHVybmluZyBIV05EPSVwXG4iLCAqbHBoV25kKTsKICB9CgogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTczXQogKgogKiBDYWxsIGEgbWV0aG9kIG9uIGFzIGFzIHlldCB1bmlkZW50aWZpZWQgb2JqZWN0LgogKgogKiBQQVJBTVMKICogIHBVbmsgW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSB1bmlkZW50aWZpZWQgaW50ZXJmYWNlLAogKiAgYXJnICBbSV0gQXJndW1lbnQgZm9yIHRoZSBjYWxsIG9uIHRoZSBvYmplY3QuCiAqCiAqIFJFVFVSTlMKICogIFNfT0suCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9TZXRPd25lcihJVW5rbm93biAqcFVuaywgVUxPTkcgYXJnKQp7CiAgc3RhdGljIGNvbnN0IEdVSUQgZ3VpZF8xNzMgPSB7CiAgICAweDU4MzZmYjAwLCAweDgxODcsIDB4MTFjZiwgeyAweGExLDB4MmIsMHgwMCwweGFhLDB4MDAsMHg0YSwweGU4LDB4MzcgfQogIH07CiAgSU1hbGxvYyAqcFVuazI7CgogIFRSQUNFKCIoJXAsJWxkKVxuIiwgcFVuaywgYXJnKTsKCiAgLyogTm90ZTogYXJnIG1heSBub3QgYmUgYSBVTE9ORyBhbmQgcFVuazIgaXMgZm9yIHN1cmUgbm90IGFuIElNYWxsb2MgLQogICAqICAgICAgIFdlIHVzZSB0aGlzIGludGVyZmFjZSBhcyBpdHMgdnRhYmxlIGVudHJ5IGlzIGNvbXBhdGlibGUgd2l0aCB0aGUKICAgKiAgICAgICBvYmplY3QgaW4gcXVlc3Rpb24uCiAgICogRklYTUU6IEZpbmQgb3V0IHdoYXQgdGhpcyBvYmplY3QgaXMgYW5kIHdoZXJlIGl0IHNob3VsZCBiZSBkZWZpbmVkLgogICAqLwogIGlmIChwVW5rICYmCiAgICAgIFNVQ0NFRURFRChJVW5rbm93bl9RdWVyeUludGVyZmFjZShwVW5rLCAmZ3VpZF8xNzMsICh2b2lkKiopJnBVbmsyKSkpCiAgewogICAgSU1hbGxvY19BbGxvYyhwVW5rMiwgYXJnKTsgLyogRmFrZWQgY2FsbCEhICovCiAgICBJTWFsbG9jX1JlbGVhc2UocFVuazIpOwogIH0KICByZXR1cm4gU19PSzsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3NF0KICoKICogQ2FsbCBlaXRoZXIgSU9iamVjdFdpdGhTaXRlX1NldFNpdGUoKSBvciBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXJfU2V0U2VjdXJpdHlTaXRlKCkgb24KICogYW4gb2JqZWN0LgogKgogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fU2V0U2l0ZSgKICAgICAgICBJVW5rbm93biAqb2JqLCAgICAgICAgLyogW2luXSAgIE9MRSBvYmplY3QgICAgICovCiAgICAgICAgSVVua25vd24gKnNpdGUpICAgICAgIC8qIFtpbl0gICBTaXRlIGludGVyZmFjZSAqLwp7CiAgICBIUkVTVUxUIGhyOwogICAgSU9iamVjdFdpdGhTaXRlICppb2Jqd2l0aHNpdGU7CiAgICBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXIgKmlzZWNtZ3I7CgogICAgaWYgKCFvYmopIHJldHVybiBFX0ZBSUw7CgogICAgaHIgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShvYmosICZJSURfSU9iamVjdFdpdGhTaXRlLCAoTFBWT0lEICopJmlvYmp3aXRoc2l0ZSk7CiAgICBUUkFDRSgiSUlEX0lPYmplY3RXaXRoU2l0ZSBRSSByZXQ9JTA4bHgsICVwXG4iLCBociwgaW9iandpdGhzaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaHIpKQogICAgewoJaHIgPSBJT2JqZWN0V2l0aFNpdGVfU2V0U2l0ZShpb2Jqd2l0aHNpdGUsIHNpdGUpOwoJVFJBQ0UoImRvbmUgSU9iamVjdFdpdGhTaXRlX1NldFNpdGUgcmV0PSUwOGx4XG4iLCBocik7CglJVW5rbm93bl9SZWxlYXNlKGlvYmp3aXRoc2l0ZSk7CiAgICB9CiAgICBlbHNlCiAgICB7CglociA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKG9iaiwgJklJRF9JSW50ZXJuZXRTZWN1cml0eU1hbmFnZXIsIChMUFZPSUQgKikmaXNlY21ncik7CglUUkFDRSgiSUlEX0lJbnRlcm5ldFNlY3VyaXR5TWFuYWdlciBRSSByZXQ9JTA4bHgsICVwXG4iLCBociwgaXNlY21ncik7CglpZiAoRkFJTEVEKGhyKSkgcmV0dXJuIGhyOwoKCWhyID0gSUludGVybmV0U2VjdXJpdHlNYW5hZ2VyX1NldFNlY3VyaXR5U2l0ZShpc2VjbWdyLCAoSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlICopc2l0ZSk7CglUUkFDRSgiZG9uZSBJSW50ZXJuZXRTZWN1cml0eU1hbmFnZXJfU2V0U2VjdXJpdHlTaXRlIHJldD0lMDhseFxuIiwgaHIpOwoJSVVua25vd25fUmVsZWFzZShpc2VjbWdyKTsKICAgIH0KICAgIHJldHVybiBocjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE3NV0KICoKICogQ2FsbCBJUGVyc2lzdF9HZXRDbGFzc0lEKCkgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biBbSV0gT2JqZWN0IHN1cHBvcnRpbmcgdGhlIElQZXJzaXN0IGludGVyZmFjZQogKiAgbHBDbGFzc0lkIFtPXSBEZXN0aW5hdGlvbiBmb3IgQ2xhc3MgSWQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gbHBDbGFzc0lkIGNvbnRhaW5zIHRoZSBDbGFzcyBJZCByZXF1ZXN0ZWQuCiAqICBGYWlsdXJlOiBFX0ZBSUwsIElmIGxwVW5rbm93biBpcyBOVUxMLAogKiAgICAgICAgICAgRV9OT0lOVEVSRkFDRSBJZiBscFVua25vd24gZG9lcyBub3Qgc3VwcG9ydCBJUGVyc2lzdCwKICogICAgICAgICAgIE9yIGFuIEhSRVNVTFQgZXJyb3IgY29kZS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0dldENsYXNzSUQoSVVua25vd24gKmxwVW5rbm93biwgQ0xTSUQqIGxwQ2xhc3NJZCkKewogIElQZXJzaXN0KiBscFBlcnNpc3Q7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBkZWJ1Z3N0cl9ndWlkKGxwQ2xhc3NJZCkpOwoKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sJklJRF9JUGVyc2lzdCwodm9pZCoqKSZscFBlcnNpc3QpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICAgIHsKICAgICAgSVBlcnNpc3RfR2V0Q2xhc3NJRChscFBlcnNpc3QsIGxwQ2xhc3NJZCk7CiAgICAgIElQZXJzaXN0X1JlbGVhc2UobHBQZXJzaXN0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzZdCiAqCiAqIFJldHJpZXZlIGEgU2VydmljZSBJbnRlcmZhY2UgZnJvbSBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gZ2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20KICogIHNpZCAgICAgICBbSV0gU2VydmljZSBJRCBmb3IgSVNlcnZpY2VQcm92aWRlcl9RdWVyeVNlcnZpY2UoKSBjYWxsCiAqICByaWlkICAgICAgW0ldIEZ1bmN0aW9uIHJlcXVlc3RlZCBmb3IgUXVlcnlTZXJ2aWNlIGNhbGwKICogIGxwcE91dCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBzZXJ2aWNlIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIGxwcE91dCBjb250YWlucyBhbiBvYmplY3QgcHJvdmlkaW5nIHRoZSByZXF1ZXN0ZWQgc2VydmljZQogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlCiAqCiAqIE5PVEVTCiAqICBscFVua25vd24gaXMgZXhwZWN0ZWQgdG8gc3VwcG9ydCB0aGUgSVNlcnZpY2VQcm92aWRlciBpbnRlcmZhY2UuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2UoSVVua25vd24qIGxwVW5rbm93biwgUkVGR1VJRCBzaWQsIFJFRklJRCByaWlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICBMUFZPSUQgKmxwcE91dCkKewogIElTZXJ2aWNlUHJvdmlkZXIqIHBTZXJ2aWNlID0gTlVMTDsKICBIUkVTVUxUIGhSZXQ7CgogIGlmICghbHBwT3V0KQogICAgcmV0dXJuIEVfRkFJTDsKCiAgKmxwcE91dCA9IE5VTEw7CgogIGlmICghbHBVbmtub3duKQogICAgcmV0dXJuIEVfRkFJTDsKCiAgLyogR2V0IGFuIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlIGZyb20gdGhlIG9iamVjdCAqLwogIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSVNlcnZpY2VQcm92aWRlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKExQVk9JRCopJnBTZXJ2aWNlKTsKCiAgaWYgKCFoUmV0ICYmIHBTZXJ2aWNlKQogIHsKICAgIFRSQUNFKCJRdWVyeUludGVyZmFjZSByZXR1cm5lZCAoSVNlcnZpY2VQcm92aWRlciopJXBcbiIsIHBTZXJ2aWNlKTsKCiAgICAvKiBHZXQgYSBTZXJ2aWNlIGludGVyZmFjZSBmcm9tIHRoZSBvYmplY3QgKi8KICAgIGhSZXQgPSBJU2VydmljZVByb3ZpZGVyX1F1ZXJ5U2VydmljZShwU2VydmljZSwgc2lkLCByaWlkLCBscHBPdXQpOwoKICAgIFRSQUNFKCIoSVNlcnZpY2VQcm92aWRlciopJXAgcmV0dXJuZWQgKElVbmtub3duKiklcFxuIiwgcFNlcnZpY2UsICpscHBPdXQpOwoKICAgIC8qIFJlbGVhc2UgdGhlIElTZXJ2aWNlUHJvdmlkZXIgaW50ZXJmYWNlICovCiAgICBJVW5rbm93bl9SZWxlYXNlKHBTZXJ2aWNlKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xNzddCiAqCiAqIExvYWRzIGEgcG9wdXAgbWVudS4KICoKICogUEFSQU1TCiAqICBoSW5zdCAgW0ldIEluc3RhbmNlIGhhbmRsZQogKiAgc3pOYW1lIFtJXSBNZW51IG5hbWUKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgU0hMb2FkTWVudVBvcHVwKEhJTlNUQU5DRSBoSW5zdCwgTFBDV1NUUiBzek5hbWUpCnsKICBITUVOVSBoTWVudSwgaFN1Yk1lbnU7CgogIGlmICgoaE1lbnUgPSBMb2FkTWVudVcoaEluc3QsIHN6TmFtZSkpKQogIHsKICAgIGlmICgoaFN1Yk1lbnUgPSBHZXRTdWJNZW51KGhNZW51LCAwKSkpCiAgICAgIFJlbW92ZU1lbnUoaE1lbnUsIDAsIE1GX0JZUE9TSVRJT04pOwoKICAgIERlc3Ryb3lNZW51KGhNZW51KTsKICAgIHJldHVybiBUUlVFOwogIH0KICByZXR1cm4gRkFMU0U7Cn0KCnR5cGVkZWYgc3RydWN0IF9lbnVtV25kRGF0YQp7CiAgVUlOVCAgIHVpTXNnSWQ7CiAgV1BBUkFNIHdQYXJhbTsKICBMUEFSQU0gbFBhcmFtOwogIExSRVNVTFQgKFdJTkFQSSAqcGZuUG9zdCkoSFdORCxVSU5ULFdQQVJBTSxMUEFSQU0pOwp9IGVudW1XbmREYXRhOwoKLyogQ2FsbGJhY2sgZm9yIFNITFdBUElfMTc4ICovCnN0YXRpYyBCT09MIENBTExCQUNLIFNITFdBUElfRW51bUNoaWxkUHJvYyhIV05EIGhXbmQsIExQQVJBTSBsUGFyYW0pCnsKICBlbnVtV25kRGF0YSAqZGF0YSA9IChlbnVtV25kRGF0YSAqKWxQYXJhbTsKCiAgVFJBQ0UoIiglcCwlcClcbiIsIGhXbmQsIGRhdGEpOwogIGRhdGEtPnBmblBvc3QoaFduZCwgZGF0YS0+dWlNc2dJZCwgZGF0YS0+d1BhcmFtLCBkYXRhLT5sUGFyYW0pOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xNzhdCiAqCiAqIFNlbmQgb3IgcG9zdCBhIG1lc3NhZ2UgdG8gZXZlcnkgY2hpbGQgb2YgYSB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICBbSV0gV2luZG93IHdob3NlIGNoaWxkcmVuIHdpbGwgZ2V0IHRoZSBtZXNzYWdlcwogKiAgdWlNc2dJZCBbSV0gTWVzc2FnZSBJZAogKiAgd1BhcmFtICBbSV0gV1BBUkFNIG9mIG1lc3NhZ2UKICogIGxQYXJhbSAgW0ldIExQQVJBTSBvZiBtZXNzYWdlCiAqICBiU2VuZCAgIFtJXSBUUlVFID0gVXNlIFNlbmRNZXNzYWdlQSgpLCBGQUxTRSA9IFVzZSBQb3N0TWVzc2FnZUEoKQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKgogKiBOT1RFUwogKiAgVGhlIGFwcHJvcHJpYXRlIEFTQ0lJIG9yIFVuaWNvZGUgZnVuY3Rpb24gaXMgY2FsbGVkIGZvciB0aGUgd2luZG93LgogKi8Kdm9pZCBXSU5BUEkgU0hQcm9wYWdhdGVNZXNzYWdlKEhXTkQgaFduZCwgVUlOVCB1aU1zZ0lkLCBXUEFSQU0gd1BhcmFtLCBMUEFSQU0gbFBhcmFtLCBCT09MIGJTZW5kKQp7CiAgZW51bVduZERhdGEgZGF0YTsKCiAgVFJBQ0UoIiglcCwldSwlZCwlbGQsJWQpXG4iLCBoV25kLCB1aU1zZ0lkLCB3UGFyYW0sIGxQYXJhbSwgYlNlbmQpOwoKICBpZihoV25kKQogIHsKICAgIGRhdGEudWlNc2dJZCA9IHVpTXNnSWQ7CiAgICBkYXRhLndQYXJhbSAgPSB3UGFyYW07CiAgICBkYXRhLmxQYXJhbSAgPSBsUGFyYW07CgogICAgaWYgKGJTZW5kKQogICAgICBkYXRhLnBmblBvc3QgPSBJc1dpbmRvd1VuaWNvZGUoaFduZCkgPyAodm9pZCopU2VuZE1lc3NhZ2VXIDogKHZvaWQqKVNlbmRNZXNzYWdlQTsKICAgIGVsc2UKICAgICAgZGF0YS5wZm5Qb3N0ID0gSXNXaW5kb3dVbmljb2RlKGhXbmQpID8gKHZvaWQqKVBvc3RNZXNzYWdlVyA6ICh2b2lkKilQb3N0TWVzc2FnZUE7CgogICAgRW51bUNoaWxkV2luZG93cyhoV25kLCBTSExXQVBJX0VudW1DaGlsZFByb2MsIChMUEFSQU0pJmRhdGEpOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE4MF0KICoKICogUmVtb3ZlIGFsbCBzdWItbWVudXMgZnJvbSBhIG1lbnUuCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgW0ldIE1lbnUgdG8gcmVtb3ZlIHN1Yi1tZW51cyBmcm9tCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IDAuICBBbGwgc3ViLW1lbnVzIHVuZGVyIGhNZW51IGFyZSByZW1vdmVkCiAqICBGYWlsdXJlOiAtMSwgaWYgYW55IHBhcmFtZXRlciBpcyBpbnZhbGlkCiAqLwpEV09SRCBXSU5BUEkgU0hSZW1vdmVBbGxTdWJNZW51cyhITUVOVSBoTWVudSkKewogIGludCBpSXRlbUNvdW50ID0gR2V0TWVudUl0ZW1Db3VudChoTWVudSkgLSAxOwogIHdoaWxlIChpSXRlbUNvdW50ID49IDApCiAgewogICAgSE1FTlUgaFN1Yk1lbnUgPSBHZXRTdWJNZW51KGhNZW51LCBpSXRlbUNvdW50KTsKICAgIGlmIChoU3ViTWVudSkKICAgICAgUmVtb3ZlTWVudShoTWVudSwgaUl0ZW1Db3VudCwgTUZfQllQT1NJVElPTik7CiAgICBpSXRlbUNvdW50LS07CiAgfQogIHJldHVybiBpSXRlbUNvdW50Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTgxXQogKgogKiBFbmFibGUgb3IgZGlzYWJsZSBhIG1lbnUgaXRlbS4KICoKICogUEFSQU1TCiAqICBoTWVudSAgIFtJXSBNZW51IGhvbGRpbmcgbWVudSBpdGVtCiAqICB1SUQgICAgIFtJXSBJRCBvZiBtZW51IGl0ZW0gdG8gZW5hYmxlL2Rpc2FibGUKICogIGJFbmFibGUgW0ldIFdoZXRoZXIgdG8gZW5hYmxlIChUUlVFKSBvciBkaXNhYmxlIChGQUxTRSkgdGhlIGl0ZW0uCiAqCiAqIFJFVFVSTlMKICogIFRoZSByZXR1cm4gY29kZSBmcm9tIEVuYWJsZU1lbnVJdGVtLgogKi8KVUlOVCBXSU5BUEkgU0hFbmFibGVNZW51SXRlbShITUVOVSBoTWVudSwgVUlOVCB3SXRlbUlELCBCT09MIGJFbmFibGUpCnsKICByZXR1cm4gRW5hYmxlTWVudUl0ZW0oaE1lbnUsIHdJdGVtSUQsIGJFbmFibGUgPyBNRl9FTkFCTEVEIDogTUZfR1JBWUVEKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQAlbU0hMV0FQSS4xODJdCiAqCiAqIENoZWNrIG9yIHVuY2hlY2sgYSBtZW51IGl0ZW0uCiAqCiAqIFBBUkFNUwogKiAgaE1lbnUgIFtJXSBNZW51IGhvbGRpbmcgbWVudSBpdGVtCiAqICB1SUQgICAgW0ldIElEIG9mIG1lbnUgaXRlbSB0byBjaGVjay91bmNoZWNrCiAqICBiQ2hlY2sgW0ldIFdoZXRoZXIgdG8gY2hlY2sgKFRSVUUpIG9yIHVuY2hlY2sgKEZBTFNFKSB0aGUgaXRlbS4KICoKICogUkVUVVJOUwogKiAgVGhlIHJldHVybiBjb2RlIGZyb20gQ2hlY2tNZW51SXRlbS4KICovCkRXT1JEIFdJTkFQSSBTSENoZWNrTWVudUl0ZW0oSE1FTlUgaE1lbnUsIFVJTlQgdUlELCBCT09MIGJDaGVjaykKewogIHJldHVybiBDaGVja01lbnVJdGVtKGhNZW51LCB1SUQsIGJDaGVjayA/IE1GX0NIRUNLRUQgOiBNRl9VTkNIRUNLRUQpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTgzXQogKgogKiBSZWdpc3RlciBhIHdpbmRvdyBjbGFzcyBpZiBpdCBpc24ndCBhbHJlYWR5LgogKgogKiBQQVJBTVMKICogIGxwV25kQ2xhc3MgW0ldIFdpbmRvdyBjbGFzcyB0byByZWdpc3RlcgogKgogKiBSRVRVUk5TCiAqICBUaGUgcmVzdWx0IG9mIHRoZSBSZWdpc3RlckNsYXNzQSBjYWxsLgogKi8KRFdPUkQgV0lOQVBJIFNIUmVnaXN0ZXJDbGFzc0EoV05EQ0xBU1NBICp3bmRjbGFzcykKewogIFdORENMQVNTQSB3Y2E7CiAgaWYgKEdldENsYXNzSW5mb0Eod25kY2xhc3MtPmhJbnN0YW5jZSwgd25kY2xhc3MtPmxwc3pDbGFzc05hbWUsICZ3Y2EpKQogICAgcmV0dXJuIFRSVUU7CiAgcmV0dXJuIChEV09SRClSZWdpc3RlckNsYXNzQSh3bmRjbGFzcyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4xODZdCiAqLwpCT09MIFdJTkFQSSBTSFNpbXVsYXRlRHJvcChJRHJvcFRhcmdldCAqcERyb3AsIElEYXRhT2JqZWN0ICpwRGF0YU9iaiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZ3JmS2V5U3RhdGUsIFBQT0lOVEwgbHBQdCwgRFdPUkQqIHBkd0VmZmVjdCkKewogIERXT1JEIGR3RWZmZWN0ID0gRFJPUEVGRkVDVF9MSU5LIHwgRFJPUEVGRkVDVF9NT1ZFIHwgRFJPUEVGRkVDVF9DT1BZOwogIFBPSU5UTCBwdCA9IHsgMCwgMCB9OwoKICBpZiAoIWxwUHQpCiAgICBscFB0ID0gJnB0OwoKICBpZiAoIXBkd0VmZmVjdCkKICAgIHBkd0VmZmVjdCA9ICZkd0VmZmVjdDsKCiAgSURyb3BUYXJnZXRfRHJhZ0VudGVyKHBEcm9wLCBwRGF0YU9iaiwgZ3JmS2V5U3RhdGUsICpscFB0LCBwZHdFZmZlY3QpOwoKICBpZiAoKnBkd0VmZmVjdCkKICAgIHJldHVybiBJRHJvcFRhcmdldF9Ecm9wKHBEcm9wLCBwRGF0YU9iaiwgZ3JmS2V5U3RhdGUsICpscFB0LCBwZHdFZmZlY3QpOwoKICBJRHJvcFRhcmdldF9EcmFnTGVhdmUocERyb3ApOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTg3XQogKgogKiBDYWxsIElQZXJzaXN0UHJvcGVydHlCYWdfTG9hZCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJUGVyc2lzdFByb3BlcnR5QmFnIGludGVyZmFjZQogKiAgbHBQcm9wQmFnIFtPXSBEZXN0aW5hdGlvbiBmb3IgbG9hZGVkIElQcm9wZXJ0eUJhZwogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0ZBSUwgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpEV09SRCBXSU5BUEkgU0hMb2FkRnJvbVByb3BlcnR5QmFnKElVbmtub3duICpscFVua25vd24sIElQcm9wZXJ0eUJhZyogbHBQcm9wQmFnKQp7CiAgSVBlcnNpc3RQcm9wZXJ0eUJhZyogbHBQUEJhZzsKICBIUkVTVUxUIGhSZXQgPSBFX0ZBSUw7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwUHJvcEJhZyk7CgogIGlmIChscFVua25vd24pCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JUGVyc2lzdFByb3BlcnR5QmFnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwUFBCYWcpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscFBQQmFnKQogICAgewogICAgICBoUmV0ID0gSVBlcnNpc3RQcm9wZXJ0eUJhZ19Mb2FkKGxwUFBCYWcsIGxwUHJvcEJhZywgTlVMTCk7CiAgICAgIElQZXJzaXN0UHJvcGVydHlCYWdfUmVsZWFzZShscFBQQmFnKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjE4OF0KICoKICogQ2FsbCBJT2xlQ29udHJvbFNpdGVfVHJhbnNsYXRlQWNjZWxlcmF0b3IoKSAgb24gYW4gb2JqZWN0LgogKgogKiBQQVJBTVMKICogIGxwVW5rbm93biAgIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSU9sZUNvbnRyb2xTaXRlIGludGVyZmFjZS4KICogIGxwTXNnICAgICAgIFtJXSBLZXkgbWVzc2FnZSB0byBiZSBwcm9jZXNzZWQuCiAqICBkd01vZGlmaWVycyBbSV0gRmxhZ3MgY29udGFpbmluZyB0aGUgc3RhdGUgb2YgdGhlIG1vZGlmaWVyIGtleXMuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUsIG9yIEVfSU5WQUxJREFSRyBpZiBscFVua25vd24gaXMgTlVMTC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1RyYW5zbGF0ZUFjY2VsZXJhdG9yT0NTKElVbmtub3duICpscFVua25vd24sIExQTVNHIGxwTXNnLCBEV09SRCBkd01vZGlmaWVycykKewogIElPbGVDb250cm9sU2l0ZSogbHBDU2l0ZSA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICBUUkFDRSgiKCVwLCVwLDB4JTA4bHgpXG4iLCBscFVua25vd24sIGxwTXNnLCBkd01vZGlmaWVycyk7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lPbGVDb250cm9sU2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscENTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBDU2l0ZSkKICAgIHsKICAgICAgaFJldCA9IElPbGVDb250cm9sU2l0ZV9UcmFuc2xhdGVBY2NlbGVyYXRvcihscENTaXRlLCBscE1zZywgZHdNb2RpZmllcnMpOwogICAgICBJT2xlQ29udHJvbFNpdGVfUmVsZWFzZShscENTaXRlKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS4xODldCiAqCiAqIENhbGwgSU9sZUNvbnRyb2xTaXRlX0dldEV4dGVuZGVkQ29udHJvbCgpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJT2xlQ29udHJvbFNpdGUgaW50ZXJmYWNlLgogKiAgbHBwRGlzcCAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgcmVzdWx0aW5nIElEaXNwYXRjaC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEFuIEhSRVNVTFQgZXJyb3IgY29kZSwgb3IgRV9GQUlMIGlmIGxwVW5rbm93biBpcyBOVUxMLgogKi8KRFdPUkQgV0lOQVBJIElVbmtub3duX09uRm9jdXNPQ1MoSVVua25vd24gKmxwVW5rbm93biwgSURpc3BhdGNoKiogbHBwRGlzcCkKewogIElPbGVDb250cm9sU2l0ZSogbHBDU2l0ZSA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9GQUlMOwoKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBVbmtub3duLCBscHBEaXNwKTsKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSU9sZUNvbnRyb2xTaXRlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwQ1NpdGUpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscENTaXRlKQogICAgewogICAgICBoUmV0ID0gSU9sZUNvbnRyb2xTaXRlX0dldEV4dGVuZGVkQ29udHJvbChscENTaXRlLCBscHBEaXNwKTsKICAgICAgSU9sZUNvbnRyb2xTaXRlX1JlbGVhc2UobHBDU2l0ZSk7CiAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgIFtTSExXQVBJLjE5MF0KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0hhbmRsZUlSZXN0cmljdChMUFVOS05PV04gbHBVbmtub3duLCBQVk9JRCBscEFyZzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQVk9JRCBscEFyZzIsIFBWT0lEIGxwQXJnMywgUFZPSUQgbHBBcmc0KQp7CiAgLyogRklYTUU6IHtEMTJGMjZCMi1EOTBBLTExRDAtODMwRC0wMEFBMDA1QjQzODN9IC0gV2hhdCBvYmplY3QgZG9lcyB0aGlzIHJlcHJlc2VudD8gKi8KICBzdGF0aWMgY29uc3QgRFdPUkQgc2VydmljZV9pZFtdID0geyAweGQxMmYyNmIyLCAweDExZDBkOTBhLCAweGFhMDAwZDgzLCAweDgzNDM1YjAwIH07CiAgLyogRklYTUU6IHtEMTJGMjZCMS1EOTBBLTExRDAtODMwRC0wMEFBMDA1QjQzODN9IC0gQWxzbyBVbmtub3duL3VuZG9jdW1lbnRlZCAqLwogIHN0YXRpYyBjb25zdCBEV09SRCBmdW5jdGlvbl9pZFtdID0geyAweGQxMmYyNmIxLCAweDExZDBkOTBhLCAweGFhMDAwZDgzLCAweDgzNDM1YjAwIH07CiAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwogIExQVU5LTk9XTiBscFVua0lubmVyID0gTlVMTDsgLyogRklYTUU6IFJlYWwgdHlwZSBpcyB1bmtub3duICovCgogIFRSQUNFKCIoJXAsJXAsJXAsJXAsJXApXG4iLCBscFVua25vd24sIGxwQXJnMSwgbHBBcmcyLCBscEFyZzMsIGxwQXJnNCk7CgogIGlmIChscFVua25vd24gJiYgbHBBcmc0KQogIHsKICAgICBoUmV0ID0gSVVua25vd25fUXVlcnlTZXJ2aWNlKGxwVW5rbm93biwgKFJFRkdVSUQpc2VydmljZV9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChSRUZHVUlEKWZ1bmN0aW9uX2lkLCAodm9pZCoqKSZscFVua0lubmVyKTsKCiAgICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscFVua0lubmVyKQogICAgIHsKICAgICAgIC8qIEZJWE1FOiBUaGUgdHlwZSBvZiBzZXJ2aWNlIG9iamVjdCByZXF1ZXN0ZWQgaXMgdW5rbm93biwgaG93ZXZlcgoJKiB0ZXN0aW5nIHNob3dzIHRoYXQgaXRzIGZpcnN0IG1ldGhvZCBpcyBjYWxsZWQgd2l0aCA0IHBhcmFtZXRlcnMuCgkqIEZha2UgdGhpcyBieSB1c2luZyBJUGFyc2VEaXNwbGF5TmFtZV9QYXJzZURpc3BsYXlOYW1lIHNpbmNlIHRoZQoJKiBzaWduYXR1cmUgYW5kIHBvc2l0aW9uIGluIHRoZSB2dGFibGUgbWF0Y2hlcyBvdXIgdW5rbm93biBvYmplY3QgdHlwZS4KCSovCiAgICAgICBoUmV0ID0gSVBhcnNlRGlzcGxheU5hbWVfUGFyc2VEaXNwbGF5TmFtZSgoTFBQQVJTRURJU1BMQVlOQU1FKWxwVW5rSW5uZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBscEFyZzEsIGxwQXJnMiwgbHBBcmczLCBscEFyZzQpOwogICAgICAgSVVua25vd25fUmVsZWFzZShscFVua0lubmVyKTsKICAgICB9CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICAgIFtTSExXQVBJLjE5Ml0KICoKICogR2V0IGEgc3ViLW1lbnUgZnJvbSBhIG1lbnUgaXRlbS4KICoKICogUEFSQU1TCiAqICBoTWVudSBbSV0gTWVudSB0byBnZXQgc3ViLW1lbnUgZnJvbQogKiAgdUlEICAgW0ldIElEIG9mIG1lbnUgaXRlbSBjb250YWluaW5nIHN1Yi1tZW51CiAqCiAqIFJFVFVSTlMKICogIFRoZSBzdWItbWVudSBvZiB0aGUgaXRlbSwgb3IgYSBOVUxMIGhhbmRsZSBpZiBhbnkgcGFyYW1ldGVycyBhcmUgaW52YWxpZC4KICovCkhNRU5VIFdJTkFQSSBTSEdldE1lbnVGcm9tSUQoSE1FTlUgaE1lbnUsIFVJTlQgdUlEKQp7CiAgTUVOVUlURU1JTkZPVyBtaTsKCiAgVFJBQ0UoIiglcCwldSlcbiIsIGhNZW51LCB1SUQpOwoKICBtaS5jYlNpemUgPSBzaXplb2YobWkpOwogIG1pLmZNYXNrID0gTUlJTV9TVUJNRU5VOwoKICBpZiAoIUdldE1lbnVJdGVtSW5mb1coaE1lbnUsIHVJRCwgRkFMU0UsICZtaSkpCiAgICByZXR1cm4gTlVMTDsKCiAgcmV0dXJuIG1pLmhTdWJNZW51Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTkzXQogKgogKiBHZXQgdGhlIGNvbG9yIGRlcHRoIG9mIHRoZSBwcmltYXJ5IGRpc3BsYXkuCiAqCiAqIFBBUkFNUwogKiAgTm9uZS4KICoKICogUkVUVVJOUwogKiAgVGhlIGNvbG9yIGRlcHRoIG9mIHRoZSBwcmltYXJ5IGRpc3BsYXkuCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRDdXJDb2xvclJlcyh2b2lkKQp7CiAgICBIREMgaGRjOwogICAgRFdPUkQgcmV0OwoKICAgIFRSQUNFKCIoKVxuIik7CgogICAgaGRjID0gR2V0REMoMCk7CiAgICByZXQgPSBHZXREZXZpY2VDYXBzKGhkYywgQklUU1BJWEVMKSAqIEdldERldmljZUNhcHMoaGRjLCBQTEFORVMpOwogICAgUmVsZWFzZURDKDAsIGhkYyk7CiAgICByZXR1cm4gcmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTk0XQogKgogKiBXYWl0IGZvciBhIG1lc3NhZ2UgdG8gYXJyaXZlLCB3aXRoIGEgdGltZW91dC4KICoKICogUEFSQU1TCiAqICBoYW5kICAgICAgW0ldIEhhbmRsZSB0byBxdWVyeQogKiAgZHdUaW1lb3V0IFtJXSBUaW1lb3V0IGluIHRpY2tzIG9yIElORklOSVRFIHRvIG5ldmVyIHRpbWVvdXQKICoKICogUkVUVVJOUwogKiAgU1RBVFVTX1RJTUVPVVQgaWYgbm8gbWVzc2FnZSBpcyByZWNlaXZlZCBiZWZvcmUgZHdUaW1lb3V0IHRpY2tzIHBhc3Nlcy4KICogIE90aGVyd2lzZSByZXR1cm5zIHRoZSB2YWx1ZSBmcm9tIE1zZ1dhaXRGb3JNdWx0aXBsZU9iamVjdHNFeCB3aGVuIGEKICogIG1lc3NhZ2UgaXMgYXZhaWxhYmxlLgogKi8KRFdPUkQgV0lOQVBJIFNIV2FpdEZvclNlbmRNZXNzYWdlVGhyZWFkKEhBTkRMRSBoYW5kLCBEV09SRCBkd1RpbWVvdXQpCnsKICBEV09SRCBkd0VuZFRpY2tzID0gR2V0VGlja0NvdW50KCkgKyBkd1RpbWVvdXQ7CiAgRFdPUkQgZHdSZXQ7CgogIHdoaWxlICgoZHdSZXQgPSBNc2dXYWl0Rm9yTXVsdGlwbGVPYmplY3RzRXgoMSwgJmhhbmQsIGR3VGltZW91dCwgUVNfU0VORE1FU1NBR0UsIDApKSA9PSAxKQogIHsKICAgIE1TRyBtc2c7CgogICAgUGVla01lc3NhZ2VXKCZtc2csIE5VTEwsIDAsIDAsIFBNX05PUkVNT1ZFKTsKCiAgICBpZiAoZHdUaW1lb3V0ICE9IElORklOSVRFKQogICAgewogICAgICAgIGlmICgoaW50KShkd1RpbWVvdXQgPSBkd0VuZFRpY2tzIC0gR2V0VGlja0NvdW50KCkpIDw9IDApCiAgICAgICAgICAgIHJldHVybiBXQUlUX1RJTUVPVVQ7CiAgICB9CiAgfQoKICByZXR1cm4gZHdSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICBbU0hMV0FQSS4xOTVdCiAqCiAqIERldGVybWluZSBpZiBhIHNoZWxsIGZvbGRlciBjYW4gYmUgZXhwYW5kZWQuCiAqCiAqIFBBUkFNUwogKiAgbHBGb2xkZXIgW0ldIFBhcmVudCBmb2xkZXIgY29udGFpbmluZyB0aGUgb2JqZWN0IHRvIHRlc3QuCiAqICBwaWRsICAgICBbSV0gSWQgb2YgdGhlIG9iamVjdCB0byB0ZXN0LgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLCBpZiB0aGUgb2JqZWN0IGlzIGV4cGFuZGFibGUsIFNfRkFMU0Ugb3RoZXJ3aXNlLgogKiAgRmFpbHVyZTogRV9JTlZBTElEQVJHLCBpZiBhbnkgYXJndW1lbnQgaXMgaW52YWxpZC4KICoKICogTk9URVMKICogIElmIHRoZSBvYmplY3QgdG8gYmUgdGVzdGVkIGRvZXMgbm90IGV4cG9zZSB0aGUgSVF1ZXJ5SW5mbygpIGludGVyZmFjZSBpdAogKiAgd2lsbCBub3QgYmUgaWRlbnRpZmllZCBhcyBhbiBleHBhbmRhYmxlIGZvbGRlci4KICovCkhSRVNVTFQgV0lOQVBJIFNISXNFeHBhbmRhYmxlRm9sZGVyKExQU0hFTExGT0xERVIgbHBGb2xkZXIsIExQQ0lURU1JRExJU1QgcGlkbCkKewogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKICBJUXVlcnlJbmZvICpscEluZm87CgogIGlmIChscEZvbGRlciAmJiBwaWRsKQogIHsKICAgIGhSZXQgPSBJU2hlbGxGb2xkZXJfR2V0VUlPYmplY3RPZihscEZvbGRlciwgTlVMTCwgMSwgJnBpZGwsICZJSURfSVF1ZXJ5SW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCAodm9pZCoqKSZscEluZm8pOwogICAgaWYgKEZBSUxFRChoUmV0KSkKICAgICAgaFJldCA9IFNfRkFMU0U7IC8qIERvZXNuJ3QgZXhwb3NlIElRdWVyeUluZm8gKi8KICAgIGVsc2UKICAgIHsKICAgICAgRFdPUkQgZHdGbGFncyA9IDA7CgogICAgICAvKiBNU0ROIHN0YXRlcyBvZiBJUXVlcnlJbmZvX0dldEluZm9GbGFncygpIHRoYXQgIlRoaXMgbWV0aG9kIGlzIG5vdAogICAgICAgKiBjdXJyZW50bHkgdXNlZCIuIFJlYWxseT8gWW91IHdvdWxkbid0IGJlIGhvbGRpbmcgb3V0IG9uIG1lIHdvdWxkIHlvdT8KICAgICAgICovCiAgICAgIGhSZXQgPSBJUXVlcnlJbmZvX0dldEluZm9GbGFncyhscEluZm8sICZkd0ZsYWdzKTsKCiAgICAgIGlmIChTVUNDRUVERUQoaFJldCkpCiAgICAgIHsKICAgICAgICAvKiAweDIgaXMgYW4gdW5kb2N1bWVudGVkIGZsYWcgYXBwYXJlbnRseSBpbmRpY2F0aW5nIGV4cGFuZGFiaWxpdHkgKi8KICAgICAgICBoUmV0ID0gZHdGbGFncyAmIDB4MiA/IFNfT0sgOiBTX0ZBTFNFOwogICAgICB9CgogICAgICBJUXVlcnlJbmZvX1JlbGVhc2UobHBJbmZvKTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQCAgICAgICBbU0hMV0FQSS4xOTddCiAqCiAqIEJsYW5rIG91dCBhIHJlZ2lvbiBvZiB0ZXh0IGJ5IGRyYXdpbmcgdGhlIGJhY2tncm91bmQgb25seS4KICoKICogUEFSQU1TCiAqICBoREMgICBbSV0gRGV2aWNlIGNvbnRleHQgdG8gZHJhdyBpbgogKiAgcFJlY3QgW0ldIEFyZWEgdG8gZHJhdyBpbgogKiAgY1JlZiAgW0ldIENvbG9yIHRvIGRyYXcgaW4KICoKICogUkVUVVJOUwogKiAgTm90aGluZy4KICovCkRXT1JEIFdJTkFQSSBTSEZpbGxSZWN0Q2xyKEhEQyBoREMsIExQQ1JFQ1QgcFJlY3QsIENPTE9SUkVGIGNSZWYpCnsKICAgIENPTE9SUkVGIGNPbGRDb2xvciA9IFNldEJrQ29sb3IoaERDLCBjUmVmKTsKICAgIEV4dFRleHRPdXRBKGhEQywgMCwgMCwgRVRPX09QQVFVRSwgcFJlY3QsIDAsIDAsIDApOwogICAgU2V0QmtDb2xvcihoREMsIGNPbGRDb2xvcik7CiAgICByZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjE5OF0KICoKICogUmV0dXJuIHRoZSB2YWx1ZSBhc29jaWF0ZWQgd2l0aCBhIGtleSBpbiBhIG1hcC4KICoKICogUEFSQU1TCiAqICBscEtleXMgICBbSV0gQSBsaXN0IG9mIGtleXMgb2YgbGVuZ3RoIGlMZW4KICogIGxwVmFsdWVzIFtJXSBBIGxpc3Qgb2YgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBscEtleXMsIG9mIGxlbmd0aCBpTGVuCiAqICBpTGVuICAgICBbSV0gTGVuZ3RoIG9mIGJvdGggbHBLZXlzIGFuZCBscFZhbHVlcwogKiAgaUtleSAgICAgW0ldIFRoZSBrZXkgdmFsdWUgdG8gbG9vayB1cCBpbiBscEtleXMKICoKICogUkVUVVJOUwogKiAgVGhlIHZhbHVlIGluIGxwVmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBpS2V5LCBvciAtMSBpZiBpS2V5IGlzIG5vdAogKiAgZm91bmQgaW4gbHBLZXlzLgogKgogKiBOT1RFUwogKiAgLSBJZiB0d28gZWxlbWVudHMgaW4gdGhlIG1hcCBzaGFyZSB0aGUgc2FtZSBrZXksIHRoaXMgZnVuY3Rpb24gcmV0dXJucwogKiAgICB0aGUgdmFsdWUgY2xvc2VzdCB0byB0aGUgc3RhcnQgb2YgdGhlIG1hcAogKiAgLSBUaGUgbmF0aXZlIHZlcnNpb24gb2YgdGhpcyBmdW5jdGlvbiBjcmFzaGVzIGlmIGxwS2V5cyBvciBscFZhbHVlcyBpcyBOVUxMLgogKi8KaW50IFdJTkFQSSBTSFNlYXJjaE1hcEludChjb25zdCBpbnQgKmxwS2V5cywgY29uc3QgaW50ICpscFZhbHVlcywgaW50IGlMZW4sIGludCBpS2V5KQp7CiAgaWYgKGxwS2V5cyAmJiBscFZhbHVlcykKICB7CiAgICBpbnQgaSA9IDA7CgogICAgd2hpbGUgKGkgPCBpTGVuKQogICAgewogICAgICBpZiAobHBLZXlzW2ldID09IGlLZXkpCiAgICAgICAgcmV0dXJuIGxwVmFsdWVzW2ldOyAvKiBGb3VuZCAqLwogICAgICBpKys7CiAgICB9CiAgfQogIHJldHVybiAtMTsgLyogTm90IGZvdW5kICovCn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTk5XQogKgogKiBDb3B5IGFuIGludGVyZmFjZSBwb2ludGVyCiAqCiAqIFBBUkFNUwogKiAgIGxwcERlc3QgICBbT10gRGVzdGluYXRpb24gZm9yIGNvcHkKICogICBscFVua25vd24gW0ldIFNvdXJjZSBmb3IgY29weQogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KVk9JRCBXSU5BUEkgSVVua25vd25fU2V0KElVbmtub3duICoqbHBwRGVzdCwgSVVua25vd24gKmxwVW5rbm93bikKewogIFRSQUNFKCIoJXAsJXApXG4iLCBscHBEZXN0LCBscFVua25vd24pOwoKICBpZiAobHBwRGVzdCkKICAgIElVbmtub3duX0F0b21pY1JlbGVhc2UobHBwRGVzdCk7IC8qIFJlbGVhc2UgZXhpc3RpbmcgaW50ZXJmYWNlICovCgogIGlmIChscFVua25vd24pCiAgewogICAgLyogQ29weSAqLwogICAgSVVua25vd25fQWRkUmVmKGxwVW5rbm93bik7CiAgICAqbHBwRGVzdCA9IGxwVW5rbm93bjsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDBdCiAqCiAqLwpIUkVTVUxUIFdJTkFQSSBNYXlRU0ZvcndhcmQoSVVua25vd24qIGxwVW5rbm93biwgUFZPSUQgbHBSZXNlcnZlZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFJFRkdVSUQgcmlpZENtZEdycCwgVUxPTkcgY0NtZHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBPTEVDTUQgKnByZ0NtZHMsIE9MRUNNRFRFWFQqIHBDbWRUZXh0KQp7CiAgRklYTUUoIiglcCwlcCwlcCwlbGQsJXAsJXApIC0gc3R1YlxuIiwKICAgICAgICBscFVua25vd24sIGxwUmVzZXJ2ZWQsIHJpaWRDbWRHcnAsIGNDbWRzLCBwcmdDbWRzLCBwQ21kVGV4dCk7CgogIC8qIEZJWE1FOiBDYWxscyBJc1FTRm9yd2FyZCAmIElVbmtub3duX1F1ZXJ5U3RhdHVzICovCiAgcmV0dXJuIERSQUdEUk9QX0VfTk9UUkVHSVNURVJFRDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIwMV0KICoKICovCkhSRVNVTFQgV0lOQVBJIE1heUV4ZWNGb3J3YXJkKElVbmtub3duKiBscFVua25vd24sIElOVCBpVW5rLCBSRUZHVUlEIHBndWlkQ21kR3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIG5DbWRJRCwgRFdPUkQgbkNtZGV4ZWNvcHQsIFZBUklBTlQqIHB2YUluLAogICAgICAgICAgICAgICAgICAgICAgICAgICBWQVJJQU5UKiBwdmFPdXQpCnsKICBGSVhNRSgiKCVwLCVkLCVwLCVsZCwlbGQsJXAsJXApIC0gc3R1YiFcbiIsIGxwVW5rbm93biwgaVVuaywgcGd1aWRDbWRHcm91cCwKICAgICAgICBuQ21kSUQsIG5DbWRleGVjb3B0LCBwdmFJbiwgcHZhT3V0KTsKICByZXR1cm4gRFJBR0RST1BfRV9OT1RSRUdJU1RFUkVEOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjAyXQogKgogKi8KSFJFU1VMVCBXSU5BUEkgSXNRU0ZvcndhcmQoUkVGR1VJRCBwZ3VpZENtZEdyb3VwLFVMT05HIGNDbWRzLCBPTEVDTUQgKnByZ0NtZHMpCnsKICBGSVhNRSgiKCVwLCVsZCwlcCkgLSBzdHViIVxuIiwgcGd1aWRDbWRHcm91cCwgY0NtZHMsIHByZ0NtZHMpOwogIHJldHVybiBEUkFHRFJPUF9FX05PVFJFR0lTVEVSRUQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAJW1NITFdBUEkuMjA0XQogKgogKiBEZXRlcm1pbmUgaWYgYSB3aW5kb3cgaXMgbm90IGEgY2hpbGQgb2YgYW5vdGhlciB3aW5kb3cuCiAqCiAqIFBBUkFNUwogKiBoUGFyZW50IFtJXSBTdXNwZWN0ZWQgcGFyZW50IHdpbmRvdwogKiBoQ2hpbGQgIFtJXSBTdXNwZWN0ZWQgY2hpbGQgd2luZG93CiAqCiAqIFJFVFVSTlMKICogVFJVRTogIElmIGhDaGlsZCBpcyBhIGNoaWxkIHdpbmRvdyBvZiBoUGFyZW50CiAqIEZBTFNFOiBJZiBoQ2hpbGQgaXMgbm90IGEgY2hpbGQgd2luZG93IG9mIGhQYXJlbnQsIG9yIHRoZXkgYXJlIGVxdWFsCiAqLwpCT09MIFdJTkFQSSBTSElzQ2hpbGRPclNlbGYoSFdORCBoUGFyZW50LCBIV05EIGhDaGlsZCkKewogIFRSQUNFKCIoJXAsJXApXG4iLCBoUGFyZW50LCBoQ2hpbGQpOwoKICBpZiAoIWhQYXJlbnQgfHwgIWhDaGlsZCkKICAgIHJldHVybiBUUlVFOwogIGVsc2UgaWYoaFBhcmVudCA9PSBoQ2hpbGQpCiAgICByZXR1cm4gRkFMU0U7CiAgcmV0dXJuICFJc0NoaWxkKGhQYXJlbnQsIGhDaGlsZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgIEZEU0EgZnVuY3Rpb25zLiAgTWFuYWdlIGEgZHluYW1pYyBhcnJheSBvZiBmaXhlZCBzaXplIG1lbW9yeSBibG9ja3MuCiAqLwoKdHlwZWRlZiBzdHJ1Y3QKewogICAgRFdPUkQgbnVtX2l0ZW1zOyAgICAgICAvKiBOdW1iZXIgb2YgZWxlbWVudHMgaW5zZXJ0ZWQgKi8KICAgIHZvaWQgKm1lbTsgICAgICAgICAgICAgLyogUHRyIHRvIGFycmF5ICovCiAgICBEV09SRCBibG9ja3NfYWxsb2NlZDsgIC8qIE51bWJlciBvZiBlbGVtZW50cyBhbGxvY2F0ZWQgKi8KICAgIEJZVEUgaW5jOyAgICAgICAgICAgICAgLyogTnVtYmVyIG9mIGVsZW1lbnRzIHRvIGdyb3cgYnkgd2hlbiB3ZSBuZWVkIHRvIGV4cGFuZCAqLwogICAgQllURSBibG9ja19zaXplOyAgICAgICAvKiBTaXplIGluIGJ5dGVzIG9mIGFuIGVsZW1lbnQgKi8KICAgIEJZVEUgZmxhZ3M7ICAgICAgICAgICAgLyogRmxhZ3MgKi8KfSBGRFNBX2luZm87CgojZGVmaW5lIEZEU0FfRkxBR19JTlRFUk5BTF9BTExPQyAweDAxIC8qIFdoZW4gc2V0IHdlIGhhdmUgYWxsb2NhdGVkIG1lbSBpbnRlcm5hbGx5ICovCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjA4XQogKgogKiBJbml0aWFsaXplIGFuIEZEU0EgYXJyYXJ5LiAKICovCkJPT0wgV0lOQVBJIEZEU0FfSW5pdGlhbGl6ZShEV09SRCBibG9ja19zaXplLCBEV09SRCBpbmMsIEZEU0FfaW5mbyAqaW5mbywgdm9pZCAqbWVtLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgaW5pdF9ibG9ja3MpCnsKICAgIFRSQUNFKCIoMHglMDhseCAweCUwOGx4ICVwICVwIDB4JTA4bHgpXG4iLCBibG9ja19zaXplLCBpbmMsIGluZm8sIG1lbSwgaW5pdF9ibG9ja3MpOwoKICAgIGlmKGluYyA9PSAwKQogICAgICAgIGluYyA9IDE7CgogICAgaWYobWVtKQogICAgICAgIG1lbXNldChtZW0sIDAsIGJsb2NrX3NpemUgKiBpbml0X2Jsb2Nrcyk7CiAgICAKICAgIGluZm8tPm51bV9pdGVtcyA9IDA7CiAgICBpbmZvLT5pbmMgPSBpbmM7CiAgICBpbmZvLT5tZW0gPSBtZW07CiAgICBpbmZvLT5ibG9ja3NfYWxsb2NlZCA9IGluaXRfYmxvY2tzOwogICAgaW5mby0+YmxvY2tfc2l6ZSA9IGJsb2NrX3NpemU7CiAgICBpbmZvLT5mbGFncyA9IDA7CgogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMDldCiAqCiAqIERlc3Ryb3kgYW4gRkRTQSBhcnJheQogKi8KQk9PTCBXSU5BUEkgRkRTQV9EZXN0cm95KEZEU0FfaW5mbyAqaW5mbykKewogICAgVFJBQ0UoIiglcClcbiIsIGluZm8pOwoKICAgIGlmKGluZm8tPmZsYWdzICYgRkRTQV9GTEFHX0lOVEVSTkFMX0FMTE9DKQogICAgewogICAgICAgIEhlYXBGcmVlKEdldFByb2Nlc3NIZWFwKCksIDAsIGluZm8tPm1lbSk7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgfQoKICAgIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjEwXQogKgogKiBJbnNlcnQgZWxlbWVudCBpbnRvIGFuIEZEU0EgYXJyYXkKICovCkRXT1JEIFdJTkFQSSBGRFNBX0luc2VydEl0ZW0oRkRTQV9pbmZvICppbmZvLCBEV09SRCB3aGVyZSwgdm9pZCAqYmxvY2spCnsKICAgIFRSQUNFKCIoJXAgMHglMDhseCAlcClcbiIsIGluZm8sIHdoZXJlLCBibG9jayk7CiAgICBpZih3aGVyZSA+IGluZm8tPm51bV9pdGVtcykKICAgICAgICB3aGVyZSA9IGluZm8tPm51bV9pdGVtczsKCiAgICBpZihpbmZvLT5udW1faXRlbXMgPj0gaW5mby0+YmxvY2tzX2FsbG9jZWQpCiAgICB7CiAgICAgICAgRFdPUkQgc2l6ZSA9IChpbmZvLT5ibG9ja3NfYWxsb2NlZCArIGluZm8tPmluYykgKiBpbmZvLT5ibG9ja19zaXplOwogICAgICAgIGlmKGluZm8tPmZsYWdzICYgMHgxKQogICAgICAgICAgICBpbmZvLT5tZW0gPSBIZWFwUmVBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBpbmZvLT5tZW0sIHNpemUpOwogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIHZvaWQgKm9sZF9tZW0gPSBpbmZvLT5tZW07CiAgICAgICAgICAgIGluZm8tPm1lbSA9IEhlYXBBbGxvYyhHZXRQcm9jZXNzSGVhcCgpLCBIRUFQX1pFUk9fTUVNT1JZLCBzaXplKTsKICAgICAgICAgICAgbWVtY3B5KGluZm8tPm1lbSwgb2xkX21lbSwgaW5mby0+YmxvY2tzX2FsbG9jZWQgKiBpbmZvLT5ibG9ja19zaXplKTsKICAgICAgICB9CiAgICAgICAgaW5mby0+YmxvY2tzX2FsbG9jZWQgKz0gaW5mby0+aW5jOwogICAgICAgIGluZm8tPmZsYWdzIHw9IDB4MTsKICAgIH0KCiAgICBpZih3aGVyZSA8IGluZm8tPm51bV9pdGVtcykKICAgIHsKICAgICAgICBtZW1tb3ZlKChjaGFyKilpbmZvLT5tZW0gKyAod2hlcmUgKyAxKSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgICAgICAoY2hhciopaW5mby0+bWVtICsgd2hlcmUgKiBpbmZvLT5ibG9ja19zaXplLAogICAgICAgICAgICAgICAgKGluZm8tPm51bV9pdGVtcyAtIHdoZXJlKSAqIGluZm8tPmJsb2NrX3NpemUpOwogICAgfQogICAgbWVtY3B5KChjaGFyKilpbmZvLT5tZW0gKyB3aGVyZSAqIGluZm8tPmJsb2NrX3NpemUsIGJsb2NrLCBpbmZvLT5ibG9ja19zaXplKTsKCiAgICBpbmZvLT5udW1faXRlbXMrKzsKICAgIHJldHVybiB3aGVyZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxMV0KICoKICogRGVsZXRlIGFuIGVsZW1lbnQgZnJvbSBhbiBGRFNBIGFycmF5LgogKi8KQk9PTCBXSU5BUEkgRkRTQV9EZWxldGVJdGVtKEZEU0FfaW5mbyAqaW5mbywgRFdPUkQgd2hlcmUpCnsKICAgIFRSQUNFKCIoJXAgMHglMDhseClcbiIsIGluZm8sIHdoZXJlKTsKCiAgICBpZih3aGVyZSA+PSBpbmZvLT5udW1faXRlbXMpCiAgICAgICAgcmV0dXJuIEZBTFNFOwoKICAgIGlmKHdoZXJlIDwgaW5mby0+bnVtX2l0ZW1zIC0gMSkKICAgIHsKICAgICAgICBtZW1tb3ZlKChjaGFyKilpbmZvLT5tZW0gKyB3aGVyZSAqIGluZm8tPmJsb2NrX3NpemUsCiAgICAgICAgICAgICAgICAoY2hhciopaW5mby0+bWVtICsgKHdoZXJlICsgMSkgKiBpbmZvLT5ibG9ja19zaXplLAogICAgICAgICAgICAgICAgKGluZm8tPm51bV9pdGVtcyAtIHdoZXJlIC0gMSkgKiBpbmZvLT5ibG9ja19zaXplKTsKICAgIH0KICAgIG1lbXNldCgoY2hhciopaW5mby0+bWVtICsgKGluZm8tPm51bV9pdGVtcyAtIDEpICogaW5mby0+YmxvY2tfc2l6ZSwKICAgICAgICAgICAwLCBpbmZvLT5ibG9ja19zaXplKTsKICAgIGluZm8tPm51bV9pdGVtcy0tOwogICAgcmV0dXJuIFRSVUU7Cn0KCgp0eXBlZGVmIHN0cnVjdCB7CiAgICBSRUZJSUQgICByZWZpZDsKICAgIERXT1JEICAgIGluZHg7Cn0gSUZBQ0VfSU5ERVhfVEJMOwoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIxOV0KICoKICogQ2FsbCBJVW5rbm93bl9RdWVyeUludGVyZmFjZSgpIG9uIGEgdGFibGUgb2Ygb2JqZWN0cy4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfUE9JTlRFUiBvciBFX05PSU5URVJGQUNFLgogKi8KSFJFU1VMVCBXSU5BUEkgUUlTZWFyY2goCglMUFZPSUQgdywgICAgICAgICAgIC8qIFtpbl0gICBUYWJsZSBvZiBpbnRlcmZhY2VzICovCglJRkFDRV9JTkRFWF9UQkwgKngsIC8qIFtpbl0gICBBcnJheSBvZiBSRUZJSURzIGFuZCBpbmRleGVzIGludG8gdGhlIHRhYmxlICovCglSRUZJSUQgcmlpZCwgICAgICAgIC8qIFtpbl0gICBSRUZJSUQgdG8gZ2V0IGludGVyZmFjZSBmb3IgKi8KCUxQVk9JRCAqcHB2KSAgICAgICAgICAvKiBbb3V0XSAgRGVzdGluYXRpb24gZm9yIGludGVyZmFjZSBwb2ludGVyICovCnsKCUhSRVNVTFQgcmV0OwoJSVVua25vd24gKmFfdnRibDsKCUlGQUNFX0lOREVYX1RCTCAqeG1vdmU7CgoJVFJBQ0UoIiglcCAlcCAlcyAlcClcbiIsIHcseCxkZWJ1Z3N0cl9ndWlkKHJpaWQpLHBwdik7CglpZiAocHB2KSB7CgkgICAgeG1vdmUgPSB4OwoJICAgIHdoaWxlICh4bW92ZS0+cmVmaWQpIHsKCQlUUkFDRSgidHJ5aW5nIChpbmR4ICVsZCkgJXNcbiIsIHhtb3ZlLT5pbmR4LCBkZWJ1Z3N0cl9ndWlkKHhtb3ZlLT5yZWZpZCkpOwoJCWlmIChJc0VxdWFsSUlEKHJpaWQsIHhtb3ZlLT5yZWZpZCkpIHsKCQkgICAgYV92dGJsID0gKElVbmtub3duKikoeG1vdmUtPmluZHggKyAoTFBCWVRFKXcpOwoJCSAgICBUUkFDRSgibWF0Y2hlZCwgcmV0dXJuaW5nICglcClcbiIsIGFfdnRibCk7CgkJICAgICpwcHYgPSAoTFBWT0lEKWFfdnRibDsKCQkgICAgSVVua25vd25fQWRkUmVmKGFfdnRibCk7CgkJICAgIHJldHVybiBTX09LOwoJCX0KCQl4bW92ZSsrOwoJICAgIH0KCgkgICAgaWYgKElzRXF1YWxJSUQocmlpZCwgJklJRF9JVW5rbm93bikpIHsKCQlhX3Z0YmwgPSAoSVVua25vd24qKSh4LT5pbmR4ICsgKExQQllURSl3KTsKCQlUUkFDRSgicmV0dXJuaW5nIGZpcnN0IGZvciBJVW5rbm93biAoJXApXG4iLCBhX3Z0YmwpOwoJCSpwcHYgPSAoTFBWT0lEKWFfdnRibDsKCQlJVW5rbm93bl9BZGRSZWYoYV92dGJsKTsKCQlyZXR1cm4gU19PSzsKCSAgICB9CgkgICAgKnBwdiA9IDA7CgkgICAgcmV0ID0gRV9OT0lOVEVSRkFDRTsKCX0gZWxzZQoJICAgIHJldCA9IEVfUE9JTlRFUjsKCglUUkFDRSgiLS0gMHglMDhseFxuIiwgcmV0KTsKCXJldHVybiByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMjFdCiAqCiAqIFJlbW92ZSB0aGUgIlByb3BEbGdGb250IiBwcm9wZXJ0eSBmcm9tIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgW0ldIFdpbmRvdyB0byByZW1vdmUgdGhlIHByb3BlcnR5IGZyb20KICoKICogUkVUVVJOUwogKiAgQSBoYW5kbGUgdG8gdGhlIHJlbW92ZWQgcHJvcGVydHksIG9yIE5VTEwgaWYgaXQgZGlkIG5vdCBleGlzdC4KICovCkhBTkRMRSBXSU5BUEkgU0hSZW1vdmVEZWZhdWx0RGlhbG9nRm9udChIV05EIGhXbmQpCnsKICBIQU5ETEUgaFByb3A7CgogIFRSQUNFKCIoJXApXG4iLCBoV25kKTsKCiAgaFByb3AgPSBHZXRQcm9wQShoV25kLCAiUHJvcERsZ0ZvbnQiKTsKCiAgaWYoaFByb3ApCiAgewogICAgRGVsZXRlT2JqZWN0KGhQcm9wKTsKICAgIGhQcm9wID0gUmVtb3ZlUHJvcEEoaFduZCwgIlByb3BEbGdGb250Iik7CiAgfQogIHJldHVybiBoUHJvcDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzNl0KICoKICogTG9hZCB0aGUgaW4tcHJvY2VzcyBzZXJ2ZXIgb2YgYSBnaXZlbiBHVUlELgogKgogKiBQQVJBTVMKICogIHJlZmlpZCBbSV0gR1VJRCBvZiB0aGUgc2VydmVyIHRvIGxvYWQuCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgc2VydmVyIGRsbC4KICogIEZhaWx1cmU6IEEgTlVMTCBoYW5kbGUuCiAqLwpITU9EVUxFIFdJTkFQSSBTSFBpbkRsbE9mQ0xTSUQoUkVGSUlEIHJlZmlpZCkKewogICAgSEtFWSBuZXdrZXk7CiAgICBEV09SRCB0eXBlLCBjb3VudDsKICAgIENIQVIgdmFsdWVbTUFYX1BBVEhdLCBzdHJpbmdbTUFYX1BBVEhdOwoKICAgIHN0cmNweShzdHJpbmcsICJDTFNJRFxcIik7CiAgICBTSFN0cmluZ0Zyb21HVUlEQShyZWZpaWQsIHN0cmluZyArIDYsIHNpemVvZihzdHJpbmcpL3NpemVvZihjaGFyKSAtIDYpOwogICAgc3RyY2F0KHN0cmluZywgIlxcSW5Qcm9jU2VydmVyMzIiKTsKCiAgICBjb3VudCA9IE1BWF9QQVRIOwogICAgUmVnT3BlbktleUV4QShIS0VZX0NMQVNTRVNfUk9PVCwgc3RyaW5nLCAwLCAxLCAmbmV3a2V5KTsKICAgIFJlZ1F1ZXJ5VmFsdWVFeEEobmV3a2V5LCAwLCAwLCAmdHlwZSwgKFBCWVRFKXZhbHVlLCAmY291bnQpOwogICAgUmVnQ2xvc2VLZXkobmV3a2V5KTsKICAgIHJldHVybiBMb2FkTGlicmFyeUV4QSh2YWx1ZSwgMCwgMCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yMzddCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBTSExXQVBJXzE4My4KICovCkRXT1JEIFdJTkFQSSBTSFJlZ2lzdGVyQ2xhc3NXKFdORENMQVNTVyAqIGxwV25kQ2xhc3MpCnsKCVdORENMQVNTVyBXbmRDbGFzczsKCglUUkFDRSgiKCVwICVzKVxuIixscFduZENsYXNzLT5oSW5zdGFuY2UsIGRlYnVnc3RyX3cobHBXbmRDbGFzcy0+bHBzekNsYXNzTmFtZSkpOwoKCWlmIChHZXRDbGFzc0luZm9XKGxwV25kQ2xhc3MtPmhJbnN0YW5jZSwgbHBXbmRDbGFzcy0+bHBzekNsYXNzTmFtZSwgJlduZENsYXNzKSkKCQlyZXR1cm4gVFJVRTsKCXJldHVybiBSZWdpc3RlckNsYXNzVyhscFduZENsYXNzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzOF0KICoKICogVW5yZWdpc3RlciBhIGxpc3Qgb2YgY2xhc3Nlcy4KICoKICogUEFSQU1TCiAqICBoSW5zdCAgICAgIFtJXSBBcHBsaWNhdGlvbiBpbnN0YW5jZSB0aGF0IHJlZ2lzdGVyZWQgdGhlIGNsYXNzZXMKICogIGxwcENsYXNzZXMgW0ldIExpc3Qgb2YgY2xhc3MgbmFtZXMKICogIGlDb3VudCAgICAgW0ldIE51bWJlciBvZiBuYW1lcyBpbiBscHBDbGFzc2VzCiAqCiAqIFJFVFVSTlMKICogIE5vdGhpbmcuCiAqLwp2b2lkIFdJTkFQSSBTSFVucmVnaXN0ZXJDbGFzc2VzQShISU5TVEFOQ0UgaEluc3QsIExQQ1NUUiAqbHBwQ2xhc3NlcywgSU5UIGlDb3VudCkKewogIFdORENMQVNTQSBXbmRDbGFzczsKCiAgVFJBQ0UoIiglcCwlcCwlZClcbiIsIGhJbnN0LCBscHBDbGFzc2VzLCBpQ291bnQpOwoKICB3aGlsZSAoaUNvdW50ID4gMCkKICB7CiAgICBpZiAoR2V0Q2xhc3NJbmZvQShoSW5zdCwgKmxwcENsYXNzZXMsICZXbmRDbGFzcykpCiAgICAgIFVucmVnaXN0ZXJDbGFzc0EoKmxwcENsYXNzZXMsIGhJbnN0KTsKICAgIGxwcENsYXNzZXMrKzsKICAgIGlDb3VudC0tOwogIH0KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjIzOV0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNIVW5yZWdpc3RlckNsYXNzZXNBLgogKi8Kdm9pZCBXSU5BUEkgU0hVbnJlZ2lzdGVyQ2xhc3Nlc1coSElOU1RBTkNFIGhJbnN0LCBMUENXU1RSICpscHBDbGFzc2VzLCBJTlQgaUNvdW50KQp7CiAgV05EQ0xBU1NXIFduZENsYXNzOwoKICBUUkFDRSgiKCVwLCVwLCVkKVxuIiwgaEluc3QsIGxwcENsYXNzZXMsIGlDb3VudCk7CgogIHdoaWxlIChpQ291bnQgPiAwKQogIHsKICAgIGlmIChHZXRDbGFzc0luZm9XKGhJbnN0LCAqbHBwQ2xhc3NlcywgJlduZENsYXNzKSkKICAgICAgVW5yZWdpc3RlckNsYXNzVygqbHBwQ2xhc3NlcywgaEluc3QpOwogICAgbHBwQ2xhc3NlcysrOwogICAgaUNvdW50LS07CiAgfQp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjQwXQogKgogKiBDYWxsIFRoZSBjb3JyZWN0IChBc2NpaS9Vbmljb2RlKSBkZWZhdWx0IHdpbmRvdyBwcm9jZWR1cmUgZm9yIGEgd2luZG93LgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgIFtJXSBXaW5kb3cgdG8gY2FsbCB0aGUgZGVmYXVsdCBwcm9jZWR1cmUgZm9yCiAqICB1TWVzc2FnZSBbSV0gTWVzc2FnZSBJRAogKiAgd1BhcmFtICAgW0ldIFdQQVJBTSBvZiBtZXNzYWdlCiAqICBsUGFyYW0gICBbSV0gTFBBUkFNIG9mIG1lc3NhZ2UKICoKICogUkVUVVJOUwogKiAgVGhlIHJlc3VsdCBvZiBjYWxsaW5nIERlZldpbmRvd1Byb2NBKCkgb3IgRGVmV2luZG93UHJvY1coKS4KICovCkxSRVNVTFQgQ0FMTEJBQ0sgU0hEZWZXaW5kb3dQcm9jKEhXTkQgaFduZCwgVUlOVCB1TWVzc2FnZSwgV1BBUkFNIHdQYXJhbSwgTFBBUkFNIGxQYXJhbSkKewoJaWYgKElzV2luZG93VW5pY29kZShoV25kKSkKCQlyZXR1cm4gRGVmV2luZG93UHJvY1coaFduZCwgdU1lc3NhZ2UsIHdQYXJhbSwgbFBhcmFtKTsKCXJldHVybiBEZWZXaW5kb3dQcm9jQShoV25kLCB1TWVzc2FnZSwgd1BhcmFtLCBsUGFyYW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAgICAgICAgW1NITFdBUEkuMjU2XQogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fR2V0U2l0ZShMUFVOS05PV04gbHBVbmtub3duLCBSRUZJSUQgaWlkLCBQVk9JRCAqbHBwU2l0ZSkKewogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKICBMUE9CSkVDVFdJVEhTSVRFIGxwU2l0ZSA9IE5VTEw7CgogIFRSQUNFKCIoJXAsJXMsJXApXG4iLCBscFVua25vd24sIGRlYnVnc3RyX2d1aWQoaWlkKSwgbHBwU2l0ZSk7CgogIGlmIChscFVua25vd24gJiYgaWlkICYmIGxwcFNpdGUpCiAgewogICAgaFJldCA9IElVbmtub3duX1F1ZXJ5SW50ZXJmYWNlKGxwVW5rbm93biwgJklJRF9JT2JqZWN0V2l0aFNpdGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQqKikmbHBTaXRlKTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBTaXRlKQogICAgewogICAgICBoUmV0ID0gSU9iamVjdFdpdGhTaXRlX0dldFNpdGUobHBTaXRlLCBpaWQsIGxwcFNpdGUpOwogICAgICBJT2JqZWN0V2l0aFNpdGVfUmVsZWFzZShscFNpdGUpOwogICAgfQogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI1N10KICoKICogQ3JlYXRlIGEgd29ya2VyIHdpbmRvdyB1c2luZyBDcmVhdGVXaW5kb3dFeEEoKS4KICoKICogUEFSQU1TCiAqICB3bmRQcm9jICAgIFtJXSBXaW5kb3cgcHJvY2VkdXJlCiAqICBoV25kUGFyZW50IFtJXSBQYXJlbnQgd2luZG93CiAqICBkd0V4U3R5bGUgIFtJXSBFeHRyYSBzdHlsZSBmbGFncwogKiAgZHdTdHlsZSAgICBbSV0gU3R5bGUgZmxhZ3MKICogIGhNZW51ICAgICAgW0ldIFdpbmRvdyBtZW51CiAqICB6ICAgICAgICAgIFtJXSBVbmtub3duCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSB3aW5kb3cgaGFuZGxlIG9mIHRoZSBuZXdseSBjcmVhdGVkIHdpbmRvdy4KICogIEZhaWx1cmU6IDAuCiAqLwpIV05EIFdJTkFQSSBTSENyZWF0ZVdvcmtlcldpbmRvd0EoTE9ORyB3bmRQcm9jLCBIV05EIGhXbmRQYXJlbnQsIERXT1JEIGR3RXhTdHlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgZHdTdHlsZSwgSE1FTlUgaE1lbnUsIExPTkcgeikKewogIHN0YXRpYyBjb25zdCBjaGFyKiBzekNsYXNzID0gIldvcmtlckEiOwogIFdORENMQVNTQSB3YzsKICBIV05EIGhXbmQ7CgogIFRSQUNFKCIoMHglMDhseCwlcCwweCUwOGx4LDB4JTA4bHgsJXAsMHglMDhseClcbiIsCiAgICAgICAgIHduZFByb2MsIGhXbmRQYXJlbnQsIGR3RXhTdHlsZSwgZHdTdHlsZSwgaE1lbnUsIHopOwoKICAvKiBDcmVhdGUgV2luZG93IGNsYXNzICovCiAgd2Muc3R5bGUgICAgICAgICA9IDA7CiAgd2MubHBmblduZFByb2MgICA9IERlZldpbmRvd1Byb2NBOwogIHdjLmNiQ2xzRXh0cmEgICAgPSAwOwogIHdjLmNiV25kRXh0cmEgICAgPSA0OwogIHdjLmhJbnN0YW5jZSAgICAgPSBzaGx3YXBpX2hJbnN0YW5jZTsKICB3Yy5oSWNvbiAgICAgICAgID0gTlVMTDsKICB3Yy5oQ3Vyc29yICAgICAgID0gTG9hZEN1cnNvckEoTlVMTCwgKExQU1RSKUlEQ19BUlJPVyk7CiAgd2MuaGJyQmFja2dyb3VuZCA9IChIQlJVU0gpKENPTE9SX0JUTkZBQ0UgKyAxKTsKICB3Yy5scHN6TWVudU5hbWUgID0gTlVMTDsKICB3Yy5scHN6Q2xhc3NOYW1lID0gc3pDbGFzczsKCiAgU0hSZWdpc3RlckNsYXNzQSgmd2MpOyAvKiBSZWdpc3RlciBjbGFzcyAqLwoKICAvKiBGSVhNRTogU2V0IGV4dHJhIGJpdHMgaW4gZHdFeFN0eWxlICovCgogIGhXbmQgPSBDcmVhdGVXaW5kb3dFeEEoZHdFeFN0eWxlLCBzekNsYXNzLCAwLCBkd1N0eWxlLCAwLCAwLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgaFduZFBhcmVudCwgaE1lbnUsIHNobHdhcGlfaEluc3RhbmNlLCAwKTsKICBpZiAoaFduZCkKICB7CiAgICBTZXRXaW5kb3dMb25nUHRyVyhoV25kLCBEV0xQX01TR1JFU1VMVCwgeik7CgogICAgaWYgKHduZFByb2MpCiAgICAgIFNldFdpbmRvd0xvbmdQdHJBKGhXbmQsIEdXTFBfV05EUFJPQywgd25kUHJvYyk7CiAgfQogIHJldHVybiBoV25kOwp9Cgp0eXBlZGVmIHN0cnVjdCB0YWdQT0xJQ1lEQVRBCnsKICBEV09SRCBwb2xpY3k7ICAgICAgICAvKiBmbGFncyB2YWx1ZSBwYXNzZWQgdG8gU0hSZXN0cmljdGVkICovCiAgTFBDV1NUUiBhcHBzdHI7ICAgICAgLyogYXBwbGljYXRpb24gc3RyIHN1Y2ggYXMgIkV4cGxvcmVyIiAqLwogIExQQ1dTVFIga2V5c3RyOyAgICAgIC8qIG5hbWUgb2YgdGhlIGFjdHVhbCByZWdpc3RyeSBrZXkgLyBwb2xpY3kgKi8KfSBQT0xJQ1lEQVRBLCAqTFBQT0xJQ1lEQVRBOwoKI2RlZmluZSBTSEVMTF9OT19QT0xJQ1kgMHhmZmZmZmZmZgoKLyogZGVmYXVsdCBzaGVsbCBwb2xpY3kgcmVnaXN0cnkga2V5ICovCnN0YXRpYyBjb25zdCBXQ0hBUiBzdHJSZWdpc3RyeVBvbGljeVdbXSA9IHsnUycsJ28nLCdmJywndCcsJ3cnLCdhJywncicsJ2UnLCdcXCcsJ00nLCdpJywnYycsJ3InLCdvJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAncycsJ28nLCdmJywndCcsJ1xcJywnVycsJ2knLCduJywnZCcsJ28nLCd3JywncycsJ1xcJywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnQycsJ3UnLCdyJywncicsJ2UnLCduJywndCcsJ1YnLCdlJywncicsJ3MnLCdpJywnbycsJ24nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdcXCcsJ1AnLCdvJywnbCcsJ2knLCdjJywnaScsJ2UnLCdzJywwfTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgICAgICAgICAgICAgICAgICAgICAgICAgIFtTSExXQVBJLjI3MV0KICoKICogUmV0cmlldmUgYSBwb2xpY3kgdmFsdWUgZnJvbSB0aGUgcmVnaXN0cnkuCiAqCiAqIFBBUkFNUwogKiAgbHBTdWJLZXkgICBbSV0gICByZWdpc3RyeSBrZXkgbmFtZQogKiAgbHBTdWJOYW1lICBbSV0gICBzdWJuYW1lIG9mIHJlZ2lzdHJ5IGtleQogKiAgbHBWYWx1ZSAgICBbSV0gICB2YWx1ZSBuYW1lIG9mIHJlZ2lzdHJ5IHZhbHVlCiAqCiAqIFJFVFVSTlMKICogIHRoZSB2YWx1ZSBhc3NvY2lhdGVkIHdpdGggdGhlIHJlZ2lzdHJ5IGtleSBvciAwIGlmIG5vdCBmb3VuZAogKi8KRFdPUkQgV0lOQVBJIFNIR2V0UmVzdHJpY3Rpb24oTFBDV1NUUiBscFN1YktleSwgTFBDV1NUUiBscFN1Yk5hbWUsIExQQ1dTVFIgbHBWYWx1ZSkKewoJRFdPUkQgcmV0dmFsLCBkYXRzaXplID0gc2l6ZW9mKHJldHZhbCk7CglIS0VZIGhLZXk7CgoJaWYgKCFscFN1YktleSkKCSAgbHBTdWJLZXkgPSBzdHJSZWdpc3RyeVBvbGljeVc7CgoJcmV0dmFsID0gUmVnT3BlbktleVcoSEtFWV9MT0NBTF9NQUNISU5FLCBscFN1YktleSwgJmhLZXkpOwogICAgaWYgKHJldHZhbCAhPSBFUlJPUl9TVUNDRVNTKQoJICByZXR2YWwgPSBSZWdPcGVuS2V5VyhIS0VZX0NVUlJFTlRfVVNFUiwgbHBTdWJLZXksICZoS2V5KTsKCWlmIChyZXR2YWwgIT0gRVJST1JfU1VDQ0VTUykKCSAgcmV0dXJuIDA7CgoJU0hHZXRWYWx1ZVcoaEtleSwgbHBTdWJOYW1lLCBscFZhbHVlLCBOVUxMLCAoTFBCWVRFKSZyZXR2YWwsICZkYXRzaXplKTsKCVJlZ0Nsb3NlS2V5KGhLZXkpOwoJcmV0dXJuIHJldHZhbDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQCAgICAgICAgICAgICAgICAgICAgICAgICBbU0hMV0FQSS4yNjZdCiAqCiAqIEhlbHBlciBmdW5jdGlvbiB0byByZXRyaWV2ZSB0aGUgcG9zc2libHkgY2FjaGVkIHZhbHVlIGZvciBhIHNwZWNpZmljIHBvbGljeQogKgogKiBQQVJBTVMKICogIHBvbGljeSAgICAgW0ldICAgVGhlIHBvbGljeSB0byBsb29rIGZvcgogKiAgaW5pdGlhbCAgICBbSV0gICBNYWluIHJlZ2lzdHJ5IGtleSB0byBvcGVuLCBpZiBOVUxMIHVzZSBkZWZhdWx0CiAqICBwb2xUYWJsZSAgIFtJXSAgIFRhYmxlIG9mIGtub3duIHBvbGljaWVzLCAwIHRlcm1pbmF0ZWQKICogIHBvbEFyciAgICAgW0ldICAgQ2FjaGUgYXJyYXkgb2YgcG9saWN5IHZhbHVlcwogKgogKiBSRVRVUk5TCiAqICBUaGUgcmV0cmlldmVkIHBvbGljeSB2YWx1ZSBvciAwIGlmIG5vdCBzdWNjZXNzZnVsCiAqCiAqIE5PVEVTCiAqICBUaGlzIGZ1bmN0aW9uIGlzIHVzZWQgYnkgdGhlIG5hdGl2ZSBTSFJlc3RyaWN0ZWQgZnVuY3Rpb24gdG8gc2VhcmNoIGZvciB0aGUKICogIHBvbGljeSBhbmQgY2FjaGUgaXQgb25jZSByZXRyaWV2ZWQuIFRoZSBjdXJyZW50IFdpbmUgaW1wbGVtZW50YXRpb24gdXNlcyBhCiAqICBkaWZmZXJlbnQgUE9MSUNZREFUQSBzdHJ1Y3R1cmUgYW5kIGltcGxlbWVudHMgYSBzaW1pbGFyIGFsZ29yaXRobWUgYWRhcHRlZCB0bwogKiAgdGhhdCBzdHJ1Y3R1cmUuCiAqLwpEV09SRCBXSU5BUEkgU0hSZXN0cmljdGlvbkxvb2t1cCgKCURXT1JEIHBvbGljeSwKCUxQQ1dTVFIgaW5pdGlhbCwKCUxQUE9MSUNZREFUQSBwb2xUYWJsZSwKCUxQRFdPUkQgcG9sQXJyKQp7CglUUkFDRSgiKDB4JTA4bHggJXMgJXAgJXApXG4iLCBwb2xpY3ksIGRlYnVnc3RyX3coaW5pdGlhbCksIHBvbFRhYmxlLCBwb2xBcnIpOwoKCWlmICghcG9sVGFibGUgfHwgIXBvbEFycikKCSAgcmV0dXJuIDA7CgoJZm9yICg7cG9sVGFibGUtPnBvbGljeTsgcG9sVGFibGUrKywgcG9sQXJyKyspCgl7CgkgIGlmIChwb2xpY3kgPT0gcG9sVGFibGUtPnBvbGljeSkKCSAgewoJICAgIC8qIHdlIGhhdmUgYSBrbm93biBwb2xpY3kgKi8KCgkgICAgLyogY2hlY2sgaWYgdGhpcyBwb2xpY3kgaGFzIGJlZW4gY2FjaGVkICovCgkJaWYgKCpwb2xBcnIgPT0gU0hFTExfTk9fUE9MSUNZKQoJICAgICAgKnBvbEFyciA9IFNIR2V0UmVzdHJpY3Rpb24oaW5pdGlhbCwgcG9sVGFibGUtPmFwcHN0ciwgcG9sVGFibGUtPmtleXN0cik7CgkgICAgcmV0dXJuICpwb2xBcnI7CgkgIH0KCX0KCS8qIHdlIGRvbid0IGtub3cgdGhpcyBwb2xpY3ksIHJldHVybiAwICovCglUUkFDRSgidW5rbm93biBwb2xpY3k6ICglMDhseClcbiIsIHBvbGljeSk7CglyZXR1cm4gMDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI2N10KICoKICogR2V0IGFuIGludGVyZmFjZSBmcm9tIGFuIG9iamVjdC4KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gcHB2IGNvbnRhaW5zIHRoZSByZXF1ZXN0ZWQgaW50ZXJmYWNlLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLgogKgogKiBOT1RFUwogKiAgIFRoaXMgUXVlcnlJbnRlcmZhY2UgYXNrcyB0aGUgaW5uZXIgb2JqZWN0IGZvciBhbiBpbnRlcmZhY2UuIEluIGNhc2UKICogICBvZiBhZ2dyZWdhdGlvbiB0aGlzIHJlcXVlc3Qgd291bGQgYmUgZm9yd2FyZGVkIGJ5IHRoZSBpbm5lciB0byB0aGUKICogICBvdXRlciBvYmplY3QuIFRoaXMgZnVuY3Rpb24gYXNrcyB0aGUgaW5uZXIgb2JqZWN0IGRpcmVjdGx5IGZvciB0aGUKICogICBpbnRlcmZhY2UgY2lyY3VtdmVudGluZyB0aGUgZm9yd2FyZGluZyB0byB0aGUgb3V0ZXIgb2JqZWN0LgogKi8KSFJFU1VMVCBXSU5BUEkgU0hXZWFrUXVlcnlJbnRlcmZhY2UoCglJVW5rbm93biAqIHBVbmssICAgLyogW2luXSBPdXRlciBvYmplY3QgKi8KCUlVbmtub3duICogcElubmVyLCAvKiBbaW5dIElubmVyIG9iamVjdCAqLwoJSUlEICogcmlpZCwgLyogW2luXSBJbnRlcmZhY2UgR1VJRCB0byBxdWVyeSBmb3IgKi8KCUxQVk9JRCogcHB2KSAvKiBbb3V0XSBEZXN0aW5hdGlvbiBmb3IgcXVlcmllZCBpbnRlcmZhY2UgKi8KewoJSFJFU1VMVCBocmV0ID0gRV9OT0lOVEVSRkFDRTsKCVRSQUNFKCIocFVuaz0lcCBwSW5uZXI9JXBcblx0SUlEOiAgJXMgJXApXG4iLHBVbmsscElubmVyLGRlYnVnc3RyX2d1aWQocmlpZCksIHBwdik7CgoJKnBwdiA9IE5VTEw7CglpZihwVW5rICYmIHBJbm5lcikgewoJICAgIGhyZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShwSW5uZXIsIHJpaWQsIChMUFZPSUQqKXBwdik7CgkgICAgaWYgKFNVQ0NFRURFRChocmV0KSkgSVVua25vd25fUmVsZWFzZShwVW5rKTsKCX0KCVRSQUNFKCItLSAweCUwOGx4XG4iLCBocmV0KTsKCXJldHVybiBocmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjY4XQogKgogKiBNb3ZlIGEgcmVmZXJlbmNlIGZyb20gb25lIGludGVyZmFjZSB0byBhbm90aGVyLgogKgogKiBQQVJBTVMKICogICBscERlc3QgICAgIFtPXSBEZXN0aW5hdGlvbiB0byByZWNlaXZlIHRoZSByZWZlcmVuY2UKICogICBscHBVbmtub3duIFtPXSBTb3VyY2UgdG8gZ2l2ZSB1cCB0aGUgcmVmZXJlbmNlIHRvIGxwRGVzdAogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLgogKi8KVk9JRCBXSU5BUEkgU0hXZWFrUmVsZWFzZUludGVyZmFjZShJVW5rbm93biAqbHBEZXN0LCBJVW5rbm93biAqKmxwcFVua25vd24pCnsKICBUUkFDRSgiKCVwLCVwKVxuIiwgbHBEZXN0LCBscHBVbmtub3duKTsKCiAgaWYgKCpscHBVbmtub3duKQogIHsKICAgIC8qIENvcHkgUmVmZXJlbmNlKi8KICAgIElVbmtub3duX0FkZFJlZihscERlc3QpOwogICAgSVVua25vd25fQXRvbWljUmVsZWFzZShscHBVbmtub3duKTsgLyogUmVsZWFzZSBleGlzdGluZyBpbnRlcmZhY2UgKi8KICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNjldCiAqCiAqIENvbnZlcnQgYW4gQVNDSUkgc3RyaW5nIG9mIGEgQ0xTSUQgaW50byBhIENMU0lELgogKgogKiBQQVJBTVMKICogIGlkc3RyIFtJXSBTdHJpbmcgcmVwcmVzZW50aW5nIGEgQ0xTSUQgaW4gcmVnaXN0cnkgZm9ybWF0CiAqICBpZCAgICBbT10gRGVzdGluYXRpb24gZm9yIHRoZSBjb252ZXJ0ZWQgQ0xTSUQKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogVFJVRS4gaWQgY29udGFpbnMgdGhlIGNvbnZlcnRlZCBDTFNJRC4KICogIEZhaWx1cmU6IEZBTFNFLgogKi8KQk9PTCBXSU5BUEkgR1VJREZyb21TdHJpbmdBKExQQ1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CiAgV0NIQVIgd0Nsc2lkWzQwXTsKICBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgaWRzdHIsIC0xLCB3Q2xzaWQsIHNpemVvZih3Q2xzaWQpL3NpemVvZihXQ0hBUikpOwogIHJldHVybiBTVUNDRUVERUQoQ0xTSURGcm9tU3RyaW5nV3JhcCh3Q2xzaWQsIGlkKSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzBdCiAqCiAqIFVuaWNvZGUgdmVyc2lvbiBvZiBHVUlERnJvbVN0cmluZ0EuCiAqLwpCT09MIFdJTkFQSSBHVUlERnJvbVN0cmluZ1coTFBDV1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CiAgcmV0dXJuIFNVQ0NFRURFRChDTFNJREZyb21TdHJpbmdXcmFwKGlkc3RyLCBpZCkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjc2XQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZCBpbnRvIHRoZSBzaGVsbCwgYW5kIHNldCBhIHJlZ2lzdHJ5CiAqIGtleSBhY2NvcmRpbmdseS4KICoKICogUEFSQU1TCiAqICBOb25lLgogKgogKiBSRVRVUk5TCiAqICAxLCBJZiB0aGUgYnJvd3NlciBpcyBub3QgaW50ZWdyYXRlZC4KICogIDIsIElmIHRoZSBicm93c2VyIGlzIGludGVncmF0ZWQuCiAqCiAqIE5PVEVTCiAqICBUaGUga2V5ICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlclxJbnRlZ3JhdGVkQnJvd3NlciIgaXMKICogIGVpdGhlciBzZXQgdG8gVFJVRSwgb3IgcmVtb3ZlZCBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgYnJvd3NlciBpcyBkZWVtZWQKICogIHRvIGJlIGludGVncmF0ZWQuCiAqLwpEV09SRCBXSU5BUEkgV2hpY2hQbGF0Zm9ybSh2b2lkKQp7CiAgc3RhdGljIExQQ1NUUiBzekludGVncmF0ZWRCcm93c2VyID0gIkludGVncmF0ZWRCcm93c2VyIjsKICBzdGF0aWMgRFdPUkQgZHdTdGF0ZSA9IDA7CiAgSEtFWSBoS2V5OwogIERXT1JEIGR3UmV0LCBkd0RhdGEsIGR3U2l6ZTsKCiAgaWYgKGR3U3RhdGUpCiAgICByZXR1cm4gZHdTdGF0ZTsKCiAgLyogSWYgc2hlbGwzMiBleHBvcnRzIERsbEdldFZlcnNpb24oKSwgdGhlIGJyb3dzZXIgaXMgaW50ZWdyYXRlZCAqLwogIEdFVF9GVU5DKHBEbGxHZXRWZXJzaW9uLCBzaGVsbDMyLCAiRGxsR2V0VmVyc2lvbiIsIDEpOwogIGR3U3RhdGUgPSBwRGxsR2V0VmVyc2lvbiA/IDIgOiAxOwoKICAvKiBTZXQgb3IgZGVsZXRlIHRoZSBrZXkgYWNjb3JkaW5nbHkgKi8KICBkd1JldCA9IFJlZ09wZW5LZXlFeEEoSEtFWV9MT0NBTF9NQUNISU5FLAogICAgICAgICAgICAgICAgICAgICAgICAiU29mdHdhcmVcXE1pY3Jvc29mdFxcSW50ZXJuZXQgRXhwbG9yZXIiLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgS0VZX0FMTF9BQ0NFU1MsICZoS2V5KTsKICBpZiAoIWR3UmV0KQogIHsKICAgIGR3UmV0ID0gUmVnUXVlcnlWYWx1ZUV4QShoS2V5LCBzekludGVncmF0ZWRCcm93c2VyLCAwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChMUEJZVEUpJmR3RGF0YSwgJmR3U2l6ZSk7CgogICAgaWYgKCFkd1JldCAmJiBkd1N0YXRlID09IDEpCiAgICB7CiAgICAgIC8qIFZhbHVlIGV4aXN0cyBidXQgYnJvd3NlciBpcyBub3QgaW50ZWdyYXRlZCAqLwogICAgICBSZWdEZWxldGVWYWx1ZUEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3Nlcik7CiAgICB9CiAgICBlbHNlIGlmIChkd1JldCAmJiBkd1N0YXRlID09IDIpCiAgICB7CiAgICAgIC8qIEJyb3dzZXIgaXMgaW50ZWdyYXRlZCBidXQgdmFsdWUgZG9lcyBub3QgZXhpc3QgKi8KICAgICAgZHdEYXRhID0gVFJVRTsKICAgICAgUmVnU2V0VmFsdWVFeEEoaEtleSwgc3pJbnRlZ3JhdGVkQnJvd3NlciwgMCwgUkVHX0RXT1JELAogICAgICAgICAgICAgICAgICAgICAoTFBCWVRFKSZkd0RhdGEsIHNpemVvZihkd0RhdGEpKTsKICAgIH0KICAgIFJlZ0Nsb3NlS2V5KGhLZXkpOwogIH0KICByZXR1cm4gZHdTdGF0ZTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIFNIQ3JlYXRlV29ya2VyV2luZG93QS4KICovCkhXTkQgV0lOQVBJIFNIQ3JlYXRlV29ya2VyV2luZG93VyhMT05HIHduZFByb2MsIEhXTkQgaFduZFBhcmVudCwgRFdPUkQgZHdFeFN0eWxlLAogICAgICAgICAgICAgICAgICAgICAgICBEV09SRCBkd1N0eWxlLCBITUVOVSBoTWVudSwgTE9ORyB6KQp7CiAgc3RhdGljIGNvbnN0IFdDSEFSIHN6Q2xhc3NbXSA9IHsgJ1cnLCAnbycsICdyJywgJ2snLCAnZScsICdyJywgJ1cnLCAnXDAnIH07CiAgV05EQ0xBU1NXIHdjOwogIEhXTkQgaFduZDsKCiAgVFJBQ0UoIigweCUwOGx4LCVwLDB4JTA4bHgsMHglMDhseCwlcCwweCUwOGx4KVxuIiwKICAgICAgICAgd25kUHJvYywgaFduZFBhcmVudCwgZHdFeFN0eWxlLCBkd1N0eWxlLCBoTWVudSwgeik7CgogIC8qIElmIG91ciBPUyBpcyBuYXRpdmVseSBBU0NJSSwgdXNlIHRoZSBBU0NJSSB2ZXJzaW9uICovCiAgaWYgKCEoR2V0VmVyc2lvbigpICYgMHg4MDAwMDAwMCkpICAvKiBOVCAqLwogICAgcmV0dXJuIFNIQ3JlYXRlV29ya2VyV2luZG93QSh3bmRQcm9jLCBoV25kUGFyZW50LCBkd0V4U3R5bGUsIGR3U3R5bGUsIGhNZW51LCB6KTsKCiAgLyogQ3JlYXRlIFdpbmRvdyBjbGFzcyAqLwogIHdjLnN0eWxlICAgICAgICAgPSAwOwogIHdjLmxwZm5XbmRQcm9jICAgPSBEZWZXaW5kb3dQcm9jVzsKICB3Yy5jYkNsc0V4dHJhICAgID0gMDsKICB3Yy5jYlduZEV4dHJhICAgID0gNDsKICB3Yy5oSW5zdGFuY2UgICAgID0gc2hsd2FwaV9oSW5zdGFuY2U7CiAgd2MuaEljb24gICAgICAgICA9IE5VTEw7CiAgd2MuaEN1cnNvciAgICAgICA9IExvYWRDdXJzb3JXKE5VTEwsIChMUFdTVFIpSURDX0FSUk9XKTsKICB3Yy5oYnJCYWNrZ3JvdW5kID0gKEhCUlVTSCkoQ09MT1JfQlRORkFDRSArIDEpOwogIHdjLmxwc3pNZW51TmFtZSAgPSBOVUxMOwogIHdjLmxwc3pDbGFzc05hbWUgPSBzekNsYXNzOwoKICBTSFJlZ2lzdGVyQ2xhc3NXKCZ3Yyk7IC8qIFJlZ2lzdGVyIGNsYXNzICovCgogIC8qIEZJWE1FOiBTZXQgZXh0cmEgYml0cyBpbiBkd0V4U3R5bGUgKi8KCiAgaFduZCA9IENyZWF0ZVdpbmRvd0V4Vyhkd0V4U3R5bGUsIHN6Q2xhc3MsIDAsIGR3U3R5bGUsIDAsIDAsIDAsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICBoV25kUGFyZW50LCBoTWVudSwgc2hsd2FwaV9oSW5zdGFuY2UsIDApOwogIGlmIChoV25kKQogIHsKICAgIFNldFdpbmRvd0xvbmdQdHJXKGhXbmQsIERXTFBfTVNHUkVTVUxULCB6KTsKCiAgICBpZiAod25kUHJvYykKICAgICAgU2V0V2luZG93TG9uZ1B0clcoaFduZCwgR1dMUF9XTkRQUk9DLCB3bmRQcm9jKTsKICB9CiAgcmV0dXJuIGhXbmQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yNzldCiAqCiAqIEdldCBhbmQgc2hvdyBhIGNvbnRleHQgbWVudSBmcm9tIGEgc2hlbGwgZm9sZGVyLgogKgogKiBQQVJBTVMKICogIGhXbmQgICAgICAgICAgIFtJXSBXaW5kb3cgZGlzcGxheWluZyB0aGUgc2hlbGwgZm9sZGVyCiAqICBscEZvbGRlciAgICAgICBbSV0gSVNoZWxsRm9sZGVyIGludGVyZmFjZQogKiAgbHBBcGlkbCAgICAgICAgW0ldIElkIGZvciB0aGUgcGFydGljdWxhciBmb2xkZXIgZGVzaXJlZAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hJbnZva2VEZWZhdWx0Q29tbWFuZChIV05EIGhXbmQsIElTaGVsbEZvbGRlciogbHBGb2xkZXIsIExQQ0lURU1JRExJU1QgbHBBcGlkbCkKewogIHJldHVybiBTSEludm9rZUNvbW1hbmQoaFduZCwgbHBGb2xkZXIsIGxwQXBpZGwsIEZBTFNFKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI4MV0KICoKICogX1NIUGFja0Rpc3BQYXJhbXNWCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFBhY2tEaXNwUGFyYW1zVihMUFZPSUQgdywgTFBWT0lEIHgsIExQVk9JRCB5LCBMUFZPSUQgeikKewoJRklYTUUoIiVwICVwICVwICVwXG4iLHcseCx5LHopOwoJcmV0dXJuIEVfRkFJTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgIFtTSExXQVBJLjI4Ml0KICoKICogVGhpcyBmdW5jdGlvbiBzZWVtcyB0byBiZSBhIGZvcndhcmQgdG8gU0hQYWNrRGlzcFBhcmFtc1YgKHdoYXRldmVyIFRIQVQKICogZnVuY3Rpb24gZG9lcy4uLikuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSFBhY2tEaXNwUGFyYW1zKExQVk9JRCB3LCBMUFZPSUQgeCwgTFBWT0lEIHksIExQVk9JRCB6KQp7CiAgRklYTUUoIiVwICVwICVwICVwXG4iLCB3LCB4LCB5LCB6KTsKICByZXR1cm4gRV9GQUlMOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg0XQogKgogKiBfSUNvbm5lY3Rpb25Qb2ludF9TaW1wbGVJbnZva2UKICovCkRXT1JEIFdJTkFQSSBJQ29ubmVjdGlvblBvaW50X1NpbXBsZUludm9rZSgKCUxQVk9JRCB4LAoJTFBWT0lEIHksCglMUFZPSUQgeikKewogICAgICAgIEZJWE1FKCIoJXAgJXAgJXApIHN0dWJcbiIseCx5LHopOwoJcmV0dXJuIDA7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODVdCiAqCiAqIE5vdGlmeSBhbiBJQ29ubmVjdGlvblBvaW50IG9iamVjdCBvZiBjaGFuZ2VzLgogKgogKiBQQVJBTVMKICogIGxwQ1AgICBbSV0gT2JqZWN0IHRvIG5vdGlmeQogKiAgZGlzcElEIFtJXQogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9OT0lOVEVSRkFDRSwgaWYgbHBDUCBpcyBOVUxMIG9yIGRvZXMgbm90IHN1cHBvcnQgdGhlCiAqICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50IGludGVyZmFjZS4KICovCkhSRVNVTFQgV0lOQVBJIElDb25uZWN0aW9uUG9pbnRfT25DaGFuZ2VkKElDb25uZWN0aW9uUG9pbnQqIGxwQ1AsIERJU1BJRCBkaXNwSUQpCnsKICBJRW51bUNvbm5lY3Rpb25zICpscEVudW07CiAgSFJFU1VMVCBoUmV0ID0gRV9OT0lOVEVSRkFDRTsKCiAgVFJBQ0UoIiglcCwweCU4bFgpXG4iLCBscENQLCBkaXNwSUQpOwoKICAvKiBHZXQgYW4gZW51bWVyYXRvciBmb3IgdGhlIGNvbm5lY3Rpb25zICovCiAgaWYgKGxwQ1ApCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9FbnVtQ29ubmVjdGlvbnMobHBDUCwgJmxwRW51bSk7CgogIGlmIChTVUNDRUVERUQoaFJldCkpCiAgewogICAgSVByb3BlcnR5Tm90aWZ5U2luayAqbHBTaW5rOwogICAgQ09OTkVDVERBVEEgY29ubkRhdGE7CiAgICBVTE9ORyB1bEZldGNoZWQ7CgogICAgLyogQ2FsbCBPbkNoYW5nZWQoKSBmb3IgZXZlcnkgbm90aWZ5IHNpbmsgaW4gdGhlIGNvbm5lY3Rpb24gcG9pbnQgKi8KICAgIHdoaWxlIChJRW51bUNvbm5lY3Rpb25zX05leHQobHBFbnVtLCAxLCAmY29ubkRhdGEsICZ1bEZldGNoZWQpID09IFNfT0spCiAgICB7CiAgICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fUXVlcnlJbnRlcmZhY2UoY29ubkRhdGEucFVuaywgJklJRF9JUHJvcGVydHlOb3RpZnlTaW5rLCAodm9pZCoqKSZscFNpbmspKSAmJgogICAgICAgICAgbHBTaW5rKQogICAgICB7CiAgICAgICAgSVByb3BlcnR5Tm90aWZ5U2lua19PbkNoYW5nZWQobHBTaW5rLCBkaXNwSUQpOwogICAgICAgIElQcm9wZXJ0eU5vdGlmeVNpbmtfUmVsZWFzZShscFNpbmspOwogICAgICB9CiAgICAgIElVbmtub3duX1JlbGVhc2UoY29ubkRhdGEucFVuayk7CiAgICB9CgogICAgSUVudW1Db25uZWN0aW9uc19SZWxlYXNlKGxwRW51bSk7CiAgfQogIHJldHVybiBoUmV0Owp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMjg3XQogKgogKiBOb3RpZnkgYW4gSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lciBvYmplY3Qgb2YgY2hhbmdlcy4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCB0byBub3RpZnkKICogIGRpc3BJRCAgICBbSV0KICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4KICogIEZhaWx1cmU6IEVfTk9JTlRFUkZBQ0UsIGlmIGxwVW5rbm93biBpcyBOVUxMIG9yIGRvZXMgbm90IHN1cHBvcnQgdGhlCiAqICAgICAgICAgICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyIGludGVyZmFjZS4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0NQQ29udGFpbmVyT25DaGFuZ2VkKElVbmtub3duICpscFVua25vd24sIERJU1BJRCBkaXNwSUQpCnsKICBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyKiBscENQQyA9IE5VTEw7CiAgSFJFU1VMVCBoUmV0ID0gRV9OT0lOVEVSRkFDRTsKCiAgVFJBQ0UoIiglcCwweCU4bFgpXG4iLCBscFVua25vd24sIGRpc3BJRCk7CgogIGlmIChscFVua25vd24pCiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lDb25uZWN0aW9uUG9pbnRDb250YWluZXIsICh2b2lkKiopJmxwQ1BDKTsKCiAgaWYgKFNVQ0NFRURFRChoUmV0KSkKICB7CiAgICBJQ29ubmVjdGlvblBvaW50KiBscENQOwoKICAgIGhSZXQgPSBJQ29ubmVjdGlvblBvaW50Q29udGFpbmVyX0ZpbmRDb25uZWN0aW9uUG9pbnQobHBDUEMsICZJSURfSVByb3BlcnR5Tm90aWZ5U2luaywgJmxwQ1ApOwogICAgSUNvbm5lY3Rpb25Qb2ludENvbnRhaW5lcl9SZWxlYXNlKGxwQ1BDKTsKCiAgICBoUmV0ID0gSUNvbm5lY3Rpb25Qb2ludF9PbkNoYW5nZWQobHBDUCwgZGlzcElEKTsKICAgIElDb25uZWN0aW9uUG9pbnRfUmVsZWFzZShscENQKTsKICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yODldCiAqCiAqIFNlZSBQbGF5U291bmRXLgogKi8KQk9PTCBXSU5BUEkgUGxheVNvdW5kV3JhcFcoTFBDV1NUUiBwc3pTb3VuZCwgSE1PRFVMRSBobW9kLCBEV09SRCBmZHdTb3VuZCkKewogIEdFVF9GVU5DKHBQbGF5U291bmRXLCB3aW5tbSwgIlBsYXlTb3VuZFciLCBGQUxTRSk7CiAgcmV0dXJuIHBQbGF5U291bmRXKHBzelNvdW5kLCBobW9kLCBmZHdTb3VuZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTRdCiAqLwpCT09MIFdJTkFQSSBTSEdldEluaVN0cmluZ1coTFBTVFIgc3RyMSwgTFBTVFIgc3RyMiwgTFBTVFIgcFN0ciwgRFdPUkQgc29tZV9sZW4sICBMUENTVFIgbHBTdHIyKQp7CiAgICAvKgogICAgICogc3RyMToJCSJJIgkiSSIJcHVzaGwgZXNwKzB4MjAKICAgICAqIHN0cjI6CQkiVSIJIkkiCXB1c2hsIDB4NzdjOTM4MTAKICAgICAqIChpcyAiSSIgYW5kICJVIiAiaW50ZWdlciIgYW5kICJ1bnNpZ25lZCIgPz8pCiAgICAgKgogICAgICogcFN0cjoJCSIiCSIiCXB1c2hsIGVheAogICAgICogc29tZV9sZW46CTB4ODI0CTB4MTA0CXB1c2hsIDB4ODI0CiAgICAgKiBscFN0cjI6CQkiJWwiCSIlbCIJcHVzaGwgZXNwKzB4YwogICAgICoKICAgICAqIHNobHdhcGkuIFN0ckNweU5XKGxwU3RyMiwgaXJyZWxldmFudF92YXIsIDB4MTA0KTsKICAgICAqIExvY2FsQWxsb2MoMHgwMCwgc29tZV9sZW4pIC0+IGlycmVsZXZhbnRfdmFyCiAgICAgKiBMb2NhbEFsbG9jKDB4NDAsIGlycmVsZXZhbnRfbGVuKSAtPiBwU3RyCiAgICAgKiBzaGx3YXBpLjI5NChzdHIxLCBzdHIyLCBwU3RyLCBzb21lX2xlbiwgbHBTdHIyKTsKICAgICAqIHNobHdhcGkuUGF0aFJlbW92ZUJsYW5rc1cocFN0cik7CiAgICAgKi8KICAgIEZJWE1FKCIoJyVzJywgJyVzJywgJyVzJywgJTA4bHgsICclcycpOiBzdHViIVxuIiwgc3RyMSwgc3RyMiwgcFN0ciwgc29tZV9sZW4sIGxwU3RyMik7CiAgICByZXR1cm4gVFJVRTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjI5NV0KICoKICogQ2FsbGVkIGJ5IElDUTIwMDBiIGluc3RhbGwgdmlhIFNIRE9DVlc6CiAqIHN0cjE6ICJJbnRlcm5ldFNob3J0Y3V0IgogKiB4OiBzb21lIHVua25vd24gcG9pbnRlcgogKiBzdHIyOiAiaHR0cDovL2ZyZWUuYW9sLmNvbS90cnlhb2xmcmVlL2luZGV4LmFkcD8xMzkyNjkiCiAqIHN0cjM6ICJDOlxcV0lORE9XU1xcRGVza3RvcC5uZXcyXFxGcmVlIEFPTCAmIFVubGltaXRlZCBJbnRlcm5ldC51cmwiCiAqCiAqIEluIHNob3J0OiB0aGlzIG9uZSBtYXliZSBjcmVhdGVzIGEgZGVza3RvcCBsaW5rIDotKQogKi8KQk9PTCBXSU5BUEkgU0hTZXRJbmlTdHJpbmdXKExQV1NUUiBzdHIxLCBMUFZPSUQgeCwgTFBXU1RSIHN0cjIsIExQV1NUUiBzdHIzKQp7CiAgICBGSVhNRSgiKCclcycsICVwLCAnJXMnLCAnJXMnKSwgc3R1Yi5cbiIsIGRlYnVnc3RyX3coc3RyMSksIHgsIGRlYnVnc3RyX3coc3RyMiksIGRlYnVnc3RyX3coc3RyMykpOwogICAgcmV0dXJuIFRSVUU7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4yOTldCiAqCiAqIFNlZSBDT01DVEwzMl80MTcuCiAqLwpCT09MIFdJTkFQSSBFeHRUZXh0T3V0V3JhcFcoSERDIGhkYywgSU5UIHgsIElOVCB5LCBVSU5UIGZsYWdzLCBjb25zdCBSRUNUICpscHJlY3QsCiAgICAgICAgICAgICAgICAgICAgICAgICBMUENXU1RSIHN0ciwgVUlOVCBjb3VudCwgY29uc3QgSU5UICpscER4KQp7CiAgICBHRVRfRlVOQyhwQ09NQ1RMMzJfNDE3LCBjb21jdGwzMiwgKExQQ1NUUik0MTcsIEZBTFNFKTsKICAgIHJldHVybiBwQ09NQ1RMMzJfNDE3KGhkYywgeCwgeSwgZmxhZ3MsIGxwcmVjdCwgc3RyLCBjb3VudCwgbHBEeCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMTNdCiAqCiAqIFNlZSBTSEdldEZpbGVJbmZvVy4KICovCkRXT1JEIFdJTkFQSSBTSEdldEZpbGVJbmZvV3JhcFcoTFBDV1NUUiBwYXRoLCBEV09SRCBkd0ZpbGVBdHRyaWJ1dGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgU0hGSUxFSU5GT1cgKnBzZmksIFVJTlQgc2l6ZW9mcHNmaSwgVUlOVCBmbGFncykKewogIEdFVF9GVU5DKHBTSEdldEZpbGVJbmZvVywgc2hlbGwzMiwgIlNIR2V0RmlsZUluZm9XIiwgMCk7CiAgcmV0dXJuIHBTSEdldEZpbGVJbmZvVyhwYXRoLCBkd0ZpbGVBdHRyaWJ1dGVzLCBwc2ZpLCBzaXplb2Zwc2ZpLCBmbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMThdCiAqCiAqIFNlZSBEcmFnUXVlcnlGaWxlVy4KICovClVJTlQgV0lOQVBJIERyYWdRdWVyeUZpbGVXcmFwVyhIRFJPUCBoRHJvcCwgVUlOVCBsRmlsZSwgTFBXU1RSIGxwc3pGaWxlLCBVSU5UIGxMZW5ndGgpCnsKICBHRVRfRlVOQyhwRHJhZ1F1ZXJ5RmlsZVcsIHNoZWxsMzIsICJEcmFnUXVlcnlGaWxlVyIsIDApOwogIHJldHVybiBwRHJhZ1F1ZXJ5RmlsZVcoaERyb3AsIGxGaWxlLCBscHN6RmlsZSwgbExlbmd0aCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzNdCiAqCiAqIFNlZSBTSEJyb3dzZUZvckZvbGRlclcuCiAqLwpMUElURU1JRExJU1QgV0lOQVBJIFNIQnJvd3NlRm9yRm9sZGVyV3JhcFcoTFBCUk9XU0VJTkZPVyBscEJpKQp7CiAgR0VUX0ZVTkMocFNIQnJvd3NlRm9yRm9sZGVyVywgc2hlbGwzMiwgIlNIQnJvd3NlRm9yRm9sZGVyVyIsIE5VTEwpOwogIHJldHVybiBwU0hCcm93c2VGb3JGb2xkZXJXKGxwQmkpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM0XQogKgogKiBTZWUgU0hHZXRQYXRoRnJvbUlETGlzdFcuCiAqLwpCT09MIFdJTkFQSSBTSEdldFBhdGhGcm9tSURMaXN0V3JhcFcoTFBDSVRFTUlETElTVCBwaWRsLExQV1NUUiBwc3pQYXRoKQp7CiAgR0VUX0ZVTkMocFNIR2V0UGF0aEZyb21JRExpc3RXLCBzaGVsbDMyLCAiU0hHZXRQYXRoRnJvbUlETGlzdFciLCAwKTsKICByZXR1cm4gcFNIR2V0UGF0aEZyb21JRExpc3RXKHBpZGwsIHBzelBhdGgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM1XQogKgogKiBTZWUgU2hlbGxFeGVjdXRlRXhXLgogKi8KQk9PTCBXSU5BUEkgU2hlbGxFeGVjdXRlRXhXcmFwVyhMUFNIRUxMRVhFQ1VURUlORk9XIGxwRXhlY0luZm8pCnsKICBHRVRfRlVOQyhwU2hlbGxFeGVjdXRlRXhXLCBzaGVsbDMyLCAiU2hlbGxFeGVjdXRlRXhXIiwgRkFMU0UpOwogIHJldHVybiBwU2hlbGxFeGVjdXRlRXhXKGxwRXhlY0luZm8pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzM2XQogKgogKiBTZWUgU0hGaWxlT3BlcmF0aW9uVy4KICovCkhJQ09OIFdJTkFQSSBTSEZpbGVPcGVyYXRpb25XcmFwVyhMUFNIRklMRU9QU1RSVUNUVyBscEZpbGVPcCkKewogIEdFVF9GVU5DKHBTSEZpbGVPcGVyYXRpb25XLCBzaGVsbDMyLCAiU0hGaWxlT3BlcmF0aW9uVyIsIDApOwogIHJldHVybiBwU0hGaWxlT3BlcmF0aW9uVyhscEZpbGVPcCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zMzddCiAqCiAqIFNlZSBFeHRyYWN0SWNvbkV4Vy4KICovClVJTlQgV0lOQVBJIEV4dHJhY3RJY29uRXhXcmFwVyhMUENXU1RSIGxwc3pGaWxlLCBJTlQgbkljb25JbmRleCwgSElDT04gKnBoaWNvbkxhcmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgSElDT04gKnBoaWNvblNtYWxsLCBVSU5UIG5JY29ucykKewogIEdFVF9GVU5DKHBFeHRyYWN0SWNvbkV4Vywgc2hlbGwzMiwgIkV4dHJhY3RJY29uRXhXIiwgMCk7CiAgcmV0dXJuIHBFeHRyYWN0SWNvbkV4VyhscHN6RmlsZSwgbkljb25JbmRleCwgcGhpY29uTGFyZ2UsIHBoaWNvblNtYWxsLCBuSWNvbnMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzQyXQogKgogKi8KTE9ORyBXSU5BUEkgU0hJbnRlcmxvY2tlZENvbXBhcmVFeGNoYW5nZSggUExPTkcgZGVzdCwgTE9ORyB4Y2hnLCBMT05HIGNvbXBhcmUpCnsKICAgICAgICByZXR1cm4gSW50ZXJsb2NrZWRDb21wYXJlRXhjaGFuZ2UoZGVzdCwgeGNoZywgY29tcGFyZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTBdCiAqCiAqIFNlZSBHZXRGaWxlVmVyc2lvbkluZm9TaXplVy4KICovCkRXT1JEIFdJTkFQSSBHZXRGaWxlVmVyc2lvbkluZm9TaXplV3JhcFcoCglMUFdTVFIgeCwKCUxQVk9JRCB5KQp7CiAgICAgICAgRFdPUkQgcmV0OwoKCUdFVF9GVU5DKHBHZXRGaWxlVmVyc2lvbkluZm9TaXplVywgdmVyc2lvbiwgIkdldEZpbGVWZXJzaW9uSW5mb1NpemVXIiwgMCk7CglyZXQgPSBwR2V0RmlsZVZlcnNpb25JbmZvU2l6ZVcoeCwgeSk7CglyZXR1cm4gMHgyMDggKyByZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTFdCiAqCiAqIFNlZSBHZXRGaWxlVmVyc2lvbkluZm9XLgogKi8KQk9PTCAgV0lOQVBJIEdldEZpbGVWZXJzaW9uSW5mb1dyYXBXKAoJTFBXU1RSIHcsICAgLyogW2luXSBwYXRoIHRvIGRsbCAqLwoJRFdPUkQgIHgsICAgLyogW2luXSBwYXJtIDIgdG8gR2V0RmlsZVZlcnNpb25JbmZvQSAqLwoJRFdPUkQgIHksICAgLyogW2luXSByZXR1cm4gdmFsdWUgZnJvbSBTSExXQVBJXzM1MCgpIC0gYXNzdW1lIGxlbmd0aCAqLwoJTFBWT0lEIHopICAgLyogW2luL291dF0gYnVmZmVyICgrMHgyMDggc2VudCB0byBHZXRGaWxlVmVyc2lvbkluZm9BKCkpICovCnsKICAgIEdFVF9GVU5DKHBHZXRGaWxlVmVyc2lvbkluZm9XLCB2ZXJzaW9uLCAiR2V0RmlsZVZlcnNpb25JbmZvVyIsIDApOwogICAgcmV0dXJuIHBHZXRGaWxlVmVyc2lvbkluZm9XKHcsIHgsIHktMHgyMDgsIChjaGFyKil6KzB4MjA4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM1Ml0KICoKICogU2VlIFZlclF1ZXJ5VmFsdWVXLgogKi8KV09SRCBXSU5BUEkgVmVyUXVlcnlWYWx1ZVdyYXBXKAoJTFBWT0lEIHcsICAgLyogW2luXSBCdWZmZXIgZnJvbSBTSExXQVBJXzM1MSgpICovCglMUFdTVFIgeCwgICAvKiBbaW5dICAgVmFsdWUgdG8gcmV0cmlldmUgLSBjb252ZXJ0ZWQgYW5kIHBhc3NlZCB0byBWZXJRdWVyeVZhbHVlQSgpIGFzICMyICovCglMUFZPSUQgeSwgICAvKiBbb3V0XSAgVmVyIGJ1ZmZlciAtIHBhc3NlZCB0byBWZXJRdWVyeVZhbHVlQSBhcyAjMyAqLwoJVUlOVCogIHopICAgLyogW2luXSAgIFZlciBsZW5ndGggLSBwYXNzZWQgdG8gVmVyUXVlcnlWYWx1ZUEgYXMgIzQgKi8KewogICAgR0VUX0ZVTkMocFZlclF1ZXJ5VmFsdWVXLCB2ZXJzaW9uLCAiVmVyUXVlcnlWYWx1ZVciLCAwKTsKICAgIHJldHVybiBwVmVyUXVlcnlWYWx1ZVcoKGNoYXIqKXcrMHgyMDgsIHgsIHksIHopOwp9CgojZGVmaW5lIElzSWZhY2UodHlwZSkgU1VDQ0VFREVEKChoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEXyMjdHlwZSwgKHZvaWQqKikmbHBPYmopKSkKI2RlZmluZSBJU2hlbGxCcm93c2VyX0VuYWJsZU1vZGVsZXNzIElTaGVsbEJyb3dzZXJfRW5hYmxlTW9kZWxlc3NTQgojZGVmaW5lIEVuYWJsZU1vZGVsZXNzKHR5cGUpIHR5cGUjI19FbmFibGVNb2RlbGVzcygodHlwZSopbHBPYmosIGJNb2RlbGVzcykKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTVdCiAqCiAqIENoYW5nZSB0aGUgbW9kYWxpdHkgb2YgYSBzaGVsbCBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3QgdG8gbWFrZSBtb2RlbGVzcwogKiAgYk1vZGVsZXNzIFtJXSBUUlVFPU1ha2UgbW9kZWxlc3MsIEZBTFNFPU1ha2UgbW9kYWwKICoKICogUkVUVVJOUwogKiAgU3VjY2VzczogU19PSy4gVGhlIG1vZGFsaXR5IGxwVW5rbm93biBpcyBjaGFuZ2VkLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlIGluZGljYXRpbmcgdGhlIGVycm9yLgogKgogKiBOT1RFUwogKiAgbHBVbmtub3duIG11c3Qgc3VwcG9ydCB0aGUgSU9sZUluUGxhY2VGcmFtZSBpbnRlcmZhY2UsIHRoZQogKiAgSUludGVybmV0U2VjdXJpdHlNZ3JTaXRlIGludGVyZmFjZSwgdGhlIElTaGVsbEJyb3dzZXIgaW50ZXJmYWNlCiAqICB0aGUgSURvY0hvc3RVSUhhbmRsZXIgaW50ZXJmYWNlLCBvciB0aGUgSU9sZUluUGxhY2VBY3RpdmVPYmplY3QgaW50ZXJmYWNlLAogKiAgb3IgdGhpcyBjYWxsIHdpbGwgZmFpbC4KICovCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX0VuYWJsZU1vZGVsZXNzKElVbmtub3duICpscFVua25vd24sIEJPT0wgYk1vZGVsZXNzKQp7CiAgSVVua25vd24gKmxwT2JqOwogIEhSRVNVTFQgaFJldDsKCiAgVFJBQ0UoIiglcCwlZClcbiIsIGxwVW5rbm93biwgYk1vZGVsZXNzKTsKCiAgaWYgKCFscFVua25vd24pCiAgICByZXR1cm4gRV9GQUlMOwoKICBpZiAoSXNJZmFjZShJT2xlSW5QbGFjZUFjdGl2ZU9iamVjdCkpCiAgICBFbmFibGVNb2RlbGVzcyhJT2xlSW5QbGFjZUFjdGl2ZU9iamVjdCk7CiAgZWxzZSBpZiAoSXNJZmFjZShJT2xlSW5QbGFjZUZyYW1lKSkKICAgIEVuYWJsZU1vZGVsZXNzKElPbGVJblBsYWNlRnJhbWUpOwogIGVsc2UgaWYgKElzSWZhY2UoSVNoZWxsQnJvd3NlcikpCiAgICBFbmFibGVNb2RlbGVzcyhJU2hlbGxCcm93c2VyKTsKI2lmIDAKICAvKiBGSVhNRTogV2luZSBoYXMgbm8gaGVhZGVycyBmb3IgdGhlc2Ugb2JqZWN0cyB5ZXQgKi8KICBlbHNlIGlmIChJc0lmYWNlKElJbnRlcm5ldFNlY3VyaXR5TWdyU2l0ZSkpCiAgICBFbmFibGVNb2RlbGVzcyhJSW50ZXJuZXRTZWN1cml0eU1nclNpdGUpOwogIGVsc2UgaWYgKElzSWZhY2UoSURvY0hvc3RVSUhhbmRsZXIpKQogICAgRW5hYmxlTW9kZWxlc3MoSURvY0hvc3RVSUhhbmRsZXIpOwojZW5kaWYKICBlbHNlCiAgICByZXR1cm4gaFJldDsKCiAgSVVua25vd25fUmVsZWFzZShscE9iaik7CiAgcmV0dXJuIFNfT0s7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNTddCiAqCiAqIFNlZSBTSEdldE5ld0xpbmtJbmZvVy4KICovCkJPT0wgV0lOQVBJIFNIR2V0TmV3TGlua0luZm9XcmFwVyhMUENXU1RSIHBzekxpbmtUbywgTFBDV1NUUiBwc3pEaXIsIExQV1NUUiBwc3pOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICBCT09MICpwZk11c3RDb3B5LCBVSU5UIHVGbGFncykKewogIEdFVF9GVU5DKHBTSEdldE5ld0xpbmtJbmZvVywgc2hlbGwzMiwgIlNIR2V0TmV3TGlua0luZm9XIiwgRkFMU0UpOwogIHJldHVybiBwU0hHZXROZXdMaW5rSW5mb1cocHN6TGlua1RvLCBwc3pEaXIsIHBzek5hbWUsIHBmTXVzdENvcHksIHVGbGFncyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS4zNThdCiAqCiAqIFNlZSBTSERlZkV4dHJhY3RJY29uVy4KICovClVJTlQgV0lOQVBJIFNIRGVmRXh0cmFjdEljb25XcmFwVyhMUENXU1RSIHBzekljb25GaWxlLCBpbnQgaUluZGV4LCBVSU5UIHVGbGFncywgSElDT04qIHBoaWNvbkxhcmdlLAogICAgICAgICAgICAgICAgICAgICAgICAgSElDT04qIHBoaWNvblNtYWxsLCBVSU5UIG5JY29uU2l6ZSkKewogIEdFVF9GVU5DKHBTSERlZkV4dHJhY3RJY29uVywgc2hlbGwzMiwgIlNIRGVmRXh0cmFjdEljb25XIiwgMCk7CiAgcmV0dXJuIHBTSERlZkV4dHJhY3RJY29uVyhwc3pJY29uRmlsZSwgaUluZGV4LCB1RmxhZ3MsIHBoaWNvbkxhcmdlLCBwaGljb25TbWFsbCwgbkljb25TaXplKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM2M10KICoKICogR2V0IGFuZCBzaG93IGEgY29udGV4dCBtZW51IGZyb20gYSBzaGVsbCBmb2xkZXIuCiAqCiAqIFBBUkFNUwogKiAgaFduZCAgICAgICAgICAgW0ldIFdpbmRvdyBkaXNwbGF5aW5nIHRoZSBzaGVsbCBmb2xkZXIKICogIGxwRm9sZGVyICAgICAgIFtJXSBJU2hlbGxGb2xkZXIgaW50ZXJmYWNlCiAqICBscEFwaWRsICAgICAgICBbSV0gSWQgZm9yIHRoZSBwYXJ0aWN1bGFyIGZvbGRlciBkZXNpcmVkCiAqICBiSW52b2tlRGVmYXVsdCBbSV0gV2hldGhlciB0byBpbnZva2UgdGhlIGRlZmF1bHQgbWVudSBpdGVtCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFNfT0suIElmIGJJbnZva2VEZWZhdWx0IGlzIFRSVUUsIHRoZSBkZWZhdWx0IG1lbnUgYWN0aW9uIHdhcwogKiAgICAgICAgICAgZXhlY3V0ZWQuCiAqICBGYWlsdXJlOiBBbiBIUkVTVUxUIGVycm9yIGNvZGUgaW5kaWNhdGluZyB0aGUgZXJyb3IuCiAqLwpIUkVTVUxUIFdJTkFQSSBTSEludm9rZUNvbW1hbmQoSFdORCBoV25kLCBJU2hlbGxGb2xkZXIqIGxwRm9sZGVyLCBMUENJVEVNSURMSVNUIGxwQXBpZGwsIEJPT0wgYkludm9rZURlZmF1bHQpCnsKICBJQ29udGV4dE1lbnUgKmlDb250ZXh0OwogIEhSRVNVTFQgaFJldCA9IEVfRkFJTDsKCiAgVFJBQ0UoIiglcCwlcCwlcCwlZClcbiIsIGhXbmQsIGxwRm9sZGVyLCBscEFwaWRsLCBiSW52b2tlRGVmYXVsdCk7CgogIGlmICghbHBGb2xkZXIpCiAgICByZXR1cm4gaFJldDsKCiAgLyogR2V0IHRoZSBjb250ZXh0IG1lbnUgZnJvbSB0aGUgc2hlbGwgZm9sZGVyICovCiAgaFJldCA9IElTaGVsbEZvbGRlcl9HZXRVSU9iamVjdE9mKGxwRm9sZGVyLCBoV25kLCAxLCAmbHBBcGlkbCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJklJRF9JQ29udGV4dE1lbnUsIDAsICh2b2lkKiopJmlDb250ZXh0KTsKICBpZiAoU1VDQ0VFREVEKGhSZXQpKQogIHsKICAgIEhNRU5VIGhNZW51OwogICAgaWYgKChoTWVudSA9IENyZWF0ZVBvcHVwTWVudSgpKSkKICAgIHsKICAgICAgSFJFU1VMVCBoUXVlcnk7CiAgICAgIERXT1JEIGR3RGVmYXVsdElkID0gMDsKCiAgICAgIC8qIEFkZCB0aGUgY29udGV4dCBtZW51IGVudHJpZXMgdG8gdGhlIHBvcHVwICovCiAgICAgIGhRdWVyeSA9IElDb250ZXh0TWVudV9RdWVyeUNvbnRleHRNZW51KGlDb250ZXh0LCBoTWVudSwgMCwgMSwgMHg3RkZGLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiSW52b2tlRGVmYXVsdCA/IENNRl9OT1JNQUwgOiBDTUZfREVGQVVMVE9OTFkpOwoKICAgICAgaWYgKFNVQ0NFRURFRChoUXVlcnkpKQogICAgICB7CiAgICAgICAgaWYgKGJJbnZva2VEZWZhdWx0ICYmCiAgICAgICAgICAgIChkd0RlZmF1bHRJZCA9IEdldE1lbnVEZWZhdWx0SXRlbShoTWVudSwgMCwgMCkpICE9IDB4RkZGRkZGRkYpCiAgICAgICAgewogICAgICAgICAgQ01JTlZPS0VDT01NQU5ESU5GTyBjbUljaTsKICAgICAgICAgIC8qIEludm9rZSB0aGUgZGVmYXVsdCBpdGVtICovCiAgICAgICAgICBtZW1zZXQoJmNtSWNpLDAsc2l6ZW9mKGNtSWNpKSk7CiAgICAgICAgICBjbUljaS5jYlNpemUgPSBzaXplb2YoY21JY2kpOwogICAgICAgICAgY21JY2kuZk1hc2sgPSBDTUlDX01BU0tfQVNZTkNPSzsKICAgICAgICAgIGNtSWNpLmh3bmQgPSBoV25kOwogICAgICAgICAgY21JY2kubHBWZXJiID0gTUFLRUlOVFJFU09VUkNFQShkd0RlZmF1bHRJZCk7CiAgICAgICAgICBjbUljaS5uU2hvdyA9IFNXX1NDUk9MTENISUxEUkVOOwoKICAgICAgICAgIGhSZXQgPSBJQ29udGV4dE1lbnVfSW52b2tlQ29tbWFuZChpQ29udGV4dCwgJmNtSWNpKTsKICAgICAgICB9CiAgICAgIH0KICAgICAgRGVzdHJveU1lbnUoaE1lbnUpOwogICAgfQogICAgSUNvbnRleHRNZW51X1JlbGVhc2UoaUNvbnRleHQpOwogIH0KICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3MF0KICoKICogU2VlIEV4dHJhY3RJY29uVy4KICovCkhJQ09OIFdJTkFQSSBFeHRyYWN0SWNvbldyYXBXKEhJTlNUQU5DRSBoSW5zdGFuY2UsIExQQ1dTVFIgbHBzekV4ZUZpbGVOYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgVUlOVCBuSWNvbkluZGV4KQp7CiAgR0VUX0ZVTkMocEV4dHJhY3RJY29uVywgc2hlbGwzMiwgIkV4dHJhY3RJY29uVyIsIE5VTEwpOwogIHJldHVybiBwRXh0cmFjdEljb25XKGhJbnN0YW5jZSwgbHBzekV4ZUZpbGVOYW1lLCBuSWNvbkluZGV4KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3Nl0KICovCkxBTkdJRCBXSU5BUEkgTUxHZXRVSUxhbmd1YWdlKHZvaWQpCnsKICAgIEZJWE1FKCIoKSBzdHViXG4iKTsKICAgIC8qIEZJWE1FOiBUaGlzIHNob3VsZCBiZSBhIGZvcndhcmQgaW4gdGhlIC5zcGVjIGZpbGUgdG8gdGhlIHdpbjJrIGZ1bmN0aW9uCiAgICAgKiBrZXJuZWwzMi5HZXRVc2VyRGVmYXVsdFVJTGFuZ3VhZ2UsIGhvd2V2ZXIgdGhhdCBmdW5jdGlvbiBpc24ndCB0aGVyZSB5ZXQuCiAgICAgKi8KICAgIHJldHVybiBHZXRVc2VyRGVmYXVsdExhbmdJRCgpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMzc3XQogKgogKiBMb2FkIGEgbGlicmFyeSBmcm9tIHRoZSBkaXJlY3Rvcnkgb2YgYSBwYXJ0aWN1bGFyIHByb2Nlc3MuCiAqCiAqIFBBUkFNUwogKiAgbmV3X21vZCAgIFtJXSBMaWJyYXJ5IG5hbWUKICogIGluc3RfaHduZCBbSV0gTW9kdWxlIHdob3NlIGRpcmVjdG9yeSBpcyB0byBiZSB1c2VkCiAqICBkd0ZsYWdzICAgW0ldIEZsYWdzIGNvbnRyb2xsaW5nIHRoZSBsb2FkCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IEEgaGFuZGxlIHRvIHRoZSBsb2FkZWQgbW9kdWxlCiAqICBGYWlsdXJlOiBBIE5VTEwgaGFuZGxlLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeUEoTFBDU1RSIG5ld19tb2QsIEhNT0RVTEUgaW5zdF9od25kLCBEV09SRCBkd0ZsYWdzKQp7CiAgLyogRklYTUU6IE5hdGl2ZSBhcHBlYXJzIHRvIGRvIERQQV9DcmVhdGUgYW5kIGEgRFBBX0luc2VydFB0ciBmb3IKICAgKiAgICAgICAgZWFjaCBjYWxsIGhlcmUuCiAgICogRklYTUU6IE5hdGl2ZSBzaG93cyBjYWxscyB0bzoKICAgKiAgU0hSZWdHZXRVU1ZhbHVlIGZvciAiU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogICAgICAgICAgICAgICAgICAgICAgQ2hlY2tWZXJzaW9uCiAgICogIFJlZ09wZW5LZXlFeEEgZm9yICJIS0xNXFNvZnR3YXJlXE1pY3Jvc29mdFxJbnRlcm5ldCBFeHBsb3JlciIKICAgKiAgUmVnUXVlcnlWYWx1ZUV4QSBmb3IgIkxQS0luc3RhbGxlZCIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLQ1VcU29mdHdhcmVcTWljcm9zb2Z0XEludGVybmV0IEV4cGxvcmVyXEludGVybmF0aW9uYWwiCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJSZXNvdXJjZUxvY2FsZSIKICAgKiAgUmVnQ2xvc2VLZXkKICAgKiAgUmVnT3BlbktleUV4QSBmb3IgIkhLTE1cU29mdHdhcmVcTWljcm9zb2Z0XEFjdGl2ZSBTZXR1cFxJbnN0YWxsZWQgQ29tcG9uZW50c1x7Z3VpZH0iCiAgICogIFJlZ1F1ZXJ5VmFsdWVFeEEgZm9yICJMb2NhbGUiCiAgICogIFJlZ0Nsb3NlS2V5CiAgICogIGFuZCB0aGVuIHRlc3RzIHRoZSBMb2NhbGUgKCJlbiIgZm9yIG1lKS4KICAgKiAgICAgY29kZSBiZWxvdwogICAqICBhZnRlciB0aGUgY29kZSB0aGVuIGEgRFBBX0NyZWF0ZSAoZmlyc3QgdGltZSkgYW5kIERQQV9JbnNlcnRQdHIgYXJlIGRvbmUuCiAgICovCiAgICBDSEFSIG1vZF9wYXRoWzIqTUFYX1BBVEhdOwogICAgTFBTVFIgcHRyOwogICAgRFdPUkQgbGVuOwoKICAgIEZJWE1FKCIoJXMsJXAsMHglMDhseCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfYShuZXdfbW9kKSwgaW5zdF9od25kLCBkd0ZsYWdzKTsKICAgIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lQShpbnN0X2h3bmQsIG1vZF9wYXRoLCBzaXplb2YobW9kX3BhdGgpKTsKICAgIGlmICghbGVuIHx8IGxlbiA+PSBzaXplb2YobW9kX3BhdGgpKSByZXR1cm4gTlVMTDsKCiAgICBwdHIgPSBzdHJyY2hyKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweShwdHIrMSwgbmV3X21vZCk7CglUUkFDRSgibG9hZGluZyAlc1xuIiwgZGVidWdzdHJfYShtb2RfcGF0aCkpOwoJcmV0dXJuIExvYWRMaWJyYXJ5QShtb2RfcGF0aCk7CiAgICB9CiAgICByZXR1cm4gTlVMTDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM3OF0KICoKICogVW5pY29kZSB2ZXJzaW9uIG9mIE1MTG9hZExpYnJhcnlBLgogKi8KSE1PRFVMRSBXSU5BUEkgTUxMb2FkTGlicmFyeVcoTFBDV1NUUiBuZXdfbW9kLCBITU9EVUxFIGluc3RfaHduZCwgRFdPUkQgZHdGbGFncykKewogICAgV0NIQVIgbW9kX3BhdGhbMipNQVhfUEFUSF07CiAgICBMUFdTVFIgcHRyOwogICAgRFdPUkQgbGVuOwoKICAgIEZJWE1FKCIoJXMsJXAsMHglMDhseCkgc2VtaS1zdHViIVxuIiwgZGVidWdzdHJfdyhuZXdfbW9kKSwgaW5zdF9od25kLCBkd0ZsYWdzKTsKICAgIGxlbiA9IEdldE1vZHVsZUZpbGVOYW1lVyhpbnN0X2h3bmQsIG1vZF9wYXRoLCBzaXplb2YobW9kX3BhdGgpIC8gc2l6ZW9mKFdDSEFSKSk7CiAgICBpZiAoIWxlbiB8fCBsZW4gPj0gc2l6ZW9mKG1vZF9wYXRoKSAvIHNpemVvZihXQ0hBUikpIHJldHVybiBOVUxMOwoKICAgIHB0ciA9IHN0cnJjaHJXKG1vZF9wYXRoLCAnXFwnKTsKICAgIGlmIChwdHIpIHsKCXN0cmNweVcocHRyKzEsIG5ld19tb2QpOwoJVFJBQ0UoImxvYWRpbmcgJXNcbiIsIGRlYnVnc3RyX3cobW9kX3BhdGgpKTsKCXJldHVybiBMb2FkTGlicmFyeVcobW9kX3BhdGgpOwogICAgfQogICAgcmV0dXJuIE5VTEw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIENvbG9yQWRqdXN0THVtYSAgICAgIFtTSExXQVBJLkBdCiAqCiAqIEFkanVzdCB0aGUgbHVtaW5vc2l0eSBvZiBhIGNvbG9yCiAqCiAqIFBBUkFNUwogKiAgY1JHQiAgICAgICAgIFtJXSBSR0IgdmFsdWUgdG8gY29udmVydAogKiAgZHdMdW1hICAgICAgIFtJXSBMdW1hIGFkanVzdG1lbnQKICogIGJVbmtub3duICAgICBbSV0gVW5rbm93bgogKgogKiBSRVRVUk5TCiAqICBUaGUgYWRqdXN0ZWQgUkdCIGNvbG9yLgogKi8KQ09MT1JSRUYgV0lOQVBJIENvbG9yQWRqdXN0THVtYShDT0xPUlJFRiBjUkdCLCBpbnQgZHdMdW1hLCBCT09MIGJVbmtub3duKQp7CiAgVFJBQ0UoIigweCU4bHgsJWQsJWQpXG4iLCBjUkdCLCBkd0x1bWEsIGJVbmtub3duKTsKCiAgaWYgKGR3THVtYSkKICB7CiAgICBXT1JEIHdILCB3TCwgd1M7CgogICAgQ29sb3JSR0JUb0hMUyhjUkdCLCAmd0gsICZ3TCwgJndTKTsKCiAgICBGSVhNRSgiSWdub3JpbmcgbHVtYSBhZGp1c3RtZW50XG4iKTsKCiAgICAvKiBGSVhNRTogVGhlIGFqZHVzdG1lbnQgaXMgbm90IGxpbmVhciAqLwoKICAgIGNSR0IgPSBDb2xvckhMU1RvUkdCKHdILCB3TCwgd1MpOwogIH0KICByZXR1cm4gY1JHQjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM4OV0KICoKICogU2VlIEdldFNhdmVGaWxlTmFtZVcuCiAqLwpCT09MIFdJTkFQSSBHZXRTYXZlRmlsZU5hbWVXcmFwVyhMUE9QRU5GSUxFTkFNRVcgb2ZuKQp7CiAgR0VUX0ZVTkMocEdldFNhdmVGaWxlTmFtZVcsIGNvbWRsZzMyLCAiR2V0U2F2ZUZpbGVOYW1lVyIsIEZBTFNFKTsKICByZXR1cm4gcEdldFNhdmVGaWxlTmFtZVcob2ZuKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM5MF0KICoKICogU2VlIFdOZXRSZXN0b3JlQ29ubmVjdGlvblcuCiAqLwpEV09SRCBXSU5BUEkgV05ldFJlc3RvcmVDb25uZWN0aW9uV3JhcFcoSFdORCBod25kT3duZXIsIExQV1NUUiBscHN6RGV2aWNlKQp7CiAgR0VUX0ZVTkMocFdOZXRSZXN0b3JlQ29ubmVjdGlvblcsIG1wciwgIldOZXRSZXN0b3JlQ29ubmVjdGlvblciLCAwKTsKICByZXR1cm4gcFdOZXRSZXN0b3JlQ29ubmVjdGlvblcoaHduZE93bmVyLCBscHN6RGV2aWNlKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjM5MV0KICoKICogU2VlIFdOZXRHZXRMYXN0RXJyb3JXLgogKi8KRFdPUkQgV0lOQVBJIFdOZXRHZXRMYXN0RXJyb3JXcmFwVyhMUERXT1JEIGxwRXJyb3IsIExQV1NUUiBscEVycm9yQnVmLCBEV09SRCBuRXJyb3JCdWZTaXplLAogICAgICAgICAgICAgICAgICAgICAgICAgTFBXU1RSIGxwTmFtZUJ1ZiwgRFdPUkQgbk5hbWVCdWZTaXplKQp7CiAgR0VUX0ZVTkMocFdOZXRHZXRMYXN0RXJyb3JXLCBtcHIsICJXTmV0R2V0TGFzdEVycm9yVyIsIDApOwogIHJldHVybiBwV05ldEdldExhc3RFcnJvclcobHBFcnJvciwgbHBFcnJvckJ1ZiwgbkVycm9yQnVmU2l6ZSwgbHBOYW1lQnVmLCBuTmFtZUJ1ZlNpemUpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAxXQogKgogKiBTZWUgUGFnZVNldHVwRGxnVy4KICovCkJPT0wgV0lOQVBJIFBhZ2VTZXR1cERsZ1dyYXBXKExQUEFHRVNFVFVQRExHVyBwYWdlZGxnKQp7CiAgR0VUX0ZVTkMocFBhZ2VTZXR1cERsZ1csIGNvbWRsZzMyLCAiUGFnZVNldHVwRGxnVyIsIEZBTFNFKTsKICByZXR1cm4gcFBhZ2VTZXR1cERsZ1cocGFnZWRsZyk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MDJdCiAqCiAqIFNlZSBQcmludERsZ1cuCiAqLwpCT09MIFdJTkFQSSBQcmludERsZ1dyYXBXKExQUFJJTlRETEdXIHByaW50ZGxnKQp7CiAgR0VUX0ZVTkMocFByaW50RGxnVywgY29tZGxnMzIsICJQcmludERsZ1ciLCBGQUxTRSk7CiAgcmV0dXJuIHBQcmludERsZ1cocHJpbnRkbGcpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDAzXQogKgogKiBTZWUgR2V0T3BlbkZpbGVOYW1lVy4KICovCkJPT0wgV0lOQVBJIEdldE9wZW5GaWxlTmFtZVdyYXBXKExQT1BFTkZJTEVOQU1FVyBvZm4pCnsKICBHRVRfRlVOQyhwR2V0T3BlbkZpbGVOYW1lVywgY29tZGxnMzIsICJHZXRPcGVuRmlsZU5hbWVXIiwgRkFMU0UpOwogIHJldHVybiBwR2V0T3BlbkZpbGVOYW1lVyhvZm4pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDA0XQogKi8KSFJFU1VMVCBXSU5BUEkgSVVua25vd25fRW51bU9iamVjdHMoTFBTSEVMTEZPTERFUiBscEZvbGRlciwgSFdORCBod25kLCBTSENPTlRGIGZsYWdzLCBJRW51bUlETGlzdCAqKnBwZW51bSkKewogICAgSVBlcnNpc3QgKnBlcnNpc3Q7CiAgICBIUkVTVUxUIGhyOwoKICAgIGhyID0gSVNoZWxsRm9sZGVyX1F1ZXJ5SW50ZXJmYWNlKGxwRm9sZGVyLCAmSUlEX0lQZXJzaXN0LCAoTFBWT0lEKSZwZXJzaXN0KTsKICAgIGlmKFNVQ0NFRURFRChocikpCiAgICB7CiAgICAgICAgQ0xTSUQgY2xzaWQ7CiAgICAgICAgaHIgPSBJUGVyc2lzdF9HZXRDbGFzc0lEKHBlcnNpc3QsICZjbHNpZCk7CiAgICAgICAgaWYoU1VDQ0VFREVEKGhyKSkKICAgICAgICB7CiAgICAgICAgICAgIGlmKElzRXF1YWxDTFNJRCgmY2xzaWQsICZDTFNJRF9TaGVsbEZTRm9sZGVyKSkKICAgICAgICAgICAgICAgIGhyID0gSVNoZWxsRm9sZGVyX0VudW1PYmplY3RzKGxwRm9sZGVyLCBod25kLCBmbGFncywgcHBlbnVtKTsKICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgaHIgPSBFX0ZBSUw7CiAgICAgICAgfQogICAgICAgIElQZXJzaXN0X1JlbGVhc2UocGVyc2lzdCk7CiAgICB9CiAgICByZXR1cm4gaHI7Cn0KCi8qIElOVEVSTkFMOiBNYXAgZnJvbSBITFMgY29sb3Igc3BhY2UgdG8gUkdCICovCnN0YXRpYyBXT1JEIFdJTkFQSSBDb252ZXJ0SHVlKGludCB3SHVlLCBXT1JEIHdNaWQxLCBXT1JEIHdNaWQyKQp7CiAgd0h1ZSA9IHdIdWUgPiAyNDAgPyB3SHVlIC0gMjQwIDogd0h1ZSA8IDAgPyB3SHVlICsgMjQwIDogd0h1ZTsKCiAgaWYgKHdIdWUgPiAxNjApCiAgICByZXR1cm4gd01pZDE7CiAgZWxzZSBpZiAod0h1ZSA+IDEyMCkKICAgIHdIdWUgPSAxNjAgLSB3SHVlOwogIGVsc2UgaWYgKHdIdWUgPiA0MCkKICAgIHJldHVybiB3TWlkMjsKCiAgcmV0dXJuICgod0h1ZSAqICh3TWlkMiAtIHdNaWQxKSArIDIwKSAvIDQwKSArIHdNaWQxOwp9CgovKiBDb252ZXJ0IHRvIFJHQiBhbmQgc2NhbGUgaW50byBSR0IgcmFuZ2UgKDAuLjI1NSkgKi8KI2RlZmluZSBHRVRfUkdCKGgpIChDb252ZXJ0SHVlKGgsIHdNaWQxLCB3TWlkMikgKiAyNTUgKyAxMjApIC8gMjQwCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIENvbG9ySExTVG9SR0IJW1NITFdBUEkuQF0KICoKICogQ29udmVydCBmcm9tIGhscyBjb2xvciBzcGFjZSBpbnRvIGFuIHJnYiBDT0xPUlJFRi4KICoKICogUEFSQU1TCiAqICB3SHVlICAgICAgICBbSV0gSHVlIGFtb3VudAogKiAgd0x1bWlub3NpdHkgW0ldIEx1bWlub3NpdHkgYW1vdW50CiAqICB3U2F0dXJhdGlvbiBbSV0gU2F0dXJhdGlvbiBhbW91bnQKICoKICogUkVUVVJOUwogKiAgQSBDT0xPUlJFRiByZXByZXNlbnRpbmcgdGhlIGNvbnZlcnRlZCBjb2xvci4KICoKICogTk9URVMKICogIElucHV0IGhscyB2YWx1ZXMgYXJlIGNvbnN0cmFpbmVkIHRvIHRoZSByYW5nZSAoMC4uMjQwKS4KICovCkNPTE9SUkVGIFdJTkFQSSBDb2xvckhMU1RvUkdCKFdPUkQgd0h1ZSwgV09SRCB3THVtaW5vc2l0eSwgV09SRCB3U2F0dXJhdGlvbikKewogIFdPUkQgd1JlZDsKCiAgaWYgKHdTYXR1cmF0aW9uKQogIHsKICAgIFdPUkQgd0dyZWVuLCB3Qmx1ZSwgd01pZDEsIHdNaWQyOwoKICAgIGlmICh3THVtaW5vc2l0eSA+IDEyMCkKICAgICAgd01pZDIgPSB3U2F0dXJhdGlvbiArIHdMdW1pbm9zaXR5IC0gKHdTYXR1cmF0aW9uICogd0x1bWlub3NpdHkgKyAxMjApIC8gMjQwOwogICAgZWxzZQogICAgICB3TWlkMiA9ICgod1NhdHVyYXRpb24gKyAyNDApICogd0x1bWlub3NpdHkgKyAxMjApIC8gMjQwOwoKICAgIHdNaWQxID0gd0x1bWlub3NpdHkgKiAyIC0gd01pZDI7CgogICAgd1JlZCAgID0gR0VUX1JHQih3SHVlICsgODApOwogICAgd0dyZWVuID0gR0VUX1JHQih3SHVlKTsKICAgIHdCbHVlICA9IEdFVF9SR0Iod0h1ZSAtIDgwKTsKCiAgICByZXR1cm4gUkdCKHdSZWQsIHdHcmVlbiwgd0JsdWUpOwogIH0KCiAgd1JlZCA9IHdMdW1pbm9zaXR5ICogMjU1IC8gMjQwOwogIHJldHVybiBSR0Iod1JlZCwgd1JlZCwgd1JlZCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTNdCiAqCiAqIEdldCB0aGUgY3VycmVudCBkb2NraW5nIHN0YXR1cyBvZiB0aGUgc3lzdGVtLgogKgogKiBQQVJBTVMKICogIGR3RmxhZ3MgW0ldIERPQ0tJTkZPXyBmbGFncyBmcm9tICJ3aW5iYXNlLmgiLCB1bnVzZWQKICoKICogUkVUVVJOUwogKiAgT25lIG9mIERPQ0tJTkZPX1VORE9DS0VELCBET0NLSU5GT19VTkRPQ0tFRCwgb3IgMCBpZiB0aGUgc3lzdGVtIGlzIG5vdAogKiAgYSBub3RlYm9vay4KICovCkRXT1JEIFdJTkFQSSBTSEdldE1hY2hpbmVJbmZvKERXT1JEIGR3RmxhZ3MpCnsKICBIV19QUk9GSUxFX0lORk9BIGh3SW5mbzsKCiAgVFJBQ0UoIigweCUwOGx4KVxuIiwgZHdGbGFncyk7CgogIEdldEN1cnJlbnRId1Byb2ZpbGVBKCZod0luZm8pOwogIHN3aXRjaCAoaHdJbmZvLmR3RG9ja0luZm8gJiAoRE9DS0lORk9fRE9DS0VEfERPQ0tJTkZPX1VORE9DS0VEKSkKICB7CiAgY2FzZSBET0NLSU5GT19ET0NLRUQ6CiAgY2FzZSBET0NLSU5GT19VTkRPQ0tFRDoKICAgIHJldHVybiBod0luZm8uZHdEb2NrSW5mbyAmIChET0NLSU5GT19ET0NLRUR8RE9DS0lORk9fVU5ET0NLRUQpOwogIGRlZmF1bHQ6CiAgICByZXR1cm4gMDsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MThdCiAqCiAqIEZ1bmN0aW9uIHNlZW1zIHRvIGRvIEZyZWVMaWJyYXJ5IHBsdXMgb3RoZXIgdGhpbmdzLgogKgogKiBGSVhNRSBuYXRpdmUgc2hvd3MgdGhlIGZvbGxvd2luZyBjYWxsczoKICogICBSdGxFbnRlckNyaXRpY2FsU2VjdGlvbgogKiAgIExvY2FsRnJlZQogKiAgIEdldFByb2NBZGRyZXNzKENvbWN0bDMyPz8sIDE1MEwpCiAqICAgRFBBX0RlbGV0ZVB0cgogKiAgIFJ0bExlYXZlQ3JpdGljYWxTZWN0aW9uCiAqICBmb2xsb3dlZCBieSB0aGUgRnJlZUxpYnJhcnkuCiAqICBUaGUgYWJvdmUgY29kZSBtYXkgYmUgcmVsYXRlZCB0byAuMzc3IGFib3ZlLgogKi8KQk9PTCBXSU5BUEkgTUxGcmVlTGlicmFyeShITU9EVUxFIGhNb2R1bGUpCnsKCUZJWE1FKCIoJXApIHNlbWktc3R1YlxuIiwgaE1vZHVsZSk7CglyZXR1cm4gRnJlZUxpYnJhcnkoaE1vZHVsZSk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MTldCiAqLwpCT09MIFdJTkFQSSBTSEZsdXNoU0ZDYWNoZVdyYXAodm9pZCkgewogIEZJWE1FKCI6IHN0dWJcbiIpOwogIHJldHVybiBUUlVFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDI1XQogKi8KQk9PTCBXSU5BUEkgRGVsZXRlTWVudVdyYXAoSE1FTlUgaG1lbnUsIFVJTlQgcG9zLCBVSU5UIGZsYWdzKQp7CiAgICAvKiBGSVhNRTogVGhpcyBzaG91bGQgZG8gbW9yZSB0aGFuIHNpbXBseSBjYWxsIERlbGV0ZU1lbnUgKi8KICAgIEZJWE1FKCIlcCAlMDh4ICUwOHgpOiBzZW1pLXN0dWJcbiIsIGhtZW51LCBwb3MsIGZsYWdzKTsKICAgIHJldHVybiBEZWxldGVNZW51KGhtZW51LCBwb3MsIGZsYWdzKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBAICAgICAgW1NITFdBUEkuNDI5XQogKiBGSVhNRSBJIGhhdmUgbm8gaWRlYSB3aGF0IHRoaXMgZnVuY3Rpb24gZG9lcyBvciB3aGF0IGl0cyBhcmd1bWVudHMgYXJlLgogKi8KQk9PTCBXSU5BUEkgTUxJc01MSEluc3RhbmNlKEhJTlNUQU5DRSBoSW5zdCkKewogICAgICAgRklYTUUoIiglcCkgc3R1YlxuIiwgaEluc3QpOwogICAgICAgcmV0dXJuIEZBTFNFOwp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzMF0KICovCkRXT1JEIFdJTkFQSSBNTFNldE1MSEluc3RhbmNlKEhJTlNUQU5DRSBoSW5zdCwgSEFORExFIGhIZWFwKQp7CglGSVhNRSgiKCVwLCVwKSBzdHViXG4iLCBoSW5zdCwgaEhlYXApOwoJcmV0dXJuIEVfRkFJTDsgICAvKiBUaGlzIGlzIHdoYXQgaXMgdXNlZCBpZiBzaGx3YXBpIG5vdCBsb2FkZWQgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQzMV0KICovCkRXT1JEIFdJTkFQSSBNTENsZWFyTUxISW5zdGFuY2UoRFdPUkQgeCkKewoJRklYTUUoIigweCUwOGx4KXN0dWJcbiIsIHgpOwoJcmV0dXJuIDB4YWJiYTEyNDc7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS40MzZdCiAqCiAqIENvbnZlcnQgYW4gVW5pY29kZSBzdHJpbmcgQ0xTSUQgaW50byBhIENMU0lELgogKgogKiBQQVJBTVMKICogIGlkc3RyICAgICAgW0ldICAgc3RyaW5nIGNvbnRhaW5pbmcgYSBDTFNJRCBpbiB0ZXh0IGZvcm0KICogIGlkICAgICAgICAgW09dICAgQ0xTSUQgZXh0cmFjdGVkIGZyb20gdGhlIHN0cmluZwogKgogKiBSRVRVUk5TCiAqICBTX09LIG9uIHN1Y2Nlc3Mgb3IgRV9JTlZBTElEQVJHIG9uIGZhaWx1cmUKICoKICogTk9URVMKICogIFRoaXMgaXMgcmVhbGx5IENMU0lERnJvbVN0cmluZygpIHdoaWNoIGlzIGV4cG9ydGVkIGJ5IG9sZTMyLmRsbCwKICogIGhvd2V2ZXIgdGhlIG5hdGl2ZSBzaGx3YXBpLmRsbCBkb2VzICpub3QqIGltcG9ydCBvbGUzMi4gTm9yIGRvZXMKICogIG9sZTMyLmRsbCBpbXBvcnQgdGhpcyBvcmRpbmFsIGZyb20gc2hsd2FwaS4gVGhlcmVmb3JlIHdlIG11c3QgY29uY2x1ZGUKICogIHRoYXQgTVMgZHVwbGljYXRlZCB0aGUgY29kZSBmb3IgQ0xTSURGcm9tU3RyaW5nKCksIGFuZCB5ZXMgdGhleSBkaWQsIG9ubHkKICogIGl0IHJldHVybnMgYW4gRV9JTlZBTElEQVJHIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICogIFRoaXMgaXMgYSBkdXBsaWNhdGUgKHdpdGggY2hhbmdlcyBmb3IgVW5pY29kZSkgb2YgQ0xTSURGcm9tU3RyaW5nMTYoKQogKiAgaW4gImRsbHMvb2xlMzIvY29tcG9iai5jIi4KICovCkhSRVNVTFQgV0lOQVBJIENMU0lERnJvbVN0cmluZ1dyYXAoTFBDV1NUUiBpZHN0ciwgQ0xTSUQgKmlkKQp7CglMUENXU1RSIHMgPSBpZHN0cjsKCUJZVEUgKnA7CglJTlQgaTsKCVdDSEFSIHRhYmxlWzI1Nl07CgoJaWYgKCFzKSB7CgkgIG1lbXNldChpZCwgMCwgc2l6ZW9mKENMU0lEKSk7CgkgIHJldHVybiBTX09LOwoJfQoJZWxzZSB7ICAvKiB2YWxpZGF0ZSB0aGUgQ0xTSUQgc3RyaW5nICovCgoJICBpZiAoc3RybGVuVyhzKSAhPSAzOCkKCSAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKCSAgaWYgKChzWzBdIT1MJ3snKSB8fCAoc1s5XSE9TCctJykgfHwgKHNbMTRdIT1MJy0nKSB8fCAoc1sxOV0hPUwnLScpIHx8IChzWzI0XSE9TCctJykgfHwgKHNbMzddIT1MJ30nKSkKCSAgICByZXR1cm4gRV9JTlZBTElEQVJHOwoKCSAgZm9yIChpPTE7IGk8Mzc7IGkrKykKCSAgewoJICAgIGlmICgoaSA9PSA5KXx8KGkgPT0gMTQpfHwoaSA9PSAxOSl8fChpID09IDI0KSkKCSAgICAgIGNvbnRpbnVlOwoJICAgIGlmICghKCgoc1tpXSA+PSBMJzAnKSAmJiAoc1tpXSA8PSBMJzknKSkgIHx8CgkgICAgICAgICgoc1tpXSA+PSBMJ2EnKSAmJiAoc1tpXSA8PSBMJ2YnKSkgIHx8CgkgICAgICAgICgoc1tpXSA+PSBMJ0EnKSAmJiAoc1tpXSA8PSBMJ0YnKSkpCgkgICAgICAgKQoJICAgICAgcmV0dXJuIEVfSU5WQUxJREFSRzsKCSAgfQoJfQoKICAgIFRSQUNFKCIlcyAtPiAlcFxuIiwgZGVidWdzdHJfdyhzKSwgaWQpOwoKICAvKiBxdWljayBsb29rdXAgdGFibGUgKi8KICAgIG1lbXNldCh0YWJsZSwgMCwgMjU2KnNpemVvZihXQ0hBUikpOwoKICAgIGZvciAoaSA9IDA7IGkgPCAxMDsgaSsrKSB7Cgl0YWJsZVsnMCcgKyBpXSA9IGk7CiAgICB9CiAgICBmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7Cgl0YWJsZVsnQScgKyBpXSA9IGkrMTA7Cgl0YWJsZVsnYScgKyBpXSA9IGkrMTA7CiAgICB9CgogICAgLyogaW4gZm9ybSB7WFhYWFhYWFgtWFhYWC1YWFhYLVhYWFgtWFhYWFhYWFhYWFhYfSAqLwoKICAgIHAgPSAoQllURSAqKSBpZDsKCiAgICBzKys7CS8qIHNraXAgbGVhZGluZyBicmFjZSAgKi8KICAgIGZvciAoaSA9IDA7IGkgPCA0OyBpKyspIHsKCXBbMyAtIGldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gNDsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gMjsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJcFsxLWldID0gdGFibGVbKnNdPDw0IHwgdGFibGVbKihzKzEpXTsKCXMgKz0gMjsKICAgIH0KICAgIHAgKz0gMjsKICAgIHMrKzsJLyogc2tpcCAtICovCgogICAgLyogdGhlc2UgYXJlIGp1c3Qgc2VxdWVudGlhbCBieXRlcyAqLwogICAgZm9yIChpID0gMDsgaSA8IDI7IGkrKykgewoJKnArKyA9IHRhYmxlWypzXTw8NCB8IHRhYmxlWyoocysxKV07CglzICs9IDI7CiAgICB9CiAgICBzKys7CS8qIHNraXAgLSAqLwoKICAgIGZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKCSpwKysgPSB0YWJsZVsqc108PDQgfCB0YWJsZVsqKHMrMSldOwoJcyArPSAyOwogICAgfQoKICAgIHJldHVybiBTX09LOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDM3XQogKgogKiBEZXRlcm1pbmUgaWYgdGhlIE9TIHN1cHBvcnRzIGEgZ2l2ZW4gZmVhdHVyZS4KICoKICogUEFSQU1TCiAqICBkd0ZlYXR1cmUgW0ldIEZlYXR1cmUgcmVxdWVzdGVkICh1bmRvY3VtZW50ZWQpCiAqCiAqIFJFVFVSTlMKICogIFRSVUUgIElmIHRoZSBmZWF0dXJlIGlzIGF2YWlsYWJsZS4KICogIEZBTFNFIElmIHRoZSBmZWF0dXJlIGlzIG5vdCBhdmFpbGFibGUuCiAqLwpCT09MIFdJTkFQSSBJc09TKERXT1JEIGZlYXR1cmUpCnsKICAgIE9TVkVSU0lPTklORk9BIG9zdmk7CiAgICBEV09SRCBwbGF0Zm9ybSwgbWFqb3J2LCBtaW5vcnY7CgogICAgb3N2aS5kd09TVmVyc2lvbkluZm9TaXplID0gc2l6ZW9mKE9TVkVSU0lPTklORk9BKTsKICAgIGlmKCFHZXRWZXJzaW9uRXhBKCZvc3ZpKSkgIHsKICAgICAgICBFUlIoIkdldFZlcnNpb25FeCBmYWlsZWQiKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICB9CgogICAgbWFqb3J2ID0gb3N2aS5kd01ham9yVmVyc2lvbjsKICAgIG1pbm9ydiA9IG9zdmkuZHdNaW5vclZlcnNpb247CiAgICBwbGF0Zm9ybSA9IG9zdmkuZHdQbGF0Zm9ybUlkOwoKI2RlZmluZSBJU09TX1JFVFVSTih4KSBcCiAgICBUUkFDRSgiKDB4JWx4KSByZXQ9JWRcbiIsZmVhdHVyZSwoeCkpOyBcCiAgICByZXR1cm4gKHgpOwoKICAgIHN3aXRjaChmZWF0dXJlKSAgewogICAgY2FzZSBPU19XSU4zMlNPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMycwogICAgICAgICAgICAgICAgIHx8IHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTKQogICAgY2FzZSBPU19OVDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQpCiAgICBjYXNlIE9TX1dJTjk1T1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTKQogICAgY2FzZSBPU19OVDRPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA0KQogICAgY2FzZSBPU19XSU4yMDAwT1JHUkVBVEVSX0FMVDoKICAgIGNhc2UgT1NfV0lOMjAwME9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUpCiAgICBjYXNlIE9TX1dJTjk4T1JHUkVBVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9XSU5ET1dTICYmIG1pbm9ydiA+PSAxMCkKICAgIGNhc2UgT1NfV0lOOThfR09MRDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPT0gMTApCiAgICBjYXNlIE9TX1dJTjIwMDBQUk86CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1KQogICAgY2FzZSBPU19XSU4yMDAwU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwQURWU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19XSU4yMDAwREFUQUNFTlRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgKG1pbm9ydiA9PSAwIHx8IG1pbm9ydiA9PSAxKSkKICAgIGNhc2UgT1NfV0lOMjAwMFRFUk1JTkFMOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiAobWlub3J2ID09IDAgfHwgbWlub3J2ID09IDEpKQogICAgY2FzZSBPU19FTUJFRERFRDoKICAgICAgICBGSVhNRSgiKE9TX0VNQkVEREVEKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfVEVSTUlOQUxDTElFTlQ6CiAgICAgICAgRklYTUUoIihPU19URVJNSU5BTENMSUVOVCkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX1RFUk1JTkFMUkVNT1RFQURNSU46CiAgICAgICAgRklYTUUoIihPU19URVJNSU5BTFJFTU9URUFETUlOKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfV0lOOTVfR09MRDoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfV0lORE9XUyAmJiBtaW5vcnYgPT0gMCkKICAgIGNhc2UgT1NfTUVPUkdSRUFURVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX1dJTkRPV1MgJiYgbWlub3J2ID49IDkwKQogICAgY2FzZSBPU19YUE9SR1JFQVRFUjoKICAgICAgICBJU09TX1JFVFVSTihwbGF0Zm9ybSA9PSBWRVJfUExBVEZPUk1fV0lOMzJfTlQgJiYgbWFqb3J2ID49IDUgJiYgbWlub3J2ID49IDEpCiAgICBjYXNlIE9TX0hPTUU6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UICYmIG1ham9ydiA+PSA1ICYmIG1pbm9ydiA+PSAxKQogICAgY2FzZSBPU19QUk9GRVNTSU9OQUw6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19EQVRBQ0VOVEVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfQURWU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfVEVSTUlOQUxTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19QRVJTT05BTFRFUk1JTkFMU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCAmJiBtaW5vcnYgPj0gMSAmJiBtYWpvcnYgPj0gNSkKICAgIGNhc2UgT1NfRkFTVFVTRVJTV0lUQ0hJTkc6CiAgICAgICAgRklYTUUoIihPU19GQVNUVVNFUlNXSVRDSElORykgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGNhc2UgT1NfV0VMQ09NRUxPR09OVUk6CiAgICAgICAgRklYTUUoIihPU19XRUxDT01FTE9HT05VSSkgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gRkFMU0U7CiAgICBjYXNlIE9TX0RPTUFJTk1FTUJFUjoKICAgICAgICBGSVhNRSgiKE9TX0RPTUFJTk1FTUJFUikgV2hhdCBzaG91bGQgd2UgcmV0dXJuIGhlcmU/XG4iKTsKICAgICAgICByZXR1cm4gVFJVRTsKICAgIGNhc2UgT1NfQU5ZU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfV09XNjQzMjoKICAgICAgICBGSVhNRSgiKE9TX1dPVzY0MzIpIFNob3VsZCB3ZSBjaGVjayB0aGlzP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19XRUJTRVJWRVI6CiAgICAgICAgSVNPU19SRVRVUk4ocGxhdGZvcm0gPT0gVkVSX1BMQVRGT1JNX1dJTjMyX05UKQogICAgY2FzZSBPU19TTUFMTEJVU0lORVNTU0VSVkVSOgogICAgICAgIElTT1NfUkVUVVJOKHBsYXRmb3JtID09IFZFUl9QTEFURk9STV9XSU4zMl9OVCkKICAgIGNhc2UgT1NfVEFCTEVUUEM6CiAgICAgICAgRklYTUUoIihPU19UQUJMRVBDKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfU0VSVkVSQURNSU5VSToKICAgICAgICBGSVhNRSgiKE9TX1NFUlZFUkFETUlOVUkpIFdoYXQgc2hvdWxkIHdlIHJldHVybiBoZXJlP1xuIik7CiAgICAgICAgcmV0dXJuIEZBTFNFOwogICAgY2FzZSBPU19NRURJQUNFTlRFUjoKICAgICAgICBGSVhNRSgiKE9TX01FRElBQ0VOVEVSKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIGNhc2UgT1NfQVBQTElBTkNFOgogICAgICAgIEZJWE1FKCIoT1NfQVBQTElBTkNFKSBXaGF0IHNob3VsZCB3ZSByZXR1cm4gaGVyZT9cbiIpOwogICAgICAgIHJldHVybiBGQUxTRTsKICAgIH0KCiN1bmRlZiBJU09TX1JFVFVSTgoKICAgIFdBUk4oIigweCVseCkgdW5rbm93biBwYXJhbWV0ZXJcbiIsZmVhdHVyZSk7CgogICAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS40MzldCiAqLwpIUkVTVUxUIFdJTkFQSSBTSExvYWRSZWdVSVN0cmluZ1coSEtFWSBoa2V5LCBMUENXU1RSIHZhbHVlLCBMUFdTVFIgYnVmLCBEV09SRCBzaXplKQp7CiAgICBEV09SRCB0eXBlLCBzeiA9IHNpemU7CgogICAgaWYoUmVnUXVlcnlWYWx1ZUV4Vyhoa2V5LCB2YWx1ZSwgTlVMTCwgJnR5cGUsIChMUEJZVEUpYnVmLCAmc3opICE9IEVSUk9SX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIEVfRkFJTDsKCiAgICByZXR1cm4gU0hMb2FkSW5kaXJlY3RTdHJpbmcoYnVmLCBidWYsIHNpemUsIE5VTEwpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBAICBbU0hMV0FQSS40NzhdCiAqCiAqIENhbGwgSUlucHV0T2JqZWN0X1RyYW5zbGF0ZUFjY2VsZXJhdG9ySU8oKSBvbiBhbiBvYmplY3QuCiAqCiAqIFBBUkFNUwogKiAgbHBVbmtub3duIFtJXSBPYmplY3Qgc3VwcG9ydGluZyB0aGUgSUlucHV0T2JqZWN0IGludGVyZmFjZS4KICogIGxwTXNnICAgICBbSV0gS2V5IG1lc3NhZ2UgdG8gYmUgcHJvY2Vzc2VkLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0lOVkFMSURBUkcgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9UcmFuc2xhdGVBY2NlbGVyYXRvcklPKElVbmtub3duICpscFVua25vd24sIExQTVNHIGxwTXNnKQp7CiAgSUlucHV0T2JqZWN0KiBscElucHV0ID0gTlVMTDsKICBIUkVTVUxUIGhSZXQgPSBFX0lOVkFMSURBUkc7CgogIFRSQUNFKCIoJXAsJXApXG4iLCBscFVua25vd24sIGxwTXNnKTsKICBpZiAobHBVbmtub3duKQogIHsKICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUlucHV0T2JqZWN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkKiopJmxwSW5wdXQpOwogICAgaWYgKFNVQ0NFRURFRChoUmV0KSAmJiBscElucHV0KQogICAgewogICAgICBoUmV0ID0gSUlucHV0T2JqZWN0X1RyYW5zbGF0ZUFjY2VsZXJhdG9ySU8obHBJbnB1dCwgbHBNc2cpOwogICAgICBJSW5wdXRPYmplY3RfUmVsZWFzZShscElucHV0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEAgIFtTSExXQVBJLjQ4MV0KICoKICogQ2FsbCBJSW5wdXRPYmplY3RfSGFzRm9jdXNJTygpIG9uIGFuIG9iamVjdC4KICoKICogUEFSQU1TCiAqICBscFVua25vd24gW0ldIE9iamVjdCBzdXBwb3J0aW5nIHRoZSBJSW5wdXRPYmplY3QgaW50ZXJmYWNlLgogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLCBpZiBscFVua25vd24gaXMgYW4gSUlucHV0T2JqZWN0IG9iamVjdCBhbmQgaGFzIHRoZSBmb2N1cywKICogICAgICAgICAgIG9yIFNfRkFMU0Ugb3RoZXJ3aXNlLgogKiAgRmFpbHVyZTogQW4gSFJFU1VMVCBlcnJvciBjb2RlLCBvciBFX0lOVkFMSURBUkcgaWYgbHBVbmtub3duIGlzIE5VTEwuCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9IYXNGb2N1c0lPKElVbmtub3duICpscFVua25vd24pCnsKICBJSW5wdXRPYmplY3QqIGxwSW5wdXQgPSBOVUxMOwogIEhSRVNVTFQgaFJldCA9IEVfSU5WQUxJREFSRzsKCiAgVFJBQ0UoIiglcClcbiIsIGxwVW5rbm93bik7CiAgaWYgKGxwVW5rbm93bikKICB7CiAgICBoUmV0ID0gSVVua25vd25fUXVlcnlJbnRlcmZhY2UobHBVbmtub3duLCAmSUlEX0lJbnB1dE9iamVjdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCoqKSZscElucHV0KTsKICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgbHBJbnB1dCkKICAgIHsKICAgICAgaFJldCA9IElJbnB1dE9iamVjdF9IYXNGb2N1c0lPKGxwSW5wdXQpOwogICAgICBJSW5wdXRPYmplY3RfUmVsZWFzZShscElucHV0KTsKICAgIH0KICB9CiAgcmV0dXJuIGhSZXQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQ29sb3JSR0JUb0hMUwlbU0hMV0FQSS5AXQogKgogKiBDb252ZXJ0IGFuIHJnYiBDT0xPUlJFRiBpbnRvIHRoZSBobHMgY29sb3Igc3BhY2UuCiAqCiAqIFBBUkFNUwogKiAgY1JHQiAgICAgICAgIFtJXSBTb3VyY2UgcmdiIHZhbHVlCiAqICBwd0h1ZSAgICAgICAgW09dIERlc3RpbmF0aW9uIGZvciBjb252ZXJ0ZWQgaHVlCiAqICBwd0x1bWluYW5jZSAgW09dIERlc3RpbmF0aW9uIGZvciBjb252ZXJ0ZWQgbHVtaW5hbmNlCiAqICBwd1NhdHVyYXRpb24gW09dIERlc3RpbmF0aW9uIGZvciBjb252ZXJ0ZWQgc2F0dXJhdGlvbgogKgogKiBSRVRVUk5TCiAqICBOb3RoaW5nLiBwd0h1ZSwgcHdMdW1pbmFuY2UgYW5kIHB3U2F0dXJhdGlvbiBhcmUgc2V0IHRvIHRoZSBjb252ZXJ0ZWQKICogIHZhbHVlcy4KICoKICogTk9URVMKICogIE91dHB1dCBITFMgdmFsdWVzIGFyZSBjb25zdHJhaW5lZCB0byB0aGUgcmFuZ2UgKDAuLjI0MCkuCiAqICBGb3IgQWNocm9tYXRpYyBjb252ZXJzaW9ucywgSHVlIGlzIHNldCB0byAxNjAuCiAqLwpWT0lEIFdJTkFQSSBDb2xvclJHQlRvSExTKENPTE9SUkVGIGNSR0IsIExQV09SRCBwd0h1ZSwKCQkJICBMUFdPUkQgcHdMdW1pbmFuY2UsIExQV09SRCBwd1NhdHVyYXRpb24pCnsKICBpbnQgd1IsIHdHLCB3Qiwgd01heCwgd01pbiwgd0h1ZSwgd0x1bWlub3NpdHksIHdTYXR1cmF0aW9uOwoKICBUUkFDRSgiKCUwOGx4LCVwLCVwLCVwKVxuIiwgY1JHQiwgcHdIdWUsIHB3THVtaW5hbmNlLCBwd1NhdHVyYXRpb24pOwoKICB3UiA9IEdldFJWYWx1ZShjUkdCKTsKICB3RyA9IEdldEdWYWx1ZShjUkdCKTsKICB3QiA9IEdldEJWYWx1ZShjUkdCKTsKCiAgd01heCA9IG1heCh3UiwgbWF4KHdHLCB3QikpOwogIHdNaW4gPSBtaW4od1IsIG1pbih3Rywgd0IpKTsKCiAgLyogTHVtaW5vc2l0eSAqLwogIHdMdW1pbm9zaXR5ID0gKCh3TWF4ICsgd01pbikgKiAyNDAgKyAyNTUpIC8gNTEwOwoKICBpZiAod01heCA9PSB3TWluKQogIHsKICAgIC8qIEFjaHJvbWF0aWMgY2FzZSAqLwogICAgd1NhdHVyYXRpb24gPSAwOwogICAgLyogSHVlIGlzIG5vdyB1bnJlcHJlc2VudGFibGUsIGJ1dCB0aGlzIGlzIHdoYXQgbmF0aXZlIHJldHVybnMuLi4gKi8KICAgIHdIdWUgPSAxNjA7CiAgfQogIGVsc2UKICB7CiAgICAvKiBDaHJvbWF0aWMgY2FzZSAqLwogICAgaW50IHdEZWx0YSA9IHdNYXggLSB3TWluLCB3Uk5vcm0sIHdHTm9ybSwgd0JOb3JtOwoKICAgIC8qIFNhdHVyYXRpb24gKi8KICAgIGlmICh3THVtaW5vc2l0eSA8PSAxMjApCiAgICAgIHdTYXR1cmF0aW9uID0gKCh3TWF4ICsgd01pbikvMiArIHdEZWx0YSAqIDI0MCkgLyAod01heCArIHdNaW4pOwogICAgZWxzZQogICAgICB3U2F0dXJhdGlvbiA9ICgoNTEwIC0gd01heCAtIHdNaW4pLzIgKyB3RGVsdGEgKiAyNDApIC8gKDUxMCAtIHdNYXggLSB3TWluKTsKCiAgICAvKiBIdWUgKi8KICAgIHdSTm9ybSA9ICh3RGVsdGEvMiArIHdNYXggKiA0MCAtIHdSICogNDApIC8gd0RlbHRhOwogICAgd0dOb3JtID0gKHdEZWx0YS8yICsgd01heCAqIDQwIC0gd0cgKiA0MCkgLyB3RGVsdGE7CiAgICB3Qk5vcm0gPSAod0RlbHRhLzIgKyB3TWF4ICogNDAgLSB3QiAqIDQwKSAvIHdEZWx0YTsKCiAgICBpZiAod1IgPT0gd01heCkKICAgICAgd0h1ZSA9IHdCTm9ybSAtIHdHTm9ybTsKICAgIGVsc2UgaWYgKHdHID09IHdNYXgpCiAgICAgIHdIdWUgPSA4MCArIHdSTm9ybSAtIHdCTm9ybTsKICAgIGVsc2UKICAgICAgd0h1ZSA9IDE2MCArIHdHTm9ybSAtIHdSTm9ybTsKICAgIGlmICh3SHVlIDwgMCkKICAgICAgd0h1ZSArPSAyNDA7CiAgICBlbHNlIGlmICh3SHVlID4gMjQwKQogICAgICB3SHVlIC09IDI0MDsKICB9CiAgaWYgKHB3SHVlKQogICAgKnB3SHVlID0gd0h1ZTsKICBpZiAocHdMdW1pbmFuY2UpCiAgICAqcHdMdW1pbmFuY2UgPSB3THVtaW5vc2l0eTsKICBpZiAocHdTYXR1cmF0aW9uKQogICAgKnB3U2F0dXJhdGlvbiA9IHdTYXR1cmF0aW9uOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNIQ3JlYXRlU2hlbGxQYWxldHRlCVtTSExXQVBJLkBdCiAqLwpIUEFMRVRURSBXSU5BUEkgU0hDcmVhdGVTaGVsbFBhbGV0dGUoSERDIGhkYykKewoJRklYTUUoInN0dWJcbiIpOwoJcmV0dXJuIENyZWF0ZUhhbGZ0b25lUGFsZXR0ZShoZGMpOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKglTSEdldEludmVyc2VDTUFQIChTSExXQVBJLkApCiAqCiAqIEdldCBhbiBpbnZlcnNlIGNvbG9yIG1hcCB0YWJsZS4KICoKICogUEFSQU1TCiAqICBscENtYXAgIFtPXSBEZXN0aW5hdGlvbiBmb3IgY29sb3IgbWFwCiAqICBkd1NpemUgIFtJXSBTaXplIG9mIG1lbW9yeSBwb2ludGVkIHRvIGJ5IGxwQ21hcAogKgogKiBSRVRVUk5TCiAqICBTdWNjZXNzOiBTX09LLgogKiAgRmFpbHVyZTogRV9QT0lOVEVSLCAgICBJZiBscENtYXAgaXMgaW52YWxpZC4KICogICAgICAgICAgIEVfSU5WQUxJREFSRywgSWYgZHdGbGFncyBpcyBpbnZhbGlkCiAqICAgICAgICAgICBFX09VVE9GTUVNT1JZLCBJZiB0aGVyZSBpcyBubyBtZW1vcnkgYXZhaWxhYmxlCiAqCiAqIE5PVEVTCiAqICBkd1NpemUgbWF5IG9ubHkgYmUgQ01BUF9QVFJfU0laRSAoNCkgb3IgQ01BUF9TSVpFICg4MTkyKS4KICogIElmIGR3U2l6ZSA9IENNQVBfUFRSX1NJWkUsICpscENtYXAgaXMgc2V0IHRvIHRoZSBhZGRyZXNzIG9mIHRoaXMgRExMJ3MKICogIGludGVybmFsIENNYXAuCiAqICBJZiBkd1NpemUgPSBDTUFQX1NJWkUsIGxwQ21hcCBpcyBmaWxsZWQgd2l0aCBhIGNvcHkgb2YgdGhlIGRhdGEgZnJvbQogKiAgdGhpcyBETEwncyBpbnRlcm5hbCBDTWFwLgogKi8KSFJFU1VMVCBXSU5BUEkgU0hHZXRJbnZlcnNlQ01BUChMUERXT1JEIGRlc3QsIERXT1JEIGR3U2l6ZSkKewogICAgaWYgKGR3U2l6ZSA9PSA0KSB7CglGSVhNRSgiIC0gcmV0dXJuaW5nIGJvZ3VzIGFkZHJlc3MgZm9yIFNIR2V0SW52ZXJzZUNNQVBcbiIpOwoJKmRlc3QgPSAoRFdPUkQpMHhhYmJhMTI0OTsKCXJldHVybiAwOwogICAgfQogICAgRklYTUUoIiglcCwgJSNseCkgc3R1YlxuIiwgZGVzdCwgZHdTaXplKTsKICAgIHJldHVybiAwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIFNISXNMb3dNZW1vcnlNYWNoaW5lCVtTSExXQVBJLkBdCiAqCiAqIERldGVybWluZSBpZiB0aGUgY3VycmVudCBjb21wdXRlciBoYXMgbG93IG1lbW9yeS4KICoKICogUEFSQU1TCiAqICB4IFtJXSBGSVhNRQogKgogKiBSRVRVUk5TCiAqICBUUlVFIGlmIHRoZSB1c2VycyBtYWNoaW5lIGhhcyAxNiBNZWdhYnl0ZXMgb2YgbWVtb3J5IG9yIGxlc3MsCiAqICBGQUxTRSBvdGhlcndpc2UuCiAqLwpCT09MIFdJTkFQSSBTSElzTG93TWVtb3J5TWFjaGluZSAoRFdPUkQgeCkKewogIEZJWE1FKCIoMHglMDhseCkgc3R1YlxuIiwgeCk7CiAgcmV0dXJuIEZBTFNFOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEdldE1lbnVQb3NGcm9tSUQJW1NITFdBUEkuQF0KICoKICogUmV0dXJuIHRoZSBwb3NpdGlvbiBvZiBhIG1lbnUgaXRlbSBmcm9tIGl0cyBJZC4KICoKICogUEFSQU1TCiAqICAgaE1lbnUgW0ldIE1lbnUgY29udGFpbmluZyB0aGUgaXRlbQogKiAgIHdJRCAgIFtJXSBJZCBvZiB0aGUgbWVudSBpdGVtCiAqCiAqIFJFVFVSTlMKICogIFN1Y2Nlc3M6IFRoZSBpbmRleCBvZiB0aGUgbWVudSBpdGVtIGluIGhNZW51LgogKiAgRmFpbHVyZTogLTEsIElmIHRoZSBpdGVtIGlzIG5vdCBmb3VuZC4KICovCklOVCBXSU5BUEkgR2V0TWVudVBvc0Zyb21JRChITUVOVSBoTWVudSwgVUlOVCB3SUQpCnsKIE1FTlVJVEVNSU5GT1cgbWk7CiBJTlQgbkNvdW50ID0gR2V0TWVudUl0ZW1Db3VudChoTWVudSksIG5JdGVyID0gMDsKCiB3aGlsZSAobkl0ZXIgPCBuQ291bnQpCiB7CiAgIG1pLmNiU2l6ZSA9IHNpemVvZihtaSk7CiAgIG1pLmZNYXNrID0gTUlJTV9JRDsKICAgaWYgKEdldE1lbnVJdGVtSW5mb1coaE1lbnUsIG5JdGVyLCBUUlVFLCAmbWkpICYmIG1pLndJRCA9PSB3SUQpCiAgICAgcmV0dXJuIG5JdGVyOwogICBuSXRlcisrOwogfQogcmV0dXJuIC0xOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuMTc5XQogKgogKiBTYW1lIGFzIFNITFdBUEkuR2V0TWVudVBvc0Zyb21JRAogKi8KRFdPUkQgV0lOQVBJIFNITWVudUluZGV4RnJvbUlEKEhNRU5VIGhNZW51LCBVSU5UIHVJRCkKewogICAgcmV0dXJuIEdldE1lbnVQb3NGcm9tSUQoaE1lbnUsIHVJRCk7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgIEAJW1NITFdBUEkuNDQ4XQogKi8KVk9JRCBXSU5BUEkgRml4U2xhc2hlc0FuZENvbG9uVyhMUFdTVFIgbHB3c3RyKQp7CiAgICB3aGlsZSAoKmxwd3N0cikKICAgIHsKICAgICAgICBpZiAoKmxwd3N0ciA9PSAnLycpCiAgICAgICAgICAgICpscHdzdHIgPSAnXFwnOwogICAgICAgIGxwd3N0cisrOwogICAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgICBACVtTSExXQVBJLjQ2MV0KICovCkRXT1JEIFdJTkFQSSBTSEdldEFwcENvbXBhdEZsYWdzKERXT1JEIGR3VW5rbm93bikKewogIEZJWE1FKCIoMHglMDhseCkgc3R1YlxuIiwgZHdVbmtub3duKTsKICByZXR1cm4gMDsKfQoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgQAlbU0hMV0FQSS41NDldCiAqLwpIUkVTVUxUIFdJTkFQSSBTSENvQ3JlYXRlSW5zdGFuY2VBQyhSRUZDTFNJRCByY2xzaWQsIExQVU5LTk9XTiBwVW5rT3V0ZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIERXT1JEIGR3Q2xzQ29udGV4dCwgUkVGSUlEIGlpZCwgTFBWT0lEICpwcHYpCnsKICAgIHJldHVybiBDb0NyZWF0ZUluc3RhbmNlKHJjbHNpZCwgcFVua091dGVyLCBkd0Nsc0NvbnRleHQsIGlpZCwgcHB2KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogU0hTa2lwSnVuY3Rpb24JW1NITFdBUEkuQF0KICoKICogRGV0ZXJtaW5lIGlmIGEgYmluZCBjb250ZXh0IGNhbiBiZSBib3VuZCB0byBhbiBvYmplY3QKICoKICogUEFSQU1TCiAqICBwYmMgICAgW0ldIEJpbmQgY29udGV4dCB0byBjaGVjawogKiAgcGNsc2lkIFtJXSBDTFNJRCBvZiBvYmplY3QgdG8gYmUgYm91bmQgdG8KICoKICogUkVUVVJOUwogKiAgVFJVRTogSWYgaXQgaXMgc2FmZSB0byBiaW5kCiAqICBGQUxTRTogSWYgcGJjIGlzIGludmFsaWQgb3IgYmluZGluZyB3b3VsZCBub3QgYmUgc2FmZQogKgogKi8KQk9PTCBXSU5BUEkgU0hTa2lwSnVuY3Rpb24oSUJpbmRDdHggKnBiYywgY29uc3QgQ0xTSUQgKnBjbHNpZCkKewogIHN0YXRpYyBjb25zdCBXQ0hBUiBzelNraXBCaW5kaW5nW10gPSB7ICdTJywnaycsJ2knLCdwJywnICcsCiAgICAnQicsJ2knLCduJywnZCcsJ2knLCduJywnZycsJyAnLCdDJywnTCcsJ1MnLCdJJywnRCcsJ1wwJyB9OwogIEJPT0wgYlJldCA9IEZBTFNFOwoKICBpZiAocGJjKQogIHsKICAgIElVbmtub3duKiBscFVuazsKCiAgICBpZiAoU1VDQ0VFREVEKElCaW5kQ3R4X0dldE9iamVjdFBhcmFtKHBiYywgKExQT0xFU1RSKXN6U2tpcEJpbmRpbmcsICZscFVuaykpKQogICAgewogICAgICBDTFNJRCBjbHNpZDsKCiAgICAgIGlmIChTVUNDRUVERUQoSVVua25vd25fR2V0Q2xhc3NJRChscFVuaywgJmNsc2lkKSkgJiYKICAgICAgICAgIElzRXF1YWxHVUlEKHBjbHNpZCwgJmNsc2lkKSkKICAgICAgICBiUmV0ID0gVFJVRTsKCiAgICAgIElVbmtub3duX1JlbGVhc2UobHBVbmspOwogICAgfQogIH0KICByZXR1cm4gYlJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFNoZWxsS2V5IChTSExXQVBJLkApCiAqLwpEV09SRCBXSU5BUEkgU0hHZXRTaGVsbEtleShEV09SRCBhLCBEV09SRCBiLCBEV09SRCBjKQp7CiAgICBGSVhNRSgiKCVseCwgJWx4LCAlbHgpOiBzdHViXG4iLCBhLCBiLCBjKTsKICAgIHJldHVybiAweDUwOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoJCVNIUXVldWVVc2VyV29ya0l0ZW0gKFNITFdBUEkuQCkKICovCkhSRVNVTFQgV0lOQVBJIFNIUXVldWVVc2VyV29ya0l0ZW0oRFdPUkQgYSwgRFdPUkQgYiwgRFdPUkQgYywgRFdPUkQgZCwgRFdPUkQgZSwgRFdPUkQgZiwgRFdPUkQgZykKewogICAgRklYTUUoIiglbHgsICVseCwgJWx4LCAlbHgsICVseCwgJWx4LCAlbHgpOiBzdHViXG4iLCBhLCBiLCBjLCBkLCBlLCBmLCBnKTsKICAgIHJldHVybiBFX0ZBSUw7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgkJSVVua25vd25fT25Gb2N1c0NoYW5nZUlTIChTSExXQVBJLkApCiAqLwpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9PbkZvY3VzQ2hhbmdlSVMoTFBVTktOT1dOIGxwVW5rbm93biwgTFBVTktOT1dOIHBGb2N1c09iamVjdCwgQk9PTCBiRm9jdXMpCnsKICAgIElJbnB1dE9iamVjdFNpdGUgKnBJT1MgPSBOVUxMOwogICAgSFJFU1VMVCBoUmV0ID0gRV9JTlZBTElEQVJHOwoKICAgIFRSQUNFKCIoJXAsICVwLCAlcylcbiIsIGxwVW5rbm93biwgcEZvY3VzT2JqZWN0LCBiRm9jdXMgPyAiVFJVRSIgOiAiRkFMU0UiKTsKCiAgICBpZiAobHBVbmtub3duKQogICAgewogICAgICAgIGhSZXQgPSBJVW5rbm93bl9RdWVyeUludGVyZmFjZShscFVua25vd24sICZJSURfSUlucHV0T2JqZWN0U2l0ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKiopJnBJT1MpOwogICAgICAgIGlmIChTVUNDRUVERUQoaFJldCkgJiYgcElPUykKICAgICAgICB7CiAgICAgICAgICAgIGhSZXQgPSBJSW5wdXRPYmplY3RTaXRlX09uRm9jdXNDaGFuZ2VJUyhwSU9TLCBwRm9jdXNPYmplY3QsIGJGb2N1cyk7CiAgICAgICAgICAgIElJbnB1dE9iamVjdFNpdGVfUmVsZWFzZShwSU9TKTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gaFJldDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCQlTSEdldFZhbHVlVyAoU0hMV0FQSS5AKQogKi8KSFJFU1VMVCBXSU5BUEkgU0tHZXRWYWx1ZVcoRFdPUkQgYSwgTFBXU1RSIGIsIExQV1NUUiBjLCBEV09SRCBkLCBEV09SRCBlLCBEV09SRCBmKQp7CiAgICBGSVhNRSgiKCVseCwgJXMsICVzLCAlbHgsICVseCwgJWx4KTogc3R1YlxuIiwgYSwgZGVidWdzdHJfdyhiKSwgZGVidWdzdHJfdyhjKSwgZCwgZSwgZik7CiAgICByZXR1cm4gRV9GQUlMOwp9Cgp0eXBlZGVmIEhSRVNVTFQgKFdJTkFQSSAqRGxsR2V0VmVyc2lvbl9mdW5jKShETExWRVJTSU9OSU5GTyAqKTsKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgR2V0VUlWZXJzaW9uIChTSExXQVBJLjQ1MikKICovCkRXT1JEIFdJTkFQSSBHZXRVSVZlcnNpb24odm9pZCkKewogICAgc3RhdGljIERXT1JEIHZlcnNpb247CgogICAgaWYgKCF2ZXJzaW9uKQogICAgewogICAgICAgIERsbEdldFZlcnNpb25fZnVuYyBwRGxsR2V0VmVyc2lvbjsKICAgICAgICBITU9EVUxFIGRsbCA9IExvYWRMaWJyYXJ5QSgic2hlbGwzMi5kbGwiKTsKICAgICAgICBpZiAoIWRsbCkgcmV0dXJuIDA7CgogICAgICAgIHBEbGxHZXRWZXJzaW9uID0gKERsbEdldFZlcnNpb25fZnVuYylHZXRQcm9jQWRkcmVzcyhkbGwsICJEbGxHZXRWZXJzaW9uIik7CiAgICAgICAgaWYgKHBEbGxHZXRWZXJzaW9uKQogICAgICAgIHsKICAgICAgICAgICAgRExMVkVSU0lPTklORk8gZHZpOwogICAgICAgICAgICBkdmkuY2JTaXplID0gc2l6ZW9mKERMTFZFUlNJT05JTkZPKTsKICAgICAgICAgICAgaWYgKHBEbGxHZXRWZXJzaW9uKCZkdmkpID09IFNfT0spIHZlcnNpb24gPSBkdmkuZHdNYWpvclZlcnNpb247CiAgICAgICAgfQogICAgICAgIEZyZWVMaWJyYXJ5KCBkbGwgKTsKICAgICAgICBpZiAoIXZlcnNpb24pIHZlcnNpb24gPSAzOyAgLyogb2xkIHNoZWxsIGRsbHMgZG9uJ3QgaGF2ZSBEbGxHZXRWZXJzaW9uICovCiAgICB9CiAgICByZXR1cm4gdmVyc2lvbjsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqICAgICAgICAgICAgICBTaGVsbE1lc3NhZ2VCb3hXcmFwVyBbU0hMV0FQSS4zODhdCiAqCiAqIGxvYWRzIGEgc3RyaW5nIHJlc291cmNlIGZvciBhIG1vZHVsZSwgZGlzcGxheXMgdGhlIHN0cmluZyBpbiBhIAogKiBtZXNzYWdlIGJveCBhbmQgd3JpdGVzIGl0IGludG8gdGhlIGxvZ2ZpbGUKICoKICogUEFSQU1TCiAqICBtb2QgICAgICBbSV0gdGhlIG1vZHVsZSBjb250YWluaW5nIHRoZSBzdHJpbmcgcmVzb3VyY2UKICogIHVua25vd24xIFtJXSBGSVhNRQogKiAgdUlkICAgICAgW0ldIHRoZSBpZCBvZiB0aGUgc3RyaW5nIHJlc291cmNlCiAqICB0aXRsZSAgICBbSV0gdGhlIHRpdGxlIG9mIHRoZSBtZXNzYWdlIGJveAogKiAgdW5rbm93bjIgW0ldIEZJWE1FCiAqICBmaWxlbmFtZSBbSV0gbmFtZSBvZiB0aGUgbG9nZmlsZQogKgogKiBSRVRVUk5TCiAqICBGSVhNRQogKi8KQk9PTCBXSU5BUEkgU2hlbGxNZXNzYWdlQm94V3JhcFcoSE1PRFVMRSBtb2QsIERXT1JEIHVua25vd24xLCBVSU5UIHVJZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTFBDV1NUUiB0aXRsZSwgRFdPUkQgdW5rbm93bjIsIExQQ1dTVFIgZmlsZW5hbWUpCnsKICAgIEZJWE1FKCIlcCAlbHggJWQgJXMgJWx4ICVzXG4iLAogICAgICAgICAgbW9kLCB1bmtub3duMSwgdUlkLCBkZWJ1Z3N0cl93KHRpdGxlKSwgdW5rbm93bjIsIGRlYnVnc3RyX3coZmlsZW5hbWUpKTsKICAgIHJldHVybiBUUlVFOwp9CgpIUkVTVUxUIFdJTkFQSSBJVW5rbm93bl9RdWVyeVNlcnZpY2VFeGVjKElVbmtub3duICp1bmssIFJFRklJRCBzZXJ2aWNlLCBSRUZJSUQgY2xzaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRFdPUkQgeDEsIERXT1JEIHgyLCBEV09SRCB4Mywgdm9pZCAqKnBwdk91dCkKewogICAgRklYTUUoIiVwICVzICVzICUwOGx4ICUwOGx4ICUwOGx4ICVwXG4iLCB1bmssCiAgICAgICAgICBkZWJ1Z3N0cl9ndWlkKHNlcnZpY2UpLCBkZWJ1Z3N0cl9ndWlkKGNsc2lkKSwgeDEsIHgyLCB4MywgcHB2T3V0KTsKICAgIHJldHVybiBFX05PVElNUEw7Cn0KCkhSRVNVTFQgV0lOQVBJIElVbmtub3duX1Byb2ZmZXJTZXJ2aWNlKElVbmtub3duICp1bmssIHZvaWQgKngwLCB2b2lkICp4MSwgdm9pZCAqeDIpCnsKICAgIEZJWE1FKCIlcCAlcCAlcCAlcFxuIiwgdW5rLCB4MCwgeDEsIHgyKTsKICAgIHJldHVybiBFX05PVElNUEw7Cn0K